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