/* from Dale Schumacher's dLibs */ #include #include #include #include #include #include #include "lib.h" extern short __FRW_BIN__; size_t fwrite(_data, size, count, fp) const void *_data; size_t size; size_t count; register FILE *fp; { const char *data=_data; register size_t n, m; register long l = 0; long space; unsigned int f = fp->_flag; const char *restart_buf; int have_nl; int wrote_cr; int line_flush; if(f & _IORW) { fp->_flag |= _IOWRT; f = (fp->_flag &= ~(_IOREAD | _IOEOF)); } if(!(f & _IOWRT) /* not opened for write? */ || (f & (_IOERR | _IOEOF))) /* error/eof conditions? */ return(0); assert ((data != NULL)); assert ((size != 0)); n = count * size; assert ( n <= (size_t)LONG_MAX); /* otherwise impl will not work */ if( (f&_IOBIN) || __FRW_BIN__ ) { space = fp->_bsiz - fp->_cnt; while(n > 0) { m = (n > space)? space: n; bcopy(data, fp->_ptr, m); fp->_ptr += m; fp->_cnt += m; space -= m; if(space == 0) { if(fflush(fp)) return 0; space = fp->_bsiz; if(f & _IORW) fp->_flag |= _IOWRT; /* fflush resets this */ } l += m; data += m; n -= m; if(n < space) continue; if((m = _write(fp->_file, data, (unsigned long)n )) != (long)n) { fp->_flag |= _IOERR; return 0; } l += m; break; } } else { have_nl=1; wrote_cr=0; line_flush=0; /* this relies on having at least one byte buffer, otherwise we'll hang up when trying to write CRLF */ while(n > 0) { space = fp->_bsiz - fp->_cnt; restart_buf=data; while( space>0 && n>0 ) { if( *data=='\n' ) { if( !wrote_cr ) { if( f&_IOLBF ) line_flush=1; *fp->_ptr++='\r'; wrote_cr=1; have_nl=1; l--; /* compensate for the increment below */ } else { *fp->_ptr++='\n'; data++; wrote_cr=0; n--; } } else { *fp->_ptr++=*data++; n--; } space--; fp->_cnt++; l++; } if( space==0 ) { if( have_nl ) { if(fflush(fp)) return 0; if(f & _IORW) fp->_flag |= _IOWRT; /* fflush resets this */ have_nl=0; } else { /* this will probably happen in nonbuffered mode only: try to write as much data in one go as possible */ fp->_cnt=0; fp->_ptr=fp->_base; while( n && *data!='\n' ) { n--; data++; } if( (m=_write(fp->_file, restart_buf, data-restart_buf )) != data-restart_buf ) { fp->_flag |= _IOERR; return 0; } l+=m; } } } if( line_flush ) { if(fflush(fp)) return 0; if(f & _IORW) fp->_flag |= _IOWRT; /* fflush resets this */ } } return((l > 0) ? ((size_t)l / size) : 0); }