1 /* No user fns here. Pesch 15apr92. */
4 * Copyright (c) 1990 The Regents of the University of California.
7 * Redistribution and use in source and binary forms are permitted
8 * provided that the above copyright notice and this paragraph are
9 * duplicated in all such forms and that any documentation,
10 * advertising materials, and other materials related to such
11 * distribution and use acknowledge that the software was developed
12 * by the University of California, Berkeley. The name of the
13 * University may not be used to endorse or promote products derived
14 * from this software without specific prior written permission.
15 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
17 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
26 #define MIN(a, b) ((a) < (b) ? (a) : (b))
27 #define COPY(n) (void) memmove((void *) fp->_p, (void *) p, (size_t) (n))
29 #define GETIOV(extra_work) \
39 * Write some memory regions. Return zero on success, EOF on error.
41 * This routine is large and unsightly, but most of the ugliness due
42 * to the three different kinds of output buffering is handled here.
48 register struct __suio
*uio
;
51 register _CONST
char *p
;
52 register struct __siov
*iov
;
57 if ((len
= uio
->uio_resid
) == 0)
60 /* make sure we can write */
68 if (fp
->_flags
& __SCLE
) /* text mode */
75 if (putc(*p
, fp
) == EOF
)
82 while (uio
->uio_resid
> 0);
87 if (fp
->_flags
& __SNBF
)
90 * Unbuffered: write up to BUFSIZ bytes at a time.
95 w
= (*fp
->_write
) (fp
->_cookie
, p
, MIN (len
, BUFSIZ
));
101 while ((uio
->uio_resid
-= w
) != 0);
103 else if ((fp
->_flags
& __SLBF
) == 0)
106 * Fully buffered: fill partially full buffer, if any,
107 * and then flush. If there is no partial buffer, write
108 * one _bf._size byte chunk directly (without copying).
110 * String output is a special case: write as many bytes
111 * as fit, but pretend we wrote everything. This makes
112 * snprintf() return the number of bytes needed, rather
113 * than the number used, and avoids its write function
114 * (so that the write function can be invalid). If
115 * we are dealing with the asprintf routines, we will
116 * dynamically increase the buffer size as needed.
122 if (fp
->_flags
& __SSTR
)
124 if (len
> w
&& fp
->_flags
& __SMBF
)
125 { /* must be asprintf family */
127 int curpos
= (fp
->_p
- fp
->_bf
._base
);
128 ptr
= (unsigned char *)_realloc_r (_REENT
,
134 fp
->_p
= ptr
+ curpos
;
135 fp
->_bf
._size
= curpos
+ len
;
140 COPY (w
); /* copy MIN(fp->_w,len), */
143 w
= len
; /* but pretend copied all */
145 else if (fp
->_p
> fp
->_bf
._base
&& len
> w
)
149 /* fp->_w -= w; *//* unneeded */
154 else if (len
>= (w
= fp
->_bf
._size
))
157 w
= (*fp
->_write
) (fp
->_cookie
, p
, w
);
172 while ((uio
->uio_resid
-= w
) != 0);
177 * Line buffered: like fully buffered, but we
178 * must check for newlines. Compute the distance
179 * to the first newline (including the newline),
180 * or `infinity' if there is none, then pretend
181 * that the amount to write is MIN(len,nldist).
186 GETIOV (nlknown
= 0);
189 nl
= memchr ((void *) p
, '\n', len
);
190 nldist
= nl
? nl
+ 1 - p
: len
+ 1;
193 s
= MIN (len
, nldist
);
194 w
= fp
->_w
+ fp
->_bf
._size
;
195 if (fp
->_p
> fp
->_bf
._base
&& s
> w
)
203 else if (s
>= (w
= fp
->_bf
._size
))
205 w
= (*fp
->_write
) (fp
->_cookie
, p
, w
);
216 if ((nldist
-= w
) == 0)
218 /* copied the newline: flush and forget */
226 while ((uio
->uio_resid
-= w
) != 0);
231 fp
->_flags
|= __SERR
;