|
|
1.1 root 1: /* wraptest.c */
2:
3: /* Verification of cross-platform development wrappers */
4:
5: /* $Id: wraptest.c,v 1.44 2006/04/21 02:47:43 deuce Exp $ */
6:
7: #include <time.h> /* ctime */
8:
9: #include "genwrap.h"
10: #include "conwrap.h"
11: #include "dirwrap.h"
12: #include "filewrap.h"
13: #include "sockwrap.h"
14: #include "threadwrap.h"
15: #include "xpbeep.h"
16: #include "xpendian.h"
17:
18: #define LOCK_FNAME "test.fil"
19: #define LOCK_OFFSET 0
20: #define LOCK_LEN 4
21:
22: static void getkey(void);
23: static void sem_test_thread(void* arg);
24: static void sem_test_thread_block(void* arg);
25: static void sleep_test_thread(void* arg);
26: static void sopen_test_thread(void* arg);
27: static void sopen_child_thread(void* arg);
28: static void lock_test_thread(void* arg);
29:
30:
31: typedef struct {
32: sem_t parent_sem;
33: sem_t child_sem;
34: } thread_data_t;
35:
36: int main()
37: {
38: char str[128];
39: char compiler[128];
40: char fpath[MAX_PATH+1];
41: char* path = ".";
42: char* glob_pattern = "*wrap*";
43: int i;
44: int ch;
45: uint u;
46: time_t t;
47: glob_t g;
48: DIR* dir;
49: DIRENT* dirent;
50: thread_data_t thread_data;
51: int fd;
52: int fd2;
53: int canrelock=0;
54: clock_t ticks;
55:
56: /* Show platform details */
57: DESCRIBE_COMPILER(compiler);
58: printf("%-15s: %s\n","Platform",PLATFORM_DESC);
59: printf("%-15s: %s\n","Version",os_version(str));
60: printf("%-15s: %s\n","Compiler" ,compiler);
61: printf("%-15s: %d\n","Random Number",xp_random(1000));
62:
63: for(i=0;i<3;i++) {
64: if(_beginthread(
65: sopen_child_thread /* entry point */
66: ,0 /* stack size (0=auto) */
67: ,(void*)i /* data */
68: )==(unsigned long)-1)
69: printf("_beginthread failed\n");
70: else
71: SLEEP(1);
72: }
73: printf("Waiting for all sopen_child_threads to close...\n");
74: SLEEP(5000); /* wait for all threads to quit */
75:
76: /* Exclusive sopen test */
77: printf("\nsopen() test\n");
78: if((fd=sopen(LOCK_FNAME,O_RDWR|O_CREAT,SH_DENYRW,S_IREAD|S_IWRITE))==-1) {
79: perror(LOCK_FNAME);
80: return(errno);
81: }
82: printf("%s is opened with an exclusive (read/write) lock\n",LOCK_FNAME);
83: getkey();
84: if(_beginthread(
85: sopen_test_thread /* entry point */
86: ,0 /* stack size (0=auto) */
87: ,NULL /* data */
88: )==(unsigned long)-1)
89: printf("_beginthread failed\n");
90: else
91: SLEEP(1000);
92: close(fd);
93:
94: /* sopen()/lock test */
95: printf("\nlock() test\n");
96: if((fd=sopen(LOCK_FNAME,O_RDWR|O_CREAT,SH_DENYNO,S_IREAD|S_IWRITE))==-1) {
97: perror(LOCK_FNAME);
98: return(errno);
99: }
100: write(fd,"lock testing\n",LOCK_LEN);
101: if(lock(fd,LOCK_OFFSET,LOCK_LEN)==0)
102: printf("lock() succeeds\n");
103: else
104: printf("!FAILURE: lock() non-functional (or file already locked)\n");
105: if(lock(fd,LOCK_OFFSET,LOCK_LEN)==0) {
106: printf("!FAILURE: Subsequent lock of region was allowed (will skip some tests)\n");
107: canrelock=1;
108: }
109:
110: if(_beginthread(
111: lock_test_thread /* entry point */
112: ,0 /* stack size (0=auto) */
113: ,NULL /* data */
114: )==(unsigned long)-1)
115: printf("_beginthread failed\n");
116: else
117: SLEEP(1000);
118: if(canrelock)
119: printf("?? Skipping some tests due to inability to detect own locks\n");
120: else {
121: if(lock(fd,LOCK_OFFSET,LOCK_LEN))
122: printf("Locks in first thread survive open()/close() in other thread\n");
123: else
124: printf("!FAILURE: lock() in first thread lost by open()/close() in other thread\n");
125: if(lock(fd,LOCK_OFFSET+LOCK_LEN+1,LOCK_LEN))
126: printf("!FAILURE: file locking\n");
127: else
128: printf("Record locking\n");
129: }
130: if((fd2=sopen(LOCK_FNAME,O_RDWR,SH_DENYRW))==-1) {
131: printf("Cannot reopen SH_DENYRW while lock is held\n");
132: close(fd2);
133: }
134: else {
135: printf("!FAILURE: can reopen SH_DENYRW while lock is held\n");
136: }
137: if(unlock(fd,LOCK_OFFSET,LOCK_LEN))
138: printf("!FAILURE: unlock() non-functional\n");
139: if(lock(fd,LOCK_OFFSET+LOCK_LEN+1,LOCK_LEN))
140: printf("Cannot re-lock after non-overlapping unlock()\n");
141: else
142: printf("!FAILURE: can re-lock after non-overlappping unlock()\n");
143: if(lock(fd,LOCK_OFFSET,LOCK_LEN))
144: printf("!FAILURE: cannot re-lock unlocked area\n");
145: close(fd);
146:
147: /* getch test */
148: printf("\ngetch() test (ESC to continue)\n");
149: do {
150: ch=getch();
151: printf("getch() returned %d\n",ch);
152: } while(ch!=ESC);
153:
154: /* kbhit test */
155: printf("\nkbhit() test (any key to continue)\n");
156: while(!kbhit()) {
157: printf(".");
158: fflush(stdout);
159: SLEEP(500);
160: }
161: getch(); /* remove character from keyboard buffer */
162:
163: /* BEEP test */
164: printf("\nBEEP() test\n");
165: getkey();
166: for(i=750;i>250;i-=5)
167: BEEP(i,15);
168: for(;i<1000;i+=5)
169: BEEP(i,15);
170:
171: /* SLEEP test */
172: printf("\nSLEEP(5 second) test\n");
173: getkey();
174: t=time(NULL);
175: printf("sleeping... ");
176: fflush(stdout);
177: ticks=msclock();
178: SLEEP(5000);
179: printf("slept %ld seconds (%ld according to msclock)\n",time(NULL)-t,(msclock()-ticks)/MSCLOCKS_PER_SEC);
180:
181: /* Thread SLEEP test */
182: printf("\nThread SLEEP(5 second) test\n");
183: getkey();
184: i=0;
185: if(_beginthread(
186: sleep_test_thread /* entry point */
187: ,0 /* stack size (0=auto) */
188: ,&i /* data */
189: )==(unsigned long)-1)
190: printf("_beginthread failed\n");
191: else {
192: SLEEP(1); /* yield to child thread */
193: while(i==0) {
194: printf(".");
195: fflush(stdout);
196: SLEEP(1000);
197: }
198: }
199:
200: /* glob test */
201: printf("\nglob(%s) test\n",glob_pattern);
202: getkey();
203: i=glob(glob_pattern,GLOB_MARK,NULL,&g);
204: if(i==0) {
205: for(u=0;u<g.gl_pathc;u++)
206: printf("%s\n",g.gl_pathv[u]);
207: globfree(&g);
208: } else
209: printf("glob(%s) returned %d\n",glob_pattern,i);
210:
211: /* opendir (and other directory functions) test */
212: printf("\nopendir(%s) test\n",path);
213: getkey();
214: printf("\nDirectory of %s\n\n",FULLPATH(fpath,path,sizeof(fpath)));
215: dir=opendir(path);
216: while(dir!=NULL && (dirent=readdir(dir))!=NULL) {
217: t=fdate(dirent->d_name);
218: printf("%.24s %10lu %06o %s%c\n"
219: ,ctime(&t)
220: ,flength(dirent->d_name)
221: ,getfattr(dirent->d_name)
222: ,dirent->d_name
223: ,isdir(dirent->d_name) ? '/':0
224: );
225: }
226: if(dir!=NULL)
227: closedir(dir);
228: printf("\nFree disk space: %lu kbytes\n",getfreediskspace(path,1024));
229:
230: /* Thread (and inter-process communication) test */
231: printf("\nSemaphore test\n");
232: getkey();
233: if(sem_init(&thread_data.parent_sem
234: ,0 /* shared between processes */
235: ,0 /* initial count */
236: )) {
237: printf("sem_init failed\n");
238: }
239: if(sem_init(&thread_data.child_sem
240: ,0 /* shared between processes */
241: ,0 /* initial count */
242: )) {
243: printf("sem_init failed\n");
244: }
245: if(_beginthread(
246: sem_test_thread /* entry point */
247: ,0 /* stack size (0=auto) */
248: ,&thread_data /* data */
249: )==(unsigned long)-1)
250: printf("_beginthread failed\n");
251: else {
252: sem_wait(&thread_data.child_sem); /* wait for thread to begin */
253: for(i=0;i<10;i++) {
254: printf("<parent>");
255: sem_post(&thread_data.parent_sem);
256: sem_wait(&thread_data.child_sem);
257: }
258: sem_wait(&thread_data.child_sem); /* wait for thread to end */
259: }
260: sem_destroy(&thread_data.parent_sem);
261: sem_destroy(&thread_data.child_sem);
262:
263: printf("\nSemaphore blocking test\n");
264: getkey();
265: sem_init(&thread_data.parent_sem
266: ,0 /* shared between processes */
267: ,0 /* initial count */
268: );
269: sem_init(&thread_data.child_sem
270: ,0 /* shared between processes */
271: ,0 /* initial count */
272: );
273: if(_beginthread(
274: sem_test_thread_block /* entry point */
275: ,0 /* stack size (0=auto) */
276: ,&thread_data /* data */
277: )==(unsigned long)-1)
278: printf("_beginthread failed\n");
279: else {
280: sem_wait(&thread_data.child_sem); /* wait for thread to begin */
281: for(i=0;i<10;i++) {
282: printf("<parent>");
283: SLEEP(5000);
284: sem_post(&thread_data.parent_sem);
285: sem_wait(&thread_data.child_sem);
286: }
287: sem_wait(&thread_data.child_sem); /* wait for thread to end */
288: }
289: printf("\nsem_trywait_block test...");
290: t=time(NULL);
291: sem_trywait_block(&thread_data.parent_sem,5000);
292: printf("\ntimed-out after %ld seconds (should be 5 seconds)\n",time(NULL)-t);
293: sem_destroy(&thread_data.parent_sem);
294: sem_destroy(&thread_data.child_sem);
295: printf("\nendian check...");
296: memcpy(&i,"\x01\x02\x03\x04",4);
297: if(LE_LONG(i)==67305985) {
298: printf("OK!\n");
299: }
300: else {
301: printf("FAILED!\n");
302: }
303: return 0;
304: }
305:
306: static void getkey(void)
307: {
308: printf("Hit any key to continue...");
309: fflush(stdout);
310: getch();
311: printf("\r%30s\r","");
312: fflush(stdout);
313: }
314:
315: static void sleep_test_thread(void* arg)
316: {
317: time_t t=time(NULL);
318: printf("child sleeping");
319: fflush(stdout);
320: SLEEP(5000);
321: printf("\nchild awake after %ld seconds\n",time(NULL)-t);
322:
323: *(int*)arg=1; /* signal parent: we're done */
324: }
325:
326: static void sem_test_thread(void* arg)
327: {
328: ulong i;
329: thread_data_t* data = (thread_data_t*)arg;
330:
331: printf("sem_test_thread entry\n");
332: sem_post(&data->child_sem); /* signal parent: we've started */
333:
334: for(i=0;i<10;i++) {
335: sem_wait(&data->parent_sem);
336: printf(" <child>\n");
337: sem_post(&data->child_sem);
338: }
339:
340: printf("sem_test_thread exit\n");
341: sem_post(&data->child_sem); /* signal parent: we're done */
342: }
343:
344: static void sem_test_thread_block(void* arg)
345: {
346: ulong i;
347: thread_data_t* data = (thread_data_t*)arg;
348:
349: printf("sem_test_thread_block entry\n");
350: sem_post(&data->child_sem); /* signal parent: we've started */
351:
352: for(i=0;i<10;i++) {
353: if(sem_trywait_block(&data->parent_sem,500)) {
354: printf(" sem_trywait_block() timed out");
355: sem_wait(&data->parent_sem);
356: }
357: else {
358: printf(" FAILURE: Didn't block");
359: }
360: printf(" <child>\n");
361: sem_post(&data->child_sem);
362: }
363:
364: printf("sem_test_thread_block exit\n");
365: sem_post(&data->child_sem); /* signal parent: we're done */
366: }
367:
368: static void lock_test_thread(void* arg)
369: {
370: int fd;
371:
372: fd=sopen(LOCK_FNAME,O_RDWR,SH_DENYNO);
373: if(lock(fd,LOCK_OFFSET,LOCK_LEN)==0)
374: printf("!FAILURE: Lock not effective between threads\n");
375: else
376: printf("Locks effective between threads\n");
377: close(fd);
378: fd=sopen(LOCK_FNAME,O_RDWR,SH_DENYNO);
379: if(lock(fd,LOCK_OFFSET,LOCK_LEN))
380: printf("Locks survive file open()/close() in other thread\n");
381: else
382: printf("!FAILURE: Locks do not survive file open()/close() in other thread\n");
383: close(fd);
384: }
385:
386: static void sopen_test_thread(void* arg)
387: {
388: int fd;
389:
390: if((fd=sopen(LOCK_FNAME,O_RDWR,SH_DENYWR))!=-1)
391: printf("!FAILURE: allowed to reopen with SH_DENYWR\n");
392: else if((fd=sopen(LOCK_FNAME,O_RDWR,SH_DENYRW))!=-1)
393: printf("!FAILURE: allowed to reopen with SH_DENYRW\n");
394: else
395: printf("reopen disallowed\n");
396:
397: if(fd!=-1)
398: close(fd);
399: }
400:
401: static void sopen_child_thread(void* arg)
402: {
403: int fd;
404:
405: printf("sopen_child_thread: %d begin\n",(int)arg);
406: if((fd=sopen(LOCK_FNAME,O_RDWR,SH_DENYRW))!=-1) {
407: if(arg)
408: printf("!FAILURE: was able to reopen in child thread\n");
409: else {
410: SLEEP(5000);
411: }
412: close(fd);
413: } else if(arg==0)
414: perror(LOCK_FNAME);
415: printf("sopen_child_thread: %d end\n",(int)arg);
416: }
417:
418: /* End of wraptest.c */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.