chiark / gitweb /
reorganised to be nicer and ready to add stuff
[trains.git] / hostside / obc.c
1 /**/
2
3 #include <assert.h>
4 #include <stdlib.h>
5 #include <errno.h>
6 #include <stdarg.h>
7 #include <string.h>
8
9 #include "hostside.h"
10 #include "../layout/dlist.h"
11
12 static void *writeable(oop_source *evts, int fd,
13                        oop_event evt, void *ch_v) {
14   OutBufferChain *ch= ch_v;
15   OutBuffer *ob;
16   int r;
17   
18   assert(fd == ch->fd);
19   assert(evt == OOP_WRITE);
20
21   for (;;) {
22     ob= ch->obs.head;
23     if (!ob) {
24       events->cancel_fd(events, fd, OOP_WRITE);
25       return OOP_CONTINUE;
26     }
27     if (ch->done_of_head == ob->l) {
28       LIST_UNLINK(ch->obs, ob);
29       free(ob);
30       free(ob->m);
31       ch->done_of_head= 0;
32       continue;
33     }
34     r= write(ch->fd, ob->m + ch->done_of_head, ob->l - ch->done_of_head);
35     if (r==-1) {
36       if (errno==EINTR) continue;
37       if (errno==EWOULDBLOCK) return OOP_CONTINUE;
38       ch->error(ch,"write",strerror(errno));
39     }
40     assert(r>=0);
41     ch->done_of_head += r;
42     assert(ch->done_of_head <= ob->l);
43   }
44 }
45
46 static void addlink(OutBufferChain *ch, OutBuffer *ob) {
47   if (!ch->obs.head)
48     events->on_fd(events, ch->fd, OOP_WRITE, writeable, ch);
49   LIST_LINK_TAIL(ch->obs, ob);
50 }
51
52 void obc_init(OutBufferChain *ch) {
53   ch->done_of_head= 0;
54   LIST_INIT(ch->obs);
55 }
56
57 void ovprintf(OutBufferChain *ch, const char *fmt, va_list al) {
58   OutBuffer *ob;
59
60   ob= mmalloc(sizeof(*ob));
61   ob->l= vasprintf(&ob->m, fmt, al);  if (ob->l <= 0) diem();
62   addlink(ch, ob);
63 }
64
65 void oprintf(OutBufferChain *ch, const char *msg, ...) {
66   va_list al;
67   va_start(al,msg);
68   ovprintf(ch,msg,al);
69   va_end(al);
70 }
71
72 void owrite(OutBufferChain *ch, const char *data, int l) {
73   OutBuffer *ob;
74   ob= mmalloc(sizeof(*ob));
75   ob->l= l;
76   ob->m= mmalloc(l);
77   memcpy(ob->m, data, l);
78   addlink(ch,ob);
79 }