-static void checkmagic(unsigned long was, unsigned long should, const char *when) {
- if (was != should)
- protoerror("magic number %s was %08lx, expected %08lx",when,was,should);
-}
-
-static void getprogress(struct progress_msg *progress_r, FILE *file) {
- int i, c;
- unsigned long ul;
-
- for (;;) {
- xfread(progress_r,sizeof(struct progress_msg),file);
- switch (progress_r->type) {
- case pt_failed:
- blocksignals(SIG_BLOCK);
- fputs("userv: uservd reports that service failed\n",stderr);
- exit(-1);
- case pt_errmsg:
- blocksignals(SIG_BLOCK);
- fputs("uservd: ",stderr);
- if (progress_r->data.errmsg.messagelen>4096)
- protoerror("stderr message length %d is far too long",
- progress_r->data.errmsg.messagelen);
- for (i=0; i<progress_r->data.errmsg.messagelen; i++) {
- c= getc(file); if (c==EOF) protoreaderror(file,"in error message");
- if (isprint(c)) putc(c,stderr);
- else fprintf(stderr,"\\x%02x",(unsigned char)c);
- }
- putc('\n',stderr);
- if (ferror(stderr)) syscallerror("printing error message");
- xfread(&ul,sizeof(ul),file);
- checkmagic(ul,PROGRESS_ERRMSG_END_MAGIC,"after error message");
- blocksignals(SIG_UNBLOCK);
- break;
- default:
- return;
- }
- }
-}
-
-static void xfwritefds(int modifier, int expected, FILE *file) {
- int i, fdcount;
-
- for (i=0, fdcount=0; i<fdsetupsize; i++) {
- if (!(fdsetup[i].filename && (fdsetup[i].mods & modifier)))
- continue;
- xfwrite(&i,sizeof(int),file); fdcount++;
- }
- assert(fdcount == expected);
-}
-
-static void disconnect(void) /* DOES return, unlike in daemon */ {
- struct event_msg event_mbuf;
-
- if (!swfile) {
- fputs("userv: failed, after service program terminated\n",stderr);
- _exit(255);
- }
- memset(&event_mbuf,0,sizeof(event_mbuf));
- event_mbuf.magic= EVENT_MAGIC;
- event_mbuf.type= et_disconnect;
- xfwrite(&event_mbuf,sizeof(event_mbuf),swfile);
- xfflush(swfile);
-}
-
-static void sighandler_alrm(int ignored) /* DOES return, unlike in daemon */ {
- int es;
- es= errno;
- fputs("userv: timeout\n",stderr);
- disconnect();
- errno= es;
-}
-
-static void sighandler_chld(int ignored) /* DOES return, unlike in daemon */ {
- struct event_msg event_mbuf;
- pid_t child;
- int status, fd, r, es;