mirror of
				https://github.com/tmux/tmux.git
				synced 2025-10-26 12:27:15 +00:00 
			
		
		
		
	Sync OpenBSD patchset 386:
Convert if-shell over to the background job framework as well.
This commit is contained in:
		
							
								
								
									
										148
									
								
								cmd-if-shell.c
									
									
									
									
									
								
							
							
						
						
									
										148
									
								
								cmd-if-shell.c
									
									
									
									
									
								
							| @@ -1,7 +1,8 @@ | |||||||
| /* $Id: cmd-if-shell.c,v 1.5 2009-09-22 14:06:40 tcunha Exp $ */ | /* $Id: cmd-if-shell.c,v 1.6 2009-10-12 00:29:03 tcunha Exp $ */ | ||||||
|  |  | ||||||
| /* | /* | ||||||
|  * Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org> |  * Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org> | ||||||
|  |  * Copyright (c) 2009 Nicholas Marriott <nicm@openbsd.org> | ||||||
|  * |  * | ||||||
|  * Permission to use, copy, modify, and distribute this software for any |  * Permission to use, copy, modify, and distribute this software for any | ||||||
|  * purpose with or without fee is hereby granted, provided that the above |  * purpose with or without fee is hereby granted, provided that the above | ||||||
| @@ -17,9 +18,8 @@ | |||||||
|  */ |  */ | ||||||
|  |  | ||||||
| #include <sys/types.h> | #include <sys/types.h> | ||||||
|  | #include <sys/wait.h> | ||||||
|  |  | ||||||
| #include <errno.h> |  | ||||||
| #include <stdlib.h> |  | ||||||
| #include <string.h> | #include <string.h> | ||||||
|  |  | ||||||
| #include "tmux.h" | #include "tmux.h" | ||||||
| @@ -28,124 +28,92 @@ | |||||||
|  * Executes a tmux command if a shell command returns true. |  * Executes a tmux command if a shell command returns true. | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
| int	cmd_if_shell_parse(struct cmd *, int, char **, char **); |  | ||||||
| int	cmd_if_shell_exec(struct cmd *, struct cmd_ctx *); | int	cmd_if_shell_exec(struct cmd *, struct cmd_ctx *); | ||||||
| void	cmd_if_shell_free(struct cmd *); |  | ||||||
| void	cmd_if_shell_init(struct cmd *, int); |  | ||||||
| size_t	cmd_if_shell_print(struct cmd *, char *, size_t); |  | ||||||
|  |  | ||||||
| struct cmd_if_shell_data { | void	cmd_if_shell_callback(struct job *); | ||||||
| 	char *cmd; | void	cmd_if_shell_free(void *); | ||||||
| 	char *sh_cmd; |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| const struct cmd_entry cmd_if_shell_entry = { | const struct cmd_entry cmd_if_shell_entry = { | ||||||
| 	"if-shell", "if", | 	"if-shell", "if", | ||||||
| 	"shell-command command", | 	"shell-command command", | ||||||
| 	0, 0, | 	CMD_ARG2, 0, | ||||||
| 	cmd_if_shell_init, | 	cmd_target_init, | ||||||
| 	cmd_if_shell_parse, | 	cmd_target_parse, | ||||||
| 	cmd_if_shell_exec, | 	cmd_if_shell_exec, | ||||||
| 	cmd_if_shell_free, | 	cmd_target_free, | ||||||
| 	cmd_if_shell_print | 	cmd_target_print | ||||||
| }; | }; | ||||||
|  |  | ||||||
| void | struct cmd_if_shell_data { | ||||||
| cmd_if_shell_init(struct cmd *self, unused int arg) | 	char		*cmd; | ||||||
| { | 	struct cmd_ctx	 ctx; | ||||||
| 	struct cmd_if_shell_data	*data; | }; | ||||||
|  |  | ||||||
| 	self->data = data = xmalloc(sizeof *data); |  | ||||||
| 	data->cmd = NULL; |  | ||||||
| 	data->sh_cmd = NULL; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| int |  | ||||||
| cmd_if_shell_parse(struct cmd *self, int argc, char **argv, char **cause) |  | ||||||
| { |  | ||||||
| 	struct cmd_if_shell_data	*data; |  | ||||||
| 	int				 opt; |  | ||||||
|  |  | ||||||
| 	self->entry->init(self, KEYC_NONE); |  | ||||||
| 	data = self->data; |  | ||||||
|  |  | ||||||
| 	while ((opt = getopt(argc, argv, "")) != -1) { |  | ||||||
| 		switch (opt) { |  | ||||||
| 		default: |  | ||||||
| 			goto usage; |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	argc -= optind; |  | ||||||
| 	argv += optind; |  | ||||||
| 	if (argc != 2) |  | ||||||
| 		goto usage; |  | ||||||
|  |  | ||||||
| 	data->sh_cmd = xstrdup(argv[0]); |  | ||||||
| 	data->cmd = xstrdup(argv[1]); |  | ||||||
| 	return (0); |  | ||||||
|  |  | ||||||
| usage: |  | ||||||
| 	xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage); |  | ||||||
|  |  | ||||||
| 	self->entry->free(self); |  | ||||||
| 	return (-1); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| int | int | ||||||
| cmd_if_shell_exec(struct cmd *self, struct cmd_ctx *ctx) | cmd_if_shell_exec(struct cmd *self, struct cmd_ctx *ctx) | ||||||
| { | { | ||||||
| 	struct cmd_if_shell_data	*data = self->data; | 	struct cmd_target_data		*data = self->data; | ||||||
|  | 	struct cmd_if_shell_data	*cdata; | ||||||
|  | 	struct job			*job; | ||||||
|  |  | ||||||
|  | 	cdata = xmalloc(sizeof *cdata); | ||||||
|  | 	cdata->cmd = xstrdup(data->arg2); | ||||||
|  | 	memcpy(&cdata->ctx, ctx, sizeof cdata->ctx); | ||||||
|  |  | ||||||
|  | 	if (ctx->cmdclient != NULL) | ||||||
|  | 		ctx->cmdclient->references++; | ||||||
|  | 	if (ctx->curclient != NULL) | ||||||
|  | 		ctx->curclient->references++; | ||||||
|  |  | ||||||
|  | 	job = job_add(NULL, NULL, | ||||||
|  | 	    data->arg, cmd_if_shell_callback, cmd_if_shell_free, cdata); | ||||||
|  | 	job_run(job); | ||||||
|  |  | ||||||
|  | 	return (1);	/* don't let client exit */ | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void | ||||||
|  | cmd_if_shell_callback(struct job *job) | ||||||
|  | { | ||||||
|  | 	struct cmd_if_shell_data	*cdata = job->data; | ||||||
|  | 	struct cmd_ctx			*ctx = &cdata->ctx; | ||||||
| 	struct cmd_list			*cmdlist; | 	struct cmd_list			*cmdlist; | ||||||
| 	char				*cause; | 	char				*cause; | ||||||
| 	int				 ret; |  | ||||||
|  |  | ||||||
| 	if ((ret = system(data->sh_cmd)) < 0) { | 	if (!WIFEXITED(job->status) || WEXITSTATUS(job->status) != 0) { | ||||||
| 		ctx->error(ctx, "system error: %s", strerror(errno)); | 		job_free(job);	/* calls cmd_if_shell_free */ | ||||||
| 		return (-1); | 		return; | ||||||
| 	} else if (ret != 0) | 	} | ||||||
| 		return (0); |  | ||||||
|  |  | ||||||
| 	if (cmd_string_parse(data->cmd, &cmdlist, &cause) != 0) { | 	if (cmd_string_parse(cdata->cmd, &cmdlist, &cause) != 0) { | ||||||
| 		if (cause != NULL) { | 		if (cause != NULL) { | ||||||
| 			ctx->error(ctx, "%s", cause); | 			ctx->error(ctx, "%s", cause); | ||||||
| 			xfree(cause); | 			xfree(cause); | ||||||
| 		} | 		} | ||||||
| 		return (-1); | 		return; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if (cmd_list_exec(cmdlist, ctx) < 0) { | 	if (cmd_list_exec(cmdlist, ctx) < 0) { | ||||||
| 		cmd_list_free(cmdlist); | 		cmd_list_free(cmdlist); | ||||||
| 		return (-1); | 		return; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	cmd_list_free(cmdlist); | 	cmd_list_free(cmdlist); | ||||||
| 	return (0); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| void | void | ||||||
| cmd_if_shell_free(struct cmd *self) | cmd_if_shell_free(void *data) | ||||||
| { | { | ||||||
| 	struct cmd_if_shell_data	*data = self->data; | 	struct cmd_if_shell_data	*cdata = data; | ||||||
|  | 	struct cmd_ctx			*ctx = &cdata->ctx; | ||||||
|  |  | ||||||
| 	if (data->cmd != NULL) | 	if (ctx->cmdclient != NULL) { | ||||||
| 		xfree(data->cmd); | 		ctx->cmdclient->references--; | ||||||
| 	if (data->sh_cmd != NULL) | 		server_write_client(ctx->cmdclient, MSG_EXIT, NULL, 0); | ||||||
| 		xfree(data->sh_cmd); | 	} | ||||||
| 	xfree(data); | 	if (ctx->curclient != NULL) | ||||||
| } | 		ctx->curclient->references--; | ||||||
|  |  | ||||||
| size_t | 	xfree(cdata->cmd); | ||||||
| cmd_if_shell_print(struct cmd *self, char *buf, size_t len) | 	xfree(cdata); | ||||||
| { |  | ||||||
| 	struct cmd_if_shell_data	*data = self->data; |  | ||||||
| 	size_t				off = 0; |  | ||||||
|  |  | ||||||
| 	off += xsnprintf(buf, len, "%s", self->entry->name); |  | ||||||
| 	if (data == NULL) |  | ||||||
| 		return (off); |  | ||||||
| 	if (off < len && data->sh_cmd != NULL) |  | ||||||
| 		off += cmd_prarg(buf + off, len - off, " ", data->sh_cmd); |  | ||||||
| 	if (off < len && data->cmd != NULL) |  | ||||||
| 		off += cmd_prarg(buf + off, len - off, " ", data->cmd); |  | ||||||
| 	return (off); |  | ||||||
| } | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Tiago Cunha
					Tiago Cunha