mirror of
				https://github.com/tmux/tmux.git
				synced 2025-11-04 09:26:05 +00:00 
			
		
		
		
	Memory could be leaked if a second prompt or message appeared while another was
still present, so add a separate prompt free callback and make the _clear function responsible for calling it if necessary (rather than the individual
This commit is contained in:
		@@ -1,4 +1,4 @@
 | 
			
		||||
/* $Id: cmd-command-prompt.c,v 1.18 2009-07-15 17:50:11 nicm Exp $ */
 | 
			
		||||
/* $Id: cmd-command-prompt.c,v 1.19 2009-07-17 09:26:21 nicm Exp $ */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
			
		||||
@@ -31,6 +31,7 @@ void	cmd_command_prompt_init(struct cmd *, int);
 | 
			
		||||
int	cmd_command_prompt_exec(struct cmd *, struct cmd_ctx *);
 | 
			
		||||
 | 
			
		||||
int	cmd_command_prompt_callback(void *, const char *);
 | 
			
		||||
void	cmd_command_prompt_free(void *);
 | 
			
		||||
 | 
			
		||||
const struct cmd_entry cmd_command_prompt_entry = {
 | 
			
		||||
	"command-prompt", NULL,
 | 
			
		||||
@@ -96,7 +97,8 @@ cmd_command_prompt_exec(struct cmd *self, struct cmd_ctx *ctx)
 | 
			
		||||
		cdata->template = NULL;
 | 
			
		||||
		hdr = xstrdup(":");
 | 
			
		||||
	}
 | 
			
		||||
	status_prompt_set(c, hdr, cmd_command_prompt_callback, cdata, 0);
 | 
			
		||||
	status_prompt_set(c, hdr,
 | 
			
		||||
	    cmd_command_prompt_callback, cmd_command_prompt_free, cdata, 0);
 | 
			
		||||
	xfree(hdr);
 | 
			
		||||
 | 
			
		||||
	return (0);
 | 
			
		||||
@@ -112,10 +114,8 @@ cmd_command_prompt_callback(void *data, const char *s)
 | 
			
		||||
	char				*cause, *ptr, *buf, ch;
 | 
			
		||||
	size_t				 len, slen;
 | 
			
		||||
 | 
			
		||||
	if (s == NULL) {
 | 
			
		||||
		xfree(cdata);
 | 
			
		||||
	if (s == NULL)
 | 
			
		||||
		return (0);
 | 
			
		||||
	}
 | 
			
		||||
	slen = strlen(s);
 | 
			
		||||
 | 
			
		||||
	len = 0;
 | 
			
		||||
@@ -139,12 +139,10 @@ cmd_command_prompt_callback(void *data, const char *s)
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		xfree(cdata->template);
 | 
			
		||||
 | 
			
		||||
		buf[len] = '\0';
 | 
			
		||||
		s = buf;
 | 
			
		||||
	}
 | 
			
		||||
	xfree(cdata);
 | 
			
		||||
 | 
			
		||||
	if (cmd_string_parse(s, &cmdlist, &cause) != 0) {
 | 
			
		||||
		if (cause == NULL)
 | 
			
		||||
@@ -172,7 +170,17 @@ cmd_command_prompt_callback(void *data, const char *s)
 | 
			
		||||
	cmd_list_exec(cmdlist, &ctx);
 | 
			
		||||
	cmd_list_free(cmdlist);
 | 
			
		||||
 | 
			
		||||
	if (c->prompt_callback != (void *) &cmd_command_prompt_callback)
 | 
			
		||||
	if (c->prompt_callbackfn != (void *) &cmd_command_prompt_callback)
 | 
			
		||||
		return (1);
 | 
			
		||||
	return (0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
cmd_command_prompt_free(void *data)
 | 
			
		||||
{
 | 
			
		||||
	struct cmd_command_prompt_data	*cdata = data;
 | 
			
		||||
 | 
			
		||||
	if (cdata->template != NULL)
 | 
			
		||||
		xfree(cdata->template);
 | 
			
		||||
	xfree(cdata);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
/* $Id: cmd-confirm-before.c,v 1.6 2009-07-15 17:50:11 nicm Exp $ */
 | 
			
		||||
/* $Id: cmd-confirm-before.c,v 1.7 2009-07-17 09:26:21 nicm Exp $ */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org>
 | 
			
		||||
@@ -29,11 +29,7 @@ int	cmd_confirm_before_exec(struct cmd *, struct cmd_ctx *);
 | 
			
		||||
void	cmd_confirm_before_init(struct cmd *, int);
 | 
			
		||||
 | 
			
		||||
int	cmd_confirm_before_callback(void *, const char *);
 | 
			
		||||
 | 
			
		||||
struct cmd_confirm_before_data {
 | 
			
		||||
	struct client	*c;
 | 
			
		||||
	char		*cmd;
 | 
			
		||||
};
 | 
			
		||||
void	cmd_confirm_before_free(void *);
 | 
			
		||||
 | 
			
		||||
const struct cmd_entry cmd_confirm_before_entry = {
 | 
			
		||||
	"confirm-before", "confirm",
 | 
			
		||||
@@ -48,6 +44,11 @@ const struct cmd_entry cmd_confirm_before_entry = {
 | 
			
		||||
	cmd_target_print
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct cmd_confirm_before_data {
 | 
			
		||||
	struct client	*c;
 | 
			
		||||
	char		*cmd;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
cmd_confirm_before_init(struct cmd *self, int key)
 | 
			
		||||
{
 | 
			
		||||
@@ -91,8 +92,9 @@ cmd_confirm_before_exec(unused struct cmd *self, struct cmd_ctx *ctx)
 | 
			
		||||
	cdata = xmalloc(sizeof *cdata);
 | 
			
		||||
	cdata->cmd = xstrdup(data->arg);
 | 
			
		||||
	cdata->c = c;
 | 
			
		||||
	status_prompt_set(
 | 
			
		||||
	    cdata->c, buf, cmd_confirm_before_callback, cdata, PROMPT_SINGLE);
 | 
			
		||||
	status_prompt_set(cdata->c, buf,
 | 
			
		||||
	    cmd_confirm_before_callback, cmd_confirm_before_free, cdata,
 | 
			
		||||
	    PROMPT_SINGLE);
 | 
			
		||||
 | 
			
		||||
	xfree(buf);
 | 
			
		||||
	return (1);
 | 
			
		||||
@@ -108,7 +110,7 @@ cmd_confirm_before_callback(void *data, const char *s)
 | 
			
		||||
	char				*cause;
 | 
			
		||||
 | 
			
		||||
	if (s == NULL || tolower((u_char) s[0]) != 'y' || s[1] != '\0')
 | 
			
		||||
		goto out;
 | 
			
		||||
		return (0);
 | 
			
		||||
 | 
			
		||||
	if (cmd_string_parse(cdata->cmd, &cmdlist, &cause) != 0) {
 | 
			
		||||
		if (cause != NULL) {
 | 
			
		||||
@@ -116,7 +118,7 @@ cmd_confirm_before_callback(void *data, const char *s)
 | 
			
		||||
			status_message_set(c, "%s", cause);
 | 
			
		||||
			xfree(cause);
 | 
			
		||||
		}
 | 
			
		||||
		goto out;
 | 
			
		||||
		return (0);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ctx.msgdata = NULL;
 | 
			
		||||
@@ -132,10 +134,15 @@ cmd_confirm_before_callback(void *data, const char *s)
 | 
			
		||||
	cmd_list_exec(cmdlist, &ctx);
 | 
			
		||||
	cmd_list_free(cmdlist);
 | 
			
		||||
 | 
			
		||||
out:
 | 
			
		||||
	return (0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
cmd_confirm_before_free(void *data)
 | 
			
		||||
{
 | 
			
		||||
	struct cmd_confirm_before_data	*cdata = data;
 | 
			
		||||
 | 
			
		||||
	if (cdata->cmd != NULL)
 | 
			
		||||
		xfree(cdata->cmd);
 | 
			
		||||
	xfree(cdata);
 | 
			
		||||
 | 
			
		||||
	return (0);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
/* $Id: cmd-select-prompt.c,v 1.9 2009-07-15 17:50:11 nicm Exp $ */
 | 
			
		||||
/* $Id: cmd-select-prompt.c,v 1.10 2009-07-17 09:26:21 nicm Exp $ */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
			
		||||
@@ -55,7 +55,7 @@ cmd_select_prompt_exec(struct cmd *self, struct cmd_ctx *ctx)
 | 
			
		||||
	if (c->prompt_string != NULL)
 | 
			
		||||
		return (0);
 | 
			
		||||
 | 
			
		||||
	status_prompt_set(c, "index ", cmd_select_prompt_callback, c, 0);
 | 
			
		||||
	status_prompt_set(c, "index ", cmd_select_prompt_callback, NULL, c, 0);
 | 
			
		||||
 | 
			
		||||
	return (0);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
/* $Id: server-fn.c,v 1.71 2009-07-14 07:01:03 nicm Exp $ */
 | 
			
		||||
/* $Id: server-fn.c,v 1.72 2009-07-17 09:26:21 nicm Exp $ */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
			
		||||
@@ -171,8 +171,8 @@ server_lock(void)
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		status_prompt_clear(c);
 | 
			
		||||
		status_prompt_set(
 | 
			
		||||
		    c, "Password: ", server_lock_callback, c, PROMPT_HIDDEN);
 | 
			
		||||
		status_prompt_set(c,
 | 
			
		||||
		    "Password: ", server_lock_callback, c, NULL, PROMPT_HIDDEN);
 | 
			
		||||
  		server_redraw_client(c);
 | 
			
		||||
	}
 | 
			
		||||
	server_locked = 1;
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										31
									
								
								status.c
									
									
									
									
									
								
							
							
						
						
									
										31
									
								
								status.c
									
									
									
									
									
								
							@@ -1,4 +1,4 @@
 | 
			
		||||
/* $Id: status.c,v 1.96 2009-07-17 07:46:08 nicm Exp $ */
 | 
			
		||||
/* $Id: status.c,v 1.97 2009-07-17 09:26:21 nicm Exp $ */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
			
		||||
@@ -468,6 +468,9 @@ status_message_set(struct client *c, const char *fmt, ...)
 | 
			
		||||
	va_list		ap;
 | 
			
		||||
	int		delay;
 | 
			
		||||
 | 
			
		||||
	status_prompt_clear(c);
 | 
			
		||||
	status_message_clear(c);
 | 
			
		||||
 | 
			
		||||
	delay = options_get_number(&c->session->options, "display-time");
 | 
			
		||||
	tv.tv_sec = delay / 1000;
 | 
			
		||||
	tv.tv_usec = (delay % 1000) * 1000L;
 | 
			
		||||
@@ -493,7 +496,7 @@ status_message_clear(struct client *c)
 | 
			
		||||
	c->message_string = NULL;
 | 
			
		||||
 | 
			
		||||
	c->tty.flags &= ~(TTY_NOCURSOR|TTY_FREEZE);
 | 
			
		||||
	c->flags |= CLIENT_STATUS;
 | 
			
		||||
	c->flags |= CLIENT_REDRAW; /* screen was frozen and may have changed */
 | 
			
		||||
 | 
			
		||||
	screen_reinit(&c->status);
 | 
			
		||||
}
 | 
			
		||||
@@ -540,15 +543,20 @@ status_message_redraw(struct client *c)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
status_prompt_set(struct client *c,
 | 
			
		||||
    const char *msg, int (*fn)(void *, const char *), void *data, int flags)
 | 
			
		||||
status_prompt_set(struct client *c, const char *msg,
 | 
			
		||||
    int (*callbackfn)(void *, const char *), void (*freefn)(void *),
 | 
			
		||||
    void *data, int flags)
 | 
			
		||||
{
 | 
			
		||||
	status_message_clear(c);
 | 
			
		||||
	status_prompt_clear(c);
 | 
			
		||||
 | 
			
		||||
	c->prompt_string = xstrdup(msg);
 | 
			
		||||
 | 
			
		||||
	c->prompt_buffer = xstrdup("");
 | 
			
		||||
	c->prompt_index = 0;
 | 
			
		||||
 | 
			
		||||
	c->prompt_callback = fn;
 | 
			
		||||
	c->prompt_callbackfn = callbackfn;
 | 
			
		||||
	c->prompt_freefn = freefn;
 | 
			
		||||
	c->prompt_data = data;
 | 
			
		||||
 | 
			
		||||
	c->prompt_hindex = 0;
 | 
			
		||||
@@ -566,9 +574,12 @@ status_prompt_set(struct client *c,
 | 
			
		||||
void
 | 
			
		||||
status_prompt_clear(struct client *c)
 | 
			
		||||
{
 | 
			
		||||
	if (c->prompt_string == NULL)
 | 
			
		||||
 	if (c->prompt_string == NULL)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	if (c->prompt_freefn != NULL && c->prompt_data != NULL)
 | 
			
		||||
		c->prompt_freefn(c->prompt_data);
 | 
			
		||||
 | 
			
		||||
	mode_key_free(&c->prompt_mdata);
 | 
			
		||||
 | 
			
		||||
	xfree(c->prompt_string);
 | 
			
		||||
@@ -580,7 +591,7 @@ status_prompt_clear(struct client *c)
 | 
			
		||||
	c->prompt_buffer = NULL;
 | 
			
		||||
 | 
			
		||||
	c->tty.flags &= ~(TTY_NOCURSOR|TTY_FREEZE);
 | 
			
		||||
	c->flags |= CLIENT_STATUS;
 | 
			
		||||
	c->flags |= CLIENT_REDRAW; /* screen was frozen and may have changed */
 | 
			
		||||
 | 
			
		||||
	screen_reinit(&c->status);
 | 
			
		||||
}
 | 
			
		||||
@@ -832,14 +843,14 @@ status_prompt_key(struct client *c, int key)
 | 
			
		||||
 	case MODEKEYCMD_CHOOSE:
 | 
			
		||||
		if (*c->prompt_buffer != '\0') {
 | 
			
		||||
			status_prompt_add_history(c);
 | 
			
		||||
			if (c->prompt_callback(
 | 
			
		||||
			if (c->prompt_callbackfn(
 | 
			
		||||
			    c->prompt_data, c->prompt_buffer) == 0)
 | 
			
		||||
				status_prompt_clear(c);
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
		/* FALLTHROUGH */
 | 
			
		||||
	case MODEKEYCMD_QUIT:
 | 
			
		||||
		if (c->prompt_callback(c->prompt_data, NULL) == 0)
 | 
			
		||||
		if (c->prompt_callbackfn(c->prompt_data, NULL) == 0)
 | 
			
		||||
			status_prompt_clear(c);
 | 
			
		||||
		break;
 | 
			
		||||
	case MODEKEYCMD_OTHERKEY:
 | 
			
		||||
@@ -858,7 +869,7 @@ status_prompt_key(struct client *c, int key)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (c->prompt_flags & PROMPT_SINGLE) {
 | 
			
		||||
			if (c->prompt_callback(
 | 
			
		||||
			if (c->prompt_callbackfn(
 | 
			
		||||
			    c->prompt_data, c->prompt_buffer) == 0)
 | 
			
		||||
				status_prompt_clear(c);
 | 
			
		||||
		}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										9
									
								
								tmux.h
									
									
									
									
									
								
							
							
						
						
									
										9
									
								
								tmux.h
									
									
									
									
									
								
							@@ -1,4 +1,4 @@
 | 
			
		||||
/* $Id: tmux.h,v 1.366 2009-07-15 17:50:11 nicm Exp $ */
 | 
			
		||||
/* $Id: tmux.h,v 1.367 2009-07-17 09:26:21 nicm Exp $ */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
			
		||||
@@ -801,7 +801,8 @@ struct client {
 | 
			
		||||
	char		*prompt_string;
 | 
			
		||||
	char		*prompt_buffer;
 | 
			
		||||
	size_t		 prompt_index;
 | 
			
		||||
	int		 (*prompt_callback)(void *, const char *);
 | 
			
		||||
	int		 (*prompt_callbackfn)(void *, const char *);
 | 
			
		||||
	void		 (*prompt_freefn)(void *);
 | 
			
		||||
	void		*prompt_data;
 | 
			
		||||
 | 
			
		||||
#define PROMPT_HIDDEN 0x1
 | 
			
		||||
@@ -1277,8 +1278,8 @@ int	 status_redraw(struct client *);
 | 
			
		||||
void printflike2 status_message_set(struct client *, const char *, ...);
 | 
			
		||||
void	 status_message_clear(struct client *);
 | 
			
		||||
int	 status_message_redraw(struct client *);
 | 
			
		||||
void	 status_prompt_set(struct client *,
 | 
			
		||||
	     const char *, int (*)(void *, const char *), void *, int);
 | 
			
		||||
void	 status_prompt_set(struct client *, const char *,
 | 
			
		||||
    	     int (*)(void *, const char *), void (*)(void *), void *, int);
 | 
			
		||||
void	 status_prompt_clear(struct client *);
 | 
			
		||||
int	 status_prompt_redraw(struct client *);
 | 
			
		||||
void	 status_prompt_key(struct client *, int);
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user