Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
0
void *server_thread (void *arg)
{
    struct context *ctx = arg;
    flux_reactor_t *reactor = NULL;
    flux_watcher_t *w = NULL;

    if (!(reactor = flux_reactor_create (0)))
        goto done;
    if (!(w = flux_fd_watcher_create (reactor, ctx->fds[1],
                                      FLUX_POLLIN, s_io_cb, ctx)))
        goto done;
    flux_watcher_start (w);

    ctx->exit_rc = -1;
    if (flux_reactor_run (reactor, 0) < 0)
        goto done;

    ctx->exit_rc = 0;
done:
    if (w)
        flux_watcher_destroy (w);
    if (reactor)
        flux_reactor_destroy (reactor);
    return NULL;
}
Ejemplo n.º 3
0
int mod_main (flux_t h, int argc, char **argv)
{
    ctx_t *ctx = getctx (h);
    char *sockpath = NULL, *dfltpath = NULL;
    int rc = -1;

    /* Parse args.
     */
    if (argc > 0)
        sockpath = argv[0];
    if (!sockpath)
        sockpath = dfltpath = xasprintf ("%s/flux-api", flux_get_tmpdir ());

    /* Create listen socket and watcher to handle new connections
     */
    if ((ctx->listen_fd = listener_init (ctx, sockpath)) < 0)
        goto done;
    if (!(ctx->listen_w = flux_fd_watcher_create (ctx->listen_fd,
                                           FLUX_POLLIN | FLUX_POLLERR,
                                           listener_cb, ctx))) {
        flux_log (h, LOG_ERR, "flux_fd_watcher_create: %s", strerror (errno));
        goto done;
    }
    flux_fd_watcher_start (h, ctx->listen_w);

    /* Create/start event/response message watchers
     */
    if (flux_msg_watcher_addvec (h, htab, ctx) < 0) {
        flux_log (h, LOG_ERR, "flux_msg_watcher_addvec: %s", strerror (errno));
        goto done;
    }

    /* Start reactor
     */
    if (flux_reactor_start (h) < 0) {
        flux_log (h, LOG_ERR, "flux_reactor_start: %s", strerror (errno));
        goto done;
    }
    rc = 0;
done:
    if (dfltpath)
        free (dfltpath);
    flux_msg_watcher_delvec (h, htab);
    flux_fd_watcher_destroy (ctx->listen_w);
    if (ctx->listen_fd >= 0) {
        if (close (ctx->listen_fd) < 0)
            flux_log (h, LOG_ERR, "close listen_fd: %s", strerror (errno));
    }
    if (ctx->clients) {
        client_t *c;
        while ((c = zlist_pop (ctx->clients)))
            client_destroy (c);
    }
    return rc;
}
Ejemplo n.º 4
0
Archivo: zio.c Proyecto: trws/flux-core
/*
 *  Schedule pending data to write to zio->dstfd
 */
static int zio_flux_writer_schedule (zio_t *zio)
{
    if (!zio->reactor)
        return (-1);
    if (!zio->writer)
        zio->writer = flux_fd_watcher_create (zio->reactor,
                zio->dstfd, FLUX_POLLOUT, zio_flux_writer_cb, zio);
    if (!zio->writer)
        return (-1);
    flux_watcher_start (zio->writer);
    return (0);
}
Ejemplo n.º 5
0
Archivo: zio.c Proyecto: trws/flux-core
static int zio_flux_reader_poll (zio_t *zio)
{
    if (!zio->reactor)
        return (-1);
    if (!zio->reader)
        zio->reader = flux_fd_watcher_create (zio->reactor,
                zio->srcfd, FLUX_POLLIN, zio_flux_read_cb, zio);
    if (!zio->reader)
        return (-1);
    flux_watcher_start (zio->reader);
    return (0);
}
Ejemplo n.º 6
0
static void test_fd (flux_reactor_t *reactor)
{
    int fd[2];
    flux_watcher_t *r, *w;

    ok (socketpair (PF_LOCAL, SOCK_STREAM, 0, fd) == 0
        && set_nonblock (fd[0]) == 0 && set_nonblock (fd[1]) == 0,
        "fd: successfully created non-blocking socketpair");
    r = flux_fd_watcher_create (reactor, fd[0], FLUX_POLLIN, fdreader, NULL);
    w = flux_fd_watcher_create (reactor, fd[1], FLUX_POLLOUT, fdwriter, NULL);
    ok (r != NULL && w != NULL,
        "fd: reader and writer created");
    flux_watcher_start (r);
    flux_watcher_start (w);
    ok (flux_reactor_run (reactor, 0) == 0,
        "fd: reactor ran to completion after %lu bytes", fdwriter_bufsize);
    flux_watcher_stop (r);
    flux_watcher_stop (w);
    flux_watcher_destroy (r);
    flux_watcher_destroy (w);
    close (fd[0]);
    close (fd[1]);
}
Ejemplo n.º 7
0
static void attach (flux_t *h, const char *key, bool rawtty, int kzoutflags,
                    int blocksize)
{
    t_kzutil_ctx_t *ctx = xzmalloc (sizeof (*ctx));
    char *name;
    int fdin = dup (STDIN_FILENO);
    struct termios saved_tio;
    flux_reactor_t *r = flux_get_reactor (h);
    flux_watcher_t *w = NULL;

    log_msg ("process attached to %s", key);

    ctx->h = h;
    ctx->blocksize = blocksize;

    /* FIXME: need a ~. style escape sequence to terminate stdin
     * in raw mode.
     */
    if (rawtty) {
        if (fd_set_raw (fdin, &saved_tio, true) < 0)
            log_err_exit ("fd_set_raw stdin");
    }
    if (fd_set_nonblocking (fdin, true) < 0)
        log_err_exit ("fd_set_nonblocking stdin");

    if (asprintf (&name, "%s.stdin", key) < 0)
        oom ();
    if (!(ctx->kz[0] = kz_open (h, name, kzoutflags)))
        if (errno == EEXIST)
            log_err ("disabling stdin");
        else
            log_err_exit ("%s", name);
    else {
        if (!(w = flux_fd_watcher_create (r, fdin, FLUX_POLLIN,
                                attach_stdin_ready_cb, ctx)))
            log_err_exit ("flux_fd_watcher_create %s", name);
        flux_watcher_start (w);
    }
    free (name);

    if (asprintf (&name, "%s.stdout", key) < 0)
        oom ();
    if (!(ctx->kz[1] = kz_open (h, name, KZ_FLAGS_READ | KZ_FLAGS_NONBLOCK)))
        log_err_exit ("kz_open %s", name);
    if (kz_set_ready_cb (ctx->kz[1], attach_stdout_ready_cb, ctx) < 0)
        log_err_exit ("kz_set_ready_cb %s", name);
    free (name);
    ctx->readers++;

    if (asprintf (&name, "%s.stderr", key) < 0)
        oom ();
    if (!(ctx->kz[2] = kz_open (h, name, KZ_FLAGS_READ | KZ_FLAGS_NONBLOCK)))
        log_err_exit ("kz_open %s", name);
    if (kz_set_ready_cb (ctx->kz[2], attach_stderr_ready_cb, ctx) < 0)
        log_err_exit ("kz_set_ready_cb %s", name);
    free (name);
    ctx->readers++;

    /* Reactor terminates when ctx->readers reaches zero, i.e.
     * when EOF is read from remote stdout and stderr.
     * (Note: if they are already at eof, we will have already terminated
     * before the reactor is started, since kvs_watch callbacks make one
     * call to the callback in the context of the caller).
     */
    if (ctx->readers > 0) {
        if (flux_reactor_run (r, 0) < 0)
            log_err_exit ("flux_reactor_run");
    }

    (void)kz_close (ctx->kz[1]);
    (void)kz_close (ctx->kz[2]);

    /* FIXME: tty state needs to be restored on all exit paths.
     */
    if (rawtty) {
        if (fd_set_raw (fdin, &saved_tio, false) < 0)
            log_err_exit ("fd_set_raw stdin");
    }

    flux_watcher_destroy (w);
    free (ctx);
}
Ejemplo n.º 8
0
int main (int argc, char **argv)
{
    zio_t *zio;
    int init_fds;
    const char *name;
    struct counts c;
    int fd;
    flux_reactor_t *r;
    flux_watcher_t *w;

    memset (&c, 0, sizeof (c));

    plan (NO_PLAN);

    test_encode ();

    ok ((r = flux_reactor_create (0)) != NULL,
        "flux reactor created");

    init_fds = fdcount ();
    diag ("initial fd count: %d", init_fds);

    /* simple reader tests
     */
    ok ((zio = zio_pipe_reader_create ("test1", &c)) != NULL,
        "reader: zio_pipe_reader_create works");
    ok ((name = zio_name (zio)) != NULL && !strcmp (name, "test1"),
        "reader: zio_name returns correct name");
    ok (zio_set_close_cb (zio, close_reader) == 0,
        "reader: zio_set_close_cb works");
    ok (zio_set_send_cb (zio, send_reader) == 0,
        "reader: zio_set_send_cb works");
    ok (zio_reactor_attach (zio, r) == 0,
        "reader: zio_reactor_attach works");
    ok ((fd = zio_dst_fd (zio)) >= 0,
        "reader: zio_dst_fd returned valid file descriptor");
    ok (write (fd, "narf!", 5) == 5,
        "reader: wrote narf! to reader pipe");
    ok (zio_close_dst_fd (zio) == 0,
        "reader: zio_close_dst_fd succeeded");
    ok (flux_reactor_run (r, 0) == 0,
        "reader: reactor completed successfully");
    ok (c.send_reader == 1,
        "reader: send function called once for EOF + incomplete line");
    errno = 0;
    zio_destroy (zio);
    ok (init_fds == fdcount (),
        "reader: zio_destroy leaks no file descriptors");

    /* simple writer tests
     */
    ok ((zio = zio_pipe_writer_create ("test2", &c)) != NULL,
        "writer: zio_pipe_writer_create works");
    ok ((name = zio_name (zio)) != NULL && !strcmp (name, "test2"),
        "writer: zio_name returns correct name");
    ok (zio_set_close_cb (zio, close_writer) == 0,
        "writer: zio_set_close_cb works");
    ok ((fd = zio_src_fd (zio)) >= 0,
        "writer: zio_src_fd returned valid file descriptor");
    w = flux_fd_watcher_create (r, fd, FLUX_POLLIN, fd_read, &c);
    ok (w != NULL,
        "writer: created fd watcher");
    flux_watcher_start (w);
    ok (zio_write (zio, "narf!", 5) == 5,
        "writer: zio_write narf! works");
    ok (zio_write_eof (zio) == 0,
        "writer: zio_write_eof works");
    ok (flux_reactor_run (r, 0) == 0,
        "writer: reactor completed successfully");
    ok (c.fd_read_errors == 0 && c.fd_read_data == 5 && c.fd_read_eof == 1,
        "writer: read narf + EOF on read end of pipe");
    ok (c.close_writer == 1,
        "writer: close callback invoked");

    zio_destroy (zio);
    ok (init_fds == fdcount (),
        "writer: zio_destroy leaks no file descriptors");

    flux_watcher_destroy (w);
    flux_reactor_destroy (r);

    done_testing ();
}