nightmaremail

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

comm.c (2506B)


      1 #include "mxf-send.h"
      2 /* this file is too long ------------------------------------- COMMUNICATION */
      3 
      4 // Why's cleanup a separate function? it should just be a channel...
      5 substdio sstoqc;
      6 char sstoqcbuf[1024];
      7 substdio ssfromqc;
      8 char ssfromqcbuf[1024];
      9 
     10 stralloc comm_buf[CHANNELS] = {{0}, {0}};
     11 int comm_pos[CHANNELS];
     12 
     13 void
     14 comm_init()
     15 {
     16 	int c;
     17 	// special casing...
     18 	// this also relies on those FDs being, well...
     19 	substdio_fdbuf(&sstoqc, write, 5, sstoqcbuf, sizeof(sstoqcbuf));
     20 	substdio_fdbuf(&ssfromqc, read, 6, ssfromqcbuf, sizeof(ssfromqcbuf));
     21 	for (c = 0; c < CHANNELS; ++c)
     22 		if (ndelay_on(chanfdout[c]) == -1)
     23 			/*
     24 			 * this is so stupid: NDELAY semantics should be
     25 			 * default on write
     26 			 */
     27 			spawndied(c);	/* drastic, but better than risking
     28 					 * deadlock */
     29 }
     30 
     31 int
     32 comm_canwrite(int c)
     33 {
     34 	/* XXX: could allow a bigger buffer; say 10 recipients */
     35 	if (comm_buf[c].s && comm_buf[c].len)
     36 		return 0;
     37 	return 1;
     38 }
     39 
     40 void
     41 comm_write(int c, int delnum, unsigned long id, char *sender, char *recip)
     42 {
     43 	char ch;
     44 	if (comm_buf[c].s && comm_buf[c].len)
     45 		return;
     46 	while (!stralloc_copys(&comm_buf[c], ""))
     47 		nomem();
     48 	ch = delnum;
     49 	while (!stralloc_append(&comm_buf[c], &ch))
     50 		nomem();
     51 	fnmake_split(id, &fn);
     52 	while (!stralloc_cats(&comm_buf[c], fn.s))
     53 		nomem();
     54 	while (!stralloc_0(&comm_buf[c]))
     55 		nomem();
     56 	senderadd(&comm_buf[c], sender, recip);
     57 	while (!stralloc_0(&comm_buf[c]))
     58 		nomem();
     59 	while (!stralloc_cats(&comm_buf[c], recip))
     60 		nomem();
     61 	while (!stralloc_0(&comm_buf[c]))
     62 		nomem();
     63 	comm_pos[c] = 0;
     64 }
     65 
     66 void
     67 comm_selprep(int *nfds, fd_set * wfds)
     68 {
     69 	int c;
     70 	for (c = 0; c < CHANNELS; ++c)
     71 		if (flagspawnalive[c])
     72 			if (comm_buf[c].s && comm_buf[c].len) {
     73 				FD_SET(chanfdout[c], wfds); // if we had iolib, we could do this better.
     74 				if (*nfds <= chanfdout[c])
     75 					*nfds = chanfdout[c] + 1;
     76 			}
     77 }
     78 
     79 void
     80 comm_do(fd_set * wfds)
     81 {
     82 	int c;
     83 	for (c = 0; c < CHANNELS; ++c)
     84 		if (flagspawnalive[c])
     85 			if (comm_buf[c].s && comm_buf[c].len)
     86 				if (FD_ISSET(chanfdout[c], wfds)) {
     87 					int w; // isn't this just a nonblocking substdio?!
     88 					int len;
     89 					len = comm_buf[c].len;
     90 					w = write(chanfdout[c], comm_buf[c].s + comm_pos[c], len - comm_pos[c]);
     91 					if (w == 0 || w == -1) {
     92 						if ((w == -1) && (errno == error_pipe))
     93 							spawndied(c);
     94 						else
     95 							continue;	/* kernel select() bug;
     96 									 * can't avoid
     97 									 * busy-looping */
     98 					} else {
     99 						comm_pos[c] += w;
    100 						if (comm_pos[c] == len)
    101 							comm_buf[c].len = 0;
    102 					}
    103 				}
    104 }