/* Path is interpreted as the directory containing the unix domain socket * and broker pid. */ flux_t connector_init (const char *path, int flags) { ctx_t *c = NULL; struct sockaddr_un addr; char pidfile[PATH_MAX + 1]; char sockfile[PATH_MAX + 1]; int n, count; if (!path) { errno = EINVAL; goto error; } n = snprintf (sockfile, sizeof (sockfile), "%s/local", path); if (n >= sizeof (sockfile)) { errno = EINVAL; goto error; } n = snprintf (pidfile, sizeof (pidfile), "%s/broker.pid", path); if (n >= sizeof (pidfile)) { errno = EINVAL; goto error; } if (!(c = malloc (sizeof (*c)))) { errno = ENOMEM; goto error; } memset (c, 0, sizeof (*c)); c->magic = CTX_MAGIC; c->fd = socket (AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0); if (c->fd < 0) goto error; c->fd_nonblock = -1; for (count=0;;count++) { if (count >= env_getint("FLUX_RETRY_COUNT", 5) || !pidcheck (pidfile)) goto error; memset (&addr, 0, sizeof (struct sockaddr_un)); addr.sun_family = AF_UNIX; strncpy (addr.sun_path, sockfile, sizeof (addr.sun_path) - 1); if (connect (c->fd, (struct sockaddr *)&addr, sizeof (struct sockaddr_un)) == 0) break; usleep (100*1000); } flux_msg_iobuf_init (&c->outbuf); flux_msg_iobuf_init (&c->inbuf); if (!(c->h = flux_handle_create (c, &handle_ops, flags))) goto error; return c->h; error: if (c) { int saved_errno = errno; op_fini (c); errno = saved_errno; } return NULL; }
static void show_single_message (CT ct, char *form) { sigset_t set, oset; int status; /* Allow user executable bit so that temporary directories created by * the viewer (e.g., lynx) are going to be accessible */ umask (ct->c_umask & ~(0100)); /* * If you have a format file, then display * the message headers. */ if (form) DisplayMsgHeader(ct, form); else xpid = 0; /* Show the body of the message */ show_switch (ct, 1, 0); if (ct->c_fp) { fclose (ct->c_fp); ct->c_fp = NULL; } if (ct->c_ceclosefnx) (*ct->c_ceclosefnx) (ct); /* block a few signals */ sigemptyset (&set); sigaddset (&set, SIGHUP); sigaddset (&set, SIGINT); sigaddset (&set, SIGQUIT); sigaddset (&set, SIGTERM); sigprocmask (SIG_BLOCK, &set, &oset); while (wait (&status) != NOTOK) { pidcheck (status); continue; } /* reset the signal mask */ sigprocmask (SIG_SETMASK, &oset, &set); xpid = 0; flush_errors (); }
static int show_multi_internal (CT ct, int serial, int alternate) { int alternating, nowalternate, nowserial, result; struct multipart *m = (struct multipart *) ct->c_ctparams; struct part *part; CT p; sigset_t set, oset; alternating = 0; nowalternate = alternate; if (ct->c_subtype == MULTI_PARALLEL) { nowserial = serialsw; } else if (ct->c_subtype == MULTI_ALTERNATE) { nowalternate = 1; alternating = 1; nowserial = serial; } else { /* * multipart/mixed * mutlipart/digest * unknown subtypes of multipart (treat as mixed per rfc2046) */ nowserial = serial; } /* block a few signals */ if (!nowserial) { sigemptyset (&set); sigaddset (&set, SIGHUP); sigaddset (&set, SIGINT); sigaddset (&set, SIGQUIT); sigaddset (&set, SIGTERM); sigprocmask (SIG_BLOCK, &set, &oset); } /* * alternate -> we are a part inside an multipart/alternative * alternating -> we are a multipart/alternative */ result = alternate ? NOTOK : OK; for (part = m->mp_parts; part; part = part->mp_next) { p = part->mp_part; if (part_ok (p, 1) && type_ok (p, 1)) { int inneresult; inneresult = show_switch (p, nowserial, nowalternate); switch (inneresult) { case NOTOK: if (alternate && !alternating) { result = NOTOK; goto out; } continue; case OK: case DONE: if (alternating) { result = DONE; break; } if (alternate) { alternate = nowalternate = 0; if (result == NOTOK) result = inneresult; } continue; } break; } } if (alternating && !part) { if (!alternate) content_error (NULL, ct, "don't know how to display any of the contents"); result = NOTOK; goto out; } if (serial && !nowserial) { pid_t pid; int kids; int status; kids = 0; for (part = m->mp_parts; part; part = part->mp_next) { p = part->mp_part; if (p->c_pid > OK) { if (kill (p->c_pid, 0) == NOTOK) p->c_pid = 0; else kids++; } } while (kids > 0 && (pid = wait (&status)) != NOTOK) { pidcheck (status); for (part = m->mp_parts; part; part = part->mp_next) { p = part->mp_part; if (xpid == pid) xpid = 0; if (p->c_pid == pid) { p->c_pid = 0; kids--; break; } } } } out: if (!nowserial) { /* reset the signal mask */ sigprocmask (SIG_SETMASK, &oset, &set); } return result; }
static int show_content_aux2 (CT ct, int serial, int alternate, char *cracked, char *buffer, int fd, int xlist, int xpause, int xstdin, int xtty) { pid_t child_id; int i; char *vec[4], exec[BUFSIZ + sizeof "exec "]; if (debugsw || cracked) { fflush (stdout); fprintf (stderr, "%s msg %s", cracked ? "storing" : "show", ct->c_file); if (ct->c_partno) fprintf (stderr, " part %s", ct->c_partno); if (cracked) fprintf (stderr, " using command (cd %s; %s)\n", cracked, buffer); else fprintf (stderr, " using command %s\n", buffer); } if (xpid < 0 || (xtty && xpid)) { if (xpid < 0) xpid = -xpid; pidcheck(pidwait (xpid, NOTOK)); xpid = 0; } if (xlist) { char prompt[BUFSIZ]; if (ct->c_type == CT_MULTIPART) list_content (ct, -1, 1, 0, 0); else list_switch (ct, -1, 1, 0, 0); if (xpause && isatty (fileno (stdout))) { int intr; SIGNAL_HANDLER istat; if (SOprintf ("Press <return> to show content...")) printf ("Press <return> to show content..."); istat = SIGNAL (SIGINT, intrser); if ((intr = sigsetjmp (intrenv, 1)) == OK) { fflush (stdout); prompt[0] = 0; read (fileno (stdout), prompt, sizeof(prompt)); } SIGNAL (SIGINT, istat); if (intr != OK || prompt[0] == 'n') { (*ct->c_ceclosefnx) (ct); return (alternate ? DONE : NOTOK); } if (prompt[0] == 'q') done(OK); } } snprintf (exec, sizeof(exec), "exec %s", buffer); vec[0] = "/bin/sh"; vec[1] = "-c"; vec[2] = exec; vec[3] = NULL; fflush (stdout); for (i = 0; (child_id = fork()) == NOTOK && i < 5; i++) sleep (5); switch (child_id) { case NOTOK: advise ("fork", "unable to"); (*ct->c_ceclosefnx) (ct); return NOTOK; case OK: if (cracked) chdir (cracked); if (!xstdin) dup2 (fd, 0); close (fd); execvp ("/bin/sh", vec); fprintf (stderr, "unable to exec "); perror ("/bin/sh"); _exit (-1); /* NOTREACHED */ default: if (!serial) { ct->c_pid = child_id; if (xtty) xpid = child_id; } else { pidcheck (pidXwait (child_id, NULL)); } if (fd != NOTOK) (*ct->c_ceclosefnx) (ct); return (alternate ? DONE : OK); } }