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

glibc/2.7/libio/fileops.c

    1: /* Copyright (C) 1993, 1995, 1997-2005, 2006, 2007
    2:    Free Software Foundation, Inc.
    3:    This file is part of the GNU C Library.
    4:    Written by Per Bothner <bothner@cygnus.com>.
    5: 
    6:    The GNU C Library is free software; you can redistribute it and/or
    7:    modify it under the terms of the GNU Lesser General Public
    8:    License as published by the Free Software Foundation; either
    9:    version 2.1 of the License, or (at your option) any later version.
   10: 
   11:    The GNU C Library is distributed in the hope that it will be useful,
   12:    but WITHOUT ANY WARRANTY; without even the implied warranty of
   13:    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   14:    Lesser General Public License for more details.
   15: 
   16:    You should have received a copy of the GNU Lesser General Public
   17:    License along with the GNU C Library; if not, write to the Free
   18:    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   19:    02111-1307 USA.
   20: 
   21:    As a special exception, if you link the code in this file with
   22:    files compiled with a GNU compiler to produce an executable,
   23:    that does not cause the resulting executable to be covered by
   24:    the GNU Lesser General Public License.  This exception does not
   25:    however invalidate any other reasons why the executable file
   26:    might be covered by the GNU Lesser General Public License.
   27:    This exception applies to code released by its copyright holders
   28:    in files containing the exception.  */
   29: 
   30: 
   31: #ifndef _POSIX_SOURCE
   32: # define _POSIX_SOURCE
   33: #endif
   34: #include "libioP.h"
   35: #include <assert.h>
   36: #include <fcntl.h>
   37: #include <sys/param.h>
   38: #include <sys/types.h>
   39: #include <sys/stat.h>
   40: #include <string.h>
   41: #include <errno.h>
   42: #include <unistd.h>
   43: #ifdef __STDC__
   44: #include <stdlib.h>
   45: #endif
   46: #if _LIBC
   47: # include "../wcsmbs/wcsmbsload.h"
   48: # include "../iconv/gconv_charset.h"
   49: # include "../iconv/gconv_int.h"
   50: # include <shlib-compat.h>
   51: # include <not-cancel.h>
   52: #endif
   53: #ifndef errno
   54: extern int errno;
   55: #endif
   56: #ifndef __set_errno
   57: # define __set_errno(Val) errno = (Val)
   58: #endif
   59: 
   60: 
   61: #ifdef _LIBC
   62: # define open(Name, Flags, Prot) __open (Name, Flags, Prot)
   63: # define lseek(FD, Offset, Whence) __lseek (FD, Offset, Whence)
   64: # define read(FD, Buf, NBytes) __read (FD, Buf, NBytes)
   65: # define write(FD, Buf, NBytes) __write (FD, Buf, NBytes)
   66: # define _IO_do_write _IO_new_do_write /* For macro uses.  */
   67: # define _IO_file_close_it _IO_new_file_close_it
   68: #else
   69: # define _IO_new_do_write _IO_do_write
   70: # define _IO_new_file_attach _IO_file_attach
   71: # define _IO_new_file_close_it _IO_file_close_it
   72: # define _IO_new_file_finish _IO_file_finish
   73: # define _IO_new_file_fopen _IO_file_fopen
   74: # define _IO_new_file_init _IO_file_init
   75: # define _IO_new_file_setbuf _IO_file_setbuf
   76: # define _IO_new_file_sync _IO_file_sync
   77: # define _IO_new_file_overflow _IO_file_overflow
   78: # define _IO_new_file_seekoff _IO_file_seekoff
   79: # define _IO_new_file_underflow _IO_file_underflow
   80: # define _IO_new_file_write _IO_file_write
   81: # define _IO_new_file_xsputn _IO_file_xsputn
   82: #endif
   83: 
   84: 
   85: #ifdef _LIBC
   86: extern struct __gconv_trans_data __libio_translit attribute_hidden;
   87: #endif
   88: 
   89: 
   90: /* An fstream can be in at most one of put mode, get mode, or putback mode.
   91:    Putback mode is a variant of get mode.
   92: 
   93:    In a filebuf, there is only one current position, instead of two
   94:    separate get and put pointers.  In get mode, the current position
   95:    is that of gptr(); in put mode that of pptr().
   96: 
   97:    The position in the buffer that corresponds to the position
   98:    in external file system is normally _IO_read_end, except in putback
   99:    mode, when it is _IO_save_end.
  100:    If the field _fb._offset is >= 0, it gives the offset in
  101:    the file as a whole corresponding to eGptr(). (?)
  102: 
  103:    PUT MODE:
  104:    If a filebuf is in put mode, then all of _IO_read_ptr, _IO_read_end,
  105:    and _IO_read_base are equal to each other.  These are usually equal
  106:    to _IO_buf_base, though not necessarily if we have switched from
  107:    get mode to put mode.  (The reason is to maintain the invariant
  108:    that _IO_read_end corresponds to the external file position.)
  109:    _IO_write_base is non-NULL and usually equal to _IO_base_base.
  110:    We also have _IO_write_end == _IO_buf_end, but only in fully buffered mode.
  111:    The un-flushed character are those between _IO_write_base and _IO_write_ptr.
  112: 
  113:    GET MODE:
  114:    If a filebuf is in get or putback mode, eback() != egptr().
  115:    In get mode, the unread characters are between gptr() and egptr().
  116:    The OS file position corresponds to that of egptr().
  117: 
  118:    PUTBACK MODE:
  119:    Putback mode is used to remember "excess" characters that have
  120:    been sputbackc'd in a separate putback buffer.
  121:    In putback mode, the get buffer points to the special putback buffer.
  122:    The unread characters are the characters between gptr() and egptr()
  123:    in the putback buffer, as well as the area between save_gptr()
  124:    and save_egptr(), which point into the original reserve buffer.
  125:    (The pointers save_gptr() and save_egptr() are the values
  126:    of gptr() and egptr() at the time putback mode was entered.)
  127:    The OS position corresponds to that of save_egptr().
  128: 
  129:    LINE BUFFERED OUTPUT:
  130:    During line buffered output, _IO_write_base==base() && epptr()==base().
  131:    However, ptr() may be anywhere between base() and ebuf().
  132:    This forces a call to filebuf::overflow(int C) on every put.
  133:    If there is more space in the buffer, and C is not a '\n',
  134:    then C is inserted, and pptr() incremented.
  135: 
  136:    UNBUFFERED STREAMS:
  137:    If a filebuf is unbuffered(), the _shortbuf[1] is used as the buffer.
  138: */
  139: 
  140: #define CLOSED_FILEBUF_FLAGS \
  141:   (_IO_IS_FILEBUF+_IO_NO_READS+_IO_NO_WRITES+_IO_TIED_PUT_GET)
  142: 
  143: 
  144: void
  145: _IO_new_file_init (fp)
  146:      struct _IO_FILE_plus *fp;
  147: {
  148:   /* POSIX.1 allows another file handle to be used to change the position
  149:      of our file descriptor.  Hence we actually don't know the actual
  150:      position before we do the first fseek (and until a following fflush). */
  151:   fp->file._offset = _IO_pos_BAD;
  152:   fp->file._IO_file_flags |= CLOSED_FILEBUF_FLAGS;
  153: 
  154:   INTUSE(_IO_link_in) (fp);
  155:   fp->file._fileno = -1;
  156: }
  157: INTDEF2(_IO_new_file_init, _IO_file_init)
  158: 
  159: int
  160: _IO_new_file_close_it (fp)
  161:      _IO_FILE *fp;
  162: {
  163:   int write_status, close_status;
  164:   if (!_IO_file_is_open (fp))
  165:     return EOF;
  166: 
  167:   if ((fp->_flags & _IO_NO_WRITES) == 0
  168:       && (fp->_flags & _IO_CURRENTLY_PUTTING) != 0)
  169:     write_status = _IO_do_flush (fp);
  170:   else
  171:     write_status = 0;
  172: 
  173:   INTUSE(_IO_unsave_markers) (fp);
  174: 
  175:   close_status = _IO_SYSCLOSE (fp);
  176: 
  177:   /* Free buffer. */
  178: #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
  179:   if (fp->_mode > 0)
  180:     {
  181:       if (_IO_have_wbackup (fp))
  182:         INTUSE(_IO_free_wbackup_area) (fp);
  183:       INTUSE(_IO_wsetb) (fp, NULL, NULL, 0);
  184:       _IO_wsetg (fp, NULL, NULL, NULL);
  185:       _IO_wsetp (fp, NULL, NULL);
  186:     }
  187: #endif
  188:   INTUSE(_IO_setb) (fp, NULL, NULL, 0);
  189:   _IO_setg (fp, NULL, NULL, NULL);
  190:   _IO_setp (fp, NULL, NULL);
  191: 
  192:   INTUSE(_IO_un_link) ((struct _IO_FILE_plus *) fp);
  193:   fp->_flags = _IO_MAGIC|CLOSED_FILEBUF_FLAGS;
  194:   fp->_fileno = -1;
  195:   fp->_offset = _IO_pos_BAD;
  196: 
  197:   return close_status ? close_status : write_status;
  198: }
  199: INTDEF2(_IO_new_file_close_it, _IO_file_close_it)
  200: 
  201: void
  202: _IO_new_file_finish (fp, dummy)
  203:      _IO_FILE *fp;
  204:      int dummy;
  205: {
  206:   if (_IO_file_is_open (fp))
  207:     {
  208:       _IO_do_flush (fp);
  209:       if (!(fp->_flags & _IO_DELETE_DONT_CLOSE))
  210:         _IO_SYSCLOSE (fp);
  211:     }
  212:   INTUSE(_IO_default_finish) (fp, 0);
  213: }
  214: INTDEF2(_IO_new_file_finish, _IO_file_finish)
  215: 
  216: _IO_FILE *
  217: _IO_file_open (fp, filename, posix_mode, prot, read_write, is32not64)
  218:      _IO_FILE *fp;
  219:      const char *filename;
  220:      int posix_mode;
  221:      int prot;
  222:      int read_write;
  223:      int is32not64;
  224: {
  225:   int fdesc;
  226: #ifdef _LIBC
  227:   if (__builtin_expect (fp->_flags2 & _IO_FLAGS2_NOTCANCEL, 0))
  228:     fdesc = open_not_cancel (filename,
  229:                              posix_mode | (is32not64 ? 0 : O_LARGEFILE), prot);
  230:   else
  231:     fdesc = open (filename, posix_mode | (is32not64 ? 0 : O_LARGEFILE), prot);
  232: #else
  233:   fdesc = open (filename, posix_mode, prot);
  234: #endif
  235:   if (fdesc < 0)
  236:     return NULL;
  237:   fp->_fileno = fdesc;
  238:   _IO_mask_flags (fp, read_write,_IO_NO_READS+_IO_NO_WRITES+_IO_IS_APPENDING);
  239:   if ((read_write & _IO_IS_APPENDING) && (read_write & _IO_NO_READS))
  240:     if (_IO_SEEKOFF (fp, (_IO_off64_t)0, _IO_seek_end, _IOS_INPUT|_IOS_OUTPUT)
  241:         == _IO_pos_BAD && errno != ESPIPE)
  242:       {
  243:         close_not_cancel (fdesc);
  244:         return NULL;
  245:       }
  246:   INTUSE(_IO_link_in) ((struct _IO_FILE_plus *) fp);
  247:   return fp;
  248: }
  249: libc_hidden_def (_IO_file_open)
  250: 
  251: _IO_FILE *
  252: _IO_new_file_fopen (fp, filename, mode, is32not64)
  253:      _IO_FILE *fp;
  254:      const char *filename;
  255:      const char *mode;
  256:      int is32not64;
  257: {
  258:   int oflags = 0, omode;
  259:   int read_write;
  260:   int oprot = 0666;
  261:   int i;
  262:   _IO_FILE *result;
  263: #ifdef _LIBC
  264:   const char *cs;
  265:   const char *last_recognized;
  266: #endif
  267: 
  268:   if (_IO_file_is_open (fp))
  269:     return 0;
  270:   switch (*mode)
  271:     {
  272:     case 'r':
  273:       omode = O_RDONLY;
  274:       read_write = _IO_NO_WRITES;
  275:       break;
  276:     case 'w':
  277:       omode = O_WRONLY;
  278:       oflags = O_CREAT|O_TRUNC;
  279:       read_write = _IO_NO_READS;
  280:       break;
  281:     case 'a':
  282:       omode = O_WRONLY;
  283:       oflags = O_CREAT|O_APPEND;
  284:       read_write = _IO_NO_READS|_IO_IS_APPENDING;
  285:       break;
  286:     default:
  287:       __set_errno (EINVAL);
  288:       return NULL;
  289:     }
  290: #ifdef _LIBC
  291:   last_recognized = mode;
  292: #endif
  293:   for (i = 1; i < 6; ++i)
  294:     {
  295:       switch (*++mode)
  296:         {
  297:         case '\0':
  298:           break;
  299:         case '+':
  300:           omode = O_RDWR;
  301:           read_write &= _IO_IS_APPENDING;
  302: #ifdef _LIBC
  303:           last_recognized = mode;
  304: #endif
  305:           continue;
  306:         case 'x':
  307:           oflags |= O_EXCL;
  308: #ifdef _LIBC
  309:           last_recognized = mode;
  310: #endif
  311:           continue;
  312:         case 'b':
  313: #ifdef _LIBC
  314:           last_recognized = mode;
  315: #endif
  316:           continue;
  317:         case 'm':
  318:           fp->_flags2 |= _IO_FLAGS2_MMAP;
  319:           continue;
  320:         case 'c':
  321:           fp->_flags2 |= _IO_FLAGS2_NOTCANCEL;
  322:           break;
  323: #ifdef O_CLOEXEC
  324:         case 'e':
  325:           oflags |= O_CLOEXEC;
  326:           break;
  327: #endif
  328:         default:
  329:           /* Ignore.  */
  330:           continue;
  331:         }
  332:       break;
  333:     }
  334: 
  335:   result = _IO_file_open (fp, filename, omode|oflags, oprot, read_write,
  336:                           is32not64);
  337: 
  338: 
  339: #ifdef _LIBC
  340:   if (result != NULL)
  341:     {
  342:       /* Test whether the mode string specifies the conversion.  */
  343:       cs = strstr (last_recognized + 1, ",ccs=");
  344:       if (cs != NULL)
  345:         {
  346:           /* Yep.  Load the appropriate conversions and set the orientation
  347:              to wide.  */
  348:           struct gconv_fcts fcts;
  349:           struct _IO_codecvt *cc;
  350:           char *endp = __strchrnul (cs + 5, ',');
  351:           char ccs[endp - (cs + 5) + 3];
  352: 
  353:           *((char *) __mempcpy (ccs, cs + 5, endp - (cs + 5))) = '\0';
  354:           strip (ccs, ccs);
  355: 
  356:           if (__wcsmbs_named_conv (&fcts, ccs[2] == '\0'
  357:                                    ? upstr (ccs, cs + 5) : ccs) != 0)
  358:             {
  359:               /* Something went wrong, we cannot load the conversion modules.
  360:                  This means we cannot proceed since the user explicitly asked
  361:                  for these.  */
  362:               (void) INTUSE(_IO_file_close_it) (fp);
  363:               __set_errno (EINVAL);
  364:               return NULL;
  365:             }
  366: 
  367:           assert (fcts.towc_nsteps == 1);
  368:           assert (fcts.tomb_nsteps == 1);
  369: 
  370:           fp->_wide_data->_IO_read_ptr = fp->_wide_data->_IO_read_end;
  371:           fp->_wide_data->_IO_write_ptr = fp->_wide_data->_IO_write_base;
  372: 
  373:           /* Clear the state.  We start all over again.  */
  374:           memset (&fp->_wide_data->_IO_state, '\0', sizeof (__mbstate_t));
  375:           memset (&fp->_wide_data->_IO_last_state, '\0', sizeof (__mbstate_t));
  376: 
  377:           cc = fp->_codecvt = &fp->_wide_data->_codecvt;
  378: 
  379:           /* The functions are always the same.  */
  380:           *cc = __libio_codecvt;
  381: 
  382:           cc->__cd_in.__cd.__nsteps = fcts.towc_nsteps;
  383:           cc->__cd_in.__cd.__steps = fcts.towc;
  384: 
  385:           cc->__cd_in.__cd.__data[0].__invocation_counter = 0;
  386:           cc->__cd_in.__cd.__data[0].__internal_use = 1;
  387:           cc->__cd_in.__cd.__data[0].__flags = __GCONV_IS_LAST;
  388:           cc->__cd_in.__cd.__data[0].__statep = &result->_wide_data->_IO_state;
  389: 
  390:           /* XXX For now no transliteration.  */
  391:           cc->__cd_in.__cd.__data[0].__trans = NULL;
  392: 
  393:           cc->__cd_out.__cd.__nsteps = fcts.tomb_nsteps;
  394:           cc->__cd_out.__cd.__steps = fcts.tomb;
  395: 
  396:           cc->__cd_out.__cd.__data[0].__invocation_counter = 0;
  397:           cc->__cd_out.__cd.__data[0].__internal_use = 1;
  398:           cc->__cd_out.__cd.__data[0].__flags = __GCONV_IS_LAST;
  399:           cc->__cd_out.__cd.__data[0].__statep =
  400:             &result->_wide_data->_IO_state;
  401: 
  402:           /* And now the transliteration.  */
  403:           cc->__cd_out.__cd.__data[0].__trans = &__libio_translit;
  404: 
  405:           /* From now on use the wide character callback functions.  */
  406:           ((struct _IO_FILE_plus *) fp)->vtable = fp->_wide_data->_wide_vtable;
  407: 
  408:           /* Set the mode now.  */
  409:           result->_mode = 1;
  410:         }
  411:     }
  412: #endif  /* GNU libc */
  413: 
  414:   return result;
  415: }
  416: INTDEF2(_IO_new_file_fopen, _IO_file_fopen)
  417: 
  418: _IO_FILE *
  419: _IO_new_file_attach (fp, fd)
  420:      _IO_FILE *fp;
  421:      int fd;
  422: {
  423:   if (_IO_file_is_open (fp))
  424:     return NULL;
  425:   fp->_fileno = fd;
  426:   fp->_flags &= ~(_IO_NO_READS+_IO_NO_WRITES);
  427:   fp->_flags |= _IO_DELETE_DONT_CLOSE;
  428:   /* Get the current position of the file. */
  429:   /* We have to do that since that may be junk. */
  430:   fp->_offset = _IO_pos_BAD;
  431:   if (_IO_SEEKOFF (fp, (_IO_off64_t)0, _IO_seek_cur, _IOS_INPUT|_IOS_OUTPUT)
  432:       == _IO_pos_BAD && errno != ESPIPE)
  433:     return NULL;
  434:   return fp;
  435: }
  436: INTDEF2(_IO_new_file_attach, _IO_file_attach)
  437: 
  438: _IO_FILE *
  439: _IO_new_file_setbuf (fp, p, len)
  440:      _IO_FILE *fp;
  441:      char *p;
  442:      _IO_ssize_t len;
  443: {
  444:   if (_IO_default_setbuf (fp, p, len) == NULL)
  445:     return NULL;
  446: 
  447:   fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end
  448:     = fp->_IO_buf_base;
  449:   _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base);
  450: 
  451:   return fp;
  452: }
  453: INTDEF2(_IO_new_file_setbuf, _IO_file_setbuf)
  454: 
  455: 
  456: _IO_FILE *
  457: _IO_file_setbuf_mmap (fp, p, len)
  458:      _IO_FILE *fp;
  459:      char *p;
  460:      _IO_ssize_t len;
  461: {
  462:   _IO_FILE *result;
  463: 
  464:   /* Change the function table.  */
  465:   _IO_JUMPS ((struct _IO_FILE_plus *) fp) = &_IO_file_jumps;
  466:   fp->_wide_data->_wide_vtable = &_IO_wfile_jumps;
  467: 
  468:   /* And perform the normal operation.  */
  469:   result = _IO_new_file_setbuf (fp, p, len);
  470: 
  471:   /* If the call failed, restore to using mmap.  */
  472:   if (result == NULL)
  473:     {
  474:       _IO_JUMPS ((struct _IO_FILE_plus *) fp) = &_IO_file_jumps_mmap;
  475:       fp->_wide_data->_wide_vtable = &_IO_wfile_jumps_mmap;
  476:     }
  477: 
  478:   return result;
  479: }
  480: 
  481: static _IO_size_t new_do_write (_IO_FILE *, const char *, _IO_size_t);
  482: 
  483: /* Write TO_DO bytes from DATA to FP.
  484:    Then mark FP as having empty buffers. */
  485: 
  486: int
  487: _IO_new_do_write (fp, data, to_do)
  488:      _IO_FILE *fp;
  489:      const char *data;
  490:      _IO_size_t to_do;
  491: {
  492:   return (to_do == 0
  493:           || (_IO_size_t) new_do_write (fp, data, to_do) == to_do) ? 0 : EOF;
  494: }
  495: INTDEF2(_IO_new_do_write, _IO_do_write)
  496: 
  497: static
  498: _IO_size_t
  499: new_do_write (fp, data, to_do)
  500:      _IO_FILE *fp;
  501:      const char *data;
  502:      _IO_size_t to_do;
  503: {
  504:   _IO_size_t count;
  505:   if (fp->_flags & _IO_IS_APPENDING)
  506:     /* On a system without a proper O_APPEND implementation,
  507:        you would need to sys_seek(0, SEEK_END) here, but is
  508:        is not needed nor desirable for Unix- or Posix-like systems.
  509:        Instead, just indicate that offset (before and after) is
  510:        unpredictable. */
  511:     fp->_offset = _IO_pos_BAD;
  512:   else if (fp->_IO_read_end != fp->_IO_write_base)
  513:     {
  514:       _IO_off64_t new_pos
  515:         = _IO_SYSSEEK (fp, fp->_IO_write_base - fp->_IO_read_end, 1);
  516:       if (new_pos == _IO_pos_BAD)
  517:         return 0;
  518:       fp->_offset = new_pos;
  519:     }
  520:   count = _IO_SYSWRITE (fp, data, to_do);
  521:   if (fp->_cur_column && count)
  522:     fp->_cur_column = INTUSE(_IO_adjust_column) (fp->_cur_column - 1, data,
  523:                                                  count) + 1;
  524:   _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base);
  525:   fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_buf_base;
  526:   fp->_IO_write_end = (fp->_mode <= 0
  527:                        && (fp->_flags & (_IO_LINE_BUF+_IO_UNBUFFERED))
  528:                        ? fp->_IO_buf_base : fp->_IO_buf_end);
  529:   return count;
  530: }
  531: 
  532: int
  533: _IO_new_file_underflow (fp)
  534:      _IO_FILE *fp;
  535: {
  536:   _IO_ssize_t count;
  537: #if 0
  538:   /* SysV does not make this test; take it out for compatibility */
  539:   if (fp->_flags & _IO_EOF_SEEN)
  540:     return (EOF);
  541: #endif
  542: 
  543:   if (fp->_flags & _IO_NO_READS)
  544:     {
  545:       fp->_flags |= _IO_ERR_SEEN;
  546:       __set_errno (EBADF);
  547:       return EOF;
  548:     }
  549:   if (fp->_IO_read_ptr < fp->_IO_read_end)
  550:     return *(unsigned char *) fp->_IO_read_ptr;
  551: 
  552:   if (fp->_IO_buf_base == NULL)
  553:     {
  554:       /* Maybe we already have a push back pointer.  */
  555:       if (fp->_IO_save_base != NULL)
  556:         {
  557:           free (fp->_IO_save_base);
  558:           fp->_flags &= ~_IO_IN_BACKUP;
  559:         }
  560:       INTUSE(_IO_doallocbuf) (fp);
  561:     }
  562: 
  563:   /* Flush all line buffered files before reading. */
  564:   /* FIXME This can/should be moved to genops ?? */