-/**/
+/*
+ * daemons
+ * output buffer chains
+ */
#include <assert.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
-#include "hostside.h"
+#include "daemons.h"
#include "../layout/dlist.h"
struct OutBuffer {
int l;
};
-static void *writeable(oop_source *evts, int fd,
- oop_event evt, void *ch_v) {
- OutBufferChain *ch= ch_v;
+int obc_tryflush(OutBufferChain *ch) {
OutBuffer *ob;
int r;
- assert(fd == ch->fd);
- assert(evt == OOP_WRITE);
-
for (;;) {
ob= ch->obs.head;
if (!ob) {
- events->cancel_fd(events, fd, OOP_WRITE);
- return OOP_CONTINUE;
+ events->cancel_fd(events, ch->fd, OOP_WRITE);
+ return 0;
}
if (ch->done_of_head == ob->l) {
LIST_UNLINK(ch->obs, ob);
r= write(ch->fd, ob->m + ch->done_of_head, ob->l - ch->done_of_head);
if (r==-1) {
if (errno==EINTR) continue;
- if (errno==EWOULDBLOCK) return OOP_CONTINUE;
+ if (errno==EWOULDBLOCK) return errno;
ch->error(ch,"write",strerror(errno));
+ return errno;
}
assert(r>=0);
ch->done_of_head += r;
}
}
+static void *writeable(oop_source *evts, int fd,
+ oop_event evt, void *ch_v) {
+ OutBufferChain *ch= ch_v;
+ assert(fd == ch->fd);
+ assert(evt == OOP_WRITE);
+ obc_tryflush(ch);
+ return OOP_CONTINUE;
+}
+
static void addlink(OutBufferChain *ch, OutBuffer *ob) {
if (!ch->obs.head)
events->on_fd(events, ch->fd, OOP_WRITE, writeable, ch);
}
void obc_init(OutBufferChain *ch) {
+ int r;
ch->done_of_head= 0;
+ r= oop_fd_nonblock(ch->fd, 1);
+ if (r) diee("nonblock(OutBufferChain->fd,1)");
LIST_INIT(ch->obs);
}
va_end(al);
}
+void voerror(OutBufferChain *ch, const char *fmt, va_list al) {
+ oprintf(ch,"error ");
+ ovprintf(ch,fmt,al);
+ owrite(ch,"\n",1);
+}
+
void owrite(OutBufferChain *ch, const char *data, int l) {
OutBuffer *ob;
ob= mmalloc(sizeof(*ob));