/* 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 client_t * client_create (ctx_t *ctx, int fd) { client_t *c; socklen_t crlen = sizeof (c->ucred); flux_t h = ctx->h; c = xzmalloc (sizeof (*c)); c->fd = fd; if (!(c->uuid = zuuid_new ())) oom (); c->ctx = ctx; if (!(c->disconnect_notify = zhash_new ())) oom (); if (!(c->subscriptions = zlist_new ())) oom (); if (!(c->outqueue = zlist_new ())) oom (); if (getsockopt (fd, SOL_SOCKET, SO_PEERCRED, &c->ucred, &crlen) < 0) { flux_log (h, LOG_ERR, "getsockopt SO_PEERCRED: %s", strerror (errno)); goto error; } assert (crlen == sizeof (c->ucred)); /* Deny connections by uid other than session owner for now. */ if (c->ucred.uid != ctx->session_owner) { flux_log (h, LOG_ERR, "connect by uid=%d pid=%d denied", c->ucred.uid, (int)c->ucred.pid); goto error; } c->inw = flux_fd_watcher_create (fd, FLUX_POLLIN, client_read_cb, c); c->outw = flux_fd_watcher_create (fd, FLUX_POLLOUT, client_write_cb, c); if (!c->inw || !c->outw) { flux_log (h, LOG_ERR, "flux_fd_watcher_create: %s", strerror (errno)); goto error; } flux_fd_watcher_start (h, c->inw); flux_msg_iobuf_init (&c->inbuf); flux_msg_iobuf_init (&c->outbuf); if (set_nonblock (c->fd, true) < 0) { flux_log (h, LOG_ERR, "set_nonblock: %s", strerror (errno)); goto error; } return (c); error: client_destroy (c); return NULL; }