comparison test/dynload_plain/dynload_plain.c @ 308:7c6f19d42b31

dynload UTF-8 support for library paths: - added missing support to windows - added test code for all platforms to dynload_plain - doc update
author Tassilo Philipp
date Thu, 24 Oct 2019 23:19:20 +0200
parents f5577f6bf97a
children 5b1ff4c73194
comparison
equal deleted inserted replaced
307:d2c8ea3ef2ed 308:7c6f19d42b31
32 # include <io.h> 32 # include <io.h>
33 # define F_OK 0 33 # define F_OK 0
34 #else 34 #else
35 # include <unistd.h> 35 # include <unistd.h>
36 #endif 36 #endif
37
38
39 int strlen_utf8(const char *s)
40 {
41 int i=0, j=0;
42 while(s[i])
43 j += ((s[i++] & 0xc0) != 0x80);
44 return j;
45 }
37 46
38 47
39 int main(int argc, char* argv[]) 48 int main(int argc, char* argv[])
40 { 49 {
41 int r = 0, i; 50 int r = 0, i;
45 const char* path = NULL; 54 const char* path = NULL;
46 /* hacky/lazy list of some clib paths per platform - more/others, like version-suffixed ones */ 55 /* hacky/lazy list of some clib paths per platform - more/others, like version-suffixed ones */
47 /* can be specified in Makefile; this avoids trying to write portable directory traversal stuff */ 56 /* can be specified in Makefile; this avoids trying to write portable directory traversal stuff */
48 const char* clibs[] = { 57 const char* clibs[] = {
49 #if defined(DEF_C_DYLIB) 58 #if defined(DEF_C_DYLIB)
50 DEF_C_DYLIB, 59 DEF_C_DYLIB,
51 #endif 60 #endif
52 "/lib/libc.so", 61 "/lib/libc.so",
53 "/lib32/libc.so", 62 "/lib32/libc.so",
54 "/lib64/libc.so", 63 "/lib64/libc.so",
55 "/usr/lib/libc.so", 64 "/usr/lib/libc.so",
88 printf("printf at: %p\n", p); 97 printf("printf at: %p\n", p);
89 r += (p != NULL); 98 r += (p != NULL);
90 99
91 bs = dlGetLibraryPath(pLib, queriedPath, 200); 100 bs = dlGetLibraryPath(pLib, queriedPath, 200);
92 if(bs && bs <= 200) { 101 if(bs && bs <= 200) {
93 struct stat st0, st1; /* to check if same file */ 102 struct stat st0, st1; /* to check if same file */
94 int b; 103 int b, bs_;
95 printf("path of lib looked up via handle: %s\n", queriedPath); 104 printf("path of lib looked up via handle: %s\n", queriedPath);
96 b = (stat(path, &st0) != -1) && (stat(queriedPath, &st1) != -1); 105 b = (stat(path, &st0) != -1) && (stat(queriedPath, &st1) != -1);
97 printf("lib (inode:%d) and looked up lib (inode:%d) are same: %d\n", b?st0.st_ino:-1, b?st1.st_ino:-1, b && (st0.st_ino == st1.st_ino)); //@@@ on windows, inode numbers returned here are always 0 106 printf("lib (inode:%d) and looked up lib (inode:%d) are same: %d\n", b?st0.st_ino:-1, b?st1.st_ino:-1, b && (st0.st_ino == st1.st_ino)); //@@@ on windows, inode numbers returned here are always 0
98 r += b && (st0.st_ino == st1.st_ino); /* compare if same lib using inode */ 107 r += b && (st0.st_ino == st1.st_ino); /* compare if same lib using inode */
99 /*@@@ check if resolved path is absolute*/ 108 /*@@@ check if resolved path is absolute*/
100 109
101 /* check correct bufsize retval */ 110 /* check correct bufsize retval */
102 b = (bs == strlen(queriedPath) + 1); 111 b = (bs == strlen(queriedPath) + 1);
103 printf("looked up path's needed buffer size (%d) computed correctly: %d\n", bs, b); 112 printf("looked up path's needed buffer size (%d) computed correctly 1/2: %d\n", bs, b);
113 r += b;
114
115 /* check perfect fitting bufsize */
116 queriedPath[0] = 0;
117 bs_ = dlGetLibraryPath(pLib, queriedPath, bs);
118 b = (bs == bs_ && bs_ == strlen(queriedPath) + 1);
119 printf("looked up path's needed buffer size (%d) computed correctly 2/2: %d\n", bs_, b);
120 r += b;
121
122 /* check if dlGetLibraryPath returns size required if bufsize too small */
123 queriedPath[0] = 0;
124 bs_ = dlGetLibraryPath(pLib, queriedPath, 1); /* tiny max buffer size */
125 b = (bs == bs_ && strlen(queriedPath) == 0); /* nothing copied */
126 printf("path lookup size requirement (%d) correctly returned: %d\n", bs_, b);
104 r += b; 127 r += b;
105 } 128 }
106 else 129 else
107 printf("failed to query lib path using lib's handle\n"); 130 printf("failed to query lib path using lib's handle\n");
108 131
109 dlFreeLibrary(pLib); 132 dlFreeLibrary(pLib);
133
134 /* check if dlGetLibraryPath returns 0 when trying to lookup dummy */
135 bs = dlGetLibraryPath((DLLib*)1234, queriedPath, 200);
136 printf("path lookup failed as expected with bad lib handle: %d\n", bs == 0);
137 r += (bs == 0);
138
139 /* test UTF-8 path through dummy library that's created by this test's build */
140 {
141 static const char* pathU8 = "./dynload_plain_\xc3\x9f_test";
142 int nu8c, b;
143
144 //cp(pathU8, "/lib/libz.so.6");
145 pLib = dlLoadLibrary(pathU8); /* check if we can load a lib with a UTF-8 path */
146 printf("pLib (loaded w/ UTF-8 path %s) handle: %p\n", pathU8, pLib);
147 r += (p != NULL);
148
149 if(pLib) {
150 /* get UTF-8 path back */
151 bs = dlGetLibraryPath((DLLib*)pLib, queriedPath, 200);
152 if(bs && bs <= 200) {
153 nu8c = strlen_utf8(queriedPath); /* num of UTF-8 chars is as big as ... */
154 b = (bs > 0) && (nu8c == bs-2); /* ... buffer size minus 2 (b/c of one 2-byte UTF-8 char and "\0") */
155 printf("UTF-8 path of lib looked up via handle: %s\n", queriedPath);
156 printf("looked up UTF-8 path's needed buffer size (%d) for %d UTF-8 char string computed correctly: %d\n", bs, nu8c, b);
157 r += b;
158
159 dlFreeLibrary(pLib);
160 }
161 else
162 printf("failed to query UTF-8 lib path using lib's handle\n");
163 }
164 }
110 } 165 }
111 else 166 else
112 printf("unable to open library %s\n", path); 167 printf("unable to open library %s\n", path);
113 168
114 169
143 if(pLib) { /* need to lookup by name again, first */ 198 if(pLib) { /* need to lookup by name again, first */
144 p = dlFindSymbol(pLib, "printf"); 199 p = dlFindSymbol(pLib, "printf");
145 name = dlSymsNameFromValue(pSyms, p); 200 name = dlSymsNameFromValue(pSyms, p);
146 printf("printf symbol name by its own address (%p): %s\n", p, name?name:""); 201 printf("printf symbol name by its own address (%p): %s\n", p, name?name:"");
147 if(name) { 202 if(name) {
148 if(strcmp(name, "printf") == 0) 203 if(strcmp(name, "printf") == 0)
149 ++r; 204 ++r;
150 else { 205 else {
151 /* Symbol name returned might be an "alias". In that case, check address again (full lookup to be sure). */ 206 /* Symbol name returned might be an "alias". In that case, check address again (full lookup to be sure). */
152 void* p0 = dlFindSymbol(pLib, name); 207 void* p0 = dlFindSymbol(pLib, name);
153 printf("lookup by address returned different name (%s), which is alias of printf: %d\n", name, (p==p0)); 208 printf("lookup by address returned different name (%s), which is alias of printf: %d\n", name, (p==p0));
154 r += (p == p0); 209 r += (p == p0);
155 } 210 }
156 } 211 }
157 dlFreeLibrary(pLib); 212 dlFreeLibrary(pLib);
158 } 213 }
159 214
160 dlSymsCleanup(pSyms); 215 dlSymsCleanup(pSyms);
161 } 216 }
162 else 217 else
163 printf("dlSymsInit failed\n"); 218 printf("dlSymsInit failed\n");
164 } 219 }
165 220
166 /* Check final score of right ones to see if all worked */ 221 /* Check final score of right ones to see if all worked */
167 r = (r == 10); 222 r = (r == 15);
168 printf("result: dynload_plain: %d\n", r); 223 printf("result: dynload_plain: %d\n", r);
169 return !r; 224 return !r;
170 } 225 }
171 226