diff options
author | Nicholas Marriott <nicm@openbsd.org> | 2009-11-04 21:04:43 +0000 |
---|---|---|
committer | Nicholas Marriott <nicm@openbsd.org> | 2009-11-04 21:04:43 +0000 |
commit | 4d6091379b4486b624070492d45ad390e7442382 (patch) | |
tree | e22d1b401b804b13a9cafe71d459a55fdbf376dc /job.c | |
parent | ea8c8c5f33e0dcbf563dc54615a6c172aea70518 (diff) |
Switch jobs over to use a bufferevent.
Diffstat (limited to 'job.c')
-rw-r--r-- | job.c | 51 |
1 files changed, 40 insertions, 11 deletions
@@ -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) |