2 * fopen.c - open a stream
6 #if defined(_POSIX_SOURCE)
16 /* The next 3 defines are true in all UNIX systems known to me.
22 /* Since the O_CREAT flag is not available on all systems, we can't get it
23 * from the standard library. Furthermore, even if we know that <fcntl.h>
24 * contains such a flag, it's not sure whether it can be used, since we
25 * might be cross-compiling for another system, which may use an entirely
26 * different value for O_CREAT (or not support such a mode). The safest
27 * thing is to just use the Version 7 semantics for open, and use creat()
30 * Another problem is O_APPEND, for which the same holds. When "a"
31 * open-mode is used, an lseek() to the end is done before every write()
34 * The O_CREAT, O_TRUNC and O_APPEND given here, are only for convenience.
35 * They are not passed to open(), so the values don't have to match a value
36 * from the real world. It is enough when they are unique.
40 #define O_APPEND 0x040
42 int _open(const char *path
, int flags
);
43 int _creat(const char *path
, _mnx_Mode_t mode
);
47 fopen(const char *name
, const char *mode
)
50 int rwmode
= 0, rwflags
= 0;
55 for (i
= 0; __iotab
[i
] != 0 ; i
++)
56 if ( i
>= FOPEN_MAX
-1 )
61 flags
|= _IOREAD
| _IOREADING
;
65 flags
|= _IOWRITE
| _IOWRITING
;
67 rwflags
= O_CREAT
| O_TRUNC
;
70 flags
|= _IOWRITE
| _IOWRITING
| _IOAPPEND
;
72 rwflags
|= O_APPEND
| O_CREAT
;
84 flags
|= _IOREAD
| _IOWRITE
;
86 /* The sequence may be followed by additional characters */
93 /* Perform a creat() when the file should be truncated or when
94 * the file is opened for writing and the open() failed.
96 if ((rwflags
& O_TRUNC
)
97 || (((fd
= _open(name
, rwmode
)) < 0)
98 && (rwflags
& O_CREAT
))) {
99 if (((fd
= _creat(name
, PMODE
)) > 0) && flags
| _IOREAD
) {
101 fd
= _open(name
, rwmode
);
106 if (fd
< 0) return (FILE *)NULL
;
108 if ( fstat( fd
, &st
) < 0 ) {
113 if ( S_ISFIFO(st
.st_mode
) ) flags
|= _IOFIFO
;
115 if (( stream
= (FILE *) malloc(sizeof(FILE))) == NULL
) {
120 if ((flags
& (_IOREAD
| _IOWRITE
)) == (_IOREAD
| _IOWRITE
))
121 flags
&= ~(_IOREADING
| _IOWRITING
);
125 stream
->_flags
= flags
;