diff options
Diffstat (limited to 'newlib/libc/stdio64/fdopen64.c')
-rw-r--r-- | newlib/libc/stdio64/fdopen64.c | 120 |
1 files changed, 120 insertions, 0 deletions
diff --git a/newlib/libc/stdio64/fdopen64.c b/newlib/libc/stdio64/fdopen64.c new file mode 100644 index 000000000..96c76411f --- /dev/null +++ b/newlib/libc/stdio64/fdopen64.c @@ -0,0 +1,120 @@ +/* +FUNCTION +<<fdopen64>>---turn open file into a stream + +INDEX + fdopen64 +INDEX + _fdopen64_r + +SYNOPSIS + #include <stdio.h> + FILE *fdopen64(int <[fd]>, const char *<[mode]>); + FILE *_fdopen64_r(void *<[reent]>, + int <[fd]>, const char *<[mode]>); + +DESCRIPTION +<<fdopen64>> produces a file descriptor of type <<FILE *>>, from a +descriptor for an already-open file (returned, for example, by the +system subroutine <<open>> rather than by <<fopen>>). +The <[mode]> argument has the same meanings as in <<fopen>>. + +RETURNS +File pointer or <<NULL>>, as for <<fopen>>. +*/ + +#include <sys/types.h> +#include <sys/fcntl.h> + +#include <stdio.h> +#include <errno.h> +#include "local64.h" +#include <_syslist.h> + +extern int __sflags (); + +FILE * +_DEFUN (_fdopen64_r, (ptr, fd, mode), + struct _reent *ptr _AND + int fd _AND + _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; + 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 HAVE_FCNTL + && !(fdflags & O_APPEND) +#endif + ) + fp->_flags |= __SAPP; + fp->_file = fd; + fp->_cookie = (_PTR) 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 + +#ifndef __SINGLE_THREAD__ + __lock_init_recursive (*(_LOCK_RECURSIVE_T *)&fp->_lock); +#endif + + fp->_flags |= __SL64; + + return fp; +} + +#ifndef _REENT_ONLY + +FILE * +_DEFUN (fdopen64, (fd, mode), + int fd _AND + _CONST char *mode) +{ + return _fdopen64_r (_REENT, fd, mode); +} + +#endif |