155 lines
2.8 KiB
C
155 lines
2.8 KiB
C
/*
|
|
* flushbuf.c - flush a buffer
|
|
*/
|
|
/* $Id$ */
|
|
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <unistd.h>
|
|
#include "loc_incl.h"
|
|
|
|
#if ACKCONF_WANT_STDIO
|
|
|
|
static int
|
|
do_write(int d, char* buf, int nbytes)
|
|
{
|
|
int c;
|
|
|
|
/* POSIX actually allows write() to return a positive value less
|
|
than nbytes, so loop ...
|
|
*/
|
|
while ((c = write(d, buf, nbytes)) > 0 && c < nbytes)
|
|
{
|
|
nbytes -= c;
|
|
buf += c;
|
|
}
|
|
return c > 0;
|
|
}
|
|
|
|
int __flushbuf(int c, FILE* stream)
|
|
{
|
|
__register_stdio_cleanup();
|
|
if (fileno(stream) < 0)
|
|
return EOF;
|
|
if (!io_testflag(stream, _IOWRITE))
|
|
return EOF;
|
|
if (io_testflag(stream, _IOREADING) && !feof(stream))
|
|
return EOF;
|
|
|
|
stream->_flags &= ~_IOREADING;
|
|
stream->_flags |= _IOWRITING;
|
|
if (!io_testflag(stream, _IONBF))
|
|
{
|
|
if (!stream->_buf)
|
|
{
|
|
if (stream == stdout && isatty(fileno(stdout)))
|
|
{
|
|
if (!(stream->_buf = (unsigned char*)malloc(BUFSIZ)))
|
|
{
|
|
stream->_flags |= _IONBF;
|
|
}
|
|
else
|
|
{
|
|
stream->_flags |= _IOLBF | _IOMYBUF;
|
|
stream->_bufsiz = BUFSIZ;
|
|
stream->_count = -1;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (!(stream->_buf = (unsigned char*)malloc(BUFSIZ)))
|
|
{
|
|
stream->_flags |= _IONBF;
|
|
}
|
|
else
|
|
{
|
|
stream->_flags |= _IOMYBUF;
|
|
stream->_bufsiz = BUFSIZ;
|
|
if (!io_testflag(stream, _IOLBF))
|
|
stream->_count = BUFSIZ - 1;
|
|
else
|
|
stream->_count = -1;
|
|
}
|
|
}
|
|
stream->_ptr = stream->_buf;
|
|
}
|
|
}
|
|
|
|
if (io_testflag(stream, _IONBF))
|
|
{
|
|
char c1 = c;
|
|
|
|
stream->_count = 0;
|
|
if (io_testflag(stream, _IOAPPEND))
|
|
{
|
|
if (lseek(fileno(stream), 0L, SEEK_END) == -1)
|
|
{
|
|
stream->_flags |= _IOERR;
|
|
return EOF;
|
|
}
|
|
}
|
|
if (write(fileno(stream), &c1, 1) != 1)
|
|
{
|
|
stream->_flags |= _IOERR;
|
|
return EOF;
|
|
}
|
|
return (unsigned char)c;
|
|
}
|
|
else if (io_testflag(stream, _IOLBF))
|
|
{
|
|
*stream->_ptr++ = c;
|
|
/* stream->_count has been updated in putc macro. */
|
|
if (c == '\n' || stream->_count == -stream->_bufsiz)
|
|
{
|
|
int count = -stream->_count;
|
|
|
|
stream->_ptr = stream->_buf;
|
|
stream->_count = 0;
|
|
|
|
if (io_testflag(stream, _IOAPPEND))
|
|
{
|
|
if (lseek(fileno(stream), 0L, SEEK_END) == -1)
|
|
{
|
|
stream->_flags |= _IOERR;
|
|
return EOF;
|
|
}
|
|
}
|
|
if (!do_write(fileno(stream), (char*)stream->_buf,
|
|
count))
|
|
{
|
|
stream->_flags |= _IOERR;
|
|
return EOF;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
int count = stream->_ptr - stream->_buf;
|
|
|
|
stream->_count = stream->_bufsiz - 1;
|
|
stream->_ptr = stream->_buf + 1;
|
|
|
|
if (count > 0)
|
|
{
|
|
if (io_testflag(stream, _IOAPPEND))
|
|
{
|
|
if (lseek(fileno(stream), 0L, SEEK_END) == -1)
|
|
{
|
|
stream->_flags |= _IOERR;
|
|
return EOF;
|
|
}
|
|
}
|
|
if (!do_write(fileno(stream), (char*)stream->_buf, count))
|
|
{
|
|
*(stream->_buf) = c;
|
|
stream->_flags |= _IOERR;
|
|
return EOF;
|
|
}
|
|
}
|
|
*(stream->_buf) = c;
|
|
}
|
|
return (unsigned char)c;
|
|
}
|
|
|
|
#endif
|