mirror of
				https://github.com/tmux/tmux.git
				synced 2025-11-04 00:56:10 +00:00 
			
		
		
		
	Merge branch 'obsd-master'
This commit is contained in:
		
							
								
								
									
										157
									
								
								arguments.c
									
									
									
									
									
								
							
							
						
						
									
										157
									
								
								arguments.c
									
									
									
									
									
								
							@@ -28,9 +28,15 @@
 | 
				
			|||||||
 * Manipulate command arguments.
 | 
					 * Manipulate command arguments.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct args_value {
 | 
				
			||||||
 | 
						char			*value;
 | 
				
			||||||
 | 
						TAILQ_ENTRY(args_value)	 entry;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					TAILQ_HEAD(args_values, args_value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct args_entry {
 | 
					struct args_entry {
 | 
				
			||||||
	u_char			 flag;
 | 
						u_char			 flag;
 | 
				
			||||||
	char			*value;
 | 
						struct args_values	 values;
 | 
				
			||||||
	RB_ENTRY(args_entry)	 entry;
 | 
						RB_ENTRY(args_entry)	 entry;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -92,12 +98,18 @@ args_free(struct args *args)
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	struct args_entry	*entry;
 | 
						struct args_entry	*entry;
 | 
				
			||||||
	struct args_entry	*entry1;
 | 
						struct args_entry	*entry1;
 | 
				
			||||||
 | 
						struct args_value	*value;
 | 
				
			||||||
 | 
						struct args_value	*value1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	cmd_free_argv(args->argc, args->argv);
 | 
						cmd_free_argv(args->argc, args->argv);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	RB_FOREACH_SAFE(entry, args_tree, &args->tree, entry1) {
 | 
						RB_FOREACH_SAFE(entry, args_tree, &args->tree, entry1) {
 | 
				
			||||||
		RB_REMOVE(args_tree, &args->tree, entry);
 | 
							RB_REMOVE(args_tree, &args->tree, entry);
 | 
				
			||||||
		free(entry->value);
 | 
							TAILQ_FOREACH_SAFE(value, &entry->values, entry, value1) {
 | 
				
			||||||
 | 
								TAILQ_REMOVE(&entry->values, value, entry);
 | 
				
			||||||
 | 
								free(value->value);
 | 
				
			||||||
 | 
								free(value);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		free(entry);
 | 
							free(entry);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -123,22 +135,69 @@ args_print_add(char **buf, size_t *len, const char *fmt, ...)
 | 
				
			|||||||
	free(s);
 | 
						free(s);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Add value to string. */
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					args_print_add_value(char **buf, size_t *len, struct args_entry *entry,
 | 
				
			||||||
 | 
					    struct args_value *value)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						static const char	 quoted[] = " #\"';$";
 | 
				
			||||||
 | 
						char			*escaped;
 | 
				
			||||||
 | 
						int			 flags;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (**buf != '\0')
 | 
				
			||||||
 | 
							args_print_add(buf, len, " -%c ", entry->flag);
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							args_print_add(buf, len, "-%c ", entry->flag);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						flags = VIS_OCTAL|VIS_TAB|VIS_NL;
 | 
				
			||||||
 | 
						if (value->value[strcspn(value->value, quoted)] != '\0')
 | 
				
			||||||
 | 
							flags |= VIS_DQ;
 | 
				
			||||||
 | 
						utf8_stravis(&escaped, value->value, flags);
 | 
				
			||||||
 | 
						if (flags & VIS_DQ)
 | 
				
			||||||
 | 
							args_print_add(buf, len, "\"%s\"", escaped);
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							args_print_add(buf, len, "%s", escaped);
 | 
				
			||||||
 | 
						free(escaped);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Add argument to string. */
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					args_print_add_argument(char **buf, size_t *len, const char *argument)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						static const char	 quoted[] = " #\"';$";
 | 
				
			||||||
 | 
						char			*escaped;
 | 
				
			||||||
 | 
						int			 flags;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (**buf != '\0')
 | 
				
			||||||
 | 
							args_print_add(buf, len, " ");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						flags = VIS_OCTAL|VIS_TAB|VIS_NL;
 | 
				
			||||||
 | 
						if (argument[strcspn(argument, quoted)] != '\0')
 | 
				
			||||||
 | 
							flags |= VIS_DQ;
 | 
				
			||||||
 | 
						utf8_stravis(&escaped, argument, flags);
 | 
				
			||||||
 | 
						if (flags & VIS_DQ)
 | 
				
			||||||
 | 
							args_print_add(buf, len, "\"%s\"", escaped);
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							args_print_add(buf, len, "%s", escaped);
 | 
				
			||||||
 | 
						free(escaped);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Print a set of arguments. */
 | 
					/* Print a set of arguments. */
 | 
				
			||||||
char *
 | 
					char *
 | 
				
			||||||
args_print(struct args *args)
 | 
					args_print(struct args *args)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	size_t		 	 len;
 | 
						size_t		 	 len;
 | 
				
			||||||
	char			*buf, *escaped;
 | 
						char			*buf;
 | 
				
			||||||
	int			 i, flags;
 | 
						int			 i;
 | 
				
			||||||
	struct args_entry	*entry;
 | 
						struct args_entry	*entry;
 | 
				
			||||||
	static const char	 quoted[] = " #\"';$";
 | 
						struct args_value	*value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	len = 1;
 | 
						len = 1;
 | 
				
			||||||
	buf = xcalloc(1, len);
 | 
						buf = xcalloc(1, len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Process the flags first. */
 | 
						/* Process the flags first. */
 | 
				
			||||||
	RB_FOREACH(entry, args_tree, &args->tree) {
 | 
						RB_FOREACH(entry, args_tree, &args->tree) {
 | 
				
			||||||
		if (entry->value != NULL)
 | 
							if (!TAILQ_EMPTY(&entry->values))
 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (*buf == '\0')
 | 
							if (*buf == '\0')
 | 
				
			||||||
@@ -148,40 +207,13 @@ args_print(struct args *args)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	/* Then the flags with arguments. */
 | 
						/* Then the flags with arguments. */
 | 
				
			||||||
	RB_FOREACH(entry, args_tree, &args->tree) {
 | 
						RB_FOREACH(entry, args_tree, &args->tree) {
 | 
				
			||||||
		if (entry->value == NULL)
 | 
							TAILQ_FOREACH(value, &entry->values, entry)
 | 
				
			||||||
			continue;
 | 
								args_print_add_value(&buf, &len, entry, value);
 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (*buf != '\0')
 | 
					 | 
				
			||||||
			args_print_add(&buf, &len, " -%c ", entry->flag);
 | 
					 | 
				
			||||||
		else
 | 
					 | 
				
			||||||
			args_print_add(&buf, &len, "-%c ", entry->flag);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		flags = VIS_OCTAL|VIS_TAB|VIS_NL;
 | 
					 | 
				
			||||||
		if (entry->value[strcspn(entry->value, quoted)] != '\0')
 | 
					 | 
				
			||||||
			flags |= VIS_DQ;
 | 
					 | 
				
			||||||
		utf8_stravis(&escaped, entry->value, flags);
 | 
					 | 
				
			||||||
		if (flags & VIS_DQ)
 | 
					 | 
				
			||||||
			args_print_add(&buf, &len, "\"%s\"", escaped);
 | 
					 | 
				
			||||||
		else
 | 
					 | 
				
			||||||
			args_print_add(&buf, &len, "%s", escaped);
 | 
					 | 
				
			||||||
		free(escaped);
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* And finally the argument vector. */
 | 
						/* And finally the argument vector. */
 | 
				
			||||||
	for (i = 0; i < args->argc; i++) {
 | 
						for (i = 0; i < args->argc; i++)
 | 
				
			||||||
		if (*buf != '\0')
 | 
							args_print_add_argument(&buf, &len, args->argv[i]);
 | 
				
			||||||
			args_print_add(&buf, &len, " ");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		flags = VIS_OCTAL|VIS_TAB|VIS_NL;
 | 
					 | 
				
			||||||
		if (args->argv[i][strcspn(args->argv[i], quoted)] != '\0')
 | 
					 | 
				
			||||||
			flags |= VIS_DQ;
 | 
					 | 
				
			||||||
		utf8_stravis(&escaped, args->argv[i], flags);
 | 
					 | 
				
			||||||
		if (flags & VIS_DQ)
 | 
					 | 
				
			||||||
			args_print_add(&buf, &len, "\"%s\"", escaped);
 | 
					 | 
				
			||||||
		else
 | 
					 | 
				
			||||||
			args_print_add(&buf, &len, "%s", escaped);
 | 
					 | 
				
			||||||
		free(escaped);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return (buf);
 | 
						return (buf);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -195,22 +227,24 @@ args_has(struct args *args, u_char ch)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
/* Set argument value in the arguments tree. */
 | 
					/* Set argument value in the arguments tree. */
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
args_set(struct args *args, u_char ch, const char *value)
 | 
					args_set(struct args *args, u_char ch, const char *s)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct args_entry	*entry;
 | 
						struct args_entry	*entry;
 | 
				
			||||||
 | 
						struct args_value	*value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Replace existing argument. */
 | 
						entry = args_find(args, ch);
 | 
				
			||||||
	if ((entry = args_find(args, ch)) != NULL) {
 | 
						if (entry == NULL) {
 | 
				
			||||||
		free(entry->value);
 | 
					 | 
				
			||||||
		entry->value = NULL;
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		entry = xcalloc(1, sizeof *entry);
 | 
							entry = xcalloc(1, sizeof *entry);
 | 
				
			||||||
		entry->flag = ch;
 | 
							entry->flag = ch;
 | 
				
			||||||
 | 
							TAILQ_INIT(&entry->values);
 | 
				
			||||||
		RB_INSERT(args_tree, &args->tree, entry);
 | 
							RB_INSERT(args_tree, &args->tree, entry);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (value != NULL)
 | 
						if (s != NULL) {
 | 
				
			||||||
		entry->value = xstrdup(value);
 | 
							value = xcalloc(1, sizeof *value);
 | 
				
			||||||
 | 
							value->value = xstrdup(s);
 | 
				
			||||||
 | 
							TAILQ_INSERT_TAIL(&entry->values, value, entry);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Get argument value. Will be NULL if it isn't present. */
 | 
					/* Get argument value. Will be NULL if it isn't present. */
 | 
				
			||||||
@@ -221,7 +255,34 @@ args_get(struct args *args, u_char ch)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	if ((entry = args_find(args, ch)) == NULL)
 | 
						if ((entry = args_find(args, ch)) == NULL)
 | 
				
			||||||
		return (NULL);
 | 
							return (NULL);
 | 
				
			||||||
	return (entry->value);
 | 
						return (TAILQ_LAST(&entry->values, args_values)->value);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Get first value in argument. */
 | 
				
			||||||
 | 
					const char *
 | 
				
			||||||
 | 
					args_first_value(struct args *args, u_char ch, struct args_value **value)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct args_entry	*entry;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ((entry = args_find(args, ch)) == NULL)
 | 
				
			||||||
 | 
							return (NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						*value = TAILQ_FIRST(&entry->values);
 | 
				
			||||||
 | 
						if (*value == NULL)
 | 
				
			||||||
 | 
							return (NULL);
 | 
				
			||||||
 | 
						return ((*value)->value);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Get next value in argument. */
 | 
				
			||||||
 | 
					const char *
 | 
				
			||||||
 | 
					args_next_value(struct args_value **value)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (*value == NULL)
 | 
				
			||||||
 | 
							return (NULL);
 | 
				
			||||||
 | 
						*value = TAILQ_NEXT(*value, entry);
 | 
				
			||||||
 | 
						if (*value == NULL)
 | 
				
			||||||
 | 
							return (NULL);
 | 
				
			||||||
 | 
						return ((*value)->value);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Convert an argument value to a number. */
 | 
					/* Convert an argument value to a number. */
 | 
				
			||||||
@@ -232,13 +293,15 @@ args_strtonum(struct args *args, u_char ch, long long minval, long long maxval,
 | 
				
			|||||||
	const char		*errstr;
 | 
						const char		*errstr;
 | 
				
			||||||
	long long 	 	 ll;
 | 
						long long 	 	 ll;
 | 
				
			||||||
	struct args_entry	*entry;
 | 
						struct args_entry	*entry;
 | 
				
			||||||
 | 
						struct args_value	*value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ((entry = args_find(args, ch)) == NULL) {
 | 
						if ((entry = args_find(args, ch)) == NULL) {
 | 
				
			||||||
		*cause = xstrdup("missing");
 | 
							*cause = xstrdup("missing");
 | 
				
			||||||
		return (0);
 | 
							return (0);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						value = TAILQ_LAST(&entry->values, args_values);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ll = strtonum(entry->value, minval, maxval, &errstr);
 | 
						ll = strtonum(value->value, minval, maxval, &errstr);
 | 
				
			||||||
	if (errstr != NULL) {
 | 
						if (errstr != NULL) {
 | 
				
			||||||
		*cause = xstrdup(errstr);
 | 
							*cause = xstrdup(errstr);
 | 
				
			||||||
		return (0);
 | 
							return (0);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -38,9 +38,9 @@ const struct cmd_entry cmd_new_window_entry = {
 | 
				
			|||||||
	.name = "new-window",
 | 
						.name = "new-window",
 | 
				
			||||||
	.alias = "neww",
 | 
						.alias = "neww",
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	.args = { "ac:dF:kn:Pt:", 0, -1 },
 | 
						.args = { "ac:de:F:kn:Pt:", 0, -1 },
 | 
				
			||||||
	.usage = "[-adkP] [-c start-directory] [-F format] [-n window-name] "
 | 
						.usage = "[-adkP] [-c start-directory] [-e environment] [-F format] "
 | 
				
			||||||
		 CMD_TARGET_WINDOW_USAGE " [command]",
 | 
							 "[-n window-name] " CMD_TARGET_WINDOW_USAGE " [command]",
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	.target = { 't', CMD_FIND_WINDOW, CMD_FIND_WINDOW_INDEX },
 | 
						.target = { 't', CMD_FIND_WINDOW, CMD_FIND_WINDOW_INDEX },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -60,8 +60,9 @@ cmd_new_window_exec(struct cmd *self, struct cmdq_item *item)
 | 
				
			|||||||
	int			 idx = item->target.idx;
 | 
						int			 idx = item->target.idx;
 | 
				
			||||||
	struct winlink		*new_wl;
 | 
						struct winlink		*new_wl;
 | 
				
			||||||
	char			*cause = NULL, *cp;
 | 
						char			*cause = NULL, *cp;
 | 
				
			||||||
	const char		*template;
 | 
						const char		*template, *add;
 | 
				
			||||||
	struct cmd_find_state	 fs;
 | 
						struct cmd_find_state	 fs;
 | 
				
			||||||
 | 
						struct args_value	*value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (args_has(args, 'a') && (idx = winlink_shuffle_up(s, wl)) == -1) {
 | 
						if (args_has(args, 'a') && (idx = winlink_shuffle_up(s, wl)) == -1) {
 | 
				
			||||||
		cmdq_error(item, "couldn't get a window index");
 | 
							cmdq_error(item, "couldn't get a window index");
 | 
				
			||||||
@@ -75,6 +76,13 @@ cmd_new_window_exec(struct cmd *self, struct cmdq_item *item)
 | 
				
			|||||||
	sc.name = args_get(args, 'n');
 | 
						sc.name = args_get(args, 'n');
 | 
				
			||||||
	sc.argc = args->argc;
 | 
						sc.argc = args->argc;
 | 
				
			||||||
	sc.argv = args->argv;
 | 
						sc.argv = args->argv;
 | 
				
			||||||
 | 
						sc.environ = environ_create();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						add = args_first_value(args, 'e', &value);
 | 
				
			||||||
 | 
						while (add != NULL) {
 | 
				
			||||||
 | 
							environ_put(sc.environ, add);
 | 
				
			||||||
 | 
							add = args_next_value(&value);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	sc.idx = idx;
 | 
						sc.idx = idx;
 | 
				
			||||||
	sc.cwd = args_get(args, 'c');
 | 
						sc.cwd = args_get(args, 'c');
 | 
				
			||||||
@@ -107,5 +115,6 @@ cmd_new_window_exec(struct cmd *self, struct cmdq_item *item)
 | 
				
			|||||||
	cmd_find_from_winlink(&fs, new_wl, 0);
 | 
						cmd_find_from_winlink(&fs, new_wl, 0);
 | 
				
			||||||
	cmdq_insert_hook(s, item, &fs, "after-new-window");
 | 
						cmdq_insert_hook(s, item, &fs, "after-new-window");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						environ_free(sc.environ);
 | 
				
			||||||
	return (CMD_RETURN_NORMAL);
 | 
						return (CMD_RETURN_NORMAL);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -34,9 +34,9 @@ const struct cmd_entry cmd_respawn_pane_entry = {
 | 
				
			|||||||
	.name = "respawn-pane",
 | 
						.name = "respawn-pane",
 | 
				
			||||||
	.alias = "respawnp",
 | 
						.alias = "respawnp",
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	.args = { "c:kt:", 0, -1 },
 | 
						.args = { "c:e:kt:", 0, -1 },
 | 
				
			||||||
	.usage = "[-c start-directory] [-k] " CMD_TARGET_PANE_USAGE
 | 
						.usage = "[-k] [-c start-directory] [-e environment] "
 | 
				
			||||||
		 " [command]",
 | 
							 CMD_TARGET_PANE_USAGE " [command]",
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	.target = { 't', CMD_FIND_PANE, 0 },
 | 
						.target = { 't', CMD_FIND_PANE, 0 },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -53,6 +53,8 @@ cmd_respawn_pane_exec(struct cmd *self, struct cmdq_item *item)
 | 
				
			|||||||
	struct winlink		*wl = item->target.wl;
 | 
						struct winlink		*wl = item->target.wl;
 | 
				
			||||||
	struct window_pane	*wp = item->target.wp;
 | 
						struct window_pane	*wp = item->target.wp;
 | 
				
			||||||
	char			*cause = NULL;
 | 
						char			*cause = NULL;
 | 
				
			||||||
 | 
						const char		*add;
 | 
				
			||||||
 | 
						struct args_value	*value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	memset(&sc, 0, sizeof sc);
 | 
						memset(&sc, 0, sizeof sc);
 | 
				
			||||||
	sc.item = item;
 | 
						sc.item = item;
 | 
				
			||||||
@@ -65,6 +67,13 @@ cmd_respawn_pane_exec(struct cmd *self, struct cmdq_item *item)
 | 
				
			|||||||
	sc.name = NULL;
 | 
						sc.name = NULL;
 | 
				
			||||||
	sc.argc = args->argc;
 | 
						sc.argc = args->argc;
 | 
				
			||||||
	sc.argv = args->argv;
 | 
						sc.argv = args->argv;
 | 
				
			||||||
 | 
						sc.environ = environ_create();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						add = args_first_value(args, 'e', &value);
 | 
				
			||||||
 | 
						while (add != NULL) {
 | 
				
			||||||
 | 
							environ_put(sc.environ, add);
 | 
				
			||||||
 | 
							add = args_next_value(&value);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	sc.idx = -1;
 | 
						sc.idx = -1;
 | 
				
			||||||
	sc.cwd = args_get(args, 'c');
 | 
						sc.cwd = args_get(args, 'c');
 | 
				
			||||||
@@ -82,5 +91,6 @@ cmd_respawn_pane_exec(struct cmd *self, struct cmdq_item *item)
 | 
				
			|||||||
	wp->flags |= PANE_REDRAW;
 | 
						wp->flags |= PANE_REDRAW;
 | 
				
			||||||
	server_status_window(wp->window);
 | 
						server_status_window(wp->window);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						environ_free(sc.environ);
 | 
				
			||||||
	return (CMD_RETURN_NORMAL);
 | 
						return (CMD_RETURN_NORMAL);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -34,9 +34,9 @@ const struct cmd_entry cmd_respawn_window_entry = {
 | 
				
			|||||||
	.name = "respawn-window",
 | 
						.name = "respawn-window",
 | 
				
			||||||
	.alias = "respawnw",
 | 
						.alias = "respawnw",
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	.args = { "c:kt:", 0, -1 },
 | 
						.args = { "c:e:kt:", 0, -1 },
 | 
				
			||||||
	.usage = "[-c start-directory] [-k] " CMD_TARGET_WINDOW_USAGE
 | 
						.usage = "[-k] [-c start-directory] [-e environment] "
 | 
				
			||||||
	         " [command]",
 | 
							 CMD_TARGET_WINDOW_USAGE " [command]",
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	.target = { 't', CMD_FIND_WINDOW, 0 },
 | 
						.target = { 't', CMD_FIND_WINDOW, 0 },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -52,6 +52,8 @@ cmd_respawn_window_exec(struct cmd *self, struct cmdq_item *item)
 | 
				
			|||||||
	struct session		*s = item->target.s;
 | 
						struct session		*s = item->target.s;
 | 
				
			||||||
	struct winlink		*wl = item->target.wl;
 | 
						struct winlink		*wl = item->target.wl;
 | 
				
			||||||
	char			*cause = NULL;
 | 
						char			*cause = NULL;
 | 
				
			||||||
 | 
						const char		*add;
 | 
				
			||||||
 | 
						struct args_value	*value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	memset(&sc, 0, sizeof sc);
 | 
						memset(&sc, 0, sizeof sc);
 | 
				
			||||||
	sc.item = item;
 | 
						sc.item = item;
 | 
				
			||||||
@@ -61,6 +63,13 @@ cmd_respawn_window_exec(struct cmd *self, struct cmdq_item *item)
 | 
				
			|||||||
	sc.name = NULL;
 | 
						sc.name = NULL;
 | 
				
			||||||
	sc.argc = args->argc;
 | 
						sc.argc = args->argc;
 | 
				
			||||||
	sc.argv = args->argv;
 | 
						sc.argv = args->argv;
 | 
				
			||||||
 | 
						sc.environ = environ_create();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						add = args_first_value(args, 'e', &value);
 | 
				
			||||||
 | 
						while (add != NULL) {
 | 
				
			||||||
 | 
							environ_put(sc.environ, add);
 | 
				
			||||||
 | 
							add = args_next_value(&value);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	sc.idx = -1;
 | 
						sc.idx = -1;
 | 
				
			||||||
	sc.cwd = args_get(args, 'c');
 | 
						sc.cwd = args_get(args, 'c');
 | 
				
			||||||
@@ -77,5 +86,6 @@ cmd_respawn_window_exec(struct cmd *self, struct cmdq_item *item)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	server_redraw_window(wl->window);
 | 
						server_redraw_window(wl->window);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						environ_free(sc.environ);
 | 
				
			||||||
	return (CMD_RETURN_NORMAL);
 | 
						return (CMD_RETURN_NORMAL);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -39,8 +39,8 @@ const struct cmd_entry cmd_split_window_entry = {
 | 
				
			|||||||
	.name = "split-window",
 | 
						.name = "split-window",
 | 
				
			||||||
	.alias = "splitw",
 | 
						.alias = "splitw",
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	.args = { "bc:dfF:l:hp:Pt:v", 0, -1 },
 | 
						.args = { "bc:de:fF:l:hp:Pt:v", 0, -1 },
 | 
				
			||||||
	.usage = "[-bdfhvP] [-c start-directory] [-F format] "
 | 
						.usage = "[-bdefhvP] [-c start-directory] [-e environment] [-F format] "
 | 
				
			||||||
		 "[-p percentage|-l size] " CMD_TARGET_PANE_USAGE " [command]",
 | 
							 "[-p percentage|-l size] " CMD_TARGET_PANE_USAGE " [command]",
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	.target = { 't', CMD_FIND_PANE, 0 },
 | 
						.target = { 't', CMD_FIND_PANE, 0 },
 | 
				
			||||||
@@ -63,8 +63,9 @@ cmd_split_window_exec(struct cmd *self, struct cmdq_item *item)
 | 
				
			|||||||
	struct layout_cell	*lc;
 | 
						struct layout_cell	*lc;
 | 
				
			||||||
	struct cmd_find_state	 fs;
 | 
						struct cmd_find_state	 fs;
 | 
				
			||||||
	int			 size, percentage, flags;
 | 
						int			 size, percentage, flags;
 | 
				
			||||||
	const char		*template;
 | 
						const char		*template, *add;
 | 
				
			||||||
	char			*cause, *cp;
 | 
						char			*cause, *cp;
 | 
				
			||||||
 | 
						struct args_value	*value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (args_has(args, 'h'))
 | 
						if (args_has(args, 'h'))
 | 
				
			||||||
		type = LAYOUT_LEFTRIGHT;
 | 
							type = LAYOUT_LEFTRIGHT;
 | 
				
			||||||
@@ -116,6 +117,13 @@ cmd_split_window_exec(struct cmd *self, struct cmdq_item *item)
 | 
				
			|||||||
	sc.name = NULL;
 | 
						sc.name = NULL;
 | 
				
			||||||
	sc.argc = args->argc;
 | 
						sc.argc = args->argc;
 | 
				
			||||||
	sc.argv = args->argv;
 | 
						sc.argv = args->argv;
 | 
				
			||||||
 | 
						sc.environ = environ_create();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						add = args_first_value(args, 'e', &value);
 | 
				
			||||||
 | 
						while (add != NULL) {
 | 
				
			||||||
 | 
							environ_put(sc.environ, add);
 | 
				
			||||||
 | 
							add = args_next_value(&value);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	sc.idx = -1;
 | 
						sc.idx = -1;
 | 
				
			||||||
	sc.cwd = args_get(args, 'c');
 | 
						sc.cwd = args_get(args, 'c');
 | 
				
			||||||
@@ -145,5 +153,6 @@ cmd_split_window_exec(struct cmd *self, struct cmdq_item *item)
 | 
				
			|||||||
	cmd_find_from_winlink_pane(&fs, wl, new_wp, 0);
 | 
						cmd_find_from_winlink_pane(&fs, wl, new_wp, 0);
 | 
				
			||||||
	cmdq_insert_hook(s, item, &fs, "after-split-window");
 | 
						cmdq_insert_hook(s, item, &fs, "after-split-window");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						environ_free(sc.environ);
 | 
				
			||||||
	return (CMD_RETURN_NORMAL);
 | 
						return (CMD_RETURN_NORMAL);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										2
									
								
								spawn.c
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								spawn.c
									
									
									
									
									
								
							@@ -291,6 +291,8 @@ spawn_pane(struct spawn_context *sc, char **cause)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	/* Create an environment for this pane. */
 | 
						/* Create an environment for this pane. */
 | 
				
			||||||
	child = environ_for_session(s, 0);
 | 
						child = environ_for_session(s, 0);
 | 
				
			||||||
 | 
						if (sc->environ != NULL)
 | 
				
			||||||
 | 
							environ_copy(sc->environ, child);
 | 
				
			||||||
	environ_set(child, "TMUX_PANE", "%%%u", new_wp->id);
 | 
						environ_set(child, "TMUX_PANE", "%%%u", new_wp->id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										28
									
								
								tmux.1
									
									
									
									
									
								
							
							
						
						
									
										28
									
								
								tmux.1
									
									
									
									
									
								
							@@ -1827,6 +1827,7 @@ option.
 | 
				
			|||||||
.It Xo Ic new-window
 | 
					.It Xo Ic new-window
 | 
				
			||||||
.Op Fl adkP
 | 
					.Op Fl adkP
 | 
				
			||||||
.Op Fl c Ar start-directory
 | 
					.Op Fl c Ar start-directory
 | 
				
			||||||
 | 
					.Op Fl e Ar environment
 | 
				
			||||||
.Op Fl F Ar format
 | 
					.Op Fl F Ar format
 | 
				
			||||||
.Op Fl n Ar window-name
 | 
					.Op Fl n Ar window-name
 | 
				
			||||||
.Op Fl t Ar target-window
 | 
					.Op Fl t Ar target-window
 | 
				
			||||||
@@ -1866,6 +1867,12 @@ See the
 | 
				
			|||||||
.Ic remain-on-exit
 | 
					.Ic remain-on-exit
 | 
				
			||||||
option to change this behaviour.
 | 
					option to change this behaviour.
 | 
				
			||||||
.Pp
 | 
					.Pp
 | 
				
			||||||
 | 
					.Fl e
 | 
				
			||||||
 | 
					takes the form
 | 
				
			||||||
 | 
					.Ql VARIABLE=value
 | 
				
			||||||
 | 
					and sets an environment variable for the newly created window; it may be
 | 
				
			||||||
 | 
					specified multiple times.
 | 
				
			||||||
 | 
					.Pp
 | 
				
			||||||
The
 | 
					The
 | 
				
			||||||
.Ev TERM
 | 
					.Ev TERM
 | 
				
			||||||
environment variable must be set to
 | 
					environment variable must be set to
 | 
				
			||||||
@@ -1878,7 +1885,9 @@ for all programs running
 | 
				
			|||||||
New windows will automatically have
 | 
					New windows will automatically have
 | 
				
			||||||
.Ql TERM=screen
 | 
					.Ql TERM=screen
 | 
				
			||||||
added to their environment, but care must be taken not to reset this in shell
 | 
					added to their environment, but care must be taken not to reset this in shell
 | 
				
			||||||
start-up files.
 | 
					start-up files or by the
 | 
				
			||||||
 | 
					.Fl e
 | 
				
			||||||
 | 
					option.
 | 
				
			||||||
.Pp
 | 
					.Pp
 | 
				
			||||||
The
 | 
					The
 | 
				
			||||||
.Fl P
 | 
					.Fl P
 | 
				
			||||||
@@ -2037,8 +2046,9 @@ This command will automatically set
 | 
				
			|||||||
.Ic window-size
 | 
					.Ic window-size
 | 
				
			||||||
to manual in the window options.
 | 
					to manual in the window options.
 | 
				
			||||||
.It Xo Ic respawn-pane
 | 
					.It Xo Ic respawn-pane
 | 
				
			||||||
.Op Fl c Ar start-directory
 | 
					 | 
				
			||||||
.Op Fl k
 | 
					.Op Fl k
 | 
				
			||||||
 | 
					.Op Fl c Ar start-directory
 | 
				
			||||||
 | 
					.Op Fl e Ar environment
 | 
				
			||||||
.Op Fl t Ar target-pane
 | 
					.Op Fl t Ar target-pane
 | 
				
			||||||
.Op Ar shell-command
 | 
					.Op Ar shell-command
 | 
				
			||||||
.Xc
 | 
					.Xc
 | 
				
			||||||
@@ -2054,9 +2064,15 @@ The pane must be already inactive, unless
 | 
				
			|||||||
is given, in which case any existing command is killed.
 | 
					is given, in which case any existing command is killed.
 | 
				
			||||||
.Fl c
 | 
					.Fl c
 | 
				
			||||||
specifies a new working directory for the pane.
 | 
					specifies a new working directory for the pane.
 | 
				
			||||||
 | 
					The
 | 
				
			||||||
 | 
					.Fl e
 | 
				
			||||||
 | 
					option has the same meaning as for the
 | 
				
			||||||
 | 
					.Ic new-window
 | 
				
			||||||
 | 
					command.
 | 
				
			||||||
.It Xo Ic respawn-window
 | 
					.It Xo Ic respawn-window
 | 
				
			||||||
.Op Fl c Ar start-directory
 | 
					 | 
				
			||||||
.Op Fl k
 | 
					.Op Fl k
 | 
				
			||||||
 | 
					.Op Fl c Ar start-directory
 | 
				
			||||||
 | 
					.Op Fl e Ar environment
 | 
				
			||||||
.Op Fl t Ar target-window
 | 
					.Op Fl t Ar target-window
 | 
				
			||||||
.Op Ar shell-command
 | 
					.Op Ar shell-command
 | 
				
			||||||
.Xc
 | 
					.Xc
 | 
				
			||||||
@@ -2072,6 +2088,11 @@ The window must be already inactive, unless
 | 
				
			|||||||
is given, in which case any existing command is killed.
 | 
					is given, in which case any existing command is killed.
 | 
				
			||||||
.Fl c
 | 
					.Fl c
 | 
				
			||||||
specifies a new working directory for the window.
 | 
					specifies a new working directory for the window.
 | 
				
			||||||
 | 
					The
 | 
				
			||||||
 | 
					.Fl e
 | 
				
			||||||
 | 
					option has the same meaning as for the
 | 
				
			||||||
 | 
					.Ic new-window
 | 
				
			||||||
 | 
					command.
 | 
				
			||||||
.It Xo Ic rotate-window
 | 
					.It Xo Ic rotate-window
 | 
				
			||||||
.Op Fl DU
 | 
					.Op Fl DU
 | 
				
			||||||
.Op Fl t Ar target-window
 | 
					.Op Fl t Ar target-window
 | 
				
			||||||
@@ -2190,6 +2211,7 @@ the command behaves like
 | 
				
			|||||||
.It Xo Ic split-window
 | 
					.It Xo Ic split-window
 | 
				
			||||||
.Op Fl bdfhvP
 | 
					.Op Fl bdfhvP
 | 
				
			||||||
.Op Fl c Ar start-directory
 | 
					.Op Fl c Ar start-directory
 | 
				
			||||||
 | 
					.Op Fl e Ar environment
 | 
				
			||||||
.Oo Fl l
 | 
					.Oo Fl l
 | 
				
			||||||
.Ar size |
 | 
					.Ar size |
 | 
				
			||||||
.Fl p Ar percentage Oc
 | 
					.Fl p Ar percentage Oc
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										4
									
								
								tmux.h
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								tmux.h
									
									
									
									
									
								
							@@ -39,6 +39,7 @@
 | 
				
			|||||||
extern char   **environ;
 | 
					extern char   **environ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct args;
 | 
					struct args;
 | 
				
			||||||
 | 
					struct args_value;
 | 
				
			||||||
struct client;
 | 
					struct client;
 | 
				
			||||||
struct cmd_find_state;
 | 
					struct cmd_find_state;
 | 
				
			||||||
struct cmdq_item;
 | 
					struct cmdq_item;
 | 
				
			||||||
@@ -1580,6 +1581,7 @@ struct spawn_context {
 | 
				
			|||||||
	const char		 *name;
 | 
						const char		 *name;
 | 
				
			||||||
	char			**argv;
 | 
						char			**argv;
 | 
				
			||||||
	int			  argc;
 | 
						int			  argc;
 | 
				
			||||||
 | 
						struct environ           *environ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	int			  idx;
 | 
						int			  idx;
 | 
				
			||||||
	const char		 *cwd;
 | 
						const char		 *cwd;
 | 
				
			||||||
@@ -1873,6 +1875,8 @@ void		 args_free(struct args *);
 | 
				
			|||||||
char		*args_print(struct args *);
 | 
					char		*args_print(struct args *);
 | 
				
			||||||
int		 args_has(struct args *, u_char);
 | 
					int		 args_has(struct args *, u_char);
 | 
				
			||||||
const char	*args_get(struct args *, u_char);
 | 
					const char	*args_get(struct args *, u_char);
 | 
				
			||||||
 | 
					const char	*args_first_value(struct args *, u_char, struct args_value **);
 | 
				
			||||||
 | 
					const char	*args_next_value(struct args_value **);
 | 
				
			||||||
long long	 args_strtonum(struct args *, u_char, long long, long long,
 | 
					long long	 args_strtonum(struct args *, u_char, long long, long long,
 | 
				
			||||||
		     char **);
 | 
							     char **);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user