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