mirror of
				https://github.com/tmux/tmux.git
				synced 2025-11-04 09:26:05 +00:00 
			
		
		
		
	Sync OpenBSD patchset 231:
Infrastructure and commands to manage the environment for processes started within tmux. There is a global environment, copied from the external environment when the server is started and each session has an (initially empty) session environment which overrides it. New commands set-environment and show-environment manipulate or display the environments. A new session option, update-environment, is a space-separated list of variables which are updated from the external environment into the session environment every time a new session is created - the default is DISPLAY.
This commit is contained in:
		
							
								
								
									
										20
									
								
								client.c
									
									
									
									
									
								
							
							
						
						
									
										20
									
								
								client.c
									
									
									
									
									
								
							@@ -1,4 +1,4 @@
 | 
			
		||||
/* $Id: client.c,v 1.60 2009-08-09 17:43:00 tcunha Exp $ */
 | 
			
		||||
/* $Id: client.c,v 1.61 2009-08-09 17:48:55 tcunha Exp $ */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
			
		||||
@@ -33,6 +33,7 @@
 | 
			
		||||
 | 
			
		||||
#include "tmux.h"
 | 
			
		||||
 | 
			
		||||
void	client_send_environ(struct client_ctx *);
 | 
			
		||||
void	client_handle_winch(struct client_ctx *);
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
@@ -99,6 +100,8 @@ server_started:
 | 
			
		||||
	cctx->srv_in = buffer_create(BUFSIZ);
 | 
			
		||||
	cctx->srv_out = buffer_create(BUFSIZ);
 | 
			
		||||
 | 
			
		||||
	if (cmdflags & CMD_SENDENVIRON)
 | 
			
		||||
		client_send_environ(cctx);
 | 
			
		||||
	if (isatty(STDIN_FILENO)) {
 | 
			
		||||
		if (ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) == -1)
 | 
			
		||||
			fatal("ioctl(TIOCGWINSZ)");
 | 
			
		||||
@@ -137,6 +140,19 @@ not_found:
 | 
			
		||||
	return (1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
client_send_environ(struct client_ctx *cctx)
 | 
			
		||||
{
 | 
			
		||||
	char		      **var;
 | 
			
		||||
	struct msg_environ_data	data;
 | 
			
		||||
 | 
			
		||||
 	for (var = environ; *var != NULL; var++) {
 | 
			
		||||
		if (strlcpy(data.var, *var, sizeof data.var) >= sizeof data.var)
 | 
			
		||||
			continue;
 | 
			
		||||
		client_write_server(cctx, MSG_ENVIRON, &data, sizeof data);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
client_main(struct client_ctx *cctx)
 | 
			
		||||
{
 | 
			
		||||
@@ -246,8 +262,8 @@ client_msg_dispatch(struct client_ctx *cctx)
 | 
			
		||||
			if (hdr.size != sizeof printdata)
 | 
			
		||||
				fatalx("bad MSG_PRINT size");
 | 
			
		||||
			buffer_read(cctx->srv_in, &printdata, sizeof printdata);
 | 
			
		||||
			printdata.msg[(sizeof printdata.msg) - 1] = '\0';
 | 
			
		||||
 | 
			
		||||
			printdata.msg[(sizeof printdata.msg) - 1] = '\0';
 | 
			
		||||
			cctx->errstr = xstrdup(printdata.msg);
 | 
			
		||||
			return (-1);
 | 
			
		||||
		case MSG_EXIT:
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
/* $Id: cmd-attach-session.c,v 1.31 2009-08-09 15:26:24 tcunha Exp $ */
 | 
			
		||||
/* $Id: cmd-attach-session.c,v 1.32 2009-08-09 17:48:55 tcunha Exp $ */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
			
		||||
@@ -29,7 +29,7 @@ int	cmd_attach_session_exec(struct cmd *, struct cmd_ctx *);
 | 
			
		||||
const struct cmd_entry cmd_attach_session_entry = {
 | 
			
		||||
	"attach-session", "attach",
 | 
			
		||||
	"[-d] " CMD_TARGET_SESSION_USAGE,
 | 
			
		||||
       	CMD_CANTNEST|CMD_STARTSERVER, CMD_CHFLAG('d'),
 | 
			
		||||
       	CMD_CANTNEST|CMD_STARTSERVER|CMD_SENDENVIRON, CMD_CHFLAG('d'),
 | 
			
		||||
	cmd_target_init,
 | 
			
		||||
	cmd_target_parse,
 | 
			
		||||
	cmd_attach_session_exec,
 | 
			
		||||
@@ -43,6 +43,7 @@ cmd_attach_session_exec(struct cmd *self, struct cmd_ctx *ctx)
 | 
			
		||||
	struct cmd_target_data	*data = self->data;
 | 
			
		||||
	struct session		*s;
 | 
			
		||||
	struct client		*c;
 | 
			
		||||
	const char		*update;
 | 
			
		||||
	char			*overrides, *cause;
 | 
			
		||||
	u_int			 i;
 | 
			
		||||
 | 
			
		||||
@@ -93,6 +94,10 @@ cmd_attach_session_exec(struct cmd *self, struct cmd_ctx *ctx)
 | 
			
		||||
 | 
			
		||||
		ctx->cmdclient->session = s;
 | 
			
		||||
		server_write_client(ctx->cmdclient, MSG_READY, NULL, 0);
 | 
			
		||||
 | 
			
		||||
		update = options_get_string(&s->options, "update-environment");
 | 
			
		||||
		environ_update(update, &ctx->cmdclient->environ, &s->environ);
 | 
			
		||||
 | 
			
		||||
		server_redraw_client(ctx->cmdclient);
 | 
			
		||||
	}
 | 
			
		||||
	recalculate_sizes();
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
/* $Id: cmd-new-session.c,v 1.50 2009-08-09 15:26:24 tcunha Exp $ */
 | 
			
		||||
/* $Id: cmd-new-session.c,v 1.51 2009-08-09 17:48:55 tcunha Exp $ */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
			
		||||
@@ -40,7 +40,7 @@ struct cmd_new_session_data {
 | 
			
		||||
const struct cmd_entry cmd_new_session_entry = {
 | 
			
		||||
	"new-session", "new",
 | 
			
		||||
	"[-d] [-n window-name] [-s session-name] [command]",
 | 
			
		||||
	CMD_STARTSERVER|CMD_CANTNEST, 0,
 | 
			
		||||
	CMD_STARTSERVER|CMD_CANTNEST|CMD_SENDENVIRON, 0,
 | 
			
		||||
	cmd_new_session_init,
 | 
			
		||||
	cmd_new_session_parse,
 | 
			
		||||
	cmd_new_session_exec,
 | 
			
		||||
@@ -108,6 +108,8 @@ cmd_new_session_exec(struct cmd *self, struct cmd_ctx *ctx)
 | 
			
		||||
{
 | 
			
		||||
	struct cmd_new_session_data	*data = self->data;
 | 
			
		||||
	struct session			*s;
 | 
			
		||||
	struct environ			 env;
 | 
			
		||||
	const char			*update;
 | 
			
		||||
	char				*overrides, *cmd, *cwd, *cause;
 | 
			
		||||
	int				 detached;
 | 
			
		||||
	u_int				 sx, sy;
 | 
			
		||||
@@ -184,13 +186,20 @@ cmd_new_session_exec(struct cmd *self, struct cmd_ctx *ctx)
 | 
			
		||||
	else
 | 
			
		||||
		cmd = options_get_string(&global_s_options, "default-command");
 | 
			
		||||
 | 
			
		||||
	/* Construct the environment. */
 | 
			
		||||
	environ_init(&env);
 | 
			
		||||
	update = options_get_string(&global_s_options, "update-environment");
 | 
			
		||||
	if (ctx->cmdclient != NULL)
 | 
			
		||||
		environ_update(update, &ctx->cmdclient->environ, &env);
 | 
			
		||||
 | 
			
		||||
	/* Create the new session. */
 | 
			
		||||
	s = session_create(data->newname, cmd, cwd, sx, sy, &cause);
 | 
			
		||||
	s = session_create(data->newname, cmd, cwd, &env, sx, sy, &cause);
 | 
			
		||||
	if (s == NULL) {
 | 
			
		||||
		ctx->error(ctx, "create session failed: %s", cause);
 | 
			
		||||
		xfree(cause);
 | 
			
		||||
		return (-1);
 | 
			
		||||
	}
 | 
			
		||||
	environ_free(&env);
 | 
			
		||||
 | 
			
		||||
	if (data->winname != NULL) {
 | 
			
		||||
		xfree(s->curw->window->name);
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
/* $Id: cmd-respawn-window.c,v 1.18 2009-07-28 22:12:16 tcunha Exp $ */
 | 
			
		||||
/* $Id: cmd-respawn-window.c,v 1.19 2009-08-09 17:48:55 tcunha Exp $ */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
			
		||||
@@ -47,7 +47,7 @@ cmd_respawn_window_exec(struct cmd *self, struct cmd_ctx *ctx)
 | 
			
		||||
	struct window		*w;
 | 
			
		||||
	struct window_pane	*wp;
 | 
			
		||||
	struct session		*s;
 | 
			
		||||
	const char	       **env;
 | 
			
		||||
	struct environ		 env;
 | 
			
		||||
	char		 	*cause;
 | 
			
		||||
 | 
			
		||||
	if ((wl = cmd_find_window(ctx, data->target, &s)) == NULL)
 | 
			
		||||
@@ -64,7 +64,10 @@ cmd_respawn_window_exec(struct cmd *self, struct cmd_ctx *ctx)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	env = server_fill_environ(s);
 | 
			
		||||
	environ_init(&env);
 | 
			
		||||
	environ_copy(&global_environ, &env);
 | 
			
		||||
	environ_copy(&s->environ, &env);
 | 
			
		||||
	server_fill_environ(s, &env);
 | 
			
		||||
 | 
			
		||||
	wp = TAILQ_FIRST(&w->panes);
 | 
			
		||||
	TAILQ_REMOVE(&w->panes, wp, entry);
 | 
			
		||||
@@ -72,9 +75,10 @@ cmd_respawn_window_exec(struct cmd *self, struct cmd_ctx *ctx)
 | 
			
		||||
 	window_destroy_panes(w);
 | 
			
		||||
	TAILQ_INSERT_HEAD(&w->panes, wp, entry);
 | 
			
		||||
	window_pane_resize(wp, w->sx, w->sy);
 | 
			
		||||
	if (window_pane_spawn(wp, data->arg, NULL, env, &cause) != 0) {
 | 
			
		||||
	if (window_pane_spawn(wp, data->arg, NULL, &env, &cause) != 0) {
 | 
			
		||||
		ctx->error(ctx, "respawn window failed: %s", cause);
 | 
			
		||||
		xfree(cause);
 | 
			
		||||
		environ_free(&env);
 | 
			
		||||
		return (-1);
 | 
			
		||||
	}
 | 
			
		||||
	layout_init(w);
 | 
			
		||||
@@ -84,5 +88,6 @@ cmd_respawn_window_exec(struct cmd *self, struct cmd_ctx *ctx)
 | 
			
		||||
	recalculate_sizes();
 | 
			
		||||
	server_redraw_window(w);
 | 
			
		||||
 | 
			
		||||
	environ_free(&env);
 | 
			
		||||
	return (0);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										88
									
								
								cmd-set-environment.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										88
									
								
								cmd-set-environment.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,88 @@
 | 
			
		||||
/* $Id: cmd-set-environment.c,v 1.1 2009-08-09 17:48:55 tcunha Exp $ */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
			
		||||
 *
 | 
			
		||||
 * Permission to use, copy, modify, and distribute this software for any
 | 
			
		||||
 * purpose with or without fee is hereby granted, provided that the above
 | 
			
		||||
 * copyright notice and this permission notice appear in all copies.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
			
		||||
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
			
		||||
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
			
		||||
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
			
		||||
 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
			
		||||
 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
			
		||||
 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include "tmux.h"
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Set an environment variable.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
int	cmd_set_environment_exec(struct cmd *, struct cmd_ctx *);
 | 
			
		||||
 | 
			
		||||
const struct cmd_entry cmd_set_environment_entry = {
 | 
			
		||||
	"set-environment", "setenv",
 | 
			
		||||
	"[-gru] " CMD_OPTION_SESSION_USAGE,
 | 
			
		||||
	0, CMD_CHFLAG('g')|CMD_CHFLAG('r')|CMD_CHFLAG('u'),
 | 
			
		||||
	NULL,
 | 
			
		||||
	cmd_option_parse,
 | 
			
		||||
	cmd_set_environment_exec,
 | 
			
		||||
	cmd_option_free,
 | 
			
		||||
	cmd_option_print
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
cmd_set_environment_exec(struct cmd *self, struct cmd_ctx *ctx)
 | 
			
		||||
{
 | 
			
		||||
	struct cmd_option_data	*data = self->data;
 | 
			
		||||
	struct session		*s;
 | 
			
		||||
	struct environ		*env;
 | 
			
		||||
 | 
			
		||||
	if (*data->option == '\0') {
 | 
			
		||||
		ctx->error(ctx, "empty variable name");
 | 
			
		||||
		return (-1);
 | 
			
		||||
	}
 | 
			
		||||
	if (strchr(data->option, '=') != NULL) {
 | 
			
		||||
		ctx->error(ctx, "variable name contains =");
 | 
			
		||||
		return (-1);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (data->chflags & CMD_CHFLAG('g'))
 | 
			
		||||
		env = &global_environ;
 | 
			
		||||
	else {
 | 
			
		||||
		if ((s = cmd_find_session(ctx, data->target)) == NULL)
 | 
			
		||||
			return (-1);
 | 
			
		||||
		env = &s->environ;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (data->chflags & CMD_CHFLAG('u')) {
 | 
			
		||||
		if (data->value != NULL) {
 | 
			
		||||
			ctx->error(ctx, "can't specify a value with -u");
 | 
			
		||||
			return (-1);
 | 
			
		||||
		}
 | 
			
		||||
		environ_unset(env, data->option);
 | 
			
		||||
	} else if (data->chflags & CMD_CHFLAG('r')) {
 | 
			
		||||
		if (data->value != NULL) {
 | 
			
		||||
			ctx->error(ctx, "can't specify a value with -r");
 | 
			
		||||
			return (-1);
 | 
			
		||||
		}
 | 
			
		||||
		environ_set(env, data->option, NULL);
 | 
			
		||||
	} else {
 | 
			
		||||
		if (data->value == NULL) {
 | 
			
		||||
			ctx->error(ctx, "no value specified");
 | 
			
		||||
			return (-1);
 | 
			
		||||
		}
 | 
			
		||||
		environ_set(env, data->option, data->value);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return (0);
 | 
			
		||||
}
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
/* $Id: cmd-set-option.c,v 1.73 2009-08-09 17:40:17 tcunha Exp $ */
 | 
			
		||||
/* $Id: cmd-set-option.c,v 1.74 2009-08-09 17:48:55 tcunha Exp $ */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
			
		||||
@@ -85,6 +85,7 @@ const struct set_option_entry set_option_table[] = {
 | 
			
		||||
	{ "status-right-length", SET_OPTION_NUMBER, 0, SHRT_MAX, NULL },
 | 
			
		||||
	{ "status-utf8", SET_OPTION_FLAG, 0, 0, NULL },	
 | 
			
		||||
	{ "terminal-overrides", SET_OPTION_STRING, 0, 0, NULL },
 | 
			
		||||
	{ "update-environment", SET_OPTION_STRING, 0, 0, NULL },
 | 
			
		||||
	{ "visual-activity", SET_OPTION_FLAG, 0, 0, NULL },
 | 
			
		||||
	{ "visual-bell", SET_OPTION_FLAG, 0, 0, NULL },	
 | 
			
		||||
	{ "visual-content", SET_OPTION_FLAG, 0, 0, NULL },
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										67
									
								
								cmd-show-environment.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								cmd-show-environment.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,67 @@
 | 
			
		||||
/* $Id: cmd-show-environment.c,v 1.1 2009-08-09 17:48:55 tcunha Exp $ */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
			
		||||
 *
 | 
			
		||||
 * Permission to use, copy, modify, and distribute this software for any
 | 
			
		||||
 * purpose with or without fee is hereby granted, provided that the above
 | 
			
		||||
 * copyright notice and this permission notice appear in all copies.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
			
		||||
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
			
		||||
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
			
		||||
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
			
		||||
 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
			
		||||
 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
			
		||||
 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include "tmux.h"
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Show environment.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
int	cmd_show_environment_exec(struct cmd *, struct cmd_ctx *);
 | 
			
		||||
 | 
			
		||||
const struct cmd_entry cmd_show_environment_entry = {
 | 
			
		||||
	"show-environment", "showenv",
 | 
			
		||||
	"[-g] " CMD_TARGET_SESSION_USAGE,
 | 
			
		||||
	0, CMD_CHFLAG('g'),
 | 
			
		||||
	cmd_target_init,
 | 
			
		||||
	cmd_target_parse,
 | 
			
		||||
	cmd_show_environment_exec,
 | 
			
		||||
	cmd_target_free,
 | 
			
		||||
	cmd_target_print
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
cmd_show_environment_exec(struct cmd *self, struct cmd_ctx *ctx)
 | 
			
		||||
{
 | 
			
		||||
	struct cmd_target_data		*data = self->data;
 | 
			
		||||
	struct session			*s;
 | 
			
		||||
	struct environ			*env;
 | 
			
		||||
	struct environ_entry		*envent;
 | 
			
		||||
 | 
			
		||||
	if (data->chflags & CMD_CHFLAG('g'))
 | 
			
		||||
		env = &global_environ;
 | 
			
		||||
	else {
 | 
			
		||||
		if ((s = cmd_find_session(ctx, data->target)) == NULL)
 | 
			
		||||
			return (-1);
 | 
			
		||||
		env = &s->environ;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	RB_FOREACH(envent, environ, env) {
 | 
			
		||||
		if (envent->value != NULL)
 | 
			
		||||
			ctx->print(ctx, "%s=%s", envent->name, envent->value);
 | 
			
		||||
		else
 | 
			
		||||
			ctx->print(ctx, "-%s", envent->name);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return (0);
 | 
			
		||||
}
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
/* $Id: cmd-split-window.c,v 1.21 2009-07-28 22:12:16 tcunha Exp $ */
 | 
			
		||||
/* $Id: cmd-split-window.c,v 1.22 2009-08-09 17:48:55 tcunha Exp $ */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
			
		||||
@@ -149,7 +149,7 @@ cmd_split_window_exec(struct cmd *self, struct cmd_ctx *ctx)
 | 
			
		||||
	struct winlink			*wl;
 | 
			
		||||
	struct window			*w;
 | 
			
		||||
	struct window_pane		*wp;
 | 
			
		||||
	const char		       **env;
 | 
			
		||||
	struct environ			 env;
 | 
			
		||||
	char		 		*cmd, *cwd, *cause;
 | 
			
		||||
	u_int				 hlimit;
 | 
			
		||||
	int				 size;
 | 
			
		||||
@@ -159,7 +159,10 @@ cmd_split_window_exec(struct cmd *self, struct cmd_ctx *ctx)
 | 
			
		||||
		return (-1);
 | 
			
		||||
	w = wl->window;
 | 
			
		||||
 | 
			
		||||
	env = server_fill_environ(s);
 | 
			
		||||
	environ_init(&env);
 | 
			
		||||
	environ_copy(&global_environ, &env);
 | 
			
		||||
	environ_copy(&s->environ, &env);
 | 
			
		||||
	server_fill_environ(s, &env);
 | 
			
		||||
 | 
			
		||||
	cmd = data->cmd;
 | 
			
		||||
	if (cmd == NULL)
 | 
			
		||||
@@ -181,7 +184,7 @@ cmd_split_window_exec(struct cmd *self, struct cmd_ctx *ctx)
 | 
			
		||||
		type = LAYOUT_LEFTRIGHT;
 | 
			
		||||
 | 
			
		||||
	wp = window_add_pane(w, hlimit);
 | 
			
		||||
	if (window_pane_spawn(wp, cmd, cwd, env, &cause) != 0)
 | 
			
		||||
	if (window_pane_spawn(wp, cmd, cwd, &env, &cause) != 0)
 | 
			
		||||
		goto error;
 | 
			
		||||
	if (layout_split_pane(w->active, type, size, wp) != 0) {
 | 
			
		||||
		cause = xstrdup("pane too small");
 | 
			
		||||
@@ -197,9 +200,11 @@ cmd_split_window_exec(struct cmd *self, struct cmd_ctx *ctx)
 | 
			
		||||
	} else
 | 
			
		||||
		server_status_session(s);
 | 
			
		||||
 | 
			
		||||
	environ_free(&env);
 | 
			
		||||
	return (0);
 | 
			
		||||
 | 
			
		||||
error:
 | 
			
		||||
	environ_free(&env);
 | 
			
		||||
	if (wp != NULL)
 | 
			
		||||
		window_remove_pane(w, wp);
 | 
			
		||||
	ctx->error(ctx, "create pane failed: %s", cause);
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										30
									
								
								cmd-string.c
									
									
									
									
									
								
							
							
						
						
									
										30
									
								
								cmd-string.c
									
									
									
									
									
								
							@@ -1,4 +1,4 @@
 | 
			
		||||
/* $Id: cmd-string.c,v 1.22 2009-08-09 15:26:24 tcunha Exp $ */
 | 
			
		||||
/* $Id: cmd-string.c,v 1.23 2009-08-09 17:48:55 tcunha Exp $ */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
			
		||||
@@ -59,21 +59,11 @@ int
 | 
			
		||||
cmd_string_parse(const char *s, struct cmd_list **cmdlist, char **cause)
 | 
			
		||||
{
 | 
			
		||||
	size_t		p;
 | 
			
		||||
	int		ch, argc, rval, have_arg;
 | 
			
		||||
	char	      **argv, *buf, *t, *u;
 | 
			
		||||
	int		ch, i, argc, rval, have_arg;
 | 
			
		||||
	char	      **argv, *buf, *t;
 | 
			
		||||
	const char     *whitespace, *equals;
 | 
			
		||||
	size_t		len;
 | 
			
		||||
 | 
			
		||||
	if ((t = strchr(s, ' ')) == NULL && (t = strchr(s, '\t')) == NULL)
 | 
			
		||||
		t = strchr(s, '\0');
 | 
			
		||||
	if ((u = strchr(s, '=')) != NULL && u < t) {
 | 
			
		||||
		if (putenv(xstrdup(s)) != 0) {
 | 
			
		||||
			xasprintf(cause, "assignment failed: %s", s);
 | 
			
		||||
			return (-1);
 | 
			
		||||
		}
 | 
			
		||||
		*cmdlist = NULL;
 | 
			
		||||
		return (0);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	argv = NULL;
 | 
			
		||||
	argc = 0;
 | 
			
		||||
 | 
			
		||||
@@ -147,6 +137,18 @@ cmd_string_parse(const char *s, struct cmd_list **cmdlist, char **cause)
 | 
			
		||||
			if (argc == 0)
 | 
			
		||||
				goto out;
 | 
			
		||||
 | 
			
		||||
			for (i = 0; i < argc; i++) {
 | 
			
		||||
				equals = strchr(argv[i], '=');
 | 
			
		||||
				whitespace = argv[i] + strcspn(argv[i], " \t");
 | 
			
		||||
				if (equals == NULL || equals > whitespace)
 | 
			
		||||
					break;
 | 
			
		||||
				environ_put(&global_environ, argv[i]);
 | 
			
		||||
				memmove(&argv[i], &argv[i + 1], argc - i - 1);
 | 
			
		||||
				argc--;
 | 
			
		||||
			}
 | 
			
		||||
			if (argc == 0)
 | 
			
		||||
				goto out;
 | 
			
		||||
 | 
			
		||||
			*cmdlist = cmd_list_parse(argc, argv, cause);
 | 
			
		||||
			if (*cmdlist == NULL)
 | 
			
		||||
				goto out;
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										4
									
								
								cmd.c
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								cmd.c
									
									
									
									
									
								
							@@ -1,4 +1,4 @@
 | 
			
		||||
/* $Id: cmd.c,v 1.111 2009-07-30 20:45:20 tcunha Exp $ */
 | 
			
		||||
/* $Id: cmd.c,v 1.112 2009-08-09 17:48:55 tcunha Exp $ */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
			
		||||
@@ -83,10 +83,12 @@ const struct cmd_entry *cmd_table[] = {
 | 
			
		||||
	&cmd_send_prefix_entry,
 | 
			
		||||
	&cmd_server_info_entry,
 | 
			
		||||
	&cmd_set_buffer_entry,
 | 
			
		||||
	&cmd_set_environment_entry,
 | 
			
		||||
	&cmd_set_option_entry,
 | 
			
		||||
	&cmd_set_password_entry,
 | 
			
		||||
	&cmd_set_window_option_entry,
 | 
			
		||||
	&cmd_show_buffer_entry,
 | 
			
		||||
	&cmd_show_environment_entry,
 | 
			
		||||
	&cmd_show_options_entry,
 | 
			
		||||
	&cmd_show_window_options_entry,
 | 
			
		||||
	&cmd_source_file_entry,
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										147
									
								
								environ.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										147
									
								
								environ.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,147 @@
 | 
			
		||||
/* $Id: environ.c,v 1.1 2009-08-09 17:48:55 tcunha Exp $ */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
			
		||||
 *
 | 
			
		||||
 * Permission to use, copy, modify, and distribute this software for any
 | 
			
		||||
 * purpose with or without fee is hereby granted, provided that the above
 | 
			
		||||
 * copyright notice and this permission notice appear in all copies.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
			
		||||
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
			
		||||
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
			
		||||
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
			
		||||
 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
			
		||||
 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
			
		||||
 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include "tmux.h"
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Environment - manipulate a set of environment variables.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
RB_GENERATE(environ, environ_entry, entry, environ_cmp);
 | 
			
		||||
 | 
			
		||||
void	environ_set1(struct environ *, char *, char *);
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
environ_cmp(struct environ_entry *envent1, struct environ_entry *envent2)
 | 
			
		||||
{
 | 
			
		||||
	return (strcmp(envent1->name, envent2->name));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
environ_init(struct environ *env)
 | 
			
		||||
{
 | 
			
		||||
	RB_INIT(env);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
environ_free(struct environ *env)
 | 
			
		||||
{
 | 
			
		||||
	struct environ_entry	*envent;
 | 
			
		||||
 | 
			
		||||
	while (!RB_EMPTY(env)) {
 | 
			
		||||
		envent = RB_ROOT(env);
 | 
			
		||||
		RB_REMOVE(environ, env, envent);
 | 
			
		||||
		xfree(envent->name);
 | 
			
		||||
		if (envent->value != NULL)
 | 
			
		||||
			xfree(envent->value);
 | 
			
		||||
		xfree(envent);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
environ_copy(struct environ *srcenv, struct environ *dstenv)
 | 
			
		||||
{
 | 
			
		||||
	struct environ_entry	*envent;
 | 
			
		||||
 | 
			
		||||
	RB_FOREACH(envent, environ, srcenv)
 | 
			
		||||
		environ_set(dstenv, envent->name, envent->value);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct environ_entry *
 | 
			
		||||
environ_find(struct environ *env, const char *name)
 | 
			
		||||
{
 | 
			
		||||
	struct environ_entry	envent;
 | 
			
		||||
 | 
			
		||||
	envent.name = (char *) name;
 | 
			
		||||
	return (RB_FIND(environ, env, &envent));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
environ_set(struct environ *env, const char *name, const char *value)
 | 
			
		||||
{
 | 
			
		||||
	struct environ_entry	*envent;
 | 
			
		||||
 | 
			
		||||
	if ((envent = environ_find(env, name)) != NULL) {
 | 
			
		||||
		if (envent->value != NULL)
 | 
			
		||||
			xfree(envent->value);
 | 
			
		||||
		if (value != NULL)
 | 
			
		||||
			envent->value = xstrdup(value);
 | 
			
		||||
		else
 | 
			
		||||
			envent->value = NULL;
 | 
			
		||||
	} else {
 | 
			
		||||
		envent = xmalloc(sizeof *envent);
 | 
			
		||||
		envent->name = xstrdup(name);
 | 
			
		||||
		if (value != NULL)
 | 
			
		||||
			envent->value = xstrdup(value);
 | 
			
		||||
		else
 | 
			
		||||
			envent->value = NULL;
 | 
			
		||||
		RB_INSERT(environ, env, envent);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
environ_put(struct environ *env, const char *var)
 | 
			
		||||
{
 | 
			
		||||
	char		*name, *value;
 | 
			
		||||
 | 
			
		||||
	value = strchr(var, '=');
 | 
			
		||||
	if (value == NULL)
 | 
			
		||||
		return;
 | 
			
		||||
	value++;
 | 
			
		||||
 | 
			
		||||
	name = xstrdup(var);
 | 
			
		||||
	name[strcspn(name, "=")] = '\0';
 | 
			
		||||
 | 
			
		||||
	environ_set(env, name, value);
 | 
			
		||||
	xfree(name);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
environ_unset(struct environ *env, const char *name)
 | 
			
		||||
{
 | 
			
		||||
	struct environ_entry	*envent;
 | 
			
		||||
 | 
			
		||||
	if ((envent = environ_find(env, name)) == NULL)
 | 
			
		||||
		return;
 | 
			
		||||
	RB_REMOVE(environ, env, envent);
 | 
			
		||||
	xfree(envent->name);
 | 
			
		||||
	if (envent->value != NULL)
 | 
			
		||||
		xfree(envent->value);
 | 
			
		||||
	xfree(envent);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
environ_update(const char *vars, struct environ *srcenv, struct environ *dstenv)
 | 
			
		||||
{
 | 
			
		||||
	struct environ_entry	*envent;
 | 
			
		||||
	char			*var, *next;
 | 
			
		||||
 | 
			
		||||
	vars = next = xstrdup(vars);
 | 
			
		||||
	while ((var = strsep(&next, " ")) != NULL) {
 | 
			
		||||
		if ((envent = environ_find(srcenv, var)) == NULL)
 | 
			
		||||
			environ_set(dstenv, var, NULL);
 | 
			
		||||
		else
 | 
			
		||||
			environ_set(dstenv, envent->name, envent->value);
 | 
			
		||||
	}
 | 
			
		||||
	xfree(vars);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										21
									
								
								server-fn.c
									
									
									
									
									
								
							
							
						
						
									
										21
									
								
								server-fn.c
									
									
									
									
									
								
							@@ -1,4 +1,4 @@
 | 
			
		||||
/* $Id: server-fn.c,v 1.79 2009-08-09 17:19:18 tcunha Exp $ */
 | 
			
		||||
/* $Id: server-fn.c,v 1.80 2009-08-09 17:48:55 tcunha Exp $ */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
			
		||||
@@ -26,25 +26,20 @@
 | 
			
		||||
 | 
			
		||||
int	server_lock_callback(void *, const char *);
 | 
			
		||||
 | 
			
		||||
const char **
 | 
			
		||||
server_fill_environ(struct session *s)
 | 
			
		||||
void
 | 
			
		||||
server_fill_environ(struct session *s, struct environ *env)
 | 
			
		||||
{
 | 
			
		||||
	static const char *env[] = { NULL /* TMUX= */, NULL /* TERM */, NULL };
 | 
			
		||||
	static char	tmuxvar[MAXPATHLEN + 256], termvar[256];
 | 
			
		||||
	char		 tmuxvar[MAXPATHLEN], *term;
 | 
			
		||||
	u_int		 idx;
 | 
			
		||||
 | 
			
		||||
	if (session_index(s, &idx) != 0)
 | 
			
		||||
		fatalx("session not found");
 | 
			
		||||
 | 
			
		||||
	xsnprintf(tmuxvar, sizeof tmuxvar,
 | 
			
		||||
	    "TMUX=%s,%ld,%u", socket_path, (long) getpid(), idx);
 | 
			
		||||
	env[0] = tmuxvar;
 | 
			
		||||
	    "%s,%ld,%u", socket_path, (long) getpid(), idx);
 | 
			
		||||
	environ_set(env, "TMUX", tmuxvar);
 | 
			
		||||
 | 
			
		||||
	xsnprintf(termvar, sizeof termvar,
 | 
			
		||||
	    "TERM=%s", options_get_string(&s->options, "default-terminal"));
 | 
			
		||||
	env[1] = termvar;
 | 
			
		||||
 | 
			
		||||
	return (env);
 | 
			
		||||
	term = options_get_string(&s->options, "default-terminal");
 | 
			
		||||
	environ_set(env, "TERM", term);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										12
									
								
								server-msg.c
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								server-msg.c
									
									
									
									
									
								
							@@ -1,4 +1,4 @@
 | 
			
		||||
/* $Id: server-msg.c,v 1.76 2009-07-30 21:01:01 tcunha Exp $ */
 | 
			
		||||
/* $Id: server-msg.c,v 1.77 2009-08-09 17:48:55 tcunha Exp $ */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
			
		||||
@@ -42,6 +42,7 @@ server_msg_dispatch(struct client *c)
 | 
			
		||||
	struct msg_identify_data identifydata;
 | 
			
		||||
	struct msg_resize_data	 resizedata;
 | 
			
		||||
	struct msg_unlock_data	 unlockdata;
 | 
			
		||||
	struct msg_environ_data	 environdata;
 | 
			
		||||
 | 
			
		||||
	for (;;) {
 | 
			
		||||
		if (BUFFER_USED(c->in) < sizeof hdr)
 | 
			
		||||
@@ -100,6 +101,15 @@ server_msg_dispatch(struct client *c)
 | 
			
		||||
			tty_start_tty(&c->tty);
 | 
			
		||||
			server_redraw_client(c);
 | 
			
		||||
			break;
 | 
			
		||||
		case MSG_ENVIRON:
 | 
			
		||||
			if (hdr.size != sizeof environdata)
 | 
			
		||||
				fatalx("bad MSG_ENVIRON size");
 | 
			
		||||
			buffer_read(c->in, &environdata, sizeof environdata);
 | 
			
		||||
 | 
			
		||||
			environdata.var[(sizeof environdata.var) - 1] = '\0';
 | 
			
		||||
			if (strchr(environdata.var, '=') != NULL)
 | 
			
		||||
				environ_put(&c->environ, environdata.var);
 | 
			
		||||
			break;
 | 
			
		||||
		default:
 | 
			
		||||
			fatalx("unexpected message");
 | 
			
		||||
		}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										24
									
								
								session.c
									
									
									
									
									
								
							
							
						
						
									
										24
									
								
								session.c
									
									
									
									
									
								
							@@ -1,4 +1,4 @@
 | 
			
		||||
/* $Id: session.c,v 1.59 2009-07-08 18:03:03 nicm Exp $ */
 | 
			
		||||
/* $Id: session.c,v 1.60 2009-08-09 17:48:55 tcunha Exp $ */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
			
		||||
@@ -112,8 +112,8 @@ session_find(const char *name)
 | 
			
		||||
 | 
			
		||||
/* Create a new session. */
 | 
			
		||||
struct session *
 | 
			
		||||
session_create(const char *name,
 | 
			
		||||
    const char *cmd, const char *cwd, u_int sx, u_int sy, char **cause)
 | 
			
		||||
session_create(const char *name, const char *cmd, const char *cwd,
 | 
			
		||||
    struct environ *env, u_int sx, u_int sy, char **cause)
 | 
			
		||||
{
 | 
			
		||||
	struct session	*s;
 | 
			
		||||
	u_int		 i;
 | 
			
		||||
@@ -128,6 +128,9 @@ session_create(const char *name,
 | 
			
		||||
	SLIST_INIT(&s->alerts);
 | 
			
		||||
	paste_init_stack(&s->buffers);
 | 
			
		||||
	options_init(&s->options, &global_s_options);
 | 
			
		||||
	environ_init(&s->environ);
 | 
			
		||||
	if (env != NULL)
 | 
			
		||||
		environ_copy(env, &s->environ);
 | 
			
		||||
 | 
			
		||||
	s->sx = sx;
 | 
			
		||||
	s->sy = sy;
 | 
			
		||||
@@ -171,6 +174,7 @@ session_destroy(struct session *s)
 | 
			
		||||
		ARRAY_TRUNC(&sessions, 1);
 | 
			
		||||
 | 
			
		||||
	session_alert_cancel(s, NULL);
 | 
			
		||||
	environ_free(&s->environ);
 | 
			
		||||
	options_free(&s->options);
 | 
			
		||||
	paste_free_stack(&s->buffers);
 | 
			
		||||
 | 
			
		||||
@@ -200,15 +204,21 @@ session_new(struct session *s,
 | 
			
		||||
    const char *name, const char *cmd, const char *cwd, int idx, char **cause)
 | 
			
		||||
{
 | 
			
		||||
	struct window	*w;
 | 
			
		||||
	const char     **env;
 | 
			
		||||
	struct environ	 env;
 | 
			
		||||
	u_int		 hlimit;
 | 
			
		||||
 | 
			
		||||
	env = server_fill_environ(s);
 | 
			
		||||
	environ_init(&env);
 | 
			
		||||
	environ_copy(&global_environ, &env);
 | 
			
		||||
	environ_copy(&s->environ, &env);
 | 
			
		||||
	server_fill_environ(s, &env);
 | 
			
		||||
 | 
			
		||||
	hlimit = options_get_number(&s->options, "history-limit");
 | 
			
		||||
	w = window_create(name, cmd, cwd, env, s->sx, s->sy, hlimit, cause);
 | 
			
		||||
	if (w == NULL)
 | 
			
		||||
	w = window_create(name, cmd, cwd, &env, s->sx, s->sy, hlimit, cause);
 | 
			
		||||
	if (w == NULL) {
 | 
			
		||||
		environ_free(&env);
 | 
			
		||||
		return (NULL);
 | 
			
		||||
	}
 | 
			
		||||
	environ_free(&env);
 | 
			
		||||
 | 
			
		||||
	if (options_get_number(&s->options, "set-remain-on-exit"))
 | 
			
		||||
		options_set_number(&w->options, "remain-on-exit", 1);
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										68
									
								
								tmux.1
									
									
									
									
									
								
							
							
						
						
									
										68
									
								
								tmux.1
									
									
									
									
									
								
							@@ -1,4 +1,4 @@
 | 
			
		||||
.\" $Id: tmux.1,v 1.144 2009-08-09 17:40:17 tcunha Exp $
 | 
			
		||||
.\" $Id: tmux.1,v 1.145 2009-08-09 17:48:55 tcunha Exp $
 | 
			
		||||
.\"
 | 
			
		||||
.\" Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
			
		||||
.\"
 | 
			
		||||
@@ -1321,6 +1321,18 @@ entry for terminals which support 88 or 256 colours:
 | 
			
		||||
.Bd -literal -offset indent
 | 
			
		||||
"*88col*:colors=88,*256col*:colors=256"
 | 
			
		||||
.Ed
 | 
			
		||||
.It Ic update-environment Ar variables
 | 
			
		||||
Set a space-separated string containing a list of environment variables to be
 | 
			
		||||
copied into the session environment when a new session is created or an
 | 
			
		||||
existing session is attached.
 | 
			
		||||
Any variables that do not exist in the source environment are set to be
 | 
			
		||||
removed from the session environment (as if
 | 
			
		||||
.Fl r
 | 
			
		||||
was given to the
 | 
			
		||||
.Ic set-environment
 | 
			
		||||
command).
 | 
			
		||||
The default is
 | 
			
		||||
.Ev DISPLAY .
 | 
			
		||||
.It Xo Ic visual-activity
 | 
			
		||||
.Op Ic on | off
 | 
			
		||||
.Xc
 | 
			
		||||
@@ -1525,6 +1537,60 @@ or the global window options if
 | 
			
		||||
.Fl g
 | 
			
		||||
is used.
 | 
			
		||||
.El
 | 
			
		||||
.Sh ENVIRONMENT
 | 
			
		||||
When the server is started,
 | 
			
		||||
.Nm
 | 
			
		||||
copies the environment into the
 | 
			
		||||
.Em global environment ;
 | 
			
		||||
in addition, each session has a
 | 
			
		||||
.Em session environment .
 | 
			
		||||
When a window is created, the session and global environments are merged with
 | 
			
		||||
the session environment overriding any variable present in both.
 | 
			
		||||
This is the initial environment passed to the new process.
 | 
			
		||||
.Pp
 | 
			
		||||
The
 | 
			
		||||
.Ic update-environment
 | 
			
		||||
session option may be used to update the session environment from the client
 | 
			
		||||
when a new session is created or an old reattached.
 | 
			
		||||
.Nm
 | 
			
		||||
also initialises the
 | 
			
		||||
.Ev TMUX
 | 
			
		||||
variable with some internal information to allow commands to be executed
 | 
			
		||||
from inside, and the
 | 
			
		||||
.Ev TERM
 | 
			
		||||
variable with the correct terminal setting of
 | 
			
		||||
.Ql screen .
 | 
			
		||||
.Pp
 | 
			
		||||
Commands to alter and view the environment are:
 | 
			
		||||
.Bl -tag -width Ds
 | 
			
		||||
.It Xo Ic set-environment
 | 
			
		||||
.Op Fl gru
 | 
			
		||||
.Op Fl t Ar target-session
 | 
			
		||||
.Ar name Op Ar value
 | 
			
		||||
.Xc
 | 
			
		||||
Set or unset an environment variable.
 | 
			
		||||
If
 | 
			
		||||
.Fl g
 | 
			
		||||
is used, the change is made in the global environment; otherwise, it is applied
 | 
			
		||||
to the session environment for
 | 
			
		||||
.Ar target-session .
 | 
			
		||||
The
 | 
			
		||||
.Fl u
 | 
			
		||||
flag unsets a variable.
 | 
			
		||||
.Fl r
 | 
			
		||||
indicates the variable is to be removed from the environment before starting a
 | 
			
		||||
new process.
 | 
			
		||||
.It Xo Ic show-environment
 | 
			
		||||
.Op Fl g
 | 
			
		||||
.Op Fl t Ar target-session
 | 
			
		||||
.Xc
 | 
			
		||||
Display the environment for
 | 
			
		||||
.Ar target-session
 | 
			
		||||
or the global environment with
 | 
			
		||||
.Fl g .
 | 
			
		||||
Variables removed from the environment are prefixed with
 | 
			
		||||
.Ql - .
 | 
			
		||||
.El
 | 
			
		||||
.Sh STATUS LINE
 | 
			
		||||
.Nm
 | 
			
		||||
includes an optional status line which is displayed in the bottom line of each
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										16
									
								
								tmux.c
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								tmux.c
									
									
									
									
									
								
							@@ -1,4 +1,4 @@
 | 
			
		||||
/* $Id: tmux.c,v 1.157 2009-08-09 17:40:17 tcunha Exp $ */
 | 
			
		||||
/* $Id: tmux.c,v 1.158 2009-08-09 17:48:55 tcunha Exp $ */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
			
		||||
@@ -49,6 +49,7 @@ volatile sig_atomic_t sigusr2;
 | 
			
		||||
char		*cfg_file;
 | 
			
		||||
struct options	 global_s_options;	/* session options */
 | 
			
		||||
struct options	 global_w_options;	/* window options */
 | 
			
		||||
struct environ	 global_environ;
 | 
			
		||||
 | 
			
		||||
int		 server_locked;
 | 
			
		||||
u_int		 password_failures;
 | 
			
		||||
@@ -271,7 +272,7 @@ main(int argc, char **argv)
 | 
			
		||||
	struct hdr	 	 hdr;
 | 
			
		||||
	struct passwd		*pw;
 | 
			
		||||
	struct msg_print_data	 printdata;
 | 
			
		||||
	char			*s, *path, *label, *home, *cause;
 | 
			
		||||
	char			*s, *path, *label, *home, *cause, **var;
 | 
			
		||||
	char			 cwd[MAXPATHLEN];
 | 
			
		||||
	void			*buf;
 | 
			
		||||
	size_t			 len;
 | 
			
		||||
@@ -329,6 +330,10 @@ main(int argc, char **argv)
 | 
			
		||||
	log_open_tty(debug_level);
 | 
			
		||||
	siginit();
 | 
			
		||||
 | 
			
		||||
	environ_init(&global_environ);
 | 
			
		||||
 	for (var = environ; *var != NULL; var++)
 | 
			
		||||
		environ_put(&global_environ, *var);
 | 
			
		||||
 | 
			
		||||
	if (!(flags & IDENTIFY_UTF8)) {
 | 
			
		||||
		/*
 | 
			
		||||
		 * If the user has set whichever of LC_ALL, LC_CTYPE or LANG
 | 
			
		||||
@@ -385,6 +390,7 @@ main(int argc, char **argv)
 | 
			
		||||
		options_set_number(&global_s_options, "status-utf8", 0);
 | 
			
		||||
	options_set_string(&global_s_options,
 | 
			
		||||
	    "terminal-overrides", "*88col*:colors=88,*256col*:colors=256");
 | 
			
		||||
	options_set_string(&global_s_options, "update-environment", "DISPLAY");
 | 
			
		||||
	options_set_number(&global_s_options, "visual-activity", 0);
 | 
			
		||||
	options_set_number(&global_s_options, "visual-bell", 0);
 | 
			
		||||
	options_set_number(&global_s_options, "visual-content", 0);
 | 
			
		||||
@@ -478,10 +484,10 @@ main(int argc, char **argv)
 | 
			
		||||
		}
 | 
			
		||||
		cmdflags &= ~CMD_STARTSERVER;
 | 
			
		||||
		TAILQ_FOREACH(cmd, cmdlist, qentry) {
 | 
			
		||||
			if (cmd->entry->flags & CMD_STARTSERVER) {
 | 
			
		||||
			if (cmd->entry->flags & CMD_STARTSERVER)
 | 
			
		||||
				cmdflags |= CMD_STARTSERVER;
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
			if (cmd->entry->flags & CMD_SENDENVIRON)
 | 
			
		||||
				cmdflags |= CMD_SENDENVIRON;
 | 
			
		||||
		}
 | 
			
		||||
		cmd_list_free(cmdlist);
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										48
									
								
								tmux.h
									
									
									
									
									
								
							
							
						
						
									
										48
									
								
								tmux.h
									
									
									
									
									
								
							@@ -1,4 +1,4 @@
 | 
			
		||||
/* $Id: tmux.h,v 1.407 2009-08-09 17:32:06 tcunha Exp $ */
 | 
			
		||||
/* $Id: tmux.h,v 1.408 2009-08-09 17:48:55 tcunha Exp $ */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
			
		||||
@@ -38,6 +38,7 @@
 | 
			
		||||
#include "compat.h"
 | 
			
		||||
 | 
			
		||||
extern char    *__progname;
 | 
			
		||||
extern char   **environ;
 | 
			
		||||
 | 
			
		||||
/* Default configuration files. */
 | 
			
		||||
#define DEFAULT_CFG ".tmux.conf"
 | 
			
		||||
@@ -68,6 +69,7 @@ extern char    *__progname;
 | 
			
		||||
#define COMMAND_LENGTH 2048	/* packed argv size */
 | 
			
		||||
#define TERMINAL_LENGTH 128	/* length of TERM environment variable */
 | 
			
		||||
#define PRINT_LENGTH 512	/* printed error/message size */
 | 
			
		||||
#define ENVIRON_LENGTH 1024	/* environment variable length */
 | 
			
		||||
 | 
			
		||||
/* Fatal errors. */
 | 
			
		||||
#define fatal(msg) log_fatal("%s: %s", __func__, msg);
 | 
			
		||||
@@ -301,6 +303,7 @@ enum msgtype {
 | 
			
		||||
	MSG_SUSPEND,
 | 
			
		||||
	MSG_UNLOCK,
 | 
			
		||||
	MSG_WAKEUP,
 | 
			
		||||
	MSG_ENVIRON
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
@@ -355,6 +358,10 @@ struct msg_unlock_data {
 | 
			
		||||
	char	       	pass[PASS_MAX];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct msg_environ_data {
 | 
			
		||||
	char	     	var[ENVIRON_LENGTH];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* Mode key commands. */
 | 
			
		||||
enum mode_key_cmd {
 | 
			
		||||
	MODEKEY_NONE,
 | 
			
		||||
@@ -764,6 +771,15 @@ struct paste_buffer {
 | 
			
		||||
};
 | 
			
		||||
ARRAY_DECL(paste_stack, struct paste_buffer *);
 | 
			
		||||
 | 
			
		||||
/* Environment variable. */
 | 
			
		||||
struct environ_entry {
 | 
			
		||||
	char		*name;
 | 
			
		||||
	char		*value;
 | 
			
		||||
 | 
			
		||||
	RB_ENTRY(environ_entry) entry;
 | 
			
		||||
};
 | 
			
		||||
RB_HEAD(environ, environ_entry);
 | 
			
		||||
 | 
			
		||||
/* Client session. */
 | 
			
		||||
struct session_alert {
 | 
			
		||||
	struct winlink	*wl;
 | 
			
		||||
@@ -791,6 +807,8 @@ struct session {
 | 
			
		||||
 | 
			
		||||
#define SESSION_UNATTACHED 0x1	/* not attached to any clients */
 | 
			
		||||
	int		 flags;
 | 
			
		||||
 | 
			
		||||
	struct environ	 environ;
 | 
			
		||||
};
 | 
			
		||||
ARRAY_DECL(sessions, struct session *);
 | 
			
		||||
 | 
			
		||||
@@ -893,6 +911,8 @@ struct client {
 | 
			
		||||
	struct buffer	*in;
 | 
			
		||||
	struct buffer	*out;
 | 
			
		||||
 | 
			
		||||
	struct environ	 environ;
 | 
			
		||||
 | 
			
		||||
	char		*title;
 | 
			
		||||
	char		*cwd;
 | 
			
		||||
 | 
			
		||||
@@ -991,6 +1011,7 @@ struct cmd_entry {
 | 
			
		||||
#define CMD_CANTNEST 0x2
 | 
			
		||||
#define CMD_ARG1 0x4
 | 
			
		||||
#define CMD_ARG01 0x8
 | 
			
		||||
#define CMD_SENDENVIRON 0x10
 | 
			
		||||
	int		 flags;
 | 
			
		||||
 | 
			
		||||
#define CMD_CHFLAG(flag) \
 | 
			
		||||
@@ -1073,6 +1094,7 @@ extern volatile sig_atomic_t sigusr1;
 | 
			
		||||
extern volatile sig_atomic_t sigusr2;
 | 
			
		||||
extern struct options global_s_options;
 | 
			
		||||
extern struct options global_w_options;
 | 
			
		||||
extern struct environ global_environ;
 | 
			
		||||
extern char	*cfg_file;
 | 
			
		||||
extern int	 server_locked;
 | 
			
		||||
extern u_int	 password_failures;
 | 
			
		||||
@@ -1122,6 +1144,18 @@ char   *options_get_string(struct options *, const char *);
 | 
			
		||||
void	options_set_number(struct options *, const char *, long long);
 | 
			
		||||
long long options_get_number(struct options *, const char *);
 | 
			
		||||
 | 
			
		||||
/* environ.c */
 | 
			
		||||
int	environ_cmp(struct environ_entry *, struct environ_entry *);
 | 
			
		||||
RB_PROTOTYPE(environ, environ_entry, entry, environ_cmp);
 | 
			
		||||
void	environ_init(struct environ *);
 | 
			
		||||
void	environ_free(struct environ *);
 | 
			
		||||
void	environ_copy(struct environ *, struct environ *);
 | 
			
		||||
struct environ_entry *environ_find(struct environ *, const char *);
 | 
			
		||||
void	environ_set(struct environ *, const char *, const char *);
 | 
			
		||||
void	environ_put(struct environ *, const char *);
 | 
			
		||||
void	environ_unset(struct environ *, const char *);
 | 
			
		||||
void 	environ_update(const char *, struct environ *, struct environ *);
 | 
			
		||||
 | 
			
		||||
/* tty.c */
 | 
			
		||||
u_char	tty_get_acs(struct tty *, u_char);
 | 
			
		||||
void	tty_reset(struct tty *);
 | 
			
		||||
@@ -1284,10 +1318,12 @@ extern const struct cmd_entry cmd_send_keys_entry;
 | 
			
		||||
extern const struct cmd_entry cmd_send_prefix_entry;
 | 
			
		||||
extern const struct cmd_entry cmd_server_info_entry;
 | 
			
		||||
extern const struct cmd_entry cmd_set_buffer_entry;
 | 
			
		||||
extern const struct cmd_entry cmd_set_environment_entry;
 | 
			
		||||
extern const struct cmd_entry cmd_set_option_entry;
 | 
			
		||||
extern const struct cmd_entry cmd_set_password_entry;
 | 
			
		||||
extern const struct cmd_entry cmd_set_window_option_entry;
 | 
			
		||||
extern const struct cmd_entry cmd_show_buffer_entry;
 | 
			
		||||
extern const struct cmd_entry cmd_show_environment_entry;
 | 
			
		||||
extern const struct cmd_entry cmd_show_options_entry;
 | 
			
		||||
extern const struct cmd_entry cmd_show_window_options_entry;
 | 
			
		||||
extern const struct cmd_entry cmd_source_file_entry;
 | 
			
		||||
@@ -1383,7 +1419,7 @@ int	 server_start(char *);
 | 
			
		||||
int	 server_msg_dispatch(struct client *);
 | 
			
		||||
 | 
			
		||||
/* server-fn.c */
 | 
			
		||||
const char **server_fill_environ(struct session *);
 | 
			
		||||
void	 server_fill_environ(struct session *, struct environ *);
 | 
			
		||||
void	 server_write_error(struct client *, const char *);
 | 
			
		||||
void	 server_write_client(
 | 
			
		||||
             struct client *, enum msgtype, const void *, size_t);
 | 
			
		||||
@@ -1553,8 +1589,8 @@ void		 winlink_stack_push(struct winlink_stack *, struct winlink *);
 | 
			
		||||
void		 winlink_stack_remove(struct winlink_stack *, struct winlink *);
 | 
			
		||||
int	 	 window_index(struct window *, u_int *);
 | 
			
		||||
struct window	*window_create1(u_int, u_int);
 | 
			
		||||
struct window	*window_create(const char *, const char *,
 | 
			
		||||
		     const char *, const char **, u_int, u_int, u_int, char **);
 | 
			
		||||
struct window	*window_create(const char *, const char *, const char *,
 | 
			
		||||
    		     struct environ *, u_int, u_int, u_int, char **);
 | 
			
		||||
void		 window_destroy(struct window *);
 | 
			
		||||
void		 window_set_active_pane(struct window *, struct window_pane *);
 | 
			
		||||
struct window_pane *window_add_pane(struct window *, u_int);
 | 
			
		||||
@@ -1567,7 +1603,7 @@ void		 window_destroy_panes(struct window *);
 | 
			
		||||
struct window_pane *window_pane_create(struct window *, u_int, u_int, u_int);
 | 
			
		||||
void		 window_pane_destroy(struct window_pane *);
 | 
			
		||||
int		 window_pane_spawn(struct window_pane *,
 | 
			
		||||
		     const char *, const char *, const char **, char **);
 | 
			
		||||
		     const char *, const char *, struct environ *, char **);
 | 
			
		||||
void		 window_pane_resize(struct window_pane *, u_int, u_int);
 | 
			
		||||
int		 window_pane_set_mode(
 | 
			
		||||
		     struct window_pane *, const struct window_mode *);
 | 
			
		||||
@@ -1647,7 +1683,7 @@ int	 session_alert_has(struct session *, struct winlink *, int);
 | 
			
		||||
int	 session_alert_has_window(struct session *, struct window *, int);
 | 
			
		||||
struct session	*session_find(const char *);
 | 
			
		||||
struct session	*session_create(const char *, const char *,
 | 
			
		||||
    		     const char *, u_int, u_int, char **);
 | 
			
		||||
    		     const char *, struct environ *, u_int, u_int, char **);
 | 
			
		||||
void	 	 session_destroy(struct session *);
 | 
			
		||||
int	 	 session_index(struct session *, u_int *);
 | 
			
		||||
struct winlink	*session_new(struct session *,
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										33
									
								
								window.c
									
									
									
									
									
								
							
							
						
						
									
										33
									
								
								window.c
									
									
									
									
									
								
							@@ -1,4 +1,4 @@
 | 
			
		||||
/* $Id: window.c,v 1.99 2009-07-28 23:04:29 tcunha Exp $ */
 | 
			
		||||
/* $Id: window.c,v 1.100 2009-08-09 17:48:55 tcunha Exp $ */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
			
		||||
@@ -252,7 +252,7 @@ window_create1(u_int sx, u_int sy)
 | 
			
		||||
 | 
			
		||||
struct window *
 | 
			
		||||
window_create(const char *name, const char *cmd, const char *cwd,
 | 
			
		||||
    const char **envp, u_int sx, u_int sy, u_int hlimit, char **cause)
 | 
			
		||||
    struct environ *env, u_int sx, u_int sy, u_int hlimit, char **cause)
 | 
			
		||||
{
 | 
			
		||||
	struct window		*w;
 | 
			
		||||
	struct window_pane	*wp;
 | 
			
		||||
@@ -260,7 +260,7 @@ window_create(const char *name, const char *cmd, const char *cwd,
 | 
			
		||||
	w = window_create1(sx, sy);
 | 
			
		||||
	wp = window_add_pane(w, hlimit);
 | 
			
		||||
	layout_init(w);
 | 
			
		||||
	if (window_pane_spawn(wp, cmd, cwd, envp, cause) != 0) {
 | 
			
		||||
	if (window_pane_spawn(wp, cmd, cwd, env, cause) != 0) {
 | 
			
		||||
		window_destroy(w);
 | 
			
		||||
		return (NULL);
 | 
			
		||||
	}
 | 
			
		||||
@@ -454,13 +454,16 @@ window_pane_destroy(struct window_pane *wp)
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
window_pane_spawn(struct window_pane *wp,
 | 
			
		||||
    const char *cmd, const char *cwd, const char **envp, char **cause)
 | 
			
		||||
    const char *cmd, const char *cwd, struct environ *env, char **cause)
 | 
			
		||||
{
 | 
			
		||||
	struct winsize	 	 ws;
 | 
			
		||||
	int		 	 mode;
 | 
			
		||||
	const char     **envq, *ptr;
 | 
			
		||||
	char		*argv0;
 | 
			
		||||
	char			*argv0, **varp, *var;
 | 
			
		||||
	ARRAY_DECL(, char *)	 varlist;
 | 
			
		||||
	struct environ_entry	*envent;
 | 
			
		||||
	const char		*ptr;
 | 
			
		||||
	struct timeval	 	 tv;
 | 
			
		||||
	u_int		 	 i;
 | 
			
		||||
 | 
			
		||||
	if (wp->fd != -1)
 | 
			
		||||
		close(wp->fd);
 | 
			
		||||
@@ -493,10 +496,22 @@ window_pane_spawn(struct window_pane *wp,
 | 
			
		||||
	case 0:
 | 
			
		||||
		if (chdir(wp->cwd) != 0)
 | 
			
		||||
			chdir("/");
 | 
			
		||||
		for (envq = envp; *envq != NULL; envq++) {
 | 
			
		||||
			if (putenv(xstrdup(*envq)) != 0)
 | 
			
		||||
				fatal("putenv failed");
 | 
			
		||||
 | 
			
		||||
		ARRAY_INIT(&varlist);
 | 
			
		||||
		for (varp = environ; *varp != NULL; varp++) {
 | 
			
		||||
			var = xstrdup(*varp);
 | 
			
		||||
			var[strcspn(var, "=")] = '\0';
 | 
			
		||||
			ARRAY_ADD(&varlist, var);
 | 
			
		||||
		}
 | 
			
		||||
		for (i = 0; i < ARRAY_LENGTH(&varlist); i++) {
 | 
			
		||||
			var = ARRAY_ITEM(&varlist, i);
 | 
			
		||||
			unsetenv(var);
 | 
			
		||||
		}
 | 
			
		||||
		RB_FOREACH(envent, environ, env) {
 | 
			
		||||
			if (envent->value != NULL)
 | 
			
		||||
				setenv(envent->name, envent->value, 1);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		sigreset();
 | 
			
		||||
		log_close();
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user