1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-05-03 13:20:26 +02:00

* fports.c (fport_write): bugfix: handle short writes for

unbuffered ports too.  optimize the buffered case by minimizing
	the number of write/flush calls.
	(write_all): new helper procedure.
This commit is contained in:
Gary Houston 2001-01-02 00:38:41 +00:00
parent 75bc0690c8
commit 0c6d2191ef
2 changed files with 73 additions and 24 deletions

View file

@ -1,3 +1,10 @@
2001-01-01 Gary Houston <ghouston@arglist.com>
* fports.c (fport_write): bugfix: handle short writes for
unbuffered ports too. optimize the buffered case by minimizing
the number of write/flush calls.
(write_all): new helper procedure.
2000-12-30 Michael Livshin <mlivshin@bigfoot.com>
* guardians.c (guardian_print): for sharing guardians, print that

View file

@ -573,35 +573,77 @@ fport_truncate (SCM port, off_t length)
scm_syserror ("ftruncate");
}
static void
fport_write (SCM port, const void *data, size_t size)
/* helper for fport_write: try to write data, using multiple system
calls if required. */
#define FUNC_NAME "write_all"
static void write_all (SCM port, const void *data, size_t remaining)
{
scm_port *pt = SCM_PTAB_ENTRY (port);
if (pt->write_buf == &pt->shortbuf)
{
/* "unbuffered" port. */
int fdes = SCM_FSTREAM (port)->fdes;
if (write (fdes, data, size) == -1)
scm_syserror ("fport_write");
}
else
{
const char *input = (char *) data;
size_t remaining = size;
while (remaining > 0)
{
int space = pt->write_end - pt->write_pos;
int write_len = (remaining > space) ? space : remaining;
ssize_t done;
memcpy (pt->write_pos, input, write_len);
pt->write_pos += write_len;
remaining -= write_len;
input += write_len;
if (write_len == space)
SCM_SYSCALL (done = write (fdes, data, remaining));
if (done == -1)
SCM_SYSERROR;
remaining -= done;
data = ((const char *) data) + done;
}
}
#undef FUNC_NAME
static void
fport_write (SCM port, const void *data, size_t size)
{
/* this procedure tries to minimize the number of writes/flushes. */
scm_port *pt = SCM_PTAB_ENTRY (port);
if (pt->write_buf == &pt->shortbuf
|| (pt->write_pos == pt->write_buf && size >= pt->write_buf_size))
{
/* "unbuffered" port, or
port with empty buffer and data won't fit in buffer. */
write_all (port, data, size);
return;
}
{
off_t space = pt->write_end - pt->write_pos;
if (size <= space)
{
/* data fits in buffer. */
memcpy (pt->write_pos, data, size);
pt->write_pos += size;
if (pt->write_pos == pt->write_end)
{
fport_flush (port);
/* we can skip the line-buffering check if nothing's buffered. */
return;
}
}
else
{
memcpy (pt->write_pos, data, space);
pt->write_pos = pt->write_end;
fport_flush (port);
{
const void *ptr = ((const char *) data) + space;
size_t remaining = size - space;
if (size >= pt->write_buf_size)
{
write_all (port, ptr, remaining);
return;
}
else
{
memcpy (pt->write_pos, ptr, remaining);
pt->write_pos += remaining;
}
}
}
/* handle line buffering. */