FILE * funopen2(const void *cookie, ssize_t (*readfn)(void *, void *, size_t), ssize_t (*writefn)(void *, const void *, size_t), off_t (*seekfn)(void *, off_t, int), int (*flushfn)(void *), int (*closefn)(void *)) { FILE *fp; int flags; if (readfn == NULL) { if (writefn == NULL) { /* illegal */ errno = EINVAL; return NULL; } else flags = __SWR; /* write only */ } else { if (writefn == NULL) flags = __SRD; /* read only */ else flags = __SRW; /* read-write */ } if ((fp = __sfp()) == NULL) return NULL; fp->_flags = flags; fp->_file = -1; fp->_cookie = __UNCONST(cookie); fp->_read = readfn; fp->_write = writefn; fp->_seek = seekfn; fp->_flush = flushfn; fp->_close = closefn; return fp; }
FILE * funopen(const void *cookie, int (*readfn)(void *, char *, int), int (*writefn)(void *, const char *, int), fpos_t (*seekfn)(void *, fpos_t, int), int (*closefn)(void *)) { FILE *fp; int flags; if (readfn == NULL) { if (writefn == NULL) { /* illegal */ errno = EINVAL; return (NULL); } else flags = __SWR; /* write only */ } else { if (writefn == NULL) flags = __SRD; /* read only */ else flags = __SRW; /* read-write */ } if ((fp = __sfp()) == NULL) return (NULL); fp->pub._flags = flags; fp->pub._fileno = -1; fp->_cookie = (void *)cookie; fp->_read = readfn; fp->_write = writefn; fp->_seek = seekfn; fp->_close = closefn; return (fp); }
/** A reentrant version of wfopen(). */ EXPORT_C FILE * _wfopen_r(struct _reent *ptr, const wchar_t *file, const wchar_t *mode) { register FILE *fp; register int f; int flags, oflags; if ((flags = __sflags (ptr, mode, &oflags)) == 0) return NULL; if ((fp = __sfp (ptr)) == NULL) return NULL; if ((f = _wopen_r (fp->_data, file, oflags, 0666)) < 0) { fp->_flags = 0; /* release */ return NULL; } fp->_file = (short)f; fp->_flags = (short)flags; fp->_cookie = (void*) fp; fp->_read = __sread; fp->_write = __swrite; fp->_seek = __sseek; fp->_close = __sclose; if (fp->_flags & __SAPP) fseek (fp, 0, SEEK_END); return fp; }
FILE * fopen(const char *file, const char *mode) { FILE *fp; int f; int flags, oflags; if ((flags = __sflags(mode, &oflags)) == 0) return (NULL); if ((fp = __sfp()) == NULL) return (NULL); if ((f = open(file, oflags, DEFFILEMODE)) < 0) { fp->_flags = 0; /* release */ return (NULL); } fp->_file = f; fp->_flags = flags; fp->_cookie = fp; fp->_read = __sread; fp->_write = __swrite; fp->_seek = __sseek; fp->_close = __sclose; /* * When opening in append mode, even though we use O_APPEND, * we need to seek to the end so that ftell() gets the right * answer. If the user then alters the seek pointer, or * the file extends, this will fail, but there is not much * we can do about this. (We could set __SAPP and check in * fseek and ftell.) */ if (oflags & O_APPEND) (void) __sseek((void *)fp, (fpos_t)0, SEEK_END); return (fp); }
FILE * _DEFUN_VOID (tmpfile) { int ret; FILE* fp; struct _reent *ptr = _REENT; CHECK_INIT(ptr); fp = __sfp(ptr); if (!fp) { return NULL; } ret = __send_to_ppe(SPE_C99_SIGNALCODE, SPE_C99_TMPFILE, &ret); if (ret) { fp->_fp = ret; return fp; } else { __sfp_free(fp); return NULL; } }
FILE * fdopen(int fd, const char *mode) { FILE *fp; int flags, oflags, fdflags, tmp; /* * File descriptors are a full int, but _file is only a short. * If we get a valid file descriptor that is greater than * SHRT_MAX, then the fd will get sign-extended into an * invalid file descriptor. Handle this case by failing the * open. */ if (fd > SHRT_MAX) { errno = EMFILE; return (NULL); } if ((flags = __sflags(mode, &oflags)) == 0) return (NULL); /* Make sure the mode the user wants is a subset of the actual mode. */ if ((fdflags = _fcntl(fd, F_GETFL, 0)) < 0) return (NULL); /* Work around incorrect O_ACCMODE. */ tmp = fdflags & (O_ACCMODE | O_EXEC); if (tmp != O_RDWR && (tmp != (oflags & O_ACCMODE))) { errno = EINVAL; return (NULL); } if ((fp = __sfp()) == NULL) return (NULL); if ((oflags & O_CLOEXEC) && _fcntl(fd, F_SETFD, FD_CLOEXEC) == -1) { fp->_flags = 0; return (NULL); } fp->_flags = flags; /* * If opened for appending, but underlying descriptor does not have * O_APPEND bit set, assert __SAPP so that __swrite() caller * will _sseek() to the end before write. */ /* XXX: Reuse __SALC for O_APPEND. */ if (fdflags & O_APPEND) fp->_flags |= __SALC; else if (oflags & O_APPEND) fp->_flags |= __SAPP; fp->_file = fd; fp->_cookie = fp; fp->_read = __sread; fp->_write = __swrite; fp->_seek = __sseek; fp->_close = __sclose; return (fp); }
FILE * fopen(const char *file, const char *mode) { FILE *fp; int f; int flags, oflags; _DIAGASSERT(file != NULL); if ((flags = __sflags(mode, &oflags)) == 0) return (NULL); if ((fp = __sfp()) == NULL) return (NULL); if ((f = open(file, oflags, DEFFILEMODE)) < 0) goto release; if (oflags & O_NONBLOCK) { struct stat st; if (fstat(f, &st) == -1) { int sverrno = errno; (void)close(f); errno = sverrno; goto release; } if (!S_ISREG(st.st_mode)) { (void)close(f); errno = EFTYPE; goto release; } } fp->_file = (short)f; fp->_flags = (unsigned short)flags; fp->_cookie = fp; fp->_read = __sread; fp->_write = __swrite; fp->_seek = __sseek; fp->_close = __sclose; /* * When opening in append mode, even though we use O_APPEND, * we need to seek to the end so that ftell() gets the right * answer. If the user then alters the seek pointer, or * the file extends, this will fail, but there is not much * we can do about this. (We could set __SAPP and check in * fseek and ftell.) */ if (oflags & O_APPEND) (void) __sseek((void *)fp, (fpos_t)0, SEEK_END); return (fp); release: fp->_flags = 0; /* release */ return (NULL); }
FILE *_fdopen_r(struct _reent *ptr, int fd, const char *mode) { register FILE *fp; int flags, oflags; #ifdef F_GETFL int fdflags, fdmode; #endif if ((flags = __sflags(ptr, mode, &oflags)) == 0) return 0; /* make sure the mode the user wants is a subset of the actual mode */ #ifdef F_GETFL if ((fdflags = _fcntl(fd, F_GETFL, 0)) < 0) return 0; fdmode = fdflags & O_ACCMODE; if (fdmode != O_RDWR && (fdmode != (oflags & O_ACCMODE))) { ptr->_errno = EBADF; return 0; } #endif if ((fp = __sfp(ptr)) == 0) return 0; fp->_flags = flags; /* * If opened for appending, but underlying descriptor * does not have O_APPEND bit set, assert __SAPP so that * __swrite() will lseek to end before each write. */ if ((oflags & O_APPEND) #ifdef F_GETFL && !(fdflags & O_APPEND) #endif ) fp->_flags |= __SAPP; fp->_file = fd; fp->_cookie = (void *)fp; #undef _read #undef _write #undef _seek #undef _close fp->_read = __sread; fp->_write = __swrite; fp->_seek = __sseek; fp->_close = __sclose; return fp; }
FILE * fdopen(int fd, const char *mode) { FILE *fp; int flags, oflags, fdflags, tmp; /* _file is only a short */ if (fd > SHRT_MAX) { errno = EMFILE; return (NULL); } if ((flags = __sflags(mode, &oflags)) == 0) return (NULL); /* Make sure the mode the user wants is a subset of the actual mode. */ if ((fdflags = fcntl(fd, F_GETFL)) < 0) return (NULL); tmp = fdflags & O_ACCMODE; if (tmp != O_RDWR && (tmp != (oflags & O_ACCMODE))) { errno = EINVAL; return (NULL); } if ((fp = __sfp()) == NULL) return (NULL); fp->_flags = flags; /* * If opened for appending, but underlying descriptor does not have * O_APPEND bit set, assert __SAPP so that __swrite() will lseek to * end before each write. */ if ((oflags & O_APPEND) && !(fdflags & O_APPEND)) fp->_flags |= __SAPP; /* * If close-on-exec was requested, then turn it on if not already */ if ((oflags & O_CLOEXEC) && !((tmp = fcntl(fd, F_GETFD)) & FD_CLOEXEC)) fcntl(fd, F_SETFD, tmp | FD_CLOEXEC); fp->_file = fd; fp->_cookie = fp; fp->_read = __sread; fp->_write = __swrite; fp->_seek = __sseek; fp->_close = __sclose; return (fp); }
FILE * open_wmemstream(wchar_t **pbuf, size_t *psize) { struct state *st; FILE *fp; if (pbuf == NULL || psize == NULL) { errno = EINVAL; return (NULL); } if ((st = malloc(sizeof(*st))) == NULL) return (NULL); if ((fp = __sfp()) == NULL) { free(st); return (NULL); } st->size = BUFSIZ * sizeof(wchar_t); if ((st->string = calloc(1, st->size)) == NULL) { free(st); fp->_flags = 0; return (NULL); } *st->string = L'\0'; st->pos = 0; st->len = 0; st->pbuf = pbuf; st->psize = psize; bzero(&st->mbs, sizeof(st->mbs)); *pbuf = st->string; *psize = st->len; fp->_flags = __SWR; fp->_file = -1; fp->_cookie = st; fp->_read = NULL; fp->_write = wmemstream_write; fp->_seek = wmemstream_seek; fp->_close = wmemstream_close; _SET_ORIENTATION(fp, 1); return (fp); }
FILE * fdopen(int fd, const char *mode) { register FILE *fp; static int nofile; int flags, oflags, fdflags, tmp; if (nofile == 0) nofile = getdtablesize(); if ((flags = __sflags(mode, &oflags)) == 0) return (NULL); /* Make sure the mode the user wants is a subset of the actual mode. */ #ifdef __ORCAC__ /* ORCA/C: Provide only required args to variadic functions */ if ((fdflags = fcntl(fd, F_GETFL)) < 0) #else if ((fdflags = fcntl(fd, F_GETFL, 0)) < 0) #endif return (NULL); tmp = fdflags & O_ACCMODE; if (tmp != O_RDWR && (tmp != (oflags & O_ACCMODE))) { errno = EINVAL; return (NULL); } if ((fp = __sfp()) == NULL) return (NULL); fp->_flags = flags; /* * If opened for appending, but underlying descriptor does not have * O_APPEND bit set, assert __SAPP so that __swrite() will lseek to * end before each write. */ if ((oflags & O_APPEND) && !(fdflags & O_APPEND)) fp->_flags |= __SAPP; fp->_file = fd; fp->_cookie = fp; fp->_read = __sread; fp->_write = __swrite; fp->_seek = __sseek; fp->_close = __sclose; return (fp); }
FILE * fopencookie(void *cookie, const char *mode, cookie_io_functions_t functions) { FILE *fp; fccookie *c; int flags; int dummy; if ((flags = __sflags (mode, &dummy)) == 0) return NULL; if (((flags & (__SRD | __SRW)) && !functions.read) || ((flags & (__SWR | __SRW)) && !functions.write)) { return NULL; } if ((fp = (FILE *) __sfp ()) == NULL) return NULL; if ((c = (fccookie *) malloc (sizeof *c)) == NULL) { fp->_flags = 0; return NULL; } fp->_file = -1; fp->_flags = flags; c->cookie = cookie; c->fp = fp; fp->_cookie = c; c->readfn = functions.read; fp->_read = fcread; c->writefn = functions.write; fp->_write = fcwrite; c->seekfn = functions.seek; fp->_seek = functions.seek ? fcseek : NULL; c->closefn = functions.close; fp->_close = fcclose; return fp; }
FILE *fdopen(int fd, const char *mode) { register FILE *fp; int flags, oflags, fdflags, tmp; if ((flags = __sflags(mode, &oflags)) == 0) return (NULL); /* Make sure the mode the user wants is a subset of the actual mode. */ if ((fdflags = fcntl(fd, F_GETFL, 0)) < 0) return (NULL); tmp = fdflags & O_ACCMODE; if (tmp != O_RDWR && (tmp != (oflags & O_ACCMODE))) { errno = EINVAL; return (NULL); } __sinit (); pthread_mutex_lock(&__sfp_mutex); while (__sfp_state) { pthread_cond_wait(&__sfp_cond, &__sfp_mutex); } if (fp = __sfp()) { fp->_flags = flags; /* * If opened for appending, but underlying descriptor does not have * O_APPEND bit set, assert __SAPP so that __swrite() will lseek to * end before each write. */ if ((oflags & O_APPEND) && !(fdflags & O_APPEND)) fp->_flags |= __SAPP; fp->_file = fd; } pthread_mutex_unlock(&__sfp_mutex); return (fp); }
FILE * fdopen(int fd, const char *mode) { FILE *fp; int flags, oflags, fdflags, tmp; if ((flags = __sflags(mode, &oflags)) == 0) return (NULL); /* Make sure the mode the user wants is a subset of the actual mode. */ if ((fdflags = _fcntl(fd, F_GETFL, 0)) < 0) return (NULL); tmp = fdflags & O_ACCMODE; if (tmp != O_RDWR && (tmp != (oflags & O_ACCMODE))) { errno = EINVAL; return (NULL); } if ((fp = __sfp()) == NULL) return (NULL); fp->pub._flags = flags; /* * If opened for appending, but underlying descriptor does not have * O_APPEND bit set, assert __SAPP so that __swrite() caller * will _sseek() to the end before write. */ if ((oflags & O_APPEND) && !(fdflags & O_APPEND)) fp->pub._flags |= __SAPP; fp->pub._fileno = fd; fp->_cookie = fp; fp->_read = __sread; fp->_write = __swrite; fp->_seek = __sseek; fp->_close = __sclose; return (fp); }
FILE * fmemopen(void *buf, size_t size, const char *mode) { struct state *st; FILE *fp; int flags, oflags; if (size == 0) { errno = EINVAL; return (NULL); } if ((flags = __sflags(mode, &oflags)) == 0) { errno = EINVAL; return (NULL); } if (buf == NULL && ((oflags & O_RDWR) == 0)) { errno = EINVAL; return (NULL); } if ((st = malloc(sizeof(*st))) == NULL) return (NULL); if ((fp = __sfp()) == NULL) { free(st); return (NULL); } st->pos = 0; st->len = (oflags & O_WRONLY) ? 0 : size; st->size = size; st->update = oflags & O_RDWR; if (buf == NULL) { if ((st->string = malloc(size)) == NULL) { free(st); fp->_flags = 0; return (NULL); } *st->string = '\0'; } else { st->string = (char *)buf; if (oflags & O_TRUNC) *st->string = '\0'; if (oflags & O_APPEND) { char *p; if ((p = memchr(st->string, '\0', size)) != NULL) st->pos = st->len = (p - st->string); else st->pos = st->len = size; } } fp->_flags = (short)flags; fp->_file = -1; fp->_cookie = (void *)st; fp->_read = (flags & __SWR) ? NULL : fmemopen_read; fp->_write = (flags & __SRD) ? NULL : fmemopen_write; fp->_seek = fmemopen_seek; fp->_close = (buf == NULL) ? fmemopen_close_free : fmemopen_close; return (fp); }
} c99_fopen_t; #ifndef _REENT_ONLY FILE * _DEFUN (fopen, (file, mode), _CONST char *file _AND _CONST char *mode) { int ret; c99_fopen_t args; FILE *fp; struct _reent *ptr = _REENT; CHECK_INIT(ptr); fp = __sfp(ptr); if (!fp) { return NULL; } args.file = file; args.mode = mode; ret = __send_to_ppe(SPE_C99_SIGNALCODE, SPE_C99_FOPEN, &args); if (ret) { fp->_fp = ret; return fp; } else { __sfp_free(fp);
FILE * _fdopen64_r (struct _reent *ptr, int fd, const char *mode) { register FILE *fp; int flags, oflags; #ifdef HAVE_FCNTL int fdflags, fdmode; #endif if ((flags = __sflags (ptr, mode, &oflags)) == 0) return 0; /* make sure the mode the user wants is a subset of the actual mode */ #ifdef HAVE_FCNTL if ((fdflags = _fcntl_r (ptr, fd, F_GETFL, 0)) < 0) return 0; fdmode = fdflags & O_ACCMODE; if (fdmode != O_RDWR && (fdmode != (oflags & O_ACCMODE))) { ptr->_errno = EBADF; return 0; } #endif if ((fp = __sfp (ptr)) == 0) return 0; _newlib_flockfile_start(fp); fp->_flags = flags; /* POSIX recommends setting the O_APPEND bit on fd to match append streams. Someone may later clear O_APPEND on fileno(fp), but the stream must still remain in append mode. Rely on __sflags setting __SAPP properly. */ #ifdef HAVE_FCNTL if ((oflags & O_APPEND) && !(fdflags & O_APPEND)) _fcntl_r (ptr, fd, F_SETFL, fdflags | O_APPEND); #endif fp->_file = fd; fp->_cookie = (void *) fp; #undef _read #undef _write #undef _seek #undef _close fp->_read = __sread; fp->_write = __swrite64; fp->_seek = __sseek; fp->_seek64 = __sseek64; fp->_close = __sclose; #ifdef __SCLE /* Explicit given mode results in explicit setting mode on fd */ if (oflags & O_BINARY) setmode(fp->_file, O_BINARY); else if (oflags & O_TEXT) setmode(fp->_file, O_TEXT); if (__stextmode(fp->_file)) fp->_flags |= __SCLE; #endif fp->_flags |= __SL64; _newlib_flockfile_end(fp); return fp; }
FILE * _funopen_r (struct _reent *ptr, const void *cookie, funread readfn, funwrite writefn, funseek seekfn, funclose closefn) { FILE *fp; funcookie *c; if (!readfn && !writefn) { __errno_r(ptr) = EINVAL; return NULL; } if ((fp = __sfp (ptr)) == NULL) return NULL; if ((c = (funcookie *) _malloc_r (ptr, sizeof *c)) == NULL) { _newlib_sfp_lock_start (); fp->_flags = 0; /* release */ #ifndef __SINGLE_THREAD__ __lock_close_recursive (fp->_lock); #endif _newlib_sfp_lock_end (); return NULL; } _newlib_flockfile_start (fp); fp->_file = -1; c->cookie = (void *) cookie; /* cast away const */ fp->_cookie = c; if (readfn) { c->readfn = readfn; fp->_read = funreader; if (writefn) { fp->_flags = __SRW; c->writefn = writefn; fp->_write = funwriter; } else { fp->_flags = __SRD; c->writefn = NULL; fp->_write = NULL; } } else { fp->_flags = __SWR; c->writefn = writefn; fp->_write = funwriter; c->readfn = NULL; fp->_read = NULL; } c->seekfn = seekfn; fp->_seek = seekfn ? funseeker : NULL; #ifdef __LARGE64_FILES fp->_seek64 = seekfn ? funseeker64 : NULL; fp->_flags |= __SL64; #endif c->closefn = closefn; fp->_close = funcloser; _newlib_flockfile_end (fp); return fp; }