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

glibc/2.7/libio/genops.c

    1: /* Copyright (C) 1993,1995,1997-2002, 2003, 2004, 2006, 2007
    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: /* Generic or default I/O operations. */
   30: 
   31: #include "libioP.h"
   32: #ifdef __STDC__
   33: #include <stdlib.h>
   34: #endif
   35: #include <string.h>
   36: #include <stdbool.h>
   37: #ifdef _LIBC
   38: #include <sched.h>
   39: #endif
   40: 
   41: #ifdef _IO_MTSAFE_IO
   42: static _IO_lock_t list_all_lock = _IO_lock_initializer;
   43: #endif
   44: 
   45: /* Used to signal modifications to the list of FILE decriptors.  */
   46: static int _IO_list_all_stamp;
   47: 
   48: 
   49: static _IO_FILE *run_fp;
   50: 
   51: static void
   52: flush_cleanup (void *not_used)
   53: {
   54:   if (run_fp != NULL)
   55:     _IO_funlockfile (run_fp);
   56: #ifdef _IO_MTSAFE_IO
   57:   _IO_lock_unlock (list_all_lock);
   58: #endif
   59: }
   60: 
   61: void
   62: _IO_un_link (fp)
   63:      struct _IO_FILE_plus *fp;
   64: {
   65:   if (fp->file._flags & _IO_LINKED)
   66:     {
   67:       struct _IO_FILE **f;
   68: #ifdef _IO_MTSAFE_IO
   69:       _IO_cleanup_region_start_noarg (flush_cleanup);
   70:       _IO_lock_lock (list_all_lock);
   71:       run_fp = (_IO_FILE *) fp;
   72:       _IO_flockfile ((_IO_FILE *) fp);
   73: #endif
   74:       if (INTUSE(_IO_list_all) == NULL)
   75:         ;
   76:       else if (fp == INTUSE(_IO_list_all))
   77:         {
   78:           INTUSE(_IO_list_all)
   79:             = (struct _IO_FILE_plus *) INTUSE(_IO_list_all)->file._chain;
   80:           ++_IO_list_all_stamp;
   81:         }
   82:       else
   83:         for (f = &INTUSE(_IO_list_all)->file._chain; *f; f = &(*f)->_chain)
   84:           if (*f == (_IO_FILE *) fp)
   85:             {
   86:               *f = fp->file._chain;
   87:               ++_IO_list_all_stamp;
   88:               break;
   89:             }
   90:       fp->file._flags &= ~_IO_LINKED;
   91: #ifdef _IO_MTSAFE_IO
   92:       _IO_funlockfile ((_IO_FILE *) fp);
   93:       run_fp = NULL;
   94:       _IO_lock_unlock (list_all_lock);
   95:       _IO_cleanup_region_end (0);
   96: #endif
   97:     }
   98: }
   99: INTDEF(_IO_un_link)
  100: 
  101: void
  102: _IO_link_in (fp)
  103:      struct _IO_FILE_plus *fp;
  104: {
  105:   if ((fp->file._flags & _IO_LINKED) == 0)
  106:     {
  107:       fp->file._flags |= _IO_LINKED;
  108: #ifdef _IO_MTSAFE_IO
  109:       _IO_cleanup_region_start_noarg (flush_cleanup);
  110:       _IO_lock_lock (list_all_lock);
  111:       run_fp = (_IO_FILE *) fp;
  112:       _IO_flockfile ((_IO_FILE *) fp);
  113: #endif
  114:       fp->file._chain = (_IO_FILE *) INTUSE(_IO_list_all);
  115:       INTUSE(_IO_list_all) = fp;
  116:       ++_IO_list_all_stamp;
  117: #ifdef _IO_MTSAFE_IO
  118:       _IO_funlockfile ((_IO_FILE *) fp);
  119:       run_fp = NULL;
  120:       _IO_lock_unlock (list_all_lock);
  121:       _IO_cleanup_region_end (0);
  122: #endif
  123:     }
  124: }
  125: INTDEF(_IO_link_in)
  126: 
  127: /* Return minimum _pos markers
  128:    Assumes the current get area is the main get area. */
  129: _IO_ssize_t _IO_least_marker (_IO_FILE *fp, char *end_p);
  130: 
  131: _IO_ssize_t
  132: _IO_least_marker (fp, end_p)
  133:      _IO_FILE *fp;
  134:      char *end_p;
  135: {
  136:   _IO_ssize_t least_so_far = end_p - fp->_IO_read_base;
  137:   struct _IO_marker *mark;
  138:   for (mark = fp->_markers; mark != NULL; mark = mark->_next)
  139:     if (mark->_pos < least_so_far)
  140:       least_so_far = mark->_pos;
  141:   return least_so_far;
  142: }
  143: 
  144: /* Switch current get area from backup buffer to (start of) main get area. */
  145: 
  146: void
  147: _IO_switch_to_main_get_area (fp)
  148:      _IO_FILE *fp;
  149: {
  150:   char *tmp;
  151:   fp->_flags &= ~_IO_IN_BACKUP;
  152:   /* Swap _IO_read_end and _IO_save_end. */
  153:   tmp = fp->_IO_read_end;
  154:   fp->_IO_read_end = fp->_IO_save_end;
  155:   fp->_IO_save_end= tmp;
  156:   /* Swap _IO_read_base and _IO_save_base. */
  157:   tmp = fp->_IO_read_base;
  158:   fp->_IO_read_base = fp->_IO_save_base;
  159:   fp->_IO_save_base = tmp;
  160:   /* Set _IO_read_ptr. */
  161:   fp->_IO_read_ptr = fp->_IO_read_base;
  162: }
  163: 
  164: /* Switch current get area from main get area to (end of) backup area. */
  165: 
  166: void
  167: _IO_switch_to_backup_area (fp)
  168:      _IO_FILE *fp;
  169: {
  170:   char *tmp;
  171:   fp->_flags |= _IO_IN_BACKUP;
  172:   /* Swap _IO_read_end and _IO_save_end. */
  173:   tmp = fp->_IO_read_end;
  174:   fp->_IO_read_end = fp->_IO_save_end;
  175:   fp->_IO_save_end = tmp;
  176:   /* Swap _IO_read_base and _IO_save_base. */
  177:   tmp = fp->_IO_read_base;
  178:   fp->_IO_read_base = fp->_IO_save_base;
  179:   fp->_IO_save_base = tmp;
  180:   /* Set _IO_read_ptr.  */
  181:   fp->_IO_read_ptr = fp->_IO_read_end;
  182: }
  183: 
  184: int
  185: _IO_switch_to_get_mode (fp)
  186:      _IO_FILE *fp;
  187: {
  188:   if (fp->_IO_write_ptr > fp->_IO_write_base)
  189:     if (_IO_OVERFLOW (fp, EOF) == EOF)
  190:       return EOF;
  191:   if (_IO_in_backup (fp))
  192:     fp->_IO_read_base = fp->_IO_backup_base;
  193:   else
  194:     {
  195:       fp->_IO_read_base = fp->_IO_buf_base;
  196:       if (fp->_IO_write_ptr > fp->_IO_read_end)
  197:         fp->_IO_read_end = fp->_IO_write_ptr;
  198:     }
  199:   fp->_IO_read_ptr = fp->_IO_write_ptr;
  200: 
  201:   fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end = fp->_IO_read_ptr;
  202: 
  203:   fp->_flags &= ~_IO_CURRENTLY_PUTTING;
  204:   return 0;
  205: }
  206: INTDEF(_IO_switch_to_get_mode)
  207: 
  208: void
  209: _IO_free_backup_area (fp)
  210:      _IO_FILE *fp;
  211: {
  212:   if (_IO_in_backup (fp))
  213:     _IO_switch_to_main_get_area (fp);  /* Just in case. */
  214:   free (fp->_IO_save_base);
  215:   fp->_IO_save_base = NULL;
  216:   fp->_IO_save_end = NULL;
  217:   fp->_IO_backup_base = NULL;
  218: }
  219: INTDEF(_IO_free_backup_area)
  220: 
  221: #if 0
  222: int
  223: _IO_switch_to_put_mode (fp)
  224:      _IO_FILE *fp;
  225: {
  226:   fp->_IO_write_base = fp->_IO_read_ptr;
  227:   fp->_IO_write_ptr = fp->_IO_read_ptr;
  228:   /* Following is wrong if line- or un-buffered? */
  229:   fp->_IO_write_end = (fp->_flags & _IO_IN_BACKUP
  230:                        ? fp->_IO_read_end : fp->_IO_buf_end);
  231: 
  232:   fp->_IO_read_ptr = fp->_IO_read_end;
  233:   fp->_IO_read_base = fp->_IO_read_end;
  234: 
  235:   fp->_flags |= _IO_CURRENTLY_PUTTING;
  236:   return 0;
  237: }
  238: #endif
  239: 
  240: int
  241: __overflow (f, ch)
  242:      _IO_FILE *f;
  243:      int ch;
  244: {
  245:   /* This is a single-byte stream.  */
  246:   if (f->_mode == 0)
  247:     _IO_fwide (f, -1);
  248:   return _IO_OVERFLOW (f, ch);
  249: }
  250: libc_hidden_def (__overflow)
  251: 
  252: static int save_for_backup (_IO_FILE *fp, char *end_p)
  253: #ifdef _LIBC
  254:      internal_function
  255: #endif
  256:      ;
  257: 
  258: static int
  259: #ifdef _LIBC
  260: internal_function
  261: #endif
  262: save_for_backup (fp, end_p)
  263:      _IO_FILE *fp;
  264:      char *end_p;
  265: {
  266:   /* Append [_IO_read_base..end_p] to backup area. */
  267:   _IO_ssize_t least_mark = _IO_least_marker (fp, end_p);
  268:   /* needed_size is how much space we need in the backup area. */
  269:   _IO_size_t needed_size = (end_p - fp->_IO_read_base) - least_mark;
  270:   /* FIXME: Dubious arithmetic if pointers are NULL */
  271:   _IO_size_t current_Bsize = fp->_IO_save_end - fp->_IO_save_base;
  272:   _IO_size_t avail; /* Extra space available for future expansion. */
  273:   _IO_ssize_t delta;
  274:   struct _IO_marker *mark;
  275:   if (needed_size > current_Bsize)
  276:     {
  277:       char *new_buffer;
  278:       avail = 100;
  279:       new_buffer = (char *) malloc (avail + needed_size);
  280:       if (new_buffer == NULL)
  281:         return EOF;            /* FIXME */
  282:       if (least_mark < 0)
  283:         {
  284: #ifdef _LIBC
  285:           __mempcpy (__mempcpy (new_buffer + avail,
  286:                                 fp->_IO_save_end + least_mark,
  287:                                 -least_mark),
  288:                      fp->_IO_read_base,
  289:                      end_p - fp->_IO_read_base);
  290: #else
  291:           memcpy (new_buffer + avail,
  292:                   fp->_IO_save_end + least_mark,
  293:                   -least_mark);
  294:           memcpy (new_buffer + avail - least_mark,
  295:                   fp->_IO_read_base,
  296:                   end_p - fp->_IO_read_base);
  297: #endif
  298:         }
  299:       else
  300:         memcpy (new_buffer + avail,
  301:                 fp->_IO_read_base + least_mark,
  302:                 needed_size);
  303:       if (fp->_IO_save_base)
  304:         free (fp->_IO_save_base);
  305:       fp->_IO_save_base = new_buffer;
  306:       fp->_IO_save_end = new_buffer + avail + needed_size;
  307:     }
  308:   else
  309:     {
  310:       avail = current_Bsize - needed_size;
  311:       if (least_mark < 0)
  312:         {
  313:           memmove (fp->_IO_save_base + avail,
  314:                    fp->_IO_save_end + least_mark,
  315:                    -least_mark);
  316:           memcpy (fp->_IO_save_base + avail - least_mark,
  317:                   fp->_IO_read_base,
  318:                   end_p - fp->_IO_read_base);
  319:         }
  320:       else if (needed_size > 0)
  321:         memcpy (fp->_IO_save_base + avail,
  322:                 fp->_IO_read_base + least_mark,
  323:                 needed_size);
  324:     }
  325:   fp->_IO_backup_base = fp->_IO_save_base + avail;
  326:   /* Adjust all the streammarkers. */
  327:   delta = end_p - fp->_IO_read_base;
  328:   for (mark = fp->_markers; mark != NULL; mark = mark->_next)
  329:     mark->_pos -= delta;
  330:   return 0;
  331: }
  332: 
  333: int
  334: __underflow (fp)
  335:      _IO_FILE *fp;
  336: {
  337: #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
  338:   if (_IO_vtable_offset (fp) == 0 && _IO_fwide (fp, -1) != -1)
  339:     return EOF;
  340: #endif
  341: 
  342:   if (fp->_mode == 0)
  343:     _IO_fwide (fp, -1);
  344:   if (_IO_in_put_mode (fp))
  345:     if (INTUSE(_IO_switch_to_get_mode) (fp) == EOF)
  346:       return EOF;
  347:   if (fp->_IO_read_ptr < fp->_IO_read_end)
  348:     return *(unsigned char *) fp->_IO_read_ptr;
  349:   if (_IO_in_backup (fp))
  350:     {
  351:       _IO_switch_to_main_get_area (fp);
  352:       if (fp->_IO_read_ptr < fp->_IO_read_end)
  353:         return *(unsigned char *) fp->_IO_read_ptr;
  354:     }
  355:   if (_IO_have_markers (fp))
  356:     {
  357:       if (save_for_backup (fp, fp->_IO_read_end))
  358:         return EOF;
  359:     }
  360:   else if (_IO_have_backup (fp))
  361:     INTUSE(_IO_free_backup_area) (fp);
  362:   return _IO_UNDERFLOW (fp);
  363: }
  364: libc_hidden_def (__underflow)
  365: 
  366: int
  367: __uflow (fp)
  368:      _IO_FILE *fp;
  369: {
  370: #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
  371:   if (_IO_vtable_offset (fp) == 0 && _IO_fwide (fp, -1) != -1)
  372:     return EOF;
  373: #endif
  374: 
  375:   if (fp->_mode == 0)
  376:     _IO_fwide (fp, -1);
  377:   if (_IO_in_put_mode (fp))
  378:     if (INTUSE(_IO_switch_to_get_mode) (fp) == EOF)
  379:       return EOF;
  380:   if (fp->_IO_read_ptr < fp->_IO_read_end)
  381:     return *(unsigned char *) fp->_IO_read_ptr++;
  382:   if (_IO_in_backup (fp))
  383:     {
  384:       _IO_switch_to_main_get_area (fp);
  385:       if (fp->_IO_read_ptr < fp->_IO_read_end)
  386:         return *(unsigned char *) fp->_IO_read_ptr++;
  387:     }
  388:   if (_IO_have_markers (fp))
  389:     {
  390:       if (save_for_backup (fp, fp->_IO_read_end))
  391:         return EOF;
  392:     }
  393:   else if (_IO_have_backup (fp))
  394:     INTUSE(_IO_free_backup_area) (fp);
  395:   return _IO_UFLOW (fp);
  396: }
  397: libc_hidden_def (__uflow)
  398: 
  399: void
  400: _IO_setb (f, b, eb, a)
  401:      _IO_FILE *f;
  402:      char *b;
  403:      char *eb;
  404:      int a;
  405: {
  406:   if (f->_IO_buf_base && !(f->_flags & _IO_USER_BUF))
  407:     FREE_BUF (f->_IO_buf_base, _IO_blen (f));
  408:   f->_IO_buf_base = b;
  409:   f->_IO_buf_end = eb;
  410:   if (a)
  411:     f->_flags &= ~_IO_USER_BUF;
  412:   else
  413:     f->_flags |= _IO_USER_BUF;
  414: }
  415: INTDEF(_IO_setb)
  416: 
  417: void
  418: _IO_doallocbuf (fp)
  419:      _IO_FILE *fp;
  420: {
  421:   if (fp->_IO_buf_base)
  422:     return;
  423:   if (!(fp->_flags & _IO_UNBUFFERED) || fp->_mode > 0)
  424:     if (_IO_DOALLOCATE (fp) != EOF)
  425:       return;
  426:   INTUSE(_IO_setb) (fp, fp->_shortbuf, fp->_shortbuf+1, 0);
  427: }
  428: INTDEF(_IO_doallocbuf)
  429: 
  430: int
  431: _IO_default_underflow (fp)
  432:      _IO_FILE *fp;
  433: {
  434:   return EOF;
  435: }
  436: 
  437: int
  438: _IO_default_uflow (fp)
  439:      _IO_FILE *fp;
  440: {
  441:   int ch = _IO_UNDERFLOW (fp);
  442:   if (ch == EOF)
  443:     return EOF;
  444:   return *(unsigned char *) fp->_IO_read_ptr++;
  445: }
  446: INTDEF(_IO_default_uflow)
  447: 
  448: _IO_size_t
  449: _IO_default_xsputn (f, data, n)
  450:      _IO_FILE *f;
  451:      const void *data;
  452:      _IO_size_t n;
  453: {
  454:   const char *s = (char *) data;
  455:   _IO_size_t more = n;
  456:   if (more <= 0)
  457:     return 0;
  458:   for (;;)
  459:     {
  460:       /* Space available. */
  461:       if (f->_IO_write_ptr < f->_IO_write_end)
  462:         {
  463:           _IO_size_t count = f->_IO_write_end - f->_IO_write_ptr;
  464:           if (count > more)
  465:             count = more;
  466:           if (count > 20)
  467:             {
  468: #ifdef _LIBC
  469:               f->_IO_write_ptr = __mempcpy (f->_IO_write_ptr, s, count);
  470: #else
  471:               memcpy (f->_IO_write_ptr, s, count);
  472:               f->_IO_write_ptr += count;
  473: #endif
  474:               s += count;
  475:             }
  476:           else if (count)
  477:             {
  478:               char *p = f->_IO_write_ptr;
  479:               _IO_ssize_t i;
  480:               for (i = count; --i >= 0; )
  481:                 *p++ = *s++;
  482:               f->_IO_write_ptr = p;
  483:             }
  484:           more -= count;
  485:         }
  486:       if (more == 0 || _IO_OVERFLOW (f, (unsigned char) *s++) == EOF)
  487:         break;
  488:       more--;
  489:     }
  490:   return n - more;
  491: }
  492: INTDEF(_IO_default_xsputn)
  493: 
  494: _IO_size_t
  495: _IO_sgetn (fp, data, n)
  496:      _IO_FILE *fp;
  497:      void *data;
  498:      _IO_size_t n;
  499: {
  500:   /* FIXME handle putback buffer here! */
  501:   return _IO_XSGETN (fp, data, n);
  502: }
  503: INTDEF(_IO_sgetn)
  504: 
  505: _IO_size_t
  506: _IO_default_xsgetn (fp, data, n)
  507:      _IO_FILE *fp;
  508:      void *data;
  509:      _IO_size_t n;
  510: {
  511:   _IO_size_t more = n;
  512:   char *s = (char*) data;
  513:   for (;;)
  514:     {
  515:       /* Data available. */
  516:       if (fp->_IO_read_ptr < fp->_IO_read_end)
  517:         {
  518:           _IO_size_t count = fp->_IO_read_end - fp->_IO_read_ptr;
  519:           if (count > more)
  520:             count = more;
  521:           if (count > 20)
  522:             {
  523: #ifdef _LIBC
  524:               s = __mempcpy (s, fp->_IO_read_ptr, count);
  525: #else
  526:               memcpy (s, fp->_IO_read_ptr, count);
  527:               s += count;
  528: #endif
  529:               fp->_IO_read_ptr += count;
  530:             }
  531:           else if (count)
  532:             {
  533:               char *p = fp->_IO_read_ptr;
  534:               int i = (int) count;
  535:               while (--i >= 0)
  536:                 *s++ = *p++;
  537:               fp->_IO_read_ptr = p;
  538:             }
  539:             more -= count;
  540:         }
  541:       if (more == 0 || __underflow (fp) == EOF)
  542:         break;
  543:     }
  544:   return n - more;
  545: }
  546: INTDEF(_IO_default_xsgetn)
  547: 
  548: #if 0
  549: /* Seems not to be needed. --drepper */
  550: int
  551: _IO_sync (fp)
  552:      _IO_FILE *fp;
  553: {
  554:   return 0;
  555: }
  556: #endif
  557: 
  558: _IO_FILE *
  559: _IO_default_setbuf (fp, p, len)
  560:      _IO_FILE *fp;
  561:      char *p;
  562:      _IO_ssize_t len;
  563: {
  564:     if (_IO_SYNC (fp) == EOF)
  565:         return NULL;
  566:     if (p == NULL || len == 0)
  567:       {
  568:         fp->_flags |= _IO_UNBUFFERED;
  569:         INTUSE(_IO_setb) (fp, fp->_shortbuf, fp->_shortbuf+1, 0);
  570:       }
  571:     else
  572:       {
  573:         fp->_flags &= ~_IO_UNBUFFERED;
  574:         INTUSE(_IO_setb) (fp, p, p+len, 0);
  575:       }
  576:     fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end = 0;
  577:     fp->_IO_read_base = fp->_IO_read_ptr = fp->_IO_read_end = 0;
  578:     return fp;
  579: }
  580: 
  581: _IO_off64_t
  582: _IO_default_seekpos (fp, pos, mode)
  583:      _IO_FILE *fp;
  584:      _IO_off64_t pos;
  585:      int mode;
  586: {
  587:   return _IO_SEEKOFF (fp, pos, 0, mode);
  588: }
  589: 
  590: int
  591: _IO_default_doallocate (fp)
  592:      _IO_FILE *fp;
  593: {
  594:   char *buf;
  595: