Subversion Repositories Kolibri OS

Rev

Rev 4921 | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. /*
  2.  * Copyright (c) 1990, 2007 The Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms are permitted
  6.  * provided that the above copyright notice and this paragraph are
  7.  * duplicated in all such forms and that any documentation,
  8.  * advertising materials, and other materials related to such
  9.  * distribution and use acknowledge that the software was developed
  10.  * by the University of California, Berkeley.  The name of the
  11.  * University may not be used to endorse or promote products derived
  12.  * from this software without specific prior written permission.
  13.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  14.  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  15.  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  16.  */
  17. /* No user fns here.  Pesch 15apr92. */
  18.  
  19. #include <_ansi.h>
  20. #include <stdio.h>
  21. #include <stdlib.h>
  22. #include <sys/stat.h>
  23. #include <sys/types.h>
  24. #include <sys/unistd.h>
  25. #include "local.h"
  26.  
  27. #define _DEFAULT_ASPRINTF_BUFSIZE 64
  28.  
  29. /*
  30.  * Allocate a file buffer, or switch to unbuffered I/O.
  31.  * Per the ANSI C standard, ALL tty devices default to line buffered.
  32.  *
  33.  * As a side effect, we set __SOPT or __SNPT (en/dis-able fseek
  34.  * optimization) right after the _fstat() that finds the buffer size.
  35.  */
  36.  
  37. _VOID
  38. _DEFUN(__smakebuf_r, (ptr, fp),
  39.        struct _reent *ptr _AND
  40.        register FILE *fp)
  41. {
  42.   register _PTR p;
  43.   int flags;
  44.   size_t size;
  45.   int couldbetty;
  46.  
  47.   if (fp->_flags & __SNBF)
  48.     {
  49.       fp->_bf._base = fp->_p = fp->_nbuf;
  50.       fp->_bf._size = 1;
  51.       return;
  52.     }
  53.   flags = __swhatbuf_r (ptr, fp, &size, &couldbetty);
  54.   if ((p = _malloc_r (ptr, size)) == NULL)
  55.     {
  56.       if (!(fp->_flags & __SSTR))
  57.         {
  58.           fp->_flags |= __SNBF;
  59.           fp->_bf._base = fp->_p = fp->_nbuf;
  60.           fp->_bf._size = 1;
  61.         }
  62.     }
  63.   else
  64.     {
  65.       ptr->__cleanup = _cleanup_r;
  66.       fp->_flags |= __SMBF;
  67.       fp->_bf._base = fp->_p = (unsigned char *) p;
  68.       fp->_bf._size = size;
  69.       if (couldbetty && _isatty_r (ptr, fp->_file))
  70.         fp->_flags |= __SLBF;
  71.       fp->_flags |= flags;
  72.     }
  73. }
  74.  
  75. /*
  76.  * Internal routine to determine `proper' buffering for a file.
  77.  */
  78. int
  79. _DEFUN(__swhatbuf_r, (ptr, fp, bufsize, couldbetty),
  80.         struct _reent *ptr _AND
  81.         FILE *fp _AND
  82.         size_t *bufsize _AND
  83.         int *couldbetty)
  84. {
  85. #ifdef _FSEEK_OPTIMIZATION
  86.   const int snpt = __SNPT;
  87. #else
  88.   const int snpt = 0;
  89. #endif
  90.  
  91. #ifdef __USE_INTERNAL_STAT64
  92.   struct stat64 st;
  93.  
  94.   if (fp->_file < 0 || _fstat64_r (ptr, fp->_file, &st) < 0)
  95. #else
  96.   struct stat st;
  97.  
  98.   if (fp->_file < 0 || _fstat_r (ptr, fp->_file, &st) < 0)
  99. #endif
  100.     {
  101.       *couldbetty = 0;
  102.       /* Check if we are be called by asprintf family for initial buffer.  */
  103.       if (fp->_flags & __SMBF)
  104.         *bufsize = _DEFAULT_ASPRINTF_BUFSIZE;
  105.       else
  106.         *bufsize = BUFSIZ;
  107.       return (0);
  108.     }
  109.  
  110.   /* could be a tty iff it is a character device */
  111.   *couldbetty = S_ISCHR(st.st_mode);
  112. #ifdef HAVE_BLKSIZE
  113.   if (st.st_blksize > 0)
  114.     {
  115.       /*
  116.        * Optimise fseek() only if it is a regular file.  (The test for
  117.        * __sseek is mainly paranoia.)  It is safe to set _blksize
  118.        * unconditionally; it will only be used if __SOPT is also set.
  119.        */
  120.       *bufsize = st.st_blksize;
  121.       fp->_blksize = st.st_blksize;
  122.       return ((st.st_mode & S_IFMT) == S_IFREG ?  __SOPT : snpt);
  123.     }
  124. #endif
  125.   *bufsize = BUFSIZ;
  126.   return (snpt);
  127. }
  128.