changeset 3884:c3dc9cedce78 HEAD

Create the gdbhelper log file only after process has died.
author Timo Sirainen <tss@iki.fi>
date Sun, 15 Jan 2006 02:50:43 +0200
parents 434d74a67a81
children b624b687fe13
files src/util/gdbhelper.c
diffstat 1 files changed, 22 insertions(+), 13 deletions(-) [+]
line wrap: on
line diff
--- a/src/util/gdbhelper.c	Sun Jan 15 02:11:36 2006 +0200
+++ b/src/util/gdbhelper.c	Sun Jan 15 02:50:43 2006 +0200
@@ -13,7 +13,7 @@
 {
 	pid_t pid = fork();
 	const char *path, *cmd;
-	int fd_in[2], fd_log, status;
+	int fd_in[2], fd_out[2], fd_log, status;
 
 	if (argc < 2)
 		i_fatal("Usage: gdbhelper <program> [<args>]");
@@ -26,13 +26,7 @@
 		(void)execvp(argv[1], argv+1);
 		i_fatal("execvp(%s) failed: %m", argv[1]);
 	default:
-		path = t_strdup_printf("/tmp/gdbhelper.%s.%s",
-				       dec2str(time(NULL)), dec2str(pid));
-		fd_log = open(path, O_CREAT | O_WRONLY, 0600);
-		if (fd_log < 0)
-			i_fatal("open(%s) failed: %m", path);
-
-		if (pipe(fd_in) < 0)
+		if (pipe(fd_in) < 0 || pipe(fd_out) < 0)
 			i_fatal("pipe() failed: %m");
 		cmd = "handle SIGPIPE nostop\n"
 			"handle SIGALRM nostop\n"
@@ -43,8 +37,8 @@
 			i_fatal("write() failed: %m");
 
 		if (dup2(fd_in[0], 0) < 0 ||
-		    dup2(fd_log, 1) < 0 ||
-		    dup2(fd_log, 2) < 0)
+		    dup2(fd_out[1], 1) < 0 ||
+		    dup2(fd_out[1], 2) < 0)
 			i_fatal("dup2() failed: %m");
 
 		cmd = t_strdup_printf("gdb %s %s", argv[1], dec2str(pid));
@@ -53,9 +47,24 @@
 
 		if (wait(&status) < 0)
 			i_fatal("wait() failed: %m");
-		if (status == 0) {
-			if (unlink(path) < 0 && errno != ENOENT)
-				i_error("unlink(%s) failed: %m", path);
+		if (status != 0) {
+			char buf[1024];
+			ssize_t ret;
+
+			path = t_strdup_printf("/tmp/gdbhelper.%s.%s",
+					       dec2str(time(NULL)),
+					       dec2str(pid));
+			fd_log = open(path, O_CREAT | O_WRONLY, 0600);
+			if (fd_log < 0)
+				i_fatal("open(%s) failed: %m", path);
+
+			while ((ret = read(fd_out[0], buf, sizeof(buf))) > 0) {
+				if (write(fd_log, buf, ret) < 0)
+					i_fatal("write(%s) failed: %m", path);
+			}
+			if (ret < 0)
+				i_fatal("read(pipe) failed: %m");
+			(void)close(fd_log);
 		}
 	}
 	return 0;