13 #include "../layout/dlist.h"
16 OutBuffer *back, *next;
21 int obc_tryflush(OutBufferChain *ch) {
29 if (ch->done_of_head == ob->l) {
30 LIST_UNLINK(ch->obs, ob);
36 r= write(ch->fd, ob->m + ch->done_of_head, ob->l - ch->done_of_head);
38 if (errno==EINTR) continue;
39 if (errno==EWOULDBLOCK) return errno;
40 ch->error(ch,"write",strerror(errno));
44 ch->done_of_head += r;
46 assert(ch->done_of_head <= ob->l);
50 static void *writeable(oop_source *evts, int fd,
51 oop_event evt, void *ch_v) {
52 OutBufferChain *ch= ch_v;
54 assert(evt == OOP_WRITE);
56 if (evts && !ch->obs.head) {
57 events->cancel_fd(events, ch->fd, OOP_WRITE);
59 if (ch->empty) ch->empty(ch);
64 static void addlink(OutBufferChain *ch, OutBuffer *ob,
65 CopyCallBack *ccb, void *ccbu) {
66 if (ccb) ccb(ob->m,ob->l,ccbu);
68 if (ch->done_of_head < 0) {
69 assert(!ch->obs.head);
70 if (events) /* in simulation, events==0 */
71 events->on_fd(events, ch->fd, OOP_WRITE, writeable, ch);
75 LIST_LINK_TAIL(ch->obs, ob);
77 if (ob->l>0 && ob->m[ob->l-1]=='\n')
79 if (ch->total > ch->limit) {
81 snprintf(what,sizeof(what)-1,"`%.*s...'", ob->l,ob->m);
82 what[sizeof(what)-1]= 0;
84 ch->error(ch,"buffer limit exceeded",what);
88 void obc_init_core(OutBufferChain *ch) {
91 if (!ch->limit) ch->limit= 128*1024;
95 void obc_init(OutBufferChain *ch) {
98 r= oop_fd_nonblock(ch->fd, 1);
99 if (r) diee("nonblock(OutBufferChain->fd,1)");
102 void ovprintf_ccb(OutBufferChain *ch, CopyCallBack *ccb, void *ccbu,
103 const char *fmt, va_list al) {
106 ob= mmalloc(sizeof(*ob));
107 ob->l= vasprintf(&ob->m, fmt, al);
108 if (ob->l < 0) diem();
109 if (!ob->l) { free(ob->m); free(ob); return; }
110 addlink(ch,ob,ccb,ccbu);
113 void ovprintf(OutBufferChain *ch, const char *fmt, va_list al) {
114 ovprintf_ccb(ch,0,0,fmt,al);
117 void oprintf(OutBufferChain *ch, const char *msg, ...) {
124 void voerror(OutBufferChain *ch, const char *fmt, va_list al) {
125 oprintf(ch,"error ");
130 void owrite(OutBufferChain *ch, const char *data, int l) {
132 ob= mmalloc(sizeof(*ob));
135 memcpy(ob->m, data, l);