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> 2000-12-30 Michael Livshin <mlivshin@bigfoot.com>
* guardians.c (guardian_print): for sharing guardians, print that * guardians.c (guardian_print): for sharing guardians, print that

View file

@ -573,41 +573,83 @@ fport_truncate (SCM port, off_t length)
scm_syserror ("ftruncate"); scm_syserror ("ftruncate");
} }
/* 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)
{
int fdes = SCM_FSTREAM (port)->fdes;
while (remaining > 0)
{
ssize_t done;
SCM_SYSCALL (done = write (fdes, data, remaining));
if (done == -1)
SCM_SYSERROR;
remaining -= done;
data = ((const char *) data) + done;
}
}
#undef FUNC_NAME
static void static void
fport_write (SCM port, const void *data, size_t size) 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); scm_port *pt = SCM_PTAB_ENTRY (port);
if (pt->write_buf == &pt->shortbuf) if (pt->write_buf == &pt->shortbuf
|| (pt->write_pos == pt->write_buf && size >= pt->write_buf_size))
{ {
/* "unbuffered" port. */ /* "unbuffered" port, or
int fdes = SCM_FSTREAM (port)->fdes; port with empty buffer and data won't fit in buffer. */
write_all (port, data, size);
if (write (fdes, data, size) == -1) return;
scm_syserror ("fport_write");
} }
else
{
const char *input = (char *) data;
size_t remaining = size;
while (remaining > 0) {
{ off_t space = pt->write_end - pt->write_pos;
int space = pt->write_end - pt->write_pos;
int write_len = (remaining > space) ? space : remaining;
memcpy (pt->write_pos, input, write_len); if (size <= space)
pt->write_pos += write_len; {
remaining -= write_len; /* data fits in buffer. */
input += write_len; memcpy (pt->write_pos, data, size);
if (write_len == space) pt->write_pos += size;
if (pt->write_pos == pt->write_end)
{
fport_flush (port); fport_flush (port);
} /* we can skip the line-buffering check if nothing's buffered. */
return;
/* handle line buffering. */ }
if ((SCM_CELL_WORD_0 (port) & SCM_BUFLINE) && memchr (data, '\n', size)) }
else
{
memcpy (pt->write_pos, data, space);
pt->write_pos = pt->write_end;
fport_flush (port); 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. */
if ((SCM_CELL_WORD_0 (port) & SCM_BUFLINE) && memchr (data, '\n', size))
fport_flush (port);
}
} }
/* becomes 1 when process is exiting: normal exception handling won't /* becomes 1 when process is exiting: normal exception handling won't