1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 1989 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* Copyright (c) 1984 AT&T */ 28 /* All Rights Reserved */ 29 30 #pragma ident "%Z%%M% %I% %E% SMI" /* from S5R2 3.6 */ 31 32 /*LINTLIBRARY*/ 33 /* 34 * This version writes directly to the buffer rather than looping on putc. 35 * Ptr args aren't checked for NULL because the program would be a 36 * catastrophic mess anyway. Better to abort than just to return NULL. 37 * 38 * This version does buffered writes larger than BUFSIZ directly, when 39 * the buffer is empty. 40 */ 41 #include <stdio.h> 42 #include "stdiom.h" 43 44 #define MIN(x, y) (x < y ? x : y) 45 46 extern char *memcpy(); 47 48 int 49 fwrite(ptr, size, count, iop) 50 char *ptr; 51 int size, count; 52 register FILE *iop; 53 { 54 register unsigned nleft; 55 register int n; 56 register unsigned char *cptr, *bufend; 57 register unsigned char *prev_ptr; 58 59 if (size <= 0 || count <= 0 || _WRTCHK(iop)) 60 return (0); 61 62 bufend = iop->_base + iop->_bufsiz; 63 nleft = count*size; 64 65 /* if the file is unbuffered, or if the iop->ptr = iop->base, and there 66 is > BUFSZ chars to write, we can do a direct write */ 67 prev_ptr = iop->_ptr; 68 if (iop->_base >= iop->_ptr) { /*this covers the unbuffered case, too*/ 69 if (((iop->_flag & _IONBF) != 0) || (nleft >= BUFSIZ)) { 70 if ((n=write(fileno(iop),ptr,nleft)) != nleft) 71 { 72 iop->_flag |= _IOERR; 73 n = (n >= 0) ? n : 0; 74 } 75 return n/size; 76 } 77 } 78 /* Put characters in the buffer */ 79 /* note that the meaning of n when just starting this loop is 80 irrelevant. It is defined in the loop */ 81 for (; ; ptr += n) { 82 while ((n = bufend - (cptr = iop->_ptr)) <= 0) /* full buf */ 83 if (_xflsbuf(iop) == EOF) 84 return (count - (nleft + size - 1)/size); 85 n = MIN(nleft, n); 86 (void) memcpy((char *) cptr, ptr, n); 87 iop->_cnt -= n; 88 iop->_ptr += n; 89 _BUFSYNC(iop); 90 /* done; flush if linebuffered with a newline */ 91 if ((nleft -= n) == 0) { 92 if (iop->_flag & (_IOLBF | _IONBF)) { 93 if ((iop->_flag & _IONBF) || (memchr(prev_ptr, 94 '\n',iop->_ptr - prev_ptr) != NULL)) { 95 (void) _xflsbuf(iop); 96 } 97 } 98 return (count); 99 } 100 } 101 } 102