-/* $OpenBSD: cmd-if-shell.c,v 1.58 2018/05/24 09:42:49 nicm Exp $ */
+/* $OpenBSD: cmd-if-shell.c,v 1.59 2018/08/23 15:45:05 nicm Exp $ */
/*
* Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org>
static void
cmd_if_shell_callback(struct job *job)
{
- struct cmd_if_shell_data *cdata = job->data;
+ struct cmd_if_shell_data *cdata = job_get_data(job);
struct client *c = cdata->client;
struct cmd_list *cmdlist;
struct cmdq_item *new_item;
char *cause, *cmd, *file = cdata->file;
u_int line = cdata->line;
+ int status;
- if (!WIFEXITED(job->status) || WEXITSTATUS(job->status) != 0)
+ status = job_get_status(job);
+ if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
cmd = cdata->cmd_else;
else
cmd = cdata->cmd_if;
-/* $OpenBSD: cmd-run-shell.c,v 1.53 2018/05/24 09:42:49 nicm Exp $ */
+/* $OpenBSD: cmd-run-shell.c,v 1.54 2018/08/23 15:45:05 nicm Exp $ */
/*
* Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org>
static void
cmd_run_shell_print(struct job *job, const char *msg)
{
- struct cmd_run_shell_data *cdata = job->data;
+ struct cmd_run_shell_data *cdata = job_get_data(job);
struct window_pane *wp = NULL;
struct cmd_find_state fs;
static void
cmd_run_shell_callback(struct job *job)
{
- struct cmd_run_shell_data *cdata = job->data;
- char *cmd = cdata->cmd, *msg, *line;
+ struct cmd_run_shell_data *cdata = job_get_data(job);
+ struct bufferevent *event = job_get_event(job);
+ char *cmd = cdata->cmd, *msg = NULL, *line;
size_t size;
- int retcode;
+ int retcode, status;
do {
- if ((line = evbuffer_readline(job->event->input)) != NULL) {
+ if ((line = evbuffer_readline(event->input)) != NULL) {
cmd_run_shell_print(job, line);
free(line);
}
} while (line != NULL);
- size = EVBUFFER_LENGTH(job->event->input);
+ size = EVBUFFER_LENGTH(event->input);
if (size != 0) {
line = xmalloc(size + 1);
- memcpy(line, EVBUFFER_DATA(job->event->input), size);
+ memcpy(line, EVBUFFER_DATA(event->input), size);
line[size] = '\0';
cmd_run_shell_print(job, line);
free(line);
}
- msg = NULL;
- if (WIFEXITED(job->status)) {
- if ((retcode = WEXITSTATUS(job->status)) != 0)
+ status = job_get_status(job);
+ if (WIFEXITED(status)) {
+ if ((retcode = WEXITSTATUS(status)) != 0)
xasprintf(&msg, "'%s' returned %d", cmd, retcode);
- } else if (WIFSIGNALED(job->status)) {
- retcode = WTERMSIG(job->status);
+ } else if (WIFSIGNALED(status)) {
+ retcode = WTERMSIG(status);
xasprintf(&msg, "'%s' terminated by signal %d", cmd, retcode);
}
if (msg != NULL)
-/* $OpenBSD: cmd-show-messages.c,v 1.27 2017/04/22 10:22:39 nicm Exp $ */
+/* $OpenBSD: cmd-show-messages.c,v 1.28 2018/08/23 15:45:05 nicm Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com>
};
static int cmd_show_messages_terminals(struct cmdq_item *, int);
-static int cmd_show_messages_jobs(struct cmdq_item *, int);
static int
cmd_show_messages_terminals(struct cmdq_item *item, int blank)
return (n != 0);
}
-static int
-cmd_show_messages_jobs(struct cmdq_item *item, int blank)
-{
- struct job *job;
- u_int n;
-
- 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++;
- }
- return (n != 0);
-}
-
static enum cmd_retval
cmd_show_messages_exec(struct cmd *self, struct cmdq_item *item)
{
done = 1;
}
if (args_has(args, 'J')) {
- cmd_show_messages_jobs(item, blank);
+ job_print_summary(item, blank);
done = 1;
}
if (done)
-/* $OpenBSD: format.c,v 1.159 2018/08/18 16:14:03 nicm Exp $ */
+/* $OpenBSD: format.c,v 1.160 2018/08/23 15:45:05 nicm Exp $ */
/*
* Copyright (c) 2011 Nicholas Marriott <nicholas.marriott@gmail.com>
static void
format_job_update(struct job *job)
{
- struct format_job *fj = job->data;
- struct evbuffer *evb = job->event->input;
+ struct format_job *fj = job_get_data(job);
+ struct evbuffer *evb = job_get_event(job)->input;
char *line = NULL, *next;
time_t t;
static void
format_job_complete(struct job *job)
{
- struct format_job *fj = job->data;
+ struct format_job *fj = job_get_data(job);
+ struct evbuffer *evb = job_get_event(job)->input;
char *line, *buf;
size_t len;
fj->job = NULL;
buf = NULL;
- if ((line = evbuffer_readline(job->event->input)) == NULL) {
- len = EVBUFFER_LENGTH(job->event->input);
+ if ((line = evbuffer_readline(evb)) == NULL) {
+ len = EVBUFFER_LENGTH(evb);
buf = xmalloc(len + 1);
if (len != 0)
- memcpy(buf, EVBUFFER_DATA(job->event->input), len);
+ memcpy(buf, EVBUFFER_DATA(evb), len);
buf[len] = '\0';
} else
buf = line;
-/* $OpenBSD: job.c,v 1.49 2018/03/08 08:09:10 nicm Exp $ */
+/* $OpenBSD: job.c,v 1.50 2018/08/23 15:45:05 nicm Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com>
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. */
-struct joblist all_jobs = LIST_HEAD_INITIALIZER(all_jobs);
+LIST_HEAD(joblist, job) all_jobs = LIST_HEAD_INITIALIZER(all_jobs);
/* Start a job running, if it isn't already. */
struct job *
/* Job died (waitpid() returned its pid). */
void
-job_died(struct job *job, int status)
+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;
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++;
+ }
+}
-/* $OpenBSD: server.c,v 1.182 2018/08/18 20:08:52 nicm Exp $ */
+/* $OpenBSD: server.c,v 1.183 2018/08/23 15:45:05 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
char *lockfile)
{
int pair[2];
- struct job *job;
sigset_t set, oldset;
struct client *c;
char *cause = NULL;
}
start_cfg();
-
server_add_accept(0);
proc_loop(server_proc, server_loop);
- LIST_FOREACH(job, &all_jobs, entry) {
- if (job->pid != -1)
- kill(job->pid, SIGTERM);
- }
-
+ job_kill_all();
status_prompt_save_history();
+
exit(0);
}
{
struct client *c;
u_int items;
- struct job *job;
do {
items = cmdq_next(NULL);
if (!TAILQ_EMPTY(&clients))
return (0);
- LIST_FOREACH(job, &all_jobs, entry) {
- if ((~job->flags & JOB_NOWAIT) && job->state == JOB_RUNNING)
- return (0);
- }
+ if (job_still_running())
+ return (0);
return (1);
}
{
struct window *w, *w1;
struct window_pane *wp;
- struct job *job;
RB_FOREACH_SAFE(w, windows, &windows, w1) {
TAILQ_FOREACH(wp, &w->panes, entry) {
}
}
}
-
- LIST_FOREACH(job, &all_jobs, entry) {
- if (pid == job->pid) {
- job_died(job, status); /* might free job */
- break;
- }
- }
+ job_check_died(pid, status);
}
/* Handle stopped children. */
-/* $OpenBSD: tmux.h,v 1.843 2018/08/22 20:06:14 nicm Exp $ */
+/* $OpenBSD: tmux.h,v 1.844 2018/08/23 15:45:05 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
struct environ;
struct format_job_tree;
struct input_ctx;
+struct job;
struct mode_tree_data;
struct mouse_event;
struct options;
RB_ENTRY(hook) entry;
};
-/* Scheduled job. */
-struct job;
-typedef void (*job_update_cb) (struct job *);
-typedef void (*job_complete_cb) (struct job *);
-typedef void (*job_free_cb) (void *);
-struct job {
- enum {
- JOB_RUNNING,
- JOB_DEAD,
- JOB_CLOSED
- } state;
-
- int flags;
-#define JOB_NOWAIT 0x1
-
- 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;
-};
-LIST_HEAD(joblist, job);
-
/* Virtual screen. */
struct screen_sel;
struct screen_titles;
extern const struct options_table_entry options_table[];
/* job.c */
-extern struct joblist all_jobs;
+typedef void (*job_update_cb) (struct job *);
+typedef void (*job_complete_cb) (struct job *);
+typedef void (*job_free_cb) (void *);
+#define JOB_NOWAIT 0x1
struct job *job_run(const char *, struct session *, const char *,
job_update_cb, job_complete_cb, job_free_cb, void *, int);
void job_free(struct job *);
-void job_died(struct job *, int);
+void job_check_died(pid_t, int);
+int job_get_status(struct job *);
+void *job_get_data(struct job *);
+struct bufferevent *job_get_event(struct job *);
+void job_kill_all(void);
+int job_still_running(void);
+void job_print_summary(struct cmdq_item *, int);
/* environ.c */
struct environ *environ_create(void);
-/* $OpenBSD: window-copy.c,v 1.195 2018/08/20 13:51:09 nicm Exp $ */
+/* $OpenBSD: window-copy.c,v 1.196 2018/08/23 15:45:05 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
expanded = format_single(NULL, arg, NULL, s, NULL, wp);
job = job_run(expanded, s, NULL, NULL, NULL, NULL, NULL, JOB_NOWAIT);
- bufferevent_write(job->event, buf, len);
+ bufferevent_write(job_get_event(job), buf, len);
free(expanded);
window_copy_copy_buffer(wp, bufname, buf, len);