=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/tmux/job.c,v retrieving revision 1.10 retrieving revision 1.11 diff -c -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 **** ! /* $OpenBSD: job.c,v 1.10 2009/11/04 20:50:11 nicm Exp $ */ /* * Copyright (c) 2009 Nicholas Marriott --- 1,4 ---- ! /* $OpenBSD: job.c,v 1.11 2009/11/04 21:04:43 nicm Exp $ */ /* * Copyright (c) 2009 Nicholas Marriott *************** *** 17,22 **** --- 17,23 ---- */ #include + #include #include #include *************** *** 35,40 **** --- 36,43 ---- RB_GENERATE(jobs, job, entry, job_cmp); + void job_callback(struct bufferevent *, short, void *); + int job_cmp(struct job *job1, struct job *job2) { *************** *** 86,99 **** job->client = c; job->fd = -1; ! job->out = buffer_create(BUFSIZ); ! memset(&job->event, 0, sizeof job->event); job->callbackfn = callbackfn; job->freefn = freefn; job->data = data; ! job->flags = flags|JOB_DONE; if (jobs != NULL) RB_INSERT(jobs, jobs, job); --- 89,101 ---- job->client = c; job->fd = -1; ! job->event = NULL; job->callbackfn = callbackfn; job->freefn = freefn; job->data = data; ! job->flags = flags; if (jobs != NULL) RB_INSERT(jobs, jobs, job); *************** *** 125,134 **** if (job->fd != -1) close(job->fd); - if (job->out != NULL) - buffer_destroy(job->out); - event_del(&job->event); xfree(job); } --- 127,136 ---- if (job->fd != -1) close(job->fd); + if (job->event != NULL) + bufferevent_free(job->event); + xfree(job); } *************** *** 138,148 **** { int nullfd, out[2], mode; ! if (!(job->flags & JOB_DONE)) return (0); - job->flags &= ~JOB_DONE; ! if (pipe(out) != 0) return (-1); switch (job->pid = fork()) { --- 140,149 ---- { int nullfd, out[2], mode; ! if (job->fd != -1 || job->pid != -1) return (0); ! if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, out) != 0) return (-1); switch (job->pid = fork()) { *************** *** 181,191 **** 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)); return (0); } } /* Kill a job. */ --- 182,220 ---- if (fcntl(job->fd, F_SETFD, FD_CLOEXEC) == -1) fatal("fcntl failed"); ! 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. */