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 /usr.bin/tmux/job.c | |
parent | c4951f362efa741b6aaf42f94c0cfb7073db3d9f (diff) |
Switch jobs over to use a bufferevent.
Diffstat (limited to 'usr.bin/tmux/job.c')
-rw-r--r-- | usr.bin/tmux/job.c | 53 |
1 files changed, 41 insertions, 12 deletions
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) |