mirror of
https://github.com/tmux/tmux.git
synced 2024-12-04 19:58:48 +00:00
Move job struct into job.c.
This commit is contained in:
parent
55db3623bf
commit
bceccc6b63
@ -132,14 +132,16 @@ cmd_if_shell_exec(struct cmd *self, struct cmdq_item *item)
|
||||
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;
|
||||
|
@ -57,7 +57,7 @@ struct cmd_run_shell_data {
|
||||
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;
|
||||
|
||||
@ -113,22 +113,23 @@ cmd_run_shell_exec(struct cmd *self, struct cmdq_item *item)
|
||||
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);
|
||||
@ -136,12 +137,12 @@ cmd_run_shell_callback(struct job *job)
|
||||
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)
|
||||
|
@ -44,7 +44,6 @@ const struct cmd_entry cmd_show_messages_entry = {
|
||||
};
|
||||
|
||||
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)
|
||||
@ -67,25 +66,6 @@ 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)
|
||||
{
|
||||
@ -104,7 +84,7 @@ 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)
|
||||
|
13
format.c
13
format.c
@ -191,8 +191,8 @@ static const char *format_lower[] = {
|
||||
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;
|
||||
|
||||
@ -221,18 +221,19 @@ format_job_update(struct job *job)
|
||||
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;
|
||||
|
100
job.c
100
job.c
@ -37,8 +37,32 @@ static void job_read_callback(struct bufferevent *, void *);
|
||||
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 *
|
||||
@ -208,8 +232,16 @@ job_error_callback(__unused struct bufferevent *bufev, __unused short events,
|
||||
|
||||
/* 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;
|
||||
@ -223,3 +255,67 @@ job_died(struct job *job, int 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++;
|
||||
}
|
||||
}
|
||||
|
25
server.c
25
server.c
@ -162,7 +162,6 @@ server_start(struct tmuxproc *client, struct event_base *base, int lockfd,
|
||||
char *lockfile)
|
||||
{
|
||||
int pair[2];
|
||||
struct job *job;
|
||||
sigset_t set, oldset;
|
||||
struct client *c;
|
||||
char *cause = NULL;
|
||||
@ -223,17 +222,13 @@ server_start(struct tmuxproc *client, struct event_base *base, int lockfd,
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@ -243,7 +238,6 @@ server_loop(void)
|
||||
{
|
||||
struct client *c;
|
||||
u_int items;
|
||||
struct job *job;
|
||||
|
||||
do {
|
||||
items = cmdq_next(NULL);
|
||||
@ -276,10 +270,8 @@ server_loop(void)
|
||||
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);
|
||||
}
|
||||
@ -457,7 +449,6 @@ server_child_exited(pid_t pid, int status)
|
||||
{
|
||||
struct window *w, *w1;
|
||||
struct window_pane *wp;
|
||||
struct job *job;
|
||||
|
||||
RB_FOREACH_SAFE(w, windows, &windows, w1) {
|
||||
TAILQ_FOREACH(wp, &w->panes, entry) {
|
||||
@ -474,13 +465,7 @@ server_child_exited(pid_t pid, int status)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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. */
|
||||
|
45
tmux.h
45
tmux.h
@ -44,6 +44,7 @@ struct cmdq_list;
|
||||
struct environ;
|
||||
struct format_job_tree;
|
||||
struct input_ctx;
|
||||
struct job;
|
||||
struct mode_tree_data;
|
||||
struct mouse_event;
|
||||
struct options;
|
||||
@ -619,37 +620,6 @@ struct hook {
|
||||
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;
|
||||
@ -1628,11 +1598,20 @@ void options_style_update_old(struct options *,
|
||||
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);
|
||||
|
@ -1687,7 +1687,7 @@ window_copy_copy_pipe(struct window_pane *wp, struct session *s,
|
||||
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);
|
||||
|
Loading…
Reference in New Issue
Block a user