}
}
+static char *connid(void)
+{
+ static struct charbuf cur;
+ int i;
+ char *ret;
+
+ for(i = 0; i < cur.d; i++) {
+ if((++cur.b[i]) > 'Z')
+ cur.b[i] = 'A';
+ else
+ goto done;
+ }
+ bufadd(cur, 'A');
+done:
+ ret = memcpy(smalloc(cur.d + 1), cur.b, cur.d);
+ ret[cur.d] = 0;
+ return(ret);
+}
+
void serve(FILE *in, struct conn *conn)
{
int pfds[2];
FILE *out;
struct hthead *req, *resp;
- char *hd;
+ char *hd, *id;
off_t dlen;
int keep;
+ id = connid();
out = NULL;
req = resp = NULL;
while(plex >= 0) {
if(!canonreq(req))
break;
+ headappheader(req, "X-Ash-Connection-ID", id);
if((conn->initreq != NULL) && conn->initreq(conn, req))
break;
if(sendreq(plex, req, pfds[0]))
break;
close(pfds[0]);
- out = mtstdopen(pfds[1], 1, 600, "r+");
+ out = mtstdopen(pfds[1], 1, 600, "r+", NULL);
if(getheader(req, "content-type") != NULL) {
if((hd = getheader(req, "content-length")) != NULL) {
if(resp != NULL)
freehthead(resp);
fclose(in);
+ free(id);
}
static void plexwatch(struct muth *muth, va_list args)
{
vavar(int, fd);
char *buf;
- int ret;
+ int i, s, ret;
+ s = 0;
while(1) {
if(block(fd, EV_READ, 0) == 0)
break;
flog(LOG_WARNING, "received error on rootplex read channel: %s", strerror(errno));
exit(1);
} else if(ret == 0) {
- exit(0);
+ s = 1;
+ free(buf);
+ break;
}
/* Maybe I'd like to implement some protocol in this direction
* some day... */
free(buf);
}
- close(plex);
- plex = -1;
+ shutdown(plex, SHUT_RDWR);
+ for(i = 0; i < listeners.d; i++) {
+ if(listeners.b[i] == muth)
+ bufdel(listeners, i);
+ }
+ if(s) {
+ flog(LOG_INFO, "root handler exited, so shutting down listening...");
+ while(listeners.d > 0)
+ resume(listeners.b[0], 0);
+ }
}
static void initroot(void *uu)
break;
case 1:
if(listeners.d > 0) {
- for(i = 0; i < listeners.d; i++)
- resume(listeners.b[i], 0);
- listeners.d = 0;
+ while(listeners.d > 0)
+ resume(listeners.b[0], 0);
flog(LOG_INFO, "no longer listening");
} else {
d = 1;