/* * fopen * This function is quite different from the function of the same * name in the BDS C Standard Library. It is also different from * the function used in almost every implementation of the U**X * Standard C Library (they vary wildly in what `mode' means). * This version of fopen accepts 4 types of modes as follows: * "r", read mode, opens an existing file for read only. "w", write * mode, opens a new file for writing clobbering any existing files * of the same name. If the file is read only it returns NULL. "u", * update mode, opens an existing file for read/write faccess. If * the file is read only, it returns NULL. "a", append mode opens * an existing file for read/write with the file pointer at the * end of the file. It also returns NULL if the file is read only. * Edit of 7/8/83 */ FILE * fopen(filename,mode) char *filename, *mode; { FILE *stream; int i, omode; if (filename == NULL || mode == NULL) return NULL; for (i = 0; i < _NFILE; i++) { /* look for a buffer */ if (filebuf[i]._base == NULL) break; /* got an io buffer */ if (i == (_NFILE - 1)) /* no buffers available */ return NULL; } stream = (&filebuf[i]); /* assign the io buffer */ if ((stream -> _base = malloc(BUFSIZ)) == NULL) return NULL; if (mode[0] == 'r') omode = 0; if (mode[0] == 'w') { if (faccess(filename,2)<0) if (faccess(filename,0) == 0) { free(stream -> _base); stream -> _base = NULL; return NULL; } if ((stream->_fd=creat(filename))<0) { free(stream -> _base); stream -> _base = NULL; return NULL; } stream -> _nextp = stream -> _base; stream -> _nleft = BUFSIZ; stream -> _flag = _IOWRT; return stream; } if (mode[0] == 'u' || mode[0] == 'a') { omode = 2; if (faccess(filename,2)<0) if (faccess(filename,0) == 0) { free(stream -> _base); stream -> _base = NULL; return NULL; } } if ((stream -> _fd = open(filename,omode))<0) { free(stream -> _base); stream -> _base = NULL; return NULL; } if (mode[0] == 'a') seek(stream->_fd,0,2); stream -> _nleft = 0; stream -> _flag = 0; if (omode = 0) stream -> _flag |= _IOREAD; stream -> _flag |= _IOWRT; return stream; } /* * fclose * Conforms very closely to the function in the Version 7 U**X * Standard C Library. It closes the specified stream, flushes * the i/o buffer and frees the i/o buffer used bye the stream. * Last Edit 7/1/83 */ int fclose(stream) FILE *stream; { int i; if (isatty(stream)) /* can't close a tty */ return ERROR; fflush(stream); /* flush the io buffer */ i = close(stream -> _fd); /* close the file */ free(stream -> _base); /* free the io buffer */ return 0; } /* * fflush * This performs essentially the same task as the function * of the same name in the BDS C 1.5 Standard library. It * need not be invoked before calls to fclose to assure * that the i/o buffer is flushed. * Last Edit 7/1/83 */ int fflush(stream) FILE *stream; { int i; if (isatty(stream)) return 0; if (stream -> _nleft == BUFSIZ) return 0; i = NSECTS - stream -> _nleft / SECSIZ; if (write(stream -> _fd, stream -> _base, i) != i) return ERROR; i = (i-1) * SECSIZ; if (stream -> _nleft) { movmem(stream -> _base + i, stream -> _base, SECSIZ); stream -> _nleft += i; stream -> _nextp -= i; return seek(stream->_fd, -1, 1); } stream -> _nleft = BUFSIZ; stream -> _nextp = stream -> _base; return 0; }