static void copy_k2f (flux_t *h, const char *src, const char *dst) { kz_t *kzin; int dstfd = STDOUT_FILENO; char *data; int len; if (!(kzin = kz_open (h, src, KZ_FLAGS_READ))) log_err_exit ("kz_open %s", src); if (strcmp (dst, "-") != 0) { if ((dstfd = creat (dst, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) < 0) log_err_exit ("%s", dst); } while ((len = kz_get (kzin, &data)) > 0) { if (write_all (dstfd, data, len) < 0) log_err_exit ("write_all %s", dst); free (data); } if (len < 0) log_err_exit ("kz_get %s", src); if (kz_close (kzin) < 0) log_err_exit ("kz_close %s", src); if (dstfd != STDOUT_FILENO) { if (close (dstfd) < 0) log_err_exit ("close %s", dst); } }
static void copy_f2k (flux_t *h, const char *src, const char *dst, int kzoutflags, int blocksize) { int srcfd = STDIN_FILENO; kz_t *kzout; char *data; int len; if (strcmp (src, "-") != 0) { if ((srcfd = open (src, O_RDONLY)) < 0) log_err_exit ("%s", src); } if (!(kzout = kz_open (h, dst, kzoutflags))) log_err_exit ("kz_open %s", dst); data = xzmalloc (blocksize); while ((len = read (srcfd, data, blocksize)) > 0) { if (kz_put (kzout, data, len) < 0) log_err_exit ("kz_put %s", dst); } if (len < 0) log_err_exit ("read %s", src); free (data); if (kz_close (kzout) < 0) log_err_exit ("kz_close %s", dst); }
static void copy_k2k (flux_t *h, const char *src, const char *dst, int kzoutflags) { kz_t *kzin, *kzout; char *json_str; bool eof = false; if (!(kzin = kz_open (h, src, KZ_FLAGS_READ | KZ_FLAGS_RAW))) log_err_exit ("kz_open %s", src); if (!(kzout = kz_open (h, dst, kzoutflags | KZ_FLAGS_RAW))) log_err_exit ("kz_open %s", dst); while (!eof && (json_str = kz_get_json (kzin))) { if (kz_put_json (kzout, json_str) < 0) log_err_exit ("kz_put_json %s", dst); eof = zio_json_eof (json_str); free (json_str); } if (json_str == NULL) log_err_exit ("kz_get %s", src); if (kz_close (kzin) < 0) log_err_exit ("kz_close %s", src); if (kz_close (kzout) < 0) log_err_exit ("kz_close %s", dst); }
kz_t *kz_gopen (flux_t h, const char *grpname, int nprocs, const char *name, int flags) { kz_t *kz; if (!(flags & KZ_FLAGS_WRITE) || !grpname || nprocs <= 0) { errno = EINVAL; return NULL; } flags |= KZ_FLAGS_NOCOMMIT_OPEN; flags |= KZ_FLAGS_NOCOMMIT_CLOSE; if (!(kz = kz_open (h, name, flags))) return NULL; kz->grpname = xstrdup (grpname); kz->nprocs = nprocs; if (kz_fence (kz) < 0) goto error; return kz; error: kz_destroy (kz); return NULL; }
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); }