123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111 |
- /*
- * fopen.c - open a stream
- */
- /* $Header$ */
- #include <stdio.h>
- #include <stdlib.h>
- #include "loc_incl.h"
- #define PMODE 0666
- /* The next 3 defines are true in all UNIX systems known to me.
- */
- #define O_RDONLY 0
- #define O_WRONLY 1
- #define O_RDWR 2
- /* Since the O_CREAT flag is not available on all systems, we can't get it
- * from the standard library. Furthermore, even if we know that <fcntl.h>
- * contains such a flag, it's not sure whether it can be used, since we
- * might be cross-compiling for another system, which may use an entirely
- * different value for O_CREAT (or not support such a mode). The safest
- * thing is to just use the Version 7 semantics for open, and use creat()
- * whenever necessary.
- *
- * Another problem is O_APPEND, for which the same holds. When "a"
- * open-mode is used, an lseek() to the end is done before every write()
- * system-call.
- *
- * The O_CREAT, O_TRUNC and O_APPEND given here, are only for convenience.
- * They are not passed to open(), so the values don't have to match a value
- * from the real world. It is enough when they are unique.
- */
- #define O_CREAT 0x010
- #define O_TRUNC 0x020
- #define O_APPEND 0x040
- int open(const char *path, int flags);
- int creat(const char *path, int mode);
- int close(int d);
- FILE *
- fopen(const char *name, const char *mode)
- {
- register int i;
- int rwmode = 0, rwflags = 0;
- FILE *stream;
- int fd, flags = 0;
- for (i = 0; __iotab[i] != 0 ; i++)
- if ( i >= FOPEN_MAX )
- return (FILE *)NULL;
- switch(*mode++) {
- case 'r':
- flags |= _IOREAD | _IOREADING;
- rwmode = O_RDONLY;
- break;
- case 'w':
- flags |= _IOWRITE | _IOWRITING;
- rwmode = O_WRONLY;
- rwflags = O_CREAT | O_TRUNC;
- break;
- case 'a':
- flags |= _IOWRITE | _IOWRITING | _IOAPPEND;
- rwmode = O_WRONLY;
- rwflags |= O_APPEND | O_CREAT;
- break;
- default:
- return (FILE *)NULL;
- }
- while (*mode) {
- switch(*mode++) {
- case 'b':
- break;
- case '+':
- rwmode = O_RDWR;
- flags |= _IOREAD | _IOWRITE;
- break;
- default:
- return (FILE *)NULL;
- }
- }
- /* Perform a creat() when the file should be truncated or when
- * the file is opened for writing and the open() failed.
- */
- if ((rwflags & O_TRUNC)
- || (((fd = open(name, rwmode)) < 0)
- && (flags & _IOWRITE)))
- fd = creat(name, PMODE);
- if (fd < 0) return (FILE *)NULL;
- if (( stream = (FILE *) malloc(sizeof(FILE))) == NULL ) {
- close(fd);
- return (FILE *)NULL;
- }
- if ((flags & (_IOREAD | _IOWRITE)) == (_IOREAD | _IOWRITE))
- flags &= ~(_IOREADING | _IOWRITING);
- stream->_count = 0;
- stream->_fd = fd;
- stream->_flags = flags;
- stream->_buf = NULL;
- __iotab[i] = stream;
- return stream;
- }
|