=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/tmux/job.c,v retrieving revision 1.49 retrieving revision 1.50 diff -c -r1.49 -r1.50 *** src/usr.bin/tmux/job.c 2018/03/08 08:09:10 1.49 --- src/usr.bin/tmux/job.c 2018/08/23 15:45:05 1.50 *************** *** 1,4 **** ! /* $OpenBSD: job.c,v 1.49 2018/03/08 08:09:10 nicm Exp $ */ /* * Copyright (c) 2009 Nicholas Marriott --- 1,4 ---- ! /* $OpenBSD: job.c,v 1.50 2018/08/23 15:45:05 nicm Exp $ */ /* * Copyright (c) 2009 Nicholas Marriott *************** *** 37,44 **** static void job_write_callback(struct bufferevent *, void *); static void job_error_callback(struct bufferevent *, short, void *); /* All jobs list. */ ! struct joblist all_jobs = LIST_HEAD_INITIALIZER(all_jobs); /* Start a job running, if it isn't already. */ struct job * --- 37,68 ---- static void job_write_callback(struct bufferevent *, void *); static void job_error_callback(struct bufferevent *, short, void *); + struct job { + enum { + JOB_RUNNING, + JOB_DEAD, + JOB_CLOSED + } state; + + int flags; + + char *cmd; + pid_t pid; + int status; + + int fd; + struct bufferevent *event; + + job_update_cb updatecb; + job_complete_cb completecb; + job_free_cb freecb; + void *data; + + LIST_ENTRY(job) entry; + }; + /* All jobs list. */ ! LIST_HEAD(joblist, job) all_jobs = LIST_HEAD_INITIALIZER(all_jobs); /* Start a job running, if it isn't already. */ struct job * *************** *** 208,215 **** /* Job died (waitpid() returned its pid). */ void ! job_died(struct job *job, int status) { log_debug("job died %p: %s, pid %ld", job, job->cmd, (long) job->pid); job->status = status; --- 232,247 ---- /* Job died (waitpid() returned its pid). */ void ! job_check_died(pid_t pid, int status) { + struct job *job; + + LIST_FOREACH(job, &all_jobs, entry) { + if (pid == job->pid) + break; + } + if (job == NULL) + return; log_debug("job died %p: %s, pid %ld", job, job->cmd, (long) job->pid); job->status = status; *************** *** 221,225 **** --- 253,321 ---- } else { job->pid = -1; job->state = JOB_DEAD; + } + } + + /* Get job status. */ + int + job_get_status(struct job *job) + { + return (job->status); + } + + /* Get job data. */ + void * + job_get_data(struct job *job) + { + return (job->data); + } + + /* Get job event. */ + struct bufferevent * + job_get_event(struct job *job) + { + return (job->event); + } + + /* Kill all jobs. */ + void + job_kill_all(void) + { + struct job *job; + + LIST_FOREACH(job, &all_jobs, entry) { + if (job->pid != -1) + kill(job->pid, SIGTERM); + } + } + + /* Are any jobs still running? */ + int + job_still_running(void) + { + struct job *job; + + LIST_FOREACH(job, &all_jobs, entry) { + if ((~job->flags & JOB_NOWAIT) && job->state == JOB_RUNNING) + return (1); + } + return (0); + } + + /* Print job summary. */ + void + job_print_summary(struct cmdq_item *item, int blank) + { + struct job *job; + u_int n = 0; + + LIST_FOREACH(job, &all_jobs, entry) { + if (blank) { + cmdq_print(item, "%s", ""); + blank = 0; + } + cmdq_print(item, "Job %u: %s [fd=%d, pid=%ld, status=%d]", + n, job->cmd, job->fd, (long)job->pid, job->status); + n++; } }