diff options
Diffstat (limited to 'libc/stdio/stdio.c')
-rw-r--r-- | libc/stdio/stdio.c | 1330 |
1 files changed, 647 insertions, 683 deletions
diff --git a/libc/stdio/stdio.c b/libc/stdio/stdio.c index 9043e6199..b34631154 100644 --- a/libc/stdio/stdio.c +++ b/libc/stdio/stdio.c @@ -19,7 +19,7 @@ void __io_init_vars(void); -extern FILE *__IO_list; /* For fflush at exit */ +extern FILE *__IO_list; /* For fflush at exit */ #define FIXED_BUFFERS 2 struct fixed_buffer { @@ -35,11 +35,12 @@ extern struct fixed_buffer _fixed_buffers[2]; #define buferr (stderr->unbuf) /* Stderr is unbuffered */ -FILE *__IO_list = 0; /* For fflush at exit */ +FILE *__IO_list = 0; /* For fflush at exit */ #if 0 static char bufin[BUFSIZ]; static char bufout[BUFSIZ]; + #ifndef buferr static char buferr[BUFSIZ]; #endif @@ -47,56 +48,54 @@ static char buferr[BUFSIZ]; #else static char *bufin; static char *bufout; + #ifndef buferr static char *buferr; #endif #endif -FILE stdin[1] = -{ +FILE stdin[1] = { #if 0 - {bufin, bufin, bufin, bufin, bufin + sizeof(bufin), + {bufin, bufin, bufin, bufin, bufin + sizeof(bufin), #else - {0, 0, 0, 0, 0, + {0, 0, 0, 0, 0, #endif - 0, _IOFBF | __MODE_READ | __MODE_IOTRAN} + 0, _IOFBF | __MODE_READ | __MODE_IOTRAN} }; -FILE stdout[1] = -{ +FILE stdout[1] = { #if 0 - {bufout, bufout, bufout, bufout, bufout + sizeof(bufout), + {bufout, bufout, bufout, bufout, bufout + sizeof(bufout), #else - {0, 0, 0, 0, 0, + {0, 0, 0, 0, 0, #endif - 1, _IOFBF | __MODE_WRITE | __MODE_IOTRAN} + 1, _IOFBF | __MODE_WRITE | __MODE_IOTRAN} }; -FILE stderr[1] = -{ +FILE stderr[1] = { #if 0 - {buferr, buferr, buferr, buferr, buferr + sizeof(buferr), + {buferr, buferr, buferr, buferr, buferr + sizeof(buferr), #else - {0, 0, 0, 0, 0, + {0, 0, 0, 0, 0, #endif - 2, _IONBF | __MODE_WRITE | __MODE_IOTRAN} + 2, _IONBF | __MODE_WRITE | __MODE_IOTRAN} }; /* Call the stdio initiliser; it's main job it to call atexit */ void __stdio_close_all(void) { - FILE *fp; - fflush(stdout); - fflush(stderr); - for (fp = __IO_list; fp; fp = fp->next) - { - fflush(fp); - close(fp->fd); - /* Note we're not de-allocating the memory */ - /* There doesn't seem to be much point :-) */ - fp->fd = -1; - } + FILE *fp; + + fflush(stdout); + fflush(stderr); + for (fp = __IO_list; fp; fp = fp->next) { + fflush(fp); + close(fp->fd); + /* Note we're not de-allocating the memory */ + /* There doesn't seem to be much point :-) */ + fp->fd = -1; + } } static int first_time = 0; @@ -106,295 +105,284 @@ struct fixed_buffer _fixed_buffers[2]; void __io_init_vars(void) { - if( first_time ) return; - first_time = 1; - - stdin->bufpos = bufin = _fixed_buffers[0].data; /*(char *)malloc(BUFSIZ)*/; - stdin->bufread = bufin; - stdin->bufwrite = bufin; - stdin->bufstart = bufin; - stdin->bufend = bufin + sizeof(bufin); - stdin->fd = 0; - stdin->mode = _IOFBF | __MODE_READ | __MODE_IOTRAN | __MODE_FREEBUF; - - _fixed_buffers[0].used = 1; - - stdout->bufpos = bufout = _fixed_buffers[1].data; /*(char *)malloc(BUFSIZ);*/ - stdout->bufread = bufout; - stdout->bufwrite = bufout; - stdout->bufstart = bufout; - stdout->bufend = bufout + sizeof(bufout); - stdout->fd = 1; - stdout->mode = _IOFBF | __MODE_WRITE | __MODE_IOTRAN | __MODE_FREEBUF; - - _fixed_buffers[1].used = 1; + if (first_time) + return; + first_time = 1; + + stdin->bufpos = bufin = _fixed_buffers[0].data; + /*(char *)malloc(BUFSIZ) */ ; + stdin->bufread = bufin; + stdin->bufwrite = bufin; + stdin->bufstart = bufin; + stdin->bufend = bufin + sizeof(bufin); + stdin->fd = 0; + stdin->mode = _IOFBF | __MODE_READ | __MODE_IOTRAN | __MODE_FREEBUF; + + _fixed_buffers[0].used = 1; + + stdout->bufpos = bufout = _fixed_buffers[1].data; /*(char *)malloc(BUFSIZ); */ + stdout->bufread = bufout; + stdout->bufwrite = bufout; + stdout->bufstart = bufout; + stdout->bufend = bufout + sizeof(bufout); + stdout->fd = 1; + stdout->mode = _IOFBF | __MODE_WRITE | __MODE_IOTRAN | __MODE_FREEBUF; + + _fixed_buffers[1].used = 1; #if 0 - stderr->bufpos = buferr = (char *)malloc(BUFSIZ); + stderr->bufpos = buferr = (char *) malloc(BUFSIZ); #else - stderr->bufpos = buferr; -#endif - stderr->bufread = buferr; - stderr->bufwrite = buferr; - stderr->bufstart = buferr; - stderr->bufend = buferr + sizeof(buferr); - stderr->fd = 2; - stderr->mode = _IONBF | __MODE_WRITE | __MODE_IOTRAN; - - if (isatty(1)) - stdout->mode |= _IOLBF; - atexit(__stdio_close_all); + stderr->bufpos = buferr; +#endif + stderr->bufread = buferr; + stderr->bufwrite = buferr; + stderr->bufstart = buferr; + stderr->bufend = buferr + sizeof(buferr); + stderr->fd = 2; + stderr->mode = _IONBF | __MODE_WRITE | __MODE_IOTRAN; + + if (isatty(1)) + stdout->mode |= _IOLBF; + atexit(__stdio_close_all); } #endif #ifdef L_fputc -int -fputc(ch, fp) -int ch; +int fputc(ch, fp) +int ch; FILE *fp; { - register int v; - Inline_init; + register int v; + + Inline_init; - v = fp->mode; - /* If last op was a read ... */ - if ((v & __MODE_READING) && fflush(fp)) - return EOF; + v = fp->mode; + /* If last op was a read ... */ + if ((v & __MODE_READING) && fflush(fp)) + return EOF; - /* Can't write or there's been an EOF or error then return EOF */ - if ((v & (__MODE_WRITE | __MODE_EOF | __MODE_ERR)) != __MODE_WRITE) - return EOF; + /* Can't write or there's been an EOF or error then return EOF */ + if ((v & (__MODE_WRITE | __MODE_EOF | __MODE_ERR)) != __MODE_WRITE) + return EOF; - /* In MSDOS translation mode */ + /* In MSDOS translation mode */ #if __MODE_IOTRAN - if (ch == '\n' && (v & __MODE_IOTRAN) && fputc('\r', fp) == EOF) - return EOF; + if (ch == '\n' && (v & __MODE_IOTRAN) && fputc('\r', fp) == EOF) + return EOF; #endif - /* Buffer is full */ - if (fp->bufpos >= fp->bufend && fflush(fp)) - return EOF; + /* Buffer is full */ + if (fp->bufpos >= fp->bufend && fflush(fp)) + return EOF; - /* Right! Do it! */ - *(fp->bufpos++) = ch; - fp->mode |= __MODE_WRITING; + /* Right! Do it! */ + *(fp->bufpos++) = ch; + fp->mode |= __MODE_WRITING; - /* Unbuffered or Line buffered and end of line */ - if (((ch == '\n' && (v & _IOLBF)) || (v & _IONBF)) - && fflush(fp)) - return EOF; + /* Unbuffered or Line buffered and end of line */ + if (((ch == '\n' && (v & _IOLBF)) || (v & _IONBF)) + && fflush(fp)) + return EOF; - /* Can the macro handle this by itself ? */ - if (v & (__MODE_IOTRAN | _IOLBF | _IONBF)) - fp->bufwrite = fp->bufstart; /* Nope */ - else - fp->bufwrite = fp->bufend; /* Yup */ + /* Can the macro handle this by itself ? */ + if (v & (__MODE_IOTRAN | _IOLBF | _IONBF)) + fp->bufwrite = fp->bufstart; /* Nope */ + else + fp->bufwrite = fp->bufend; /* Yup */ - /* Correct return val */ - return (unsigned char) ch; + /* Correct return val */ + return (unsigned char) ch; } #endif #ifdef L_fgetc -int -fgetc(fp) +int fgetc(fp) FILE *fp; { - int ch; - Inline_init; + int ch; - if (fp->mode & __MODE_WRITING) - fflush(fp); + Inline_init; + + if (fp->mode & __MODE_WRITING) + fflush(fp); #if __MODE_IOTRAN - try_again: -#endif - /* Can't read or there's been an EOF or error then return EOF */ - if ((fp->mode & (__MODE_READ | __MODE_EOF | __MODE_ERR)) != __MODE_READ) - return EOF; - - /* Nothing in the buffer - fill it up */ - if (fp->bufpos >= fp->bufread) - { - fp->bufpos = fp->bufread = fp->bufstart; - ch = fread(fp->bufpos, 1, fp->bufend - fp->bufstart, fp); - if (ch == 0) - return EOF; - fp->bufread += ch; - fp->mode |= __MODE_READING; - fp->mode &= ~__MODE_UNGOT; - } - ch = *(fp->bufpos++); + try_again: +#endif + /* Can't read or there's been an EOF or error then return EOF */ + if ((fp->mode & (__MODE_READ | __MODE_EOF | __MODE_ERR)) != + __MODE_READ) return EOF; + + /* Nothing in the buffer - fill it up */ + if (fp->bufpos >= fp->bufread) { + fp->bufpos = fp->bufread = fp->bufstart; + ch = fread(fp->bufpos, 1, fp->bufend - fp->bufstart, fp); + if (ch == 0) + return EOF; + fp->bufread += ch; + fp->mode |= __MODE_READING; + fp->mode &= ~__MODE_UNGOT; + } + ch = *(fp->bufpos++); #if __MODE_IOTRAN - /* In MSDOS translation mode; WARN: Doesn't work with UNIX macro */ - if (ch == '\r' && (fp->mode & __MODE_IOTRAN)) - goto try_again; + /* In MSDOS translation mode; WARN: Doesn't work with UNIX macro */ + if (ch == '\r' && (fp->mode & __MODE_IOTRAN)) + goto try_again; #endif - return ch; + return ch; } #endif #ifdef L_fflush -int -fflush(fp) +int fflush(fp) FILE *fp; { - int len, cc, rv=0; - char * bstart; - if (fp == NULL) /* On NULL flush the lot. */ - { - if (fflush(stdin)) - return EOF; - if (fflush(stdout)) - return EOF; - if (fflush(stderr)) - return EOF; - - for (fp = __IO_list; fp; fp = fp->next) - if (fflush(fp)) - return EOF; - - return 0; - } - - /* If there's output data pending */ - if (fp->mode & __MODE_WRITING) - { - len = fp->bufpos - fp->bufstart; - - if (len) - { - bstart = fp->bufstart; - /* - * The loop is so we don't get upset by signals or partial writes. - */ - do - { - cc = write(fp->fd, bstart, len); - if( cc > 0 ) - { - bstart+=cc; len-=cc; - } - } - while ( cc>0 || (cc == -1 && errno == EINTR)); - /* - * If we get here with len!=0 there was an error, exactly what to - * do about it is another matter ... - * - * I'll just clear the buffer. - */ - if (len) - { - fp->mode |= __MODE_ERR; - rv = EOF; - } - } - } - /* If there's data in the buffer sychronise the file positions */ - else if (fp->mode & __MODE_READING) - { - /* Humm, I think this means sync the file like fpurge() ... */ - /* Anyway the user isn't supposed to call this function when reading */ - - len = fp->bufread - fp->bufpos; /* Bytes buffered but unread */ - /* If it's a file, make it good */ - if (len > 0 && lseek(fp->fd, (long)-len, 1) < 0) - { - /* Hummm - Not certain here, I don't think this is reported */ - /* - * fp->mode |= __MODE_ERR; return EOF; - */ - } - } - - /* All done, no problem */ - fp->mode &= (~(__MODE_READING|__MODE_WRITING|__MODE_EOF|__MODE_UNGOT)); - fp->bufread = fp->bufwrite = fp->bufpos = fp->bufstart; - return rv; + int len, cc, rv = 0; + char *bstart; + + if (fp == NULL) { /* On NULL flush the lot. */ + if (fflush(stdin)) + return EOF; + if (fflush(stdout)) + return EOF; + if (fflush(stderr)) + return EOF; + + for (fp = __IO_list; fp; fp = fp->next) + if (fflush(fp)) + return EOF; + + return 0; + } + + /* If there's output data pending */ + if (fp->mode & __MODE_WRITING) { + len = fp->bufpos - fp->bufstart; + + if (len) { + bstart = fp->bufstart; + /* + * The loop is so we don't get upset by signals or partial writes. + */ + do { + cc = write(fp->fd, bstart, len); + if (cc > 0) { + bstart += cc; + len -= cc; + } + } + while (cc > 0 || (cc == -1 && errno == EINTR)); + /* + * If we get here with len!=0 there was an error, exactly what to + * do about it is another matter ... + * + * I'll just clear the buffer. + */ + if (len) { + fp->mode |= __MODE_ERR; + rv = EOF; + } + } + } + /* If there's data in the buffer sychronise the file positions */ + else if (fp->mode & __MODE_READING) { + /* Humm, I think this means sync the file like fpurge() ... */ + /* Anyway the user isn't supposed to call this function when reading */ + + len = fp->bufread - fp->bufpos; /* Bytes buffered but unread */ + /* If it's a file, make it good */ + if (len > 0 && lseek(fp->fd, (long) -len, 1) < 0) { + /* Hummm - Not certain here, I don't think this is reported */ + /* + * fp->mode |= __MODE_ERR; return EOF; + */ + } + } + + /* All done, no problem */ + fp->mode &= + (~(__MODE_READING | __MODE_WRITING | __MODE_EOF | __MODE_UNGOT)); + fp->bufread = fp->bufwrite = fp->bufpos = fp->bufstart; + return rv; } #endif #ifdef L_fgets /* Nothing special here ... */ -char * -fgets(s, count, f) +char *fgets(s, count, f) char *s; int count; FILE *f; { - char *ret; - register size_t i; - register int ch; - - ret = s; - for (i = count; i > 0; i--) - { - ch = getc(f); - if (ch == EOF) - { - if (s == ret) - return 0; - break; - } - *s++ = (char) ch; - if (ch == '\n') - break; - } - *s = 0; - - if (ferror(f)) - return 0; - return ret; + char *ret; + register size_t i; + register int ch; + + ret = s; + for (i = count; i > 0; i--) { + ch = getc(f); + if (ch == EOF) { + if (s == ret) + return 0; + break; + } + *s++ = (char) ch; + if (ch == '\n') + break; + } + *s = 0; + + if (ferror(f)) + return 0; + return ret; } #endif #ifdef L_gets -char * -gets(str) /* BAD function; DON'T use it! */ +char *gets(str) /* BAD function; DON'T use it! */ char *str; { - /* Auwlright it will work but of course _your_ program will crash */ - /* if it's given a too long line */ - register char *p = str; - register int c; - - while (((c = getc(stdin)) != EOF) && (c != '\n')) - *p++ = c; - *p = '\0'; - return (((c == EOF) && (p == str)) ? NULL : str); /* NULL == EOF */ + /* Auwlright it will work but of course _your_ program will crash */ + /* if it's given a too long line */ + register char *p = str; + register int c; + + while (((c = getc(stdin)) != EOF) && (c != '\n')) + *p++ = c; + *p = '\0'; + return (((c == EOF) && (p == str)) ? NULL : str); /* NULL == EOF */ } #endif #ifdef L_fputs -int -fputs(str, fp) +int fputs(str, fp) const char *str; FILE *fp; { - register int n = 0; - while (*str) - { - if (putc(*str++, fp) == EOF) - return (EOF); - ++n; - } - return (n); + register int n = 0; + + while (*str) { + if (putc(*str++, fp) == EOF) + return (EOF); + ++n; + } + return (n); } #endif #ifdef L_puts -int -puts(str) +int puts(str) const char *str; { - register int n; + register int n; - if (((n = fputs(str, stdout)) == EOF) - || (putc('\n', stdout) == EOF)) - return (EOF); - return (++n); + if (((n = fputs(str, stdout)) == EOF) + || (putc('\n', stdout) == EOF)) + return (EOF); + return (++n); } #endif @@ -407,56 +395,51 @@ const char *str; * This ignores __MODE__IOTRAN; probably exactly what you want. (It _is_ what * fgetc wants) */ -size_t -fread(buf, size, nelm, fp) -void *buf; -size_t size; -size_t nelm; -FILE *fp; +size_t fread(buf, size, nelm, fp) +void *buf; +size_t size; +size_t nelm; +FILE *fp; { - int len, v; - unsigned bytes, got = 0; - Inline_init; - - v = fp->mode; - - /* Want to do this to bring the file pointer up to date */ - if (v & __MODE_WRITING) - fflush(fp); - - /* Can't read or there's been an EOF or error then return zero */ - if ((v & (__MODE_READ | __MODE_EOF | __MODE_ERR)) != __MODE_READ) - return 0; - - /* This could be long, doesn't seem much point tho */ - bytes = size * nelm; - - len = fp->bufread - fp->bufpos; - if (len >= bytes) /* Enough buffered */ - { - memcpy(buf, fp->bufpos, (unsigned) bytes); - fp->bufpos += bytes; - return bytes; - } - else if (len > 0) /* Some buffered */ - { - memcpy(buf, fp->bufpos, len); - got = len; - } - - /* Need more; do it with a direct read */ - len = read(fp->fd, buf + got, (unsigned) (bytes - got)); - - /* Possibly for now _or_ later */ - if (len < 0) - { - fp->mode |= __MODE_ERR; - len = 0; - } - else if (len == 0) - fp->mode |= __MODE_EOF; - - return (got + len) / size; + int len, v; + unsigned bytes, got = 0; + + Inline_init; + + v = fp->mode; + + /* Want to do this to bring the file pointer up to date */ + if (v & __MODE_WRITING) + fflush(fp); + + /* Can't read or there's been an EOF or error then return zero */ + if ((v & (__MODE_READ | __MODE_EOF | __MODE_ERR)) != __MODE_READ) + return 0; + + /* This could be long, doesn't seem much point tho */ + bytes = size * nelm; + + len = fp->bufread - fp->bufpos; + if (len >= bytes) { /* Enough buffered */ + memcpy(buf, fp->bufpos, (unsigned) bytes); + fp->bufpos += bytes; + return bytes; + } else if (len > 0) { /* Some buffered */ + memcpy(buf, fp->bufpos, len); + got = len; + } + + /* Need more; do it with a direct read */ + len = read(fp->fd, buf + got, (unsigned) (bytes - got)); + + /* Possibly for now _or_ later */ + if (len < 0) { + fp->mode |= __MODE_ERR; + len = 0; + } else if (len == 0) + fp->mode |= __MODE_EOF; + + return (got + len) / size; } #endif @@ -469,22 +452,21 @@ FILE *fp; * * Again this ignores __MODE__IOTRAN. */ -size_t -fwrite(buf, size, nelm, fp) +size_t fwrite(buf, size, nelm, fp) const void *buf; -size_t size; -size_t nelm; -FILE *fp; +size_t size; +size_t nelm; +FILE *fp; { - register int v; - int len; - unsigned bytes, put; + register int v; + int len; + unsigned bytes, put; #ifdef STUB_FWRITE bytes = size * nelm; - while(bytes>0) { - len=write(fp->fd, buf, bytes); - if (len<=0) { + while (bytes > 0) { + len = write(fp->fd, buf, bytes); + if (len <= 0) { break; } bytes -= len; @@ -492,125 +474,119 @@ FILE *fp; } return nelm; #else - - v = fp->mode; - /* If last op was a read ... */ - if ((v & __MODE_READING) && fflush(fp)) - return 0; - - /* Can't write or there's been an EOF or error then return 0 */ - if ((v & (__MODE_WRITE | __MODE_EOF | __MODE_ERR)) != __MODE_WRITE) - return 0; - - /* This could be long, doesn't seem much point tho */ - bytes = size * nelm; - - len = fp->bufend - fp->bufpos; - - /* Flush the buffer if not enough room */ - if (bytes > len) - if (fflush(fp)) - return 0; - - len = fp->bufend - fp->bufpos; - if (bytes <= len) /* It'll fit in the buffer ? */ - { - fp->mode |= __MODE_WRITING; - memcpy(fp->bufpos, buf, bytes); - fp->bufpos += bytes; - - /* If we're not fully buffered */ - if (v & (_IOLBF | _IONBF)) - fflush(fp); - - return nelm; - } - else - /* Too big for the buffer */ - { - put = bytes; - do - { - len = write(fp->fd, buf, bytes); - if( len > 0 ) - { - buf+=len; bytes-=len; - } - } - while (len > 0 || (len == -1 && errno == EINTR)); - - if (len < 0) - fp->mode |= __MODE_ERR; - - put -= bytes; - } - - return put / size; + + v = fp->mode; + /* If last op was a read ... */ + if ((v & __MODE_READING) && fflush(fp)) + return 0; + + /* Can't write or there's been an EOF or error then return 0 */ + if ((v & (__MODE_WRITE | __MODE_EOF | __MODE_ERR)) != __MODE_WRITE) + return 0; + + /* This could be long, doesn't seem much point tho */ + bytes = size * nelm; + + len = fp->bufend - fp->bufpos; + + /* Flush the buffer if not enough room */ + if (bytes > len) + if (fflush(fp)) + return 0; + + len = fp->bufend - fp->bufpos; + if (bytes <= len) { /* It'll fit in the buffer ? */ + fp->mode |= __MODE_WRITING; + memcpy(fp->bufpos, buf, bytes); + fp->bufpos += bytes; + + /* If we're not fully buffered */ + if (v & (_IOLBF | _IONBF)) + fflush(fp); + + return nelm; + } else + /* Too big for the buffer */ + { + put = bytes; + do { + len = write(fp->fd, buf, bytes); + if (len > 0) { + buf += len; + bytes -= len; + } + } + while (len > 0 || (len == -1 && errno == EINTR)); + + if (len < 0) + fp->mode |= __MODE_ERR; + + put -= bytes; + } + + return put / size; #endif } #endif #ifdef L_rewind -void -rewind(fp) -FILE * fp; +void rewind(fp) +FILE *fp; { - fseek(fp, (long)0, 0); - clearerr(fp); + fseek(fp, (long) 0, 0); + clearerr(fp); } #endif #ifdef L_fseek -int -fseek(fp, offset, ref) +int fseek(fp, offset, ref) FILE *fp; -long offset; -int ref; +long offset; +int ref; { -#if 0 - /* FIXME: this is broken! BROKEN!!!! */ - /* if __MODE_READING and no ungetc ever done can just move pointer */ - /* This needs testing! */ - - if ( (fp->mode &(__MODE_READING | __MODE_UNGOT)) == __MODE_READING && - ( ref == SEEK_SET || ref == SEEK_CUR )) - { - long fpos = lseek(fp->fd, 0L, SEEK_CUR); - if( fpos == -1 ) return EOF; - - if( ref == SEEK_CUR ) - { - ref = SEEK_SET; - offset = fpos + offset + fp->bufpos - fp->bufread; - } - if( ref == SEEK_SET ) - { - if ( offset < fpos && offset >= fpos + fp->bufstart - fp->bufread ) - { - fp->bufpos = offset - fpos + fp->bufread; - return 0; - } - } - } -#endif - - /* Use fflush to sync the pointers */ - - if (fflush(fp) == EOF) - return EOF; - if (lseek(fp->fd, offset, ref) < 0) - return EOF; - return 0; +#if 0 + /* FIXME: this is broken! BROKEN!!!! */ + /* if __MODE_READING and no ungetc ever done can just move pointer */ + /* This needs testing! */ + + if ((fp->mode & (__MODE_READING | __MODE_UNGOT)) == __MODE_READING && + (ref == SEEK_SET || ref == SEEK_CUR)) { + long fpos = lseek(fp->fd, 0L, SEEK_CUR); + + if (fpos == -1) + return EOF; + + if (ref == SEEK_CUR) { + ref = SEEK_SET; + offset = fpos + offset + fp->bufpos - fp->bufread; + } + if (ref == SEEK_SET) { + if (offset < fpos + && offset >= fpos + fp->bufstart - fp->bufread) { + fp->bufpos = offset - fpos + fp->bufread; + return 0; + } + } + } +#endif + + /* Use fflush to sync the pointers */ + + if (fflush(fp) == EOF) + return EOF; + if (lseek(fp->fd, offset, ref) < 0) + return EOF; + return 0; } #endif #ifdef L_ftell long ftell(fp) -FILE * fp; +FILE *fp; { - if (fflush(fp) == EOF) - return EOF; - return lseek(fp->fd, 0L, SEEK_CUR); + if (fflush(fp) == EOF) + return EOF; + return lseek(fp->fd, 0L, SEEK_CUR); } #endif @@ -619,311 +595,299 @@ FILE * fp; * This Fopen is all three of fopen, fdopen and freopen. The macros in * stdio.h show the other names. */ -FILE * -__fopen(fname, fd, fp, mode) +FILE *__fopen(fname, fd, fp, mode) const char *fname; -int fd; +int fd; FILE *fp; const char *mode; { - int open_mode = 0; + int open_mode = 0; + #if __MODE_IOTRAN - int do_iosense = 1; -#endif - int fopen_mode = 0; - FILE *nfp = 0; - - /* If we've got an fp close the old one (freopen) */ - if (fp) - { - /* Careful, don't de-allocate it */ - fopen_mode |= (fp->mode & (__MODE_BUF | __MODE_FREEFIL | __MODE_FREEBUF)); - fp->mode &= ~(__MODE_FREEFIL | __MODE_FREEBUF); - fclose(fp); - } - - /* decode the new open mode */ - while (*mode) - switch (*mode++) - { - case 'r': - fopen_mode |= __MODE_READ; - break; - case 'w': - fopen_mode |= __MODE_WRITE; - open_mode = (O_CREAT | O_TRUNC); - break; - case 'a': - fopen_mode |= __MODE_WRITE; - open_mode = (O_CREAT | O_APPEND); - break; - case '+': - fopen_mode |= __MODE_RDWR; - break; + int do_iosense = 1; +#endif + int fopen_mode = 0; + FILE *nfp = 0; + + /* If we've got an fp close the old one (freopen) */ + if (fp) { + /* Careful, don't de-allocate it */ + fopen_mode |= + (fp->mode & (__MODE_BUF | __MODE_FREEFIL | __MODE_FREEBUF)); + fp->mode &= ~(__MODE_FREEFIL | __MODE_FREEBUF); + fclose(fp); + } + + /* decode the new open mode */ + while (*mode) + switch (*mode++) { + case 'r': + fopen_mode |= __MODE_READ; + break; + case 'w': + fopen_mode |= __MODE_WRITE; + open_mode = (O_CREAT | O_TRUNC); + break; + case 'a': + fopen_mode |= __MODE_WRITE; + open_mode = (O_CREAT | O_APPEND); + break; + case '+': + fopen_mode |= __MODE_RDWR; + break; #if __MODE_IOTRAN - case 'b': /* Binary */ - fopen_mode &= ~__MODE_IOTRAN; - do_iosense=0; - break; - case 't': /* Text */ - fopen_mode |= __MODE_IOTRAN; - do_iosense=0; - break; -#endif - } - - /* Add in the read/write options to mode for open() */ - switch (fopen_mode & (__MODE_READ | __MODE_WRITE)) - { - case 0: - return 0; - case __MODE_READ: - open_mode |= O_RDONLY; - break; - case __MODE_WRITE: - open_mode |= O_WRONLY; - break; - default: - open_mode |= O_RDWR; - break; - } - - /* Allocate the (FILE) before we do anything irreversable */ - if (fp == 0) - { - nfp = malloc(sizeof(FILE)); - if (nfp == 0) - return 0; - } - - /* Open the file itself */ - if (fname) - fd = open(fname, open_mode, 0666); - if (fd < 0) /* Grrrr */ - { - if (nfp) - free(nfp); - return 0; - } - - /* If this isn't freopen create a (FILE) and buffer for it */ - if (fp == 0) - { - int i; - fp = nfp; - fp->next = __IO_list; - __IO_list = fp; - - fp->mode = __MODE_FREEFIL; - if( isatty(fd) ) - { - fp->mode |= _IOLBF; + case 'b': /* Binary */ + fopen_mode &= ~__MODE_IOTRAN; + do_iosense = 0; + break; + case 't': /* Text */ + fopen_mode |= __MODE_IOTRAN; + do_iosense = 0; + break; +#endif + } + + /* Add in the read/write options to mode for open() */ + switch (fopen_mode & (__MODE_READ | __MODE_WRITE)) { + case 0: + return 0; + case __MODE_READ: + open_mode |= O_RDONLY; + break; + case __MODE_WRITE: + open_mode |= O_WRONLY; + break; + default: + open_mode |= O_RDWR; + break; + } + + /* Allocate the (FILE) before we do anything irreversable */ + if (fp == 0) { + nfp = malloc(sizeof(FILE)); + if (nfp == 0) + return 0; + } + + /* Open the file itself */ + if (fname) + fd = open(fname, open_mode, 0666); + if (fd < 0) { /* Grrrr */ + if (nfp) + free(nfp); + return 0; + } + + /* If this isn't freopen create a (FILE) and buffer for it */ + if (fp == 0) { + int i; + + fp = nfp; + fp->next = __IO_list; + __IO_list = fp; + + fp->mode = __MODE_FREEFIL; + if (isatty(fd)) { + fp->mode |= _IOLBF; #if __MODE_IOTRAN - if( do_iosense ) fopen_mode |= __MODE_IOTRAN; -#endif - } - else - fp->mode |= _IOFBF; - - for(i=0;i<FIXED_BUFFERS;i++) - if (!_fixed_buffers[i].used) { - fp->bufstart = _fixed_buffers[i].data; - _fixed_buffers[i].used = 1; - break; - } - - if (i == FIXED_BUFFERS) - fp->bufstart = malloc(BUFSIZ); - - if (fp->bufstart == 0) /* Oops, no mem */ - { /* Humm, full buffering with a two(!) byte - * buffer. */ - fp->bufstart = fp->unbuf; - fp->bufend = fp->unbuf + sizeof(fp->unbuf); - } - else - { - fp->bufend = fp->bufstart + BUFSIZ; - fp->mode |= __MODE_FREEBUF; - } - } - /* Ok, file's ready clear the buffer and save important bits */ - fp->bufpos = fp->bufread = fp->bufwrite = fp->bufstart; - fp->mode |= fopen_mode; - fp->fd = fd; - return fp; + if (do_iosense) + fopen_mode |= __MODE_IOTRAN; +#endif + } else + fp->mode |= _IOFBF; + + for (i = 0; i < FIXED_BUFFERS; i++) + if (!_fixed_buffers[i].used) { + fp->bufstart = _fixed_buffers[i].data; + _fixed_buffers[i].used = 1; + break; + } + + if (i == FIXED_BUFFERS) + fp->bufstart = malloc(BUFSIZ); + + if (fp->bufstart == 0) { /* Oops, no mem *//* Humm, full buffering with a two(!) byte + * buffer. */ + fp->bufstart = fp->unbuf; + fp->bufend = fp->unbuf + sizeof(fp->unbuf); + } else { + fp->bufend = fp->bufstart + BUFSIZ; + fp->mode |= __MODE_FREEBUF; + } + } + /* Ok, file's ready clear the buffer and save important bits */ + fp->bufpos = fp->bufread = fp->bufwrite = fp->bufstart; + fp->mode |= fopen_mode; + fp->fd = fd; + return fp; } #endif #ifdef L_fclose -int -fclose(fp) +int fclose(fp) FILE *fp; { - int rv = 0; - - if (fp == 0) - { - errno = EINVAL; - return EOF; - } - if (fflush(fp)) - return EOF; - - if (close(fp->fd)) - rv = EOF; - fp->fd = -1; - - if (fp->mode & __MODE_FREEBUF) - { - int i; - for(i=0;i<FIXED_BUFFERS;i++) - if (fp->bufstart == _fixed_buffers[i].data) { - _fixed_buffers[i].used = 0; - break; - } - if(i==FIXED_BUFFERS) - free(fp->bufstart); - fp->mode &= ~__MODE_FREEBUF; - fp->bufstart = fp->bufend = 0; - } - - if (fp->mode & __MODE_FREEFIL) - { - FILE *prev = 0, *ptr; - fp->mode = 0; - - for (ptr = __IO_list; ptr && ptr != fp; ptr = ptr->next) - ; - if (ptr == fp) - { - if (prev == 0) - __IO_list = fp->next; - else - prev->next = fp->next; - } - free(fp); - } - else - fp->mode = 0; - - return rv; + int rv = 0; + + if (fp == 0) { + errno = EINVAL; + return EOF; + } + if (fflush(fp)) + return EOF; + + if (close(fp->fd)) + rv = EOF; + fp->fd = -1; + + if (fp->mode & __MODE_FREEBUF) { + int i; + + for (i = 0; i < FIXED_BUFFERS; i++) + if (fp->bufstart == _fixed_buffers[i].data) { + _fixed_buffers[i].used = 0; + break; + } + if (i == FIXED_BUFFERS) + free(fp->bufstart); + fp->mode &= ~__MODE_FREEBUF; + fp->bufstart = fp->bufend = 0; + } + + if (fp->mode & __MODE_FREEFIL) { + FILE *prev = 0, *ptr; + + fp->mode = 0; + + for (ptr = __IO_list; ptr && ptr != fp; ptr = ptr->next); + if (ptr == fp) { + if (prev == 0) + __IO_list = fp->next; + else + prev->next = fp->next; + } + free(fp); + } else + fp->mode = 0; + + return rv; } #endif #ifdef L_setbuffer -void -setbuffer(fp, buf, size) -FILE * fp; -char * buf; +void setbuffer(fp, buf, size) +FILE *fp; +char *buf; int size; { - fflush(fp); - - if ((fp->bufstart == (unsigned char*)buf) && (fp->bufend == ((unsigned char*)buf + size))) - return; - - if( fp->mode & __MODE_FREEBUF ) { - int i; - for(i=0;i<FIXED_BUFFERS;i++) - if (fp->bufstart == _fixed_buffers[i].data) { - _fixed_buffers[i].used = 0; - break; - } - if(i==FIXED_BUFFERS) - free(fp->bufstart); - } - fp->mode &= ~(__MODE_FREEBUF|__MODE_BUF); - - if( buf == 0 ) - { - fp->bufstart = fp->unbuf; - fp->bufend = fp->unbuf + sizeof(fp->unbuf); - fp->mode |= _IONBF; - } - else - { - fp->bufstart = buf; - fp->bufend = buf+size; - fp->mode |= _IOFBF; - } - fp->bufpos = fp->bufread = fp->bufwrite = fp->bufstart; + fflush(fp); + + if ((fp->bufstart == (unsigned char *) buf) + && (fp->bufend == ((unsigned char *) buf + size))) + return; + + if (fp->mode & __MODE_FREEBUF) { + int i; + + for (i = 0; i < FIXED_BUFFERS; i++) + if (fp->bufstart == _fixed_buffers[i].data) { + _fixed_buffers[i].used = 0; + break; + } + if (i == FIXED_BUFFERS) + free(fp->bufstart); + } + fp->mode &= ~(__MODE_FREEBUF | __MODE_BUF); + + if (buf == 0) { + fp->bufstart = fp->unbuf; + fp->bufend = fp->unbuf + sizeof(fp->unbuf); + fp->mode |= _IONBF; + } else { + fp->bufstart = buf; + fp->bufend = buf + size; + fp->mode |= _IOFBF; + } + fp->bufpos = fp->bufread = fp->bufwrite = fp->bufstart; } #endif #ifdef L_setvbuf int setvbuf(fp, buf, mode, size) -FILE * fp; -char * buf; +FILE *fp; +char *buf; int mode; size_t size; { - fflush(fp); - if( fp->mode & __MODE_FREEBUF ) { - int i; - for(i=0;i<FIXED_BUFFERS;i++) - if (fp->bufstart == _fixed_buffers[i].data) { - _fixed_buffers[i].used = 0; - break; - } - if(i==FIXED_BUFFERS) - free(fp->bufstart); - } - fp->mode &= ~(__MODE_FREEBUF|__MODE_BUF); - fp->bufstart = fp->unbuf; - fp->bufend = fp->unbuf + sizeof(fp->unbuf); - fp->mode |= _IONBF; - - if( mode == _IOFBF || mode == _IOLBF ) - { - if( size <= 0 ) { size = BUFSIZ; } - if( buf == 0 ) { - if (size == BUFSIZ) { - int i; - for(i=0;i<FIXED_BUFFERS;i++) - if (!_fixed_buffers[i].used) { - _fixed_buffers[i].used = 1; - buf = _fixed_buffers[i].data; - break; - } - if(i==FIXED_BUFFERS) - buf = malloc(size); - } else { - buf = malloc(size); - } - } - if( buf == 0 ) return EOF; - - fp->bufstart = buf; - fp->bufend = buf+size; - fp->mode |= mode; - } - fp->bufpos = fp->bufread = fp->bufwrite = fp->bufstart; - return 0; + fflush(fp); + if (fp->mode & __MODE_FREEBUF) { + int i; + + for (i = 0; i < FIXED_BUFFERS; i++) + if (fp->bufstart == _fixed_buffers[i].data) { + _fixed_buffers[i].used = 0; + break; + } + if (i == FIXED_BUFFERS) + free(fp->bufstart); + } + fp->mode &= ~(__MODE_FREEBUF | __MODE_BUF); + fp->bufstart = fp->unbuf; + fp->bufend = fp->unbuf + sizeof(fp->unbuf); + fp->mode |= _IONBF; + + if (mode == _IOFBF || mode == _IOLBF) { + if (size <= 0) { + size = BUFSIZ; + } + if (buf == 0) { + if (size == BUFSIZ) { + int i; + + for (i = 0; i < FIXED_BUFFERS; i++) + if (!_fixed_buffers[i].used) { + _fixed_buffers[i].used = 1; + buf = _fixed_buffers[i].data; + break; + } + if (i == FIXED_BUFFERS) + buf = malloc(size); + } else { + buf = malloc(size); + } + } + if (buf == 0) + return EOF; + + fp->bufstart = buf; + fp->bufend = buf + size; + fp->mode |= mode; + } + fp->bufpos = fp->bufread = fp->bufwrite = fp->bufstart; + return 0; } #endif #ifdef L_ungetc -int -ungetc(c, fp) +int ungetc(c, fp) int c; FILE *fp; { - if (fp->mode & __MODE_WRITING) - fflush(fp); - - /* Can't read or there's been an error then return EOF */ - if ((fp->mode & (__MODE_READ | __MODE_ERR)) != __MODE_READ) - return EOF; - - /* Can't do fast fseeks */ - fp->mode |= __MODE_UNGOT; - - if( fp->bufpos > fp->bufstart ) - return *--fp->bufpos = (unsigned char) c; - else if( fp->bufread == fp->bufstart ) - return *fp->bufread++ = (unsigned char) c; - else - return EOF; + if (fp->mode & __MODE_WRITING) + fflush(fp); + + /* Can't read or there's been an error then return EOF */ + if ((fp->mode & (__MODE_READ | __MODE_ERR)) != __MODE_READ) + return EOF; + + /* Can't do fast fseeks */ + fp->mode |= __MODE_UNGOT; + + if (fp->bufpos > fp->bufstart) + return *--fp->bufpos = (unsigned char) c; + else if (fp->bufread == fp->bufstart) + return *fp->bufread++ = (unsigned char) c; + else + return EOF; } #endif |