=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/tmux/job.c,v retrieving revision 1.10 retrieving revision 1.11 diff -u -r1.10 -r1.11 --- src/usr.bin/tmux/job.c 2009/11/04 20:50:11 1.10 +++ src/usr.bin/tmux/job.c 2009/11/04 21:04:43 1.11 @@ -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 @@ -17,6 +17,7 @@ */ #include +#include #include #include @@ -35,6 +36,8 @@ 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->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,10 +127,10 @@ 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 @@ { 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,11 +182,39 @@ 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. */