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