Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
4349 Serge 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 
21
#include 
22
#include 
23
#include 
24
#include 
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;
6536 serge 43
  int flags;
44
  size_t size;
45
  int couldbetty;
4349 Serge 46
 
47
  if (fp->_flags & __SNBF)
48
    {
49
      fp->_bf._base = fp->_p = fp->_nbuf;
50
      fp->_bf._size = 1;
51
      return;
52
    }
6536 serge 53
  flags = __swhatbuf_r (ptr, fp, &size, &couldbetty);
4349 Serge 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;
6536 serge 71
      fp->_flags |= flags;
4349 Serge 72
    }
73
}
6536 serge 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
}