ack/lang/cem/libcc.ansi/sys/stdio/flushbuf.c

155 lines
2.8 KiB
C
Raw Normal View History

1989-05-30 13:34:25 +00:00
/*
* flushbuf.c - flush a buffer
*/
1994-06-24 14:02:31 +00:00
/* $Id$ */
1989-05-30 13:34:25 +00:00
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include "loc_incl.h"
1989-05-30 13:34:25 +00:00
#if ACKCONF_WANT_STDIO && ACKCONF_WANT_EMULATED_FILE
2018-06-23 16:54:40 +00:00
static int
2018-06-21 20:33:47 +00:00
do_write(int d, char* buf, int nbytes)
{
int c;
/* POSIX actually allows write() to return a positive value less
than nbytes, so loop ...
*/
2018-06-21 20:33:47 +00:00
while ((c = write(d, buf, nbytes)) > 0 && c < nbytes)
{
nbytes -= c;
buf += c;
}
return c > 0;
}
2018-06-21 20:33:47 +00:00
int __flushbuf(int c, FILE* stream)
1989-05-30 13:34:25 +00:00
{
__register_stdio_cleanup();
2018-06-21 20:33:47 +00:00
if (fileno(stream) < 0)
return EOF;
if (!io_testflag(stream, _IOWRITE))
return EOF;
if (io_testflag(stream, _IOREADING) && !feof(stream))
return EOF;
1989-06-26 10:37:05 +00:00
stream->_flags &= ~_IOREADING;
stream->_flags |= _IOWRITING;
2018-06-21 20:33:47 +00:00
if (!io_testflag(stream, _IONBF))
{
if (!stream->_buf)
{
if (stream == stdout && isatty(fileno(stdout)))
{
if (!(stream->_buf = (unsigned char*)malloc(BUFSIZ)))
{
1989-05-30 13:34:25 +00:00
stream->_flags |= _IONBF;
2018-06-21 20:33:47 +00:00
}
else
{
stream->_flags |= _IOLBF | _IOMYBUF;
1989-05-30 13:34:25 +00:00
stream->_bufsiz = BUFSIZ;
stream->_count = -1;
}
2018-06-21 20:33:47 +00:00
}
else
{
if (!(stream->_buf = (unsigned char*)malloc(BUFSIZ)))
{
1989-05-30 13:34:25 +00:00
stream->_flags |= _IONBF;
2018-06-21 20:33:47 +00:00
}
else
{
1989-05-30 13:34:25 +00:00
stream->_flags |= _IOMYBUF;
stream->_bufsiz = BUFSIZ;
1989-12-18 15:04:14 +00:00
if (!io_testflag(stream, _IOLBF))
stream->_count = BUFSIZ - 1;
2018-06-21 20:33:47 +00:00
else
stream->_count = -1;
1989-05-30 13:34:25 +00:00
}
}
stream->_ptr = stream->_buf;
}
}
2018-06-21 20:33:47 +00:00
if (io_testflag(stream, _IONBF))
{
1989-05-30 13:34:25 +00:00
char c1 = c;
stream->_count = 0;
2018-06-21 20:33:47 +00:00
if (io_testflag(stream, _IOAPPEND))
{
if (lseek(fileno(stream), 0L, SEEK_END) == -1)
{
1989-12-18 15:04:14 +00:00
stream->_flags |= _IOERR;
return EOF;
}
}
2018-06-21 20:33:47 +00:00
if (write(fileno(stream), &c1, 1) != 1)
{
1989-05-30 13:34:25 +00:00
stream->_flags |= _IOERR;
return EOF;
}
2018-06-21 20:33:47 +00:00
return (unsigned char)c;
}
else if (io_testflag(stream, _IOLBF))
{
1989-05-30 13:34:25 +00:00
*stream->_ptr++ = c;
/* stream->_count has been updated in putc macro. */
2018-06-21 20:33:47 +00:00
if (c == '\n' || stream->_count == -stream->_bufsiz)
{
int count = -stream->_count;
2018-06-21 20:33:47 +00:00
stream->_ptr = stream->_buf;
stream->_count = 0;
2018-06-21 20:33:47 +00:00
if (io_testflag(stream, _IOAPPEND))
{
if (lseek(fileno(stream), 0L, SEEK_END) == -1)
{
1989-12-18 15:04:14 +00:00
stream->_flags |= _IOERR;
return EOF;
}
}
2018-06-21 20:33:47 +00:00
if (!do_write(fileno(stream), (char*)stream->_buf,
count))
{
1989-05-30 13:34:25 +00:00
stream->_flags |= _IOERR;
return EOF;
}
}
2018-06-21 20:33:47 +00:00
}
else
{
1989-05-30 13:34:25 +00:00
int count = stream->_ptr - stream->_buf;
stream->_count = stream->_bufsiz - 1;
stream->_ptr = stream->_buf + 1;
2018-06-21 20:33:47 +00:00
if (count > 0)
{
if (io_testflag(stream, _IOAPPEND))
{
if (lseek(fileno(stream), 0L, SEEK_END) == -1)
{
1989-12-18 15:04:14 +00:00
stream->_flags |= _IOERR;
return EOF;
}
}
2018-06-21 20:33:47 +00:00
if (!do_write(fileno(stream), (char*)stream->_buf, count))
{
1989-05-30 13:34:25 +00:00
*(stream->_buf) = c;
stream->_flags |= _IOERR;
return EOF;
}
}
*(stream->_buf) = c;
}
2018-06-21 20:33:47 +00:00
return (unsigned char)c;
1989-05-30 13:34:25 +00:00
}
2018-06-23 16:54:40 +00:00
#endif