📄 stdio.c
字号:
while (bytes) { if ((rv = write(fp->fd, p, bytes)) < 0) { rv = 0; if (errno != EINTR) { break; } } p += rv; bytes -= rv; } if (bytes) { fp->mode |= __MODE_ERR; } DONE: return (p - (unsigned char *)buf);}#endif#ifdef L_rewindvoid rewind(fp)FILE *fp;{ clearerr(fp); /* Clear errors first, then seek in case */ fseek(fp, 0, SEEK_SET); /* there is an error seeking. */}#endif#ifdef L_fseekint fseek(FILE *fp, long int offset, int ref){#if SEEK_SET != 0 || SEEK_CUR != 1 || SEEK_END != 2#error Assumption violated -- values of SEEK_SET, SEEK_CUR, SEEK_END#endif if ((ref < 0) || (ref > 2)) { __set_errno(EINVAL); return -1; } if (WRITING(fp)) { fflush(fp); /* We'll deal with errors below. */ /* After fflush, bufpos is at CUR. */ } else if (READING(fp)) { if (ref == SEEK_CUR) { /* Correct offset to take into account position in buffer. */ offset -= (fp->bufread - fp->bufpos); if (fp->mode & __MODE_UNGOT) { /* If we had an ungetc'd char, */ --offset; /* adjust offset (clear flag below). */ } } } if ((fp->mode & __MODE_ERR) || (((ref != SEEK_CUR) || offset) && (lseek(fp->fd, offset, ref) < 0))) { return -1; } if (READING(fp)) { fp->bufpos = fp->bufread = fp->bufstart; } fp->mode &= ~(__MODE_EOF | __MODE_UNGOT); return 0;}#endif#ifdef L_ftelllong ftell(fp)FILE *fp;{ /* Note: can't do fflush here since it would discard any ungetc's. */ off_t pos; pos = lseek(fp->fd, 0, SEEK_CUR); /* Get kernels idea of position. */ if (pos < 0) { return -1; } if (WRITING(fp)) { pos += (fp->bufpos - fp->bufstart); /* Adjust for buffer position. */ } else if (READING(fp)) { pos -= (fp->bufread - fp->bufpos); /* Adjust for buffer position. */ if (fp->mode & __MODE_UNGOT) { --pos; } if (pos < 0) { /* ungetcs at start of file? */ __set_errno(EIO); pos = -1; } } return pos;}#endif#ifdef L__fopen/* * This Fopen is all three of fopen, fdopen and freopen. The macros in * stdio.h show the other names. */static __inline FILE *_alloc_stdio_stream(void){ FILE *fp; if (_free_file_list) { fp = _free_file_list; _free_file_list = fp->next; } else if (!(fp = malloc(sizeof(FILE)))) { return 0; } fp->mode = __MODE_FREEFIL | _IOFBF; /* Initially set to use builtin buffer of FILE structure. */ fp->bufstart = fp->unbuf; fp->bufend = fp->unbuf + sizeof(fp->unbuf); return fp;}FILE *__fopen(fname, fd, fp, mode)const char *fname;int fd;FILE *fp;const char *mode;{ FILE *nfp; unsigned char *p; int open_mode; int cur_mode; nfp = fp; /* Parse the mode string arg. */ switch (*mode++) { case 'r': /* read */ open_mode = O_RDONLY; break; case 'w': /* write (create or truncate)*/ open_mode = (O_WRONLY | O_CREAT | O_TRUNC); break; case 'a': /* write (create or append) */ open_mode = (O_WRONLY | O_CREAT | O_APPEND); break; default: /* illegal mode */ __set_errno(EINVAL); goto _fopen_ERROR; } if ((*mode == 'b')) { /* binary mode (nop for uClibc) */ ++mode; }#if O_RDONLY != 0 || O_WRONLY != 1 || O_RDWR != 2#error Assumption violated concerning open mode constants!#endif if (*mode == '+') { /* read-write */ ++mode; open_mode &= ~(O_RDONLY | O_WRONLY); open_mode |= O_RDWR; } while (*mode) { /* ignore everything else except ... */ if (*mode == 'x') { /* open exclusive -- GNU extension */ open_mode |= O_EXCL; } ++mode; } if (fp == 0) { /* We need a FILE so allocate it before */ if (!(nfp = _alloc_stdio_stream())) { return 0; } } if (fname) { /* Open the file itself */ fd = open(fname, open_mode, 0666); } else { /* fdopen -- check mode is compatible. */#if O_ACCMODE != 3 || O_RDONLY != 0 || O_WRONLY != 1 || O_RDWR != 2#error Assumption violated - mode constants#endif cur_mode = fcntl(fd, F_GETFL); if (cur_mode == -1) { fd = -1; } else if (!(cur_mode & O_RDWR) && ((cur_mode ^ open_mode) & O_ACCMODE)) { __set_errno(EINVAL); fd = -1; } } if (fd < 0) { /* Error from open or bad arg passed. */ _fopen_ERROR: if (nfp) { _free_stdio_stream(nfp); } return 0; } nfp->fd = fd; /* Set FILE's fd before adding to open list. */ if (fp == 0) { /* Not freopen so... */ nfp->next = __IO_list; /* use newly created FILE and */ __IO_list = nfp; /* add it to the list of open files. */ if ((p = _alloc_stdio_buffer(BUFSIZ)) != 0) { nfp->bufstart = p; nfp->bufend = p + BUFSIZ; nfp->mode |= __MODE_FREEBUF; } } /* Ok, file's ready clear the buffer and save important bits */ nfp->bufpos = nfp->bufstart; nfp->mode |= isatty(fd); nfp->bufread = nfp->bufwrite = 0; if (!(open_mode & O_WRONLY)) { nfp->bufread = nfp->bufstart; } if (open_mode & (O_WRONLY | O_RDWR)) { nfp->bufwrite = nfp->bufstart; } return nfp;}#endif#ifdef L_fcloseint fclose(fp)FILE *fp;{ FILE *prev; FILE *ptr; int rv; rv = 0; if (WRITING(fp)) { /* If there are buffered chars to write... */ rv = fflush(fp); /* write them. */ } if (close(fp->fd)) { /* Need to close even if fflush fails. */ rv = EOF; } prev = 0; /* Remove file from open list. */ for (ptr = __IO_list; ptr ; ptr = ptr->next) { if (ptr == fp) { if (prev == 0) { __IO_list = fp->next; } else { prev->next = fp->next; } break; } prev = ptr; } _free_stdio_stream(fp); /* Finally free the stream if necessary. */ return rv;}#endif#ifdef L__free_stdio_stream/* The following is only called by fclose and _fopen. */void _free_stdio_stream(FILE *fp){ _free_stdio_buffer_of_file(fp); /* Free buffer if necessary. */ if (!(fp->mode & __MODE_FREEFIL)) { return; } /* Note: we generally won't bother checking for bad pointers here. */ if ((fp >= _stdio_streams) && (fp < _stdio_streams + FIXED_STREAMS)) { assert( (fp - _stdio_streams) % ((_stdio_streams+1) -_stdio_streams) == 0 ); fp->next = _free_file_list; _free_file_list = fp; return; } free(fp);}#endif#ifdef L_setbuffervoid setbuffer(FILE *fp, char *buf, size_t size){ int mode; mode = _IOFBF; if (!buf) { mode = _IONBF; } setvbuf(fp, buf, mode, size);}#endif#ifdef L_setvbufint setvbuf(FILE *fp, char *buf, int mode, size_t size){ int allocated_buf_flag; if ((mode < 0) || (mode > 2)) { /* Illegal mode. */ return EOF; }#if FLEXIBLE_SETVBUF /* C89 standard requires no ops before setvbuf, but we can be flexible. */ /* NOTE: This will trash any chars ungetc'd!!! */ if (fseek(fp, 0, SEEK_CUR)) { return EOF; }#endif /* Note: If size == 2 we could use FILE's builting buffer as well, but */ /* I don't think the benefit is worth the code size increase. */ if ((mode == _IONBF) || (size < 1)) { size = 1; /* size == 1 _REQUIRED_ for _IONBF!!! */ buf = fp->unbuf; } fp->mode &= ~(__MODE_BUF); /* Clear current mode */ fp->mode |= mode; /* and set new one. */ allocated_buf_flag = 0; if ((!buf) && (size != (fp->bufend - fp->bufstart))) { /* No buffer supplied and requested size different from current. */ allocated_buf_flag = __MODE_FREEBUF; if (!(buf = _alloc_stdio_buffer(size))) { return EOF; /* Keep current buffer. */ } } if (buf && (buf != (char *) fp->bufstart)) { /* Want different buffer. */ _free_stdio_buffer_of_file(fp); /* Free the old buffer. */ fp->mode |= allocated_buf_flag; /* Allocated? or FILE's builtin. */ fp->bufstart = buf; fp->bufend = buf + size; fp->bufpos = fp->bufstart; if (READABLE(fp)) { fp->bufread = fp->bufstart; } if (WRITEABLE(fp)) { fp->bufwrite = fp->bufstart; } } return 0;}#endif#ifdef L_setbufvoid setbuf(FILE *fp, char *buf){ int mode; mode = _IOFBF; if (!buf) { mode = _IONBF; } setvbuf(fp, buf, mode, BUFSIZ);}#endif#ifdef L_setlinebufvoid setlinebuf(FILE *fp){ setvbuf(fp, NULL, _IOLBF, BUFSIZ);}#endif#ifdef L_ungetc/* * NOTE: Only one character of pushback is guaranteed, although sometimes * it is possible to do more. You have 1 plus as many characters of pushback * as have been read since that last buffer-fill. */int ungetc(c, fp)int c;FILE *fp;{ unsigned char *p; /* If can't read or there's been an error, or c == EOF, or ungot slot * already filled, then return EOF */ /* * This can only happen if an fgetc triggered a read (that filled * the buffer for case 2 above) and then we ungetc 3 chars. */ if (!READABLE(fp) || (fp->mode & (__MODE_UNGOT | __MODE_ERR)) || (c == EOF) ) { return EOF; } if (WRITING(fp)) { /* Commit any write-buffered chars. */ fflush(fp); } if (fp->bufpos > fp->bufstart) { /* We have space before bufpos. */ p = --fp->bufpos; } else if (fp->bufread == fp->bufpos) { /* Buffer is empty. */ p = fp->bufread++; } else { fp->mode |= __MODE_UNGOT; p = &(fp->ungot); } fp->mode &= ~(__MODE_EOF); /* Clear EOF indicator. */ if (*p != (unsigned char) c) { /* Don't store if same, because could */ *p = (unsigned char) c; /* be sscanf from a const string!!! */ } return c;}#endif#ifdef L_fopen#undef fopenFILE *fopen(const char *__restrict filename, const char *__restrict mode){ return __fopen(filename, -1, NULL, mode);}#endif#ifdef L_freopenFILE *freopen(__const char *__restrict filename, __const char *__restrict mode, FILE *__restrict fp){ /* fflush file, close the old fd, and reset modes. */ if (WRITING(fp)) { /* If anything in the write buffer... */ fflush(fp); /* write it. */ } close(fp->fd); /* Close the file. */ fp->mode &= (__MODE_FREEFIL | __MODE_FREEBUF); /* Reset the FILE modes. */ fp->mode |= _IOFBF; return __fopen(filename, -1, fp, mode);}#endif#ifdef L_fsfopenFILE *fsfopen(__const char *__restrict filename, __const char *__restrict mode, FILE *__restrict fp){ fp->mode = _IOFBF; fp->bufstart = fp->unbuf; fp->bufend = fp->unbuf + sizeof(fp->unbuf); return __fopen(filename, -1, fp, mode);}#endif#ifdef L_fdopen#undef fdopenFILE *fdopen(int fd, __const char *mode){ return __fopen(NULL, fd, NULL, mode);}#endif#ifdef L_getchar#undef getcharint getchar(void){ return getc(stdin);}#endif#ifdef L_putchar#undef putcharint putchar(int c){ return putc(c, stdout);}#endif#ifdef L_clearerr#undef clearerrvoid clearerr(FILE *fp){ fp->mode &= ~(__MODE_EOF | __MODE_ERR);}#endif#ifdef L_feof#undef feofint feof(FILE *fp){ return fp->mode & __MODE_EOF;}#endif#ifdef L_ferror#undef ferrorint ferror(FILE *fp){ return fp->mode & __MODE_ERR;}#endif#ifdef L_filenoint fileno(FILE *fp){ return fp->fd;}#endif#ifdef L_fgetposint fgetpos(FILE *fp, fpos_t *pos){ fpos_t p; if (!pos) { /* NULL pointer. */ __set_errno(EINVAL); return -1; } if ((p = ftell(fp)) < 0) { /* ftell failed. */ return -1; /* errno set by ftell. */ } *pos = p; return 0;}#endif#ifdef L_fsetposint fsetpos(FILE *fp, __const fpos_t *pos){ if (pos) { /* Pointer ok. */ return fseek(fp, *pos, SEEK_SET); } __set_errno(EINVAL); /* NULL pointer. */ return EOF;}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -