Back to index

glibc  2.9
Defines | Functions
iofdopen.c File Reference
#include "libioP.h"
#include <fcntl.h>

Go to the source code of this file.

Defines

#define _IO_fcntl   fcntl

Functions

_IO_FILE_IO_new_fdopen (int fd, const char *mode)

Define Documentation

#define _IO_fcntl   fcntl

Definition at line 43 of file iofdopen.c.


Function Documentation

_IO_FILE* _IO_new_fdopen ( int  fd,
const char *  mode 
)

Definition at line 48 of file iofdopen.c.

{
  int read_write;
  int posix_mode = 0;
  struct locked_FILE
  {
    struct _IO_FILE_plus fp;
#ifdef _IO_MTSAFE_IO
    _IO_lock_t lock;
#endif
    struct _IO_wide_data wd;
  } *new_f;
  int fd_flags;
  int i;
  int use_mmap = 0;

  switch (*mode)
    {
    case 'r':
      read_write = _IO_NO_WRITES;
      break;
    case 'w':
      read_write = _IO_NO_READS;
      break;
    case 'a':
      posix_mode = O_APPEND;
      read_write = _IO_NO_READS|_IO_IS_APPENDING;
      break;
    default:
      MAYBE_SET_EINVAL;
      return NULL;
  }
  for (i = 1; i < 5; ++i)
    {
      switch (*++mode)
       {
       case '\0':
         break;
       case '+':
         read_write &= _IO_IS_APPENDING;
         break;
       case 'm':
         use_mmap = 1;
         continue;
       case 'x':
       case 'b':
       default:
         /* Ignore */
         continue;
       }
      break;
    }
#ifdef F_GETFL
  fd_flags = _IO_fcntl (fd, F_GETFL);
#ifndef O_ACCMODE
#define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR)
#endif
  if (fd_flags == -1)
    return NULL;

  if (((fd_flags & O_ACCMODE) == O_RDONLY && !(read_write & _IO_NO_WRITES))
      || ((fd_flags & O_ACCMODE) == O_WRONLY && !(read_write & _IO_NO_READS)))
    {
      MAYBE_SET_EINVAL;
      return NULL;
    }

  /* The May 93 draft of P1003.4/D14.1 (redesignated as 1003.1b)
     [System Application Program Interface (API) Amendment 1:
     Realtime Extensions], Rationale B.8.3.3
     Open a Stream on a File Descriptor says:

         Although not explicitly required by POSIX.1, a good
         implementation of append ("a") mode would cause the
         O_APPEND flag to be set.

     (Historical implementations [such as Solaris2] do a one-time
     seek in fdopen.)

     However, we do not turn O_APPEND off if the mode is "w" (even
     though that would seem consistent) because that would be more
     likely to break historical programs.
     */
  if ((posix_mode & O_APPEND) && !(fd_flags & O_APPEND))
    {
#ifdef F_SETFL
      if (_IO_fcntl (fd, F_SETFL, fd_flags | O_APPEND) == -1)
#endif
       return NULL;
    }
#endif

  new_f = (struct locked_FILE *) malloc (sizeof (struct locked_FILE));
  if (new_f == NULL)
    return NULL;
#ifdef _IO_MTSAFE_IO
  new_f->fp.file._lock = &new_f->lock;
#endif
  /* Set up initially to use the `maybe_mmap' jump tables rather than using
     __fopen_maybe_mmap to do it, because we need them in place before we
     call _IO_file_attach or else it will allocate a buffer immediately.  */
  _IO_no_init (&new_f->fp.file, 0, 0, &new_f->wd,
#ifdef _G_HAVE_MMAP
              (use_mmap && (read_write & _IO_NO_WRITES))
              ? &_IO_wfile_jumps_maybe_mmap :
#endif
              &_IO_wfile_jumps);
  _IO_JUMPS (&new_f->fp) =
#ifdef _G_HAVE_MMAP
    (use_mmap && (read_write & _IO_NO_WRITES)) ? &_IO_file_jumps_maybe_mmap :
#endif
      &_IO_file_jumps;
  INTUSE(_IO_file_init) (&new_f->fp);
#if  !_IO_UNIFIED_JUMPTABLES
  new_f->fp.vtable = NULL;
#endif
  if (INTUSE(_IO_file_attach) ((_IO_FILE *) &new_f->fp, fd) == NULL)
    {
      INTUSE(_IO_setb) (&new_f->fp.file, NULL, NULL, 0);
      INTUSE(_IO_un_link) (&new_f->fp);
      free (new_f);
      return NULL;
    }
  new_f->fp.file._flags &= ~_IO_DELETE_DONT_CLOSE;

  new_f->fp.file._IO_file_flags =
    _IO_mask_flags (&new_f->fp.file, read_write,
                  _IO_NO_READS+_IO_NO_WRITES+_IO_IS_APPENDING);

  return &new_f->fp.file;
}

Here is the call graph for this function: