diff options
author | Nicholas Marriott <nicm@cvs.openbsd.org> | 2009-11-04 21:04:44 +0000 |
---|---|---|
committer | Nicholas Marriott <nicm@cvs.openbsd.org> | 2009-11-04 21:04:44 +0000 |
commit | 69b2d345034deaad1ed3e6a7107713027c4989c3 (patch) | |
tree | 33ea0416fb67067f8a46f96f2b4de8ab5f7b5bcf | |
parent | c4951f362efa741b6aaf42f94c0cfb7073db3d9f (diff) |
Switch jobs over to use a bufferevent.
-rw-r--r-- | usr.bin/tmux/Makefile | 4 | ||||
-rw-r--r-- | usr.bin/tmux/cmd-run-shell.c | 44 | ||||
-rw-r--r-- | usr.bin/tmux/job.c | 53 | ||||
-rw-r--r-- | usr.bin/tmux/server-job.c | 77 | ||||
-rw-r--r-- | usr.bin/tmux/server.c | 8 | ||||
-rw-r--r-- | usr.bin/tmux/status.c | 23 | ||||
-rw-r--r-- | usr.bin/tmux/tmux.h | 14 |
7 files changed, 86 insertions, 137 deletions
diff --git a/usr.bin/tmux/Makefile b/usr.bin/tmux/Makefile index a3f4d5e19e7..21bf575745e 100644 --- a/usr.bin/tmux/Makefile +++ b/usr.bin/tmux/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.26 2009/11/04 20:50:11 nicm Exp $ +# $OpenBSD: Makefile,v 1.27 2009/11/04 21:04:43 nicm Exp $ PROG= tmux SRCS= attributes.c buffer-poll.c buffer.c cfg.c \ @@ -35,7 +35,7 @@ SRCS= attributes.c buffer-poll.c buffer.c cfg.c \ layout-set.c layout.c log.c job.c \ mode-key.c names.c options-cmd.c options.c paste.c procname.c \ resize.c screen-redraw.c screen-write.c screen.c session.c status.c \ - server-fn.c server.c server-client.c server-window.c server-job.c \ + server-fn.c server.c server-client.c server-window.c \ tmux.c tty-keys.c tty-term.c tty.c utf8.c \ window-choose.c window-clock.c window-copy.c window-more.c window.c \ xterm-keys.c xmalloc.c diff --git a/usr.bin/tmux/cmd-run-shell.c b/usr.bin/tmux/cmd-run-shell.c index 3106466694e..274fbde2149 100644 --- a/usr.bin/tmux/cmd-run-shell.c +++ b/usr.bin/tmux/cmd-run-shell.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cmd-run-shell.c,v 1.4 2009/11/01 23:20:37 nicm Exp $ */ +/* $OpenBSD: cmd-run-shell.c,v 1.5 2009/11/04 21:04:43 nicm Exp $ */ /* * Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org> @@ -77,31 +77,33 @@ cmd_run_shell_callback(struct job *job) { struct cmd_run_shell_data *cdata = job->data; struct cmd_ctx *ctx = &cdata->ctx; - char *cmd, *msg, *line, *buf; - size_t off, len, llen; + char *cmd, *msg, *line; + size_t size; int retcode; + u_int lines; - buf = BUFFER_OUT(job->out); - len = BUFFER_USED(job->out); + lines = 0; + do { + if ((line = evbuffer_readline(job->event->input)) != NULL) { + ctx->print(ctx, "%s", line); + lines++; + } + } while (line != NULL); - cmd = cdata->cmd; + size = EVBUFFER_LENGTH(job->event->input); + if (size != 0) { + line = xmalloc(size + 1); + memcpy(line, EVBUFFER_DATA(job->event->input), size); + line[size] = '\0'; - if (len != 0) { - line = buf; - for (off = 0; off < len; off++) { - if (buf[off] == '\n') { - llen = buf + off - line; - if (llen > INT_MAX) - break; - ctx->print(ctx, "%.*s", (int) llen, line); - line = buf + off + 1; - } - } - llen = buf + len - line; - if (llen > 0 && llen < INT_MAX) - ctx->print(ctx, "%.*s", (int) llen, line); + ctx->print(ctx, "%s", line); + lines++; + + xfree(line); } + cmd = cdata->cmd; + msg = NULL; if (WIFEXITED(job->status)) { if ((retcode = WEXITSTATUS(job->status)) != 0) @@ -111,7 +113,7 @@ cmd_run_shell_callback(struct job *job) xasprintf(&msg, "'%s' terminated by signal %d", cmd, retcode); } if (msg != NULL) { - if (len != 0) + if (lines != 0) ctx->print(ctx, "%s", msg); else ctx->info(ctx, "%s", msg); diff --git a/usr.bin/tmux/job.c b/usr.bin/tmux/job.c index 89a5ec089ec..375507f87d8 100644 --- a/usr.bin/tmux/job.c +++ b/usr.bin/tmux/job.c @@ -1,4 +1,4 @@ -/* $OpenBSD: job.c,v 1.10 2009/11/04 20:50:11 nicm Exp $ */ +/* $OpenBSD: job.c,v 1.11 2009/11/04 21:04:43 nicm Exp $ */ /* * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net> @@ -17,6 +17,7 @@ */ #include <sys/types.h> +#include <sys/socket.h> #include <fcntl.h> #include <paths.h> @@ -35,6 +36,8 @@ struct joblist all_jobs = SLIST_HEAD_INITIALIZER(&all_jobs); RB_GENERATE(jobs, job, entry, job_cmp); +void job_callback(struct bufferevent *, short, void *); + int job_cmp(struct job *job1, struct job *job2) { @@ -86,14 +89,13 @@ job_add(struct jobs *jobs, int flags, struct client *c, const char *cmd, job->client = c; job->fd = -1; - job->out = buffer_create(BUFSIZ); - memset(&job->event, 0, sizeof job->event); + job->event = NULL; job->callbackfn = callbackfn; job->freefn = freefn; job->data = data; - job->flags = flags|JOB_DONE; + job->flags = flags; if (jobs != NULL) RB_INSERT(jobs, jobs, job); @@ -125,9 +127,9 @@ job_free(struct job *job) if (job->fd != -1) close(job->fd); - if (job->out != NULL) - buffer_destroy(job->out); - event_del(&job->event); + + if (job->event != NULL) + bufferevent_free(job->event); xfree(job); } @@ -138,11 +140,10 @@ job_run(struct job *job) { int nullfd, out[2], mode; - if (!(job->flags & JOB_DONE)) + if (job->fd != -1 || job->pid != -1) return (0); - job->flags &= ~JOB_DONE; - if (pipe(out) != 0) + if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, out) != 0) return (-1); switch (job->pid = fork()) { @@ -181,13 +182,41 @@ job_run(struct job *job) if (fcntl(job->fd, F_SETFD, FD_CLOEXEC) == -1) fatal("fcntl failed"); - if (BUFFER_USED(job->out) != 0) - buffer_remove(job->out, BUFFER_USED(job->out)); + if (job->event != NULL) + bufferevent_free(job->event); + job->event = + bufferevent_new(job->fd, NULL, NULL, job_callback, job); + bufferevent_enable(job->event, EV_READ); return (0); } } +/* Job buffer error callback. */ +void +job_callback(unused struct bufferevent *bufev, unused short events, void *data) +{ + struct job *job = data; + + bufferevent_disable(job->event, EV_READ); + close(job->fd); + job->fd = -1; + + if (job->pid == -1 && job->callbackfn != NULL) + job->callbackfn(job); +} + +/* Job died (waitpid() returned its pid). */ +void +job_died(struct job *job, int status) +{ + job->status = status; + job->pid = -1; + + if (job->fd == -1 && job->callbackfn != NULL) + job->callbackfn(job); +} + /* Kill a job. */ void job_kill(struct job *job) diff --git a/usr.bin/tmux/server-job.c b/usr.bin/tmux/server-job.c deleted file mode 100644 index b046c188fc6..00000000000 --- a/usr.bin/tmux/server-job.c +++ /dev/null @@ -1,77 +0,0 @@ -/* $OpenBSD: server-job.c,v 1.4 2009/11/04 20:50:11 nicm Exp $ */ - -/* - * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net> - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER - * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <sys/types.h> - -#include <event.h> -#include <unistd.h> - -#include "tmux.h" - -/* Register jobs for poll. */ -void -server_job_prepare(void) -{ - struct job *job; - - SLIST_FOREACH(job, &all_jobs, lentry) { - if (job->fd == -1) - continue; - event_del(&job->event); - event_set( - &job->event, job->fd, EV_READ, server_job_callback, job); - event_add(&job->event, NULL); - } -} - -/* Process a single job event. */ -void -server_job_callback(int fd, short events, void *data) -{ - struct job *job = data; - - if (job->fd == -1) - return; - - if (buffer_poll(fd, events, job->out, NULL) != 0) { - close(job->fd); - job->fd = -1; - } -} - -/* Job functions that happen once a loop. */ -void -server_job_loop(void) -{ - struct job *job; - -restart: - SLIST_FOREACH(job, &all_jobs, lentry) { - if (job->flags & JOB_DONE || job->fd != -1 || job->pid != -1) - continue; - job->flags |= JOB_DONE; - - if (job->callbackfn != NULL) { - job->callbackfn(job); - if ((!job->flags & JOB_PERSIST)) { - job_free(job); - goto restart; - } - } - } -} diff --git a/usr.bin/tmux/server.c b/usr.bin/tmux/server.c index fec61747ab1..256256d3f8a 100644 --- a/usr.bin/tmux/server.c +++ b/usr.bin/tmux/server.c @@ -1,4 +1,4 @@ -/* $OpenBSD: server.c,v 1.66 2009/11/04 20:50:11 nicm Exp $ */ +/* $OpenBSD: server.c,v 1.67 2009/11/04 21:04:43 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> @@ -214,14 +214,12 @@ server_loop(void) while (!server_should_shutdown()) { server_update_socket(); - server_job_prepare(); server_window_prepare(); server_client_prepare(); event_loopexit(&tv); event_loop(EVLOOP_ONCE); - server_job_loop(); server_window_loop(); server_client_loop(); @@ -470,8 +468,8 @@ server_child_exited(pid_t pid, int status) SLIST_FOREACH(job, &all_jobs, lentry) { if (pid == job->pid) { - job->pid = -1; - job->status = status; + job_died(job, status); /* might free job */ + break; } } } diff --git a/usr.bin/tmux/status.c b/usr.bin/tmux/status.c index 6c5220c36a1..94e27f7e764 100644 --- a/usr.bin/tmux/status.c +++ b/usr.bin/tmux/status.c @@ -1,4 +1,4 @@ -/* $OpenBSD: status.c,v 1.40 2009/11/04 20:35:19 nicm Exp $ */ +/* $OpenBSD: status.c,v 1.41 2009/11/04 21:04:43 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> @@ -486,23 +486,26 @@ status_job(struct client *c, char **iptr) void status_job_callback(struct job *job) { - char *buf; + char *line, *buf; size_t len; - len = BUFFER_USED(job->out); - buf = xmalloc(len + 1); - if (len != 0) - buffer_read(job->out, buf, len); - buf[len] = '\0'; - buf[strcspn(buf, "\n")] = '\0'; + buf = NULL; + if ((line = evbuffer_readline(job->event->input)) == NULL) { + len = EVBUFFER_LENGTH(job->event->input); + buf = xmalloc(len + 1); + if (len != 0) + memcpy(buf, EVBUFFER_DATA(job->event->input), len); + buf[len] = '\0'; + } if (job->data != NULL) xfree(job->data); else server_redraw_client(job->client); - job->data = xstrdup(buf); + job->data = xstrdup(line); - xfree(buf); + if (buf != NULL) + xfree(buf); } size_t diff --git a/usr.bin/tmux/tmux.h b/usr.bin/tmux/tmux.h index 313e960f5db..e7cefe869e9 100644 --- a/usr.bin/tmux/tmux.h +++ b/usr.bin/tmux/tmux.h @@ -1,4 +1,4 @@ -/* $OpenBSD: tmux.h,v 1.159 2009/11/04 20:50:11 nicm Exp $ */ +/* $OpenBSD: tmux.h,v 1.160 2009/11/04 21:04:43 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> @@ -661,16 +661,14 @@ struct job { struct client *client; int fd; - struct event event; - struct buffer *out; + struct bufferevent *event; void (*callbackfn)(struct job *); void (*freefn)(void *); void *data; int flags; -#define JOB_DONE 0x1 -#define JOB_PERSIST 0x2 /* don't free after callback */ +#define JOB_PERSIST 0x1 /* don't free after callback */ RB_ENTRY(job) entry; SLIST_ENTRY(job) lentry; @@ -1306,6 +1304,7 @@ struct job *job_add(struct jobs *, int, struct client *, void job_remove(struct jobs *, struct job *); void job_free(struct job *); int job_run(struct job *); +void job_died(struct job *, int); void job_kill(struct job *); /* environ.c */ @@ -1589,11 +1588,6 @@ void server_client_prepare(void); void server_client_callback(int, short, void *); void server_client_loop(void); -/* server-job.c */ -void server_job_prepare(void); -void server_job_callback(int, short, void *); -void server_job_loop(void); - /* server-window.c */ void server_window_prepare(void); void server_window_callback(int, short, void *); |