(linenum→info "unix/slp.c:2238")

glibc/2.7/libio/iofdopen.c

    1: /* Copyright (C) 1993,1994,1997,1998,1999,2000,2002,2003
    2:         Free Software Foundation, Inc.
    3:    This file is part of the GNU C Library.
    4: 
    5:    The GNU C Library is free software; you can redistribute it and/or
    6:    modify it under the terms of the GNU Lesser General Public
    7:    License as published by the Free Software Foundation; either
    8:    version 2.1 of the License, or (at your option) any later version.
    9: 
   10:    The GNU C Library is distributed in the hope that it will be useful,
   11:    but WITHOUT ANY WARRANTY; without even the implied warranty of
   12:    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   13:    Lesser General Public License for more details.
   14: 
   15:    You should have received a copy of the GNU Lesser General Public
   16:    License along with the GNU C Library; if not, write to the Free
   17:    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   18:    02111-1307 USA.
   19: 
   20:    As a special exception, if you link the code in this file with
   21:    files compiled with a GNU compiler to produce an executable,
   22:    that does not cause the resulting executable to be covered by
   23:    the GNU Lesser General Public License.  This exception does not
   24:    however invalidate any other reasons why the executable file
   25:    might be covered by the GNU Lesser General Public License.
   26:    This exception applies to code released by its copyright holders
   27:    in files containing the exception.  */
   28: 
   29: #ifdef __STDC__
   30: # include <stdlib.h>
   31: #endif
   32: #include "libioP.h"
   33: #include <fcntl.h>
   34: 
   35: #ifdef _LIBC
   36: # include <shlib-compat.h>
   37: #endif
   38: 
   39: #ifndef _IO_fcntl
   40: #ifdef _LIBC
   41: #define _IO_fcntl __fcntl
   42: #else
   43: #define _IO_fcntl fcntl
   44: #endif
   45: #endif
   46: 
   47: _IO_FILE *
   48: _IO_new_fdopen (fd, mode)
   49:      int fd;
   50:      const char *mode;
   51: {
   52:   int read_write;
   53:   int posix_mode = 0;
   54:   struct locked_FILE
   55:   {
   56:     struct _IO_FILE_plus fp;
   57: #ifdef _IO_MTSAFE_IO
   58:     _IO_lock_t lock;
   59: #endif
   60:     struct _IO_wide_data wd;
   61:   } *new_f;
   62:   int fd_flags;
   63:   int i;
   64:   int use_mmap = 0;
   65: 
   66:   switch (*mode)
   67:     {
   68:     case 'r':
   69:       read_write = _IO_NO_WRITES;
   70:       break;
   71:     case 'w':
   72:       read_write = _IO_NO_READS;
   73:       break;
   74:     case 'a':
   75:       posix_mode = O_APPEND;
   76:       read_write = _IO_NO_READS|_IO_IS_APPENDING;
   77:       break;
   78:     default:
   79:       MAYBE_SET_EINVAL;
   80:       return NULL;
   81:   }
   82:   for (i = 1; i < 5; ++i)
   83:     {
   84:       switch (*++mode)
   85:         {
   86:         case '\0':
   87:           break;
   88:         case '+':
   89:           read_write &= _IO_IS_APPENDING;
   90:           break;
   91:         case 'm':
   92:           use_mmap = 1;
   93:           continue;
   94:         case 'x':
   95:         case 'b':
   96:         default:
   97:           /* Ignore */
   98:           continue;
   99:         }
  100:       break;
  101:     }
  102: #ifdef F_GETFL
  103:   fd_flags = _IO_fcntl (fd, F_GETFL);
  104: #ifndef O_ACCMODE
  105: #define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR)
  106: #endif
  107:   if (fd_flags == -1)
  108:     return NULL;
  109: 
  110:   if (((fd_flags & O_ACCMODE) == O_RDONLY && !(read_write & _IO_NO_WRITES))
  111:       || ((fd_flags & O_ACCMODE) == O_WRONLY && !(read_write & _IO_NO_READS)))
  112:     {
  113:       MAYBE_SET_EINVAL;
  114:       return NULL;
  115:     }
  116: 
  117:   /* The May 93 draft of P1003.4/D14.1 (redesignated as 1003.1b)
  118:      [System Application Program Interface (API) Amendment 1:
  119:      Realtime Extensions], Rationale B.8.3.3
  120:      Open a Stream on a File Descriptor says:
  121: 
  122:          Although not explicitly required by POSIX.1, a good
  123:          implementation of append ("a") mode would cause the
  124:          O_APPEND flag to be set.
  125: 
  126:      (Historical implementations [such as Solaris2] do a one-time
  127:      seek in fdopen.)
  128: 
  129:      However, we do not turn O_APPEND off if the mode is "w" (even
  130:      though that would seem consistent) because that would be more
  131:      likely to break historical programs.
  132:      */
  133:   if ((posix_mode & O_APPEND) && !(fd_flags & O_APPEND))
  134:     {
  135: #ifdef F_SETFL
  136:       if (_IO_fcntl (fd, F_SETFL, fd_flags | O_APPEND) == -1)
  137: #endif
  138:         return NULL;
  139:     }
  140: #endif
  141: 
  142:   new_f = (struct locked_FILE *) malloc (sizeof (struct locked_FILE));
  143:   if (new_f == NULL)
  144:     return NULL;
  145: #ifdef _IO_MTSAFE_IO
  146:   new_f->fp.file._lock = &new_f->lock;
  147: #endif
  148:   /* Set up initially to use the `maybe_mmap' jump tables rather than using
  149:      __fopen_maybe_mmap to do it, because we need them in place before we
  150:      call _IO_file_attach or else it will allocate a buffer immediately.  */
  151:   _IO_no_init (&new_f->fp.file, 0, 0, &new_f->wd,
  152: #ifdef _G_HAVE_MMAP
  153:                (use_mmap && (read_write & _IO_NO_WRITES))
  154:                ? &_IO_wfile_jumps_maybe_mmap :
  155: #endif
  156:                &_IO_wfile_jumps);
  157:   _IO_JUMPS (&new_f->fp) =
  158: #ifdef _G_HAVE_MMAP
  159:     (use_mmap && (read_write & _IO_NO_WRITES)) ? &_IO_file_jumps_maybe_mmap :
  160: #endif
  161:       &_IO_file_jumps;
  162:   INTUSE(_IO_file_init) (&new_f->fp);
  163: #if  !_IO_UNIFIED_JUMPTABLES
  164:   new_f->fp.vtable = NULL;
  165: #endif
  166:   if (INTUSE(_IO_file_attach) ((_IO_FILE *) &new_f->fp, fd) == NULL)
  167:     {
  168:       INTUSE(_IO_setb) (&new_f->fp.file, NULL, NULL, 0);
  169:       INTUSE(_IO_un_link) (&new_f->fp);
  170:       free (new_f);
  171:       return NULL;
  172:     }
  173:   new_f->fp.file._flags &= ~_IO_DELETE_DONT_CLOSE;
  174: 
  175:   new_f->fp.file._IO_file_flags =
  176:     _IO_mask_flags (&new_f->fp.file, read_write,
  177:                     _IO_NO_READS+_IO_NO_WRITES+_IO_IS_APPENDING);
  178: 
  179:   return &new_f->fp.file;
  180: }
  181: INTDEF2(_IO_new_fdopen, _IO_fdopen)
  182: 
  183: strong_alias (_IO_new_fdopen, __new_fdopen)
  184: versioned_symbol (libc, _IO_new_fdopen, _IO_fdopen, GLIBC_2_1);
  185: versioned_symbol (libc, __new_fdopen, fdopen, GLIBC_2_1);
Syntax (Markdown)