void ul_free_pty(struct ul_pty *pty)
{
struct ul_pty_child_buffer *hd;
- while((hd = pty->child_buffer_head)) {
+
+ while ((hd = pty->child_buffer_head)) {
pty->child_buffer_head = hd->next;
free(hd);
}
- while((hd = pty->free_buffers)) {
+
+ while ((hd = pty->free_buffers)) {
pty->free_buffers = hd->next;
free(hd);
}
static int schedule_child_write(struct ul_pty *pty, char *buf, size_t bufsz, int final)
{
struct ul_pty_child_buffer *stash;
+
if (pty->free_buffers) {
stash = pty->free_buffers;
pty->free_buffers = stash->next;
if (!stash)
return -1;
+ assert(bufsz <= sizeof(stash->buf));
+
memcpy(stash->buf, buf, bufsz);
stash->size = bufsz;
stash->final_input = final ? 1 : 0;
static int flush_child_buffers(struct ul_pty *pty, int *anything)
{
- int ret = 0, any = 0;
+ int rc = 0, any = 0;
+
while (pty->child_buffer_head) {
struct ul_pty_child_buffer *hd = pty->child_buffer_head;
+ ssize_t ret;
- if(hd->final_input)
+ if (hd->final_input)
drain_child_buffers(pty);
DBG(IO, ul_debugobj(hd, " stdin --> master trying %zu bytes", hd->size - hd->cursor));
- ssize_t ret = write(pty->master, hd->buf + hd->cursor, hd->size - hd->cursor);
+
+ ret = write(pty->master, hd->buf + hd->cursor, hd->size - hd->cursor);
if (ret == -1) {
DBG(IO, ul_debugobj(hd, " EAGAIN"));
if (!(errno == EINTR || errno == EAGAIN))
- ret = -errno;
+ rc = -errno;
goto out;
}
DBG(IO, ul_debugobj(hd, " wrote %zd", ret));
any = 1;
hd->cursor += ret;
+
if (hd->cursor == hd->size) {
pty->child_buffer_head = hd->next;
- if(!hd->next)
+ if (!hd->next)
pty->child_buffer_tail = NULL;
hd->next = pty->free_buffers;
pty->free_buffers = hd;
}
}
-
out:
/* without sync write_output() will write both input &
* shell output that looks like double echoing */
if (anything)
*anything = any;
- return ret;
+ return rc;
}
void ul_pty_write_eof_to_child(struct ul_pty *pty)
} else
timeout = pty->poll_timeout;
+ /* use POLLOUT (aka "writing is now possible") if data queued */
if (pty->child_buffer_head)
pfd[POLLFD_MASTER].events |= POLLOUT;
else
}
if (rc) {
+ int anything = 1;
+
ul_pty_write_eof_to_child(pty);
- for (int anything = 1; anything;)
+ for (anything = 1; anything;)
flush_child_buffers(pty, &anything);
break;
}