1 /* Test of opening a file stream.
2    Copyright (C) 2007-2020 Free Software Foundation, Inc.
3 
4    This program is free software: you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation; either version 3 of the License, or
7    (at your option) any later version.
8 
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13 
14    You should have received a copy of the GNU General Public License
15    along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
16 
17 /* Written by Bruno Haible <bruno@clisp.org>, 2007.  */
18 
19 /* Include <config.h> and a form of <stdio.h> first.  */
20 
21 #include <errno.h>
22 #include <unistd.h>
23 
24 #include "macros.h"
25 
26 /* Test fopen.  Assumes BASE is defined.  */
27 
28 static int
test_fopen(void)29 test_fopen (void)
30 {
31   FILE *f;
32   /* Remove anything from prior partial run.  */
33   unlink (BASE "file");
34 
35   /* Read requires existing file.  */
36   errno = 0;
37   ASSERT (fopen (BASE "file", "r") == NULL);
38   ASSERT (errno == ENOENT);
39 
40   /* Write can create a file.  */
41   f = fopen (BASE "file", "w");
42   ASSERT (f);
43   ASSERT (fclose (f) == 0);
44 
45   /* Trailing slash is invalid on non-directory.  */
46   errno = 0;
47   ASSERT (fopen (BASE "file/", "r") == NULL);
48   ASSERT (errno == ENOTDIR || errno == EISDIR || errno == EINVAL);
49 
50   errno = 0;
51   ASSERT (fopen (BASE "file/", "r+") == NULL);
52   ASSERT (errno == ENOTDIR || errno == EISDIR || errno == EINVAL);
53 
54   /* Cannot create a directory.  */
55   errno = 0;
56   ASSERT (fopen ("nonexist.ent/", "w") == NULL);
57   ASSERT (errno == ENOTDIR || errno == EISDIR || errno == ENOENT
58           || errno == EINVAL);
59 
60   /* Directories cannot be opened for writing.  */
61   errno = 0;
62   ASSERT (fopen (".", "w") == NULL);
63   ASSERT (errno == EISDIR || errno == EINVAL || errno == EACCES);
64 
65   errno = 0;
66   ASSERT (fopen ("./", "w") == NULL);
67   ASSERT (errno == EISDIR || errno == EINVAL || errno == EACCES);
68 
69   errno = 0;
70   ASSERT (fopen (".", "r+") == NULL);
71   ASSERT (errno == EISDIR || errno == EINVAL || errno == EACCES);
72 
73   errno = 0;
74   ASSERT (fopen ("./", "r+") == NULL);
75   ASSERT (errno == EISDIR || errno == EINVAL || errno == EACCES);
76 
77   /* /dev/null must exist, and be writable.  */
78   f = fopen ("/dev/null", "r");
79   ASSERT (f);
80   ASSERT (fclose (f) == 0);
81   f = fopen ("/dev/null", "w");
82   ASSERT (f);
83   ASSERT (fclose (f) == 0);
84 
85   /* Cleanup.  */
86   ASSERT (unlink (BASE "file") == 0);
87 
88   return 0;
89 }
90