1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <sys/errno.h>
5 #include <sys/types.h>
6 #include <sys/fcntl.h>
7 #include <sys/stat.h>
8 #include <sys/time.h>
9 #include <errno.h>
10 #include <sys/wait.h>
11 /* TESTS :
12  * - open(const char *pathname, int flags, mode_t mode);
13 1) Attempt to create file that already exists - EEXIST
14 2) Attempt to open a directory for writing - EISDIR
15 3) Pathname does not exist - ENOENT
16 4) Open for write but no write permission - EACCES
17 
18 read(int fd, void *buf, size_t count);
19 1) Read using invalid file descriptor - EBADF
20 
21 write(int fd, const void *buf, size_t count);
22 1) Write using invalid file descriptor - EBADF
23 2) Attempt to write to read-only file - EBADF
24 
25 lseek(int fildes, off_t offset, int whence);
26 1) Seeking on an invalid file descriptor - EBADF
27 2) Invalid "whence" (3rd param) value -  EINVAL
28 
29 close(int fd);
30 1) Attempt to close an invalid file descriptor - EBADF
31 
32 stat(const char *file_name, struct stat *buf);
33 1) Pathname is a null string -  ENOENT
34 2) Pathname does not exist - ENOENT
35 
36 fstat(int filedes, struct stat *buf);
37 1) Attempt to stat using an invalid file descriptor - EBADF
38 
39 isatty (int desc);
40 Not applicable. We will test that it returns 1 when expected and a case
41 where it should return 0.
42 
43 rename(const char *oldpath, const char *newpath);
44 1) newpath is an existing directory, but oldpath is not a directory. - EISDIR
45 2) newpath is a non-empty directory. - ENOTEMPTY or EEXIST
46 3) newpath is a subdirectory of old path. - EINVAL
47 4) oldpath does not exist. - ENOENT
48 
49 unlink(const char *pathname);
50 1) pathname does not have write access. - EACCES
51 2) pathname does not exist. - ENOENT
52 
53 time(time_t *t);
54 Not applicable.
55 
56 system (const char * string);
57 1) Invalid string/command. -  returns 127.  */
58 
59 static const char *strerrno (int err);
60 
61 #define FILENAME    "foo.fileio.test"
62 #define RENAMED     "bar.fileio.test"
63 #define NONEXISTANT "nofoo.fileio.test"
64 #define NOWRITE     "nowrt.fileio.test"
65 #define TESTDIR1     "dir1.fileio.test"
66 #define TESTDIR2     "dir2.fileio.test"
67 #define TESTSUBDIR   "dir1.fileio.test/subdir.fileio.test"
68 
69 #define STRING      "Hello World"
70 
71 int
test_open()72 test_open ()
73 {
74   int ret;
75 
76   /* Test opening */
77   errno = 0;
78   ret = open (FILENAME, O_CREAT | O_TRUNC | O_RDWR, S_IWUSR | S_IRUSR);
79   printf ("open 1: ret = %d, errno = %d %s\n", ret, errno,
80 	  ret >= 0 ? "OK" : "");
81   if (ret >= 0)
82     close (ret);
83   /* Creating an already existing file (created by fileio.exp) */
84   errno = 0;
85   ret = open (FILENAME, O_CREAT | O_EXCL | O_WRONLY, S_IWUSR | S_IRUSR);
86   printf ("open 2: ret = %d, errno = %d %s\n", ret, errno,
87 	  strerrno (errno));
88   if (ret >= 0)
89     close (ret);
90   /* Open directory (for writing) */
91   errno = 0;
92   ret = open (".", O_WRONLY);
93   printf ("open 3: ret = %d, errno = %d %s\n", ret, errno,
94 	  strerrno (errno));
95   if (ret >= 0)
96     close (ret);
97   /* Opening nonexistant file */
98   errno = 0;
99   ret = open (NONEXISTANT, O_RDONLY);
100   printf ("open 4: ret = %d, errno = %d %s\n", ret, errno,
101 	  strerrno (errno));
102   if (ret >= 0)
103     close (ret);
104   /* Open for write but no write permission */
105   errno = 0;
106   ret = open (NOWRITE, O_CREAT | O_RDONLY, S_IRUSR);
107   if (ret >= 0)
108     {
109       close (ret);
110       errno = 0;
111       ret = open (NOWRITE, O_WRONLY);
112       printf ("open 5: ret = %d, errno = %d %s\n", ret, errno,
113 	      strerrno (errno));
114       if (ret >= 0)
115 	close (ret);
116     }
117   else
118     printf ("open 5: ret = %d, errno = %d\n", ret, errno);
119 }
120 
121 int
test_write()122 test_write ()
123 {
124   int fd, ret;
125 
126   /* Test writing */
127   errno = 0;
128   fd = open (FILENAME, O_WRONLY);
129   if (fd >= 0)
130     {
131       errno = 0;
132       ret = write (fd, STRING, strlen (STRING));
133       printf ("write 1: ret = %d, errno = %d %s\n", ret, errno,
134               ret == strlen (STRING) ? "OK" : "");
135       close (fd);
136     }
137   else
138     printf ("write 1: ret = %d, errno = %d\n", ret, errno);
139   /* Write using invalid file descriptor */
140   errno = 0;
141   ret = write (999, STRING, strlen (STRING));
142   printf ("write 2: ret = %d, errno = %d, %s\n", ret, errno,
143 	  strerrno (errno));
144   /* Write to a read-only file */
145   errno = 0;
146   fd = open (FILENAME, O_RDONLY);
147   if (fd >= 0)
148     {
149       errno = 0;
150       ret = write (fd, STRING, strlen (STRING));
151       printf ("write 3: ret = %d, errno = %d %s\n", ret, errno,
152 	      strerrno (errno));
153     }
154   else
155     printf ("write 3: ret = %d, errno = %d\n", ret, errno);
156 }
157 
158 int
test_read()159 test_read ()
160 {
161   int fd, ret;
162   char buf[16];
163 
164   /* Test reading */
165   errno = 0;
166   fd = open (FILENAME, O_RDONLY);
167   if (fd >= 0)
168     {
169       memset (buf, 0, 16);
170       errno = 0;
171       ret = read (fd, buf, 16);
172       buf[15] = '\0'; /* Don't trust anybody... */
173       if (ret == strlen (STRING))
174         printf ("read 1: %s %s\n", buf, !strcmp (buf, STRING) ? "OK" : "");
175       else
176 	printf ("read 1: ret = %d, errno = %d\n", ret, errno);
177       close (fd);
178     }
179   else
180     printf ("read 1: ret = %d, errno = %d\n", ret, errno);
181   /* Read using invalid file descriptor */
182   errno = 0;
183   ret = read (999, buf, 16);
184   printf ("read 2: ret = %d, errno = %d %s\n", ret, errno,
185 	  strerrno (errno));
186 }
187 
188 int
test_lseek()189 test_lseek ()
190 {
191   int fd;
192   off_t ret = 0;
193 
194   /* Test seeking */
195   errno = 0;
196   fd = open (FILENAME, O_RDONLY);
197   if (fd >= 0)
198     {
199       errno = 0;
200       ret = lseek (fd, 0, SEEK_CUR);
201       printf ("lseek 1: ret = %ld, errno = %d, %s\n", (long) ret, errno,
202               ret == 0 ? "OK" : "");
203       errno = 0;
204       ret = lseek (fd, 0, SEEK_END);
205       printf ("lseek 2: ret = %ld, errno = %d, %s\n", (long) ret, errno,
206               ret == 11 ? "OK" : "");
207       errno = 0;
208       ret = lseek (fd, 3, SEEK_SET);
209       printf ("lseek 3: ret = %ld, errno = %d, %s\n", (long) ret, errno,
210               ret == 3 ? "OK" : "");
211       close (fd);
212     }
213   else
214     {
215       printf ("lseek 1: ret = %d, errno = %d\n", ret, errno);
216       printf ("lseek 2: ret = %d, errno = %d\n", ret, errno);
217       printf ("lseek 3: ret = %d, errno = %d\n", ret, errno);
218     }
219   /* Seeking on an invalid file descriptor */
220 
221 }
222 
223 int
test_close()224 test_close ()
225 {
226   int fd, ret;
227 
228   /* Test close */
229   errno = 0;
230   fd = open (FILENAME, O_RDONLY);
231   if (fd >= 0)
232     {
233       errno = 0;
234       ret = close (fd);
235       printf ("close 1: ret = %d, errno = %d, %s\n", ret, errno,
236               ret == 0 ? "OK" : "");
237     }
238   else
239     printf ("close 1: ret = %d, errno = %d\n", ret, errno);
240   /* Close an invalid file descriptor */
241   errno = 0;
242   ret = close (999);
243   printf ("close 2: ret = %d, errno = %d, %s\n", ret, errno,
244   	  strerrno (errno));
245 }
246 
247 int
test_stat()248 test_stat ()
249 {
250   int ret;
251   struct stat st;
252 
253   /* Test stat */
254   errno = 0;
255   ret = stat (FILENAME, &st);
256   if (!ret)
257     printf ("stat 1: ret = %d, errno = %d %s\n", ret, errno,
258 	    st.st_size == 11 ? "OK" : "");
259   else
260     printf ("stat 1: ret = %d, errno = %d\n", ret, errno);
261   /* NULL pathname */
262   errno = 0;
263   ret = stat (NULL, &st);
264   printf ("stat 2: ret = %d, errno = %d %s\n", ret, errno,
265   	  strerrno (errno));
266   /* Empty pathname */
267   errno = 0;
268   ret = stat ("", &st);
269   printf ("stat 3: ret = %d, errno = %d %s\n", ret, errno,
270   	  strerrno (errno));
271   /* Nonexistant file */
272   errno = 0;
273   ret = stat (NONEXISTANT, &st);
274   printf ("stat 4: ret = %d, errno = %d %s\n", ret, errno,
275   	  strerrno (errno));
276 }
277 
278 int
test_fstat()279 test_fstat ()
280 {
281   int fd, ret;
282   struct stat st;
283 
284   /* Test fstat */
285   errno = 0;
286   fd = open (FILENAME, O_RDONLY);
287   if (fd >= 0)
288     {
289       errno = 0;
290       ret = fstat (fd, &st);
291       if (!ret)
292 	printf ("fstat 1: ret = %d, errno = %d %s\n", ret, errno,
293 		st.st_size == 11 ? "OK" : "");
294       else
295 	printf ("fstat 1: ret = %d, errno = %d\n", ret, errno);
296       close (fd);
297     }
298   else
299     printf ("fstat 1: ret = %d, errno = %d\n", ret, errno);
300   /* Fstat using invalid file descriptor */
301   errno = 0;
302   ret = fstat (999, &st);
303   printf ("fstat 2: ret = %d, errno = %d %s\n", ret, errno,
304   	  strerrno (errno));
305 }
306 
307 int
test_isatty()308 test_isatty ()
309 {
310   int fd;
311 
312   /* Check std I/O */
313   printf ("isatty 1: stdin %s\n", isatty (0) ? "yes OK" : "no");
314   printf ("isatty 2: stdout %s\n", isatty (1) ? "yes OK" : "no");
315   printf ("isatty 3: stderr %s\n", isatty (2) ? "yes OK" : "no");
316   /* Check invalid fd */
317   printf ("isatty 4: invalid %s\n", isatty (999) ? "yes" : "no OK");
318   /* Check open file */
319   fd = open (FILENAME, O_RDONLY);
320   if (fd >= 0)
321     {
322       printf ("isatty 5: file %s\n", isatty (fd) ? "yes" : "no OK");
323       close (fd);
324     }
325   else
326     printf ("isatty 5: file couldn't open\n");
327 }
328 
329 
330 int
test_system()331 test_system ()
332 {
333   /*
334    * Requires test framework to switch on "set remote system-call-allowed 1"
335    */
336   int ret;
337   char sys[512];
338 
339   /* This test prepares the directory for test_rename() */
340   sprintf (sys, "mkdir -p %s %s", TESTSUBDIR, TESTDIR2);
341   ret = system (sys);
342   if (ret == 127)
343     printf ("system 1: ret = %d /bin/sh unavailable???\n", ret);
344   else
345     printf ("system 1: ret = %d %s\n", ret, ret == 0 ? "OK" : "");
346   /* Invalid command (just guessing ;-) ) */
347   ret = system ("wrtzlpfrmpft");
348   printf ("system 2: ret = %d %s\n", ret, WEXITSTATUS (ret) == 127 ? "OK" : "");
349 }
350 
351 int
test_rename()352 test_rename ()
353 {
354   int ret;
355   struct stat st;
356 
357   /* Test rename */
358   errno = 0;
359   ret = rename (FILENAME, RENAMED);
360   if (!ret)
361     {
362       errno = 0;
363       ret = stat (FILENAME, &st);
364       if (ret && errno == ENOENT)
365         {
366 	  errno = 0;
367 	  ret = stat (RENAMED, &st);
368 	  printf ("rename 1: ret = %d, errno = %d %s\n", ret, errno,
369 		  strerrno (errno));
370 	  errno = 0;
371 	}
372       else
373 	printf ("rename 1: ret = %d, errno = %d\n", ret, errno);
374     }
375   else
376     printf ("rename 1: ret = %d, errno = %d\n", ret, errno);
377   /* newpath is existing directory, oldpath is not a directory */
378   errno = 0;
379   ret = rename (RENAMED, TESTDIR2);
380   printf ("rename 2: ret = %d, errno = %d %s\n", ret, errno,
381 	  strerrno (errno));
382   /* newpath is a non-empty directory */
383   errno = 0;
384   ret = rename (TESTDIR2, TESTDIR1);
385   printf ("rename 3: ret = %d, errno = %d %s\n", ret, errno,
386           strerrno (errno));
387   /* newpath is a subdirectory of old path */
388   errno = 0;
389   ret = rename (TESTDIR1, TESTSUBDIR);
390   printf ("rename 4: ret = %d, errno = %d %s\n", ret, errno,
391 	  strerrno (errno));
392   /* oldpath does not exist */
393   errno = 0;
394   ret = rename (NONEXISTANT, FILENAME);
395   printf ("rename 5: ret = %d, errno = %d %s\n", ret, errno,
396 	  strerrno (errno));
397 }
398 
399 int
test_unlink()400 test_unlink ()
401 {
402   int ret;
403   char name[256];
404   char sys[512];
405 
406   /* Test unlink */
407   errno = 0;
408   ret = unlink (RENAMED);
409   printf ("unlink 1: ret = %d, errno = %d %s\n", ret, errno,
410 	  strerrno (errno));
411   /* No write access */
412   sprintf (name, "%s/%s", TESTDIR2, FILENAME);
413   errno = 0;
414   ret = open (name, O_CREAT | O_RDONLY, S_IRUSR | S_IWUSR);
415   if (ret >= 0)
416     {
417       sprintf (sys, "chmod -w %s", TESTDIR2);
418       ret = system (sys);
419       if (!ret)
420         {
421 	  errno = 0;
422 	  ret = unlink (name);
423 	  printf ("unlink 2: ret = %d, errno = %d %s\n", ret, errno,
424 		  strerrno (errno));
425         }
426       else
427 	printf ("unlink 2: ret = %d chmod failed\n", ret, errno);
428     }
429   else
430     printf ("unlink 2: ret = %d, errno = %d\n", ret, errno);
431   /* pathname doesn't exist */
432   errno = 0;
433   ret = unlink (NONEXISTANT);
434   printf ("unlink 3: ret = %d, errno = %d %s\n", ret, errno,
435           strerrno (errno));
436 }
437 
438 int
test_time()439 test_time ()
440 {
441   time_t ret, t;
442 
443   errno = 0;
444   ret = time (&t);
445   printf ("time 1: ret = %ld, errno = %d, t = %ld %s\n", (long) ret, errno, (long) t, ret == t ? "OK" : "");
446   errno = 0;
447   ret = time (NULL);
448   printf ("time 2: ret = %ld, errno = %d, t = %ld %s\n",
449 	  (long) ret, errno, (long) t, ret >= t && ret < t + 10 ? "OK" : "");
450 }
451 
452 static const char *
strerrno(int err)453 strerrno (int err)
454 {
455   switch (err)
456     {
457     case 0: return "OK";
458 #ifdef EACCES
459     case EACCES: return "EACCES";
460 #endif
461 #ifdef EBADF
462     case EBADF: return "EBADF";
463 #endif
464 #ifdef EEXIST
465     case EEXIST: return "EEXIST";
466 #endif
467 #ifdef EFAULT
468     case EFAULT: return "EFAULT";
469 #endif
470 #ifdef EINVAL
471     case EINVAL: return "EINVAL";
472 #endif
473 #ifdef EISDIR
474     case EISDIR: return "EISDIR";
475 #endif
476 #ifdef ENOENT
477     case ENOENT: return "ENOENT";
478 #endif
479 #ifdef ENOTEMPTY
480     case ENOTEMPTY: return "ENOTEMPTY";
481 #endif
482 #ifdef EBUSY
483     case EBUSY: return "EBUSY";
484 #endif
485     default: return "E??";
486     }
487 }
488 
489 int
main()490 main ()
491 {
492   /* Don't change the order of the calls.  They partly depend on each other */
493   test_open ();
494   test_write ();
495   test_read ();
496   test_lseek ();
497   test_close ();
498   test_stat ();
499   test_fstat ();
500   test_isatty ();
501   test_system ();
502   test_rename ();
503   test_unlink ();
504   test_time ();
505   return 0;
506 }
507