changeset 7431:33d8adcc2d44 HEAD

client_command_free()/cancel(): Take pointer-to-pointer parameter and set it to NULL to make sure it's not accessed again.
author Timo Sirainen <tss@iki.fi>
date Thu, 20 Mar 2008 16:26:27 +0200
parents 2b89ceb0f6af
children 9b8590b3749b
files src/imap/client.c src/imap/client.h src/imap/cmd-append.c src/imap/cmd-idle.c src/imap/cmd-search.c src/imap/cmd-x-cancel.c src/imap/imap-sync.c
diffstat 7 files changed, 29 insertions(+), 22 deletions(-) [+]
line wrap: on
line diff
--- a/src/imap/client.c	Thu Mar 20 15:42:57 2008 +0200
+++ b/src/imap/client.c	Thu Mar 20 16:26:27 2008 +0200
@@ -66,8 +66,9 @@
 	return client;
 }
 
-void client_command_cancel(struct client_command_context *cmd)
+void client_command_cancel(struct client_command_context **_cmd)
 {
+	struct client_command_context *cmd = *_cmd;
 	bool cmd_ret;
 
 	cmd->cancel = TRUE;
@@ -76,7 +77,7 @@
 		if (cmd->client->output->closed)
 			i_panic("command didn't cancel itself: %s", cmd->name);
 	} else {
-		client_command_free(cmd);
+		client_command_free(_cmd);
 	}
 }
 
@@ -112,6 +113,7 @@
 
 void client_destroy(struct client *client, const char *reason)
 {
+	struct client_command_context *cmd;
 	i_assert(!client->destroyed);
 	client->destroyed = TRUE;
 
@@ -127,11 +129,13 @@
 
 	/* finish off all the queued commands. */
 	if (client->output_lock != NULL)
-		client_command_cancel(client->output_lock);
+		client_command_cancel(&client->output_lock);
 	if (client->input_lock != NULL)
-		client_command_cancel(client->input_lock);
-	while (client->command_queue != NULL)
-		client_command_cancel(client->command_queue);
+		client_command_cancel(&client->input_lock);
+	while (client->command_queue != NULL) {
+		cmd = client->command_queue;
+		client_command_cancel(&cmd);
+	}
 
 	if (client->mailbox != NULL)
 		mailbox_close(&client->mailbox);
@@ -398,10 +402,13 @@
 	return cmd;
 }
 
-void client_command_free(struct client_command_context *cmd)
+void client_command_free(struct client_command_context **_cmd)
 {
+	struct client_command_context *cmd = *_cmd;
 	struct client *client = cmd->client;
 
+	*_cmd = NULL;
+
 	/* reset input idle time because command output might have taken a
 	   long time and we don't want to disconnect client immediately then */
 	client->last_input = ioloop_time;
@@ -545,7 +552,7 @@
 		/* command is being executed - continue it */
 		if (cmd->func(cmd) || cmd->state == CLIENT_COMMAND_STATE_DONE) {
 			/* command execution was finished */
-			client_command_free(cmd);
+			client_command_free(&cmd);
 			client_add_missing_io(client);
 			return TRUE;
 		}
@@ -587,7 +594,7 @@
 		/* unknown command */
 		client_send_command_error(cmd, "Unknown command.");
 		cmd->param_error = TRUE;
-		client_command_free(cmd);
+		client_command_free(&cmd);
 		return TRUE;
 	} else {
 		i_assert(!client->disconnected);
@@ -698,7 +705,7 @@
 			client_command_new(client);
 		cmd->param_error = TRUE;
 		client_send_command_error(cmd, "Too long argument.");
-		client_command_free(cmd);
+		client_command_free(&cmd);
 	}
 	o_stream_uncork(output);
 	o_stream_unref(&output);
@@ -715,7 +722,7 @@
 		(void)client_handle_unfinished_cmd(cmd);
 	else {
 		/* command execution was finished */
-		client_command_free(cmd);
+		client_command_free(&cmd);
 	}
 }
 
--- a/src/imap/client.h	Thu Mar 20 15:42:57 2008 +0200
+++ b/src/imap/client.h	Thu Mar 20 16:26:27 2008 +0200
@@ -127,8 +127,8 @@
 void clients_init(void);
 void clients_deinit(void);
 
-void client_command_cancel(struct client_command_context *cmd);
-void client_command_free(struct client_command_context *cmd);
+void client_command_cancel(struct client_command_context **cmd);
+void client_command_free(struct client_command_context **cmd);
 
 bool client_handle_unfinished_cmd(struct client_command_context *cmd);
 void client_continue_pending_input(struct client **_client);
--- a/src/imap/cmd-append.c	Thu Mar 20 15:42:57 2008 +0200
+++ b/src/imap/cmd-append.c	Thu Mar 20 16:26:27 2008 +0200
@@ -51,7 +51,7 @@
 		cmd_append_finish(cmd->context);
 		/* Reset command so that client_destroy() doesn't try to call
 		   cmd_append_continue_message() anymore. */
-		client_command_free(cmd);
+		client_command_free(&cmd);
 		client_destroy(client, "Disconnected in APPEND");
 		return;
 	case -2:
@@ -69,7 +69,7 @@
 
 		client_send_command_error(cmd, "Too long argument.");
 		cmd->param_error = TRUE;
-		client_command_free(cmd);
+		client_command_free(&cmd);
 		return;
 	}
 
@@ -79,7 +79,7 @@
 	if (!finished && cmd->state != CLIENT_COMMAND_STATE_DONE)
 		(void)client_handle_unfinished_cmd(cmd);
 	else
-		client_command_free(cmd);
+		client_command_free(&cmd);
 	(void)cmd_sync_delayed(client);
 	client_continue_pending_input(&client);
 }
--- a/src/imap/cmd-idle.c	Thu Mar 20 15:42:57 2008 +0200
+++ b/src/imap/cmd-idle.c	Thu Mar 20 16:26:27 2008 +0200
@@ -54,7 +54,7 @@
 
 	o_stream_uncork(client->output);
 	if (free_cmd)
-		client_command_free(ctx->cmd);
+		client_command_free(&ctx->cmd);
 }
 
 static void idle_client_input(struct cmd_idle_context *ctx)
--- a/src/imap/cmd-search.c	Thu Mar 20 15:42:57 2008 +0200
+++ b/src/imap/cmd-search.c	Thu Mar 20 16:26:27 2008 +0200
@@ -135,7 +135,7 @@
 	if (!finished)
 		(void)client_handle_unfinished_cmd(cmd);
 	else
-		client_command_free(cmd);
+		client_command_free(&cmd);
 	(void)cmd_sync_delayed(client);
 	client_continue_pending_input(&client);
 }
--- a/src/imap/cmd-x-cancel.c	Thu Mar 20 15:42:57 2008 +0200
+++ b/src/imap/cmd-x-cancel.c	Thu Mar 20 16:26:27 2008 +0200
@@ -16,7 +16,7 @@
 	for (; cancel_cmd != NULL; cancel_cmd = cancel_cmd->next) {
 		if (cancel_cmd->tag != NULL && cancel_cmd != cmd &&
 		    strcmp(cancel_cmd->tag, tag) == 0) {
-			client_command_cancel(cancel_cmd);
+			client_command_cancel(&cancel_cmd);
 			client_send_tagline(cmd, "OK Command cancelled.");
 			return TRUE;
 		}
--- a/src/imap/imap-sync.c	Thu Mar 20 15:42:57 2008 +0200
+++ b/src/imap/imap-sync.c	Thu Mar 20 16:26:27 2008 +0200
@@ -235,7 +235,7 @@
 		    cmd != sync_cmd &&
 		    cmd->sync->counter+1 == client->sync_counter) {
 			if (cmd_finish_sync(cmd))
-				client_command_free(cmd);
+				client_command_free(&cmd);
 		}
 	}
 	return cmd_finish_sync(sync_cmd);
@@ -306,7 +306,7 @@
 		return FALSE;
 	}
 
-	client_command_free(sync_cmd);
+	client_command_free(&sync_cmd);
 	(void)cmd_sync_delayed(client);
 	return TRUE;
 }
@@ -372,7 +372,7 @@
 		if (cmd->state == CLIENT_COMMAND_STATE_WAIT_SYNC &&
 		    (cmd->sync->flags & MAILBOX_SYNC_FLAG_FAST) != 0) {
 			if (cmd_finish_sync(cmd)) {
-				client_command_free(cmd);
+				client_command_free(&cmd);
 				ret = TRUE;
 			}
 		}