Back to index

glibc  2.9
oldiofdopen.c
Go to the documentation of this file.
00001 /* Copyright (C) 1993,94,97,99,2000,2002,2003,2004
00002    Free Software Foundation, Inc.
00003    This file is part of the GNU C Library.
00004 
00005    The GNU C Library is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Lesser General Public
00007    License as published by the Free Software Foundation; either
00008    version 2.1 of the License, or (at your option) any later version.
00009 
00010    The GNU C Library is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Lesser General Public License for more details.
00014 
00015    You should have received a copy of the GNU Lesser General Public
00016    License along with the GNU C Library; if not, write to the Free
00017    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00018    02111-1307 USA.
00019 
00020    As a special exception, if you link the code in this file with
00021    files compiled with a GNU compiler to produce an executable,
00022    that does not cause the resulting executable to be covered by
00023    the GNU Lesser General Public License.  This exception does not
00024    however invalidate any other reasons why the executable file
00025    might be covered by the GNU Lesser General Public License.
00026    This exception applies to code released by its copyright holders
00027    in files containing the exception.  */
00028 
00029 #include <shlib-compat.h>
00030 #if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
00031 
00032 #define _IO_USE_OLD_IO_FILE
00033 #ifdef __STDC__
00034 # include <stdlib.h>
00035 #endif
00036 #include "libioP.h"
00037 #include <fcntl.h>
00038 
00039 #ifndef _IO_fcntl
00040 # define _IO_fcntl __fcntl
00041 #endif
00042 
00043 _IO_FILE *
00044 attribute_compat_text_section
00045 _IO_old_fdopen (fd, mode)
00046      int fd;
00047      const char *mode;
00048 {
00049   int read_write;
00050   int posix_mode = 0;
00051   struct locked_FILE
00052   {
00053     struct _IO_FILE_complete_plus fp;
00054 #ifdef _IO_MTSAFE_IO
00055     _IO_lock_t lock;
00056 #endif
00057   } *new_f;
00058   int fd_flags;
00059 
00060   switch (*mode++)
00061     {
00062     case 'r':
00063       read_write = _IO_NO_WRITES;
00064       break;
00065     case 'w':
00066       read_write = _IO_NO_READS;
00067       break;
00068     case 'a':
00069       posix_mode = O_APPEND;
00070       read_write = _IO_NO_READS|_IO_IS_APPENDING;
00071       break;
00072     default:
00073       MAYBE_SET_EINVAL;
00074       return NULL;
00075   }
00076   if (mode[0] == '+' || (mode[0] == 'b' && mode[1] == '+'))
00077     read_write &= _IO_IS_APPENDING;
00078 #ifdef F_GETFL
00079   fd_flags = _IO_fcntl (fd, F_GETFL);
00080 #ifndef O_ACCMODE
00081 #define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR)
00082 #endif
00083   if (fd_flags == -1
00084       || ((fd_flags & O_ACCMODE) == O_RDONLY && !(read_write & _IO_NO_WRITES))
00085       || ((fd_flags & O_ACCMODE) == O_WRONLY && !(read_write & _IO_NO_READS)))
00086     return NULL;
00087 
00088   /* The May 93 draft of P1003.4/D14.1 (redesignated as 1003.1b)
00089      [System Application Program Interface (API) Amendment 1:
00090      Realtime Extensions], Rationale B.8.3.3
00091      Open a Stream on a File Descriptor says:
00092 
00093          Although not explicitly required by POSIX.1, a good
00094          implementation of append ("a") mode would cause the
00095          O_APPEND flag to be set.
00096 
00097      (Historical implementations [such as Solaris2] do a one-time
00098      seek in fdopen.)
00099 
00100      However, we do not turn O_APPEND off if the mode is "w" (even
00101      though that would seem consistent) because that would be more
00102      likely to break historical programs.
00103      */
00104   if ((posix_mode & O_APPEND) && !(fd_flags & O_APPEND))
00105     {
00106 #ifdef F_SETFL
00107       if (_IO_fcntl (fd, F_SETFL, fd_flags | O_APPEND) == -1)
00108 #endif
00109        return NULL;
00110     }
00111 #endif
00112 
00113   new_f = (struct locked_FILE *) malloc (sizeof (struct locked_FILE));
00114   if (new_f == NULL)
00115     return NULL;
00116 #ifdef _IO_MTSAFE_IO
00117   new_f->fp.file._file._lock = &new_f->lock;
00118 #endif
00119   _IO_old_init (&new_f->fp.file._file, 0);
00120   _IO_JUMPS ((struct _IO_FILE_plus *) &new_f->fp) = &_IO_old_file_jumps;
00121   _IO_old_file_init ((struct _IO_FILE_plus *) &new_f->fp);
00122 #if  !_IO_UNIFIED_JUMPTABLES
00123   new_f->fp.vtable = NULL;
00124 #endif
00125   if (_IO_old_file_attach (&new_f->fp.file._file, fd) == NULL)
00126     {
00127       INTUSE(_IO_un_link) ((struct _IO_FILE_plus *) &new_f->fp);
00128       free (new_f);
00129       return NULL;
00130     }
00131   new_f->fp.file._file._flags &= ~_IO_DELETE_DONT_CLOSE;
00132 
00133   new_f->fp.file._file._IO_file_flags =
00134     _IO_mask_flags (&new_f->fp.file._file, read_write,
00135                   _IO_NO_READS+_IO_NO_WRITES+_IO_IS_APPENDING);
00136 
00137   return (_IO_FILE *) &new_f->fp;
00138 }
00139 
00140 strong_alias (_IO_old_fdopen, __old_fdopen)
00141 compat_symbol (libc, _IO_old_fdopen, _IO_fdopen, GLIBC_2_0);
00142 compat_symbol (libc, __old_fdopen, fdopen, GLIBC_2_0);
00143 
00144 #endif