Mercurial > dovecot > core-2.2
annotate src/util/gdbhelper.c @ 22644:2ed6735ffc7a
director: Change request callback to take mail_host parameter
This allows accessing the IP address both as struct and as string without
any conversions.
author | Timo Sirainen <timo.sirainen@dovecot.fi> |
---|---|
date | Sat, 04 Nov 2017 02:05:26 +0200 |
parents | 2e2563132d5f |
children | cb108f786fb4 |
rev | line source |
---|---|
21390
2e2563132d5f
Updated copyright notices to include the year 2017.
Stephan Bosch <stephan.bosch@dovecot.fi>
parents:
19552
diff
changeset
|
1 /* Copyright (c) 2006-2017 Dovecot authors, see the included COPYING file */ |
3864 | 2 |
3 #include "lib.h" | |
4 | |
5 #include <string.h> | |
6 #include <fcntl.h> | |
7 #include <unistd.h> | |
8 #include <time.h> | |
9 #include <sys/wait.h> | |
10 | |
11 int main(int argc, char *argv[]) | |
12 { | |
13 pid_t pid = fork(); | |
14 const char *path, *cmd; | |
3884
c3dc9cedce78
Create the gdbhelper log file only after process has died.
Timo Sirainen <tss@iki.fi>
parents:
3865
diff
changeset
|
15 int fd_in[2], fd_out[2], fd_log, status; |
3864 | 16 |
17 if (argc < 2) | |
18 i_fatal("Usage: gdbhelper <program> [<args>]"); | |
19 | |
20 switch (pid) { | |
21 case 1: | |
22 i_fatal("fork() failed: %m"); | |
23 case 0: | |
24 /* child */ | |
25 (void)execvp(argv[1], argv+1); | |
26 i_fatal("execvp(%s) failed: %m", argv[1]); | |
27 default: | |
3884
c3dc9cedce78
Create the gdbhelper log file only after process has died.
Timo Sirainen <tss@iki.fi>
parents:
3865
diff
changeset
|
28 if (pipe(fd_in) < 0 || pipe(fd_out) < 0) |
3864 | 29 i_fatal("pipe() failed: %m"); |
30 cmd = "handle SIGPIPE nostop\n" | |
31 "handle SIGALRM nostop\n" | |
4850 | 32 "handle SIG32 nostop\n" |
3864 | 33 "cont\n" |
3865
749d42902341
Use "bt full" for printing backtrace.
Timo Sirainen <tss@iki.fi>
parents:
3864
diff
changeset
|
34 "bt full\n" |
3864 | 35 "quit\n"; |
36 if (write(fd_in[1], cmd, strlen(cmd)) < 0) | |
37 i_fatal("write() failed: %m"); | |
38 | |
39 if (dup2(fd_in[0], 0) < 0 || | |
3884
c3dc9cedce78
Create the gdbhelper log file only after process has died.
Timo Sirainen <tss@iki.fi>
parents:
3865
diff
changeset
|
40 dup2(fd_out[1], 1) < 0 || |
c3dc9cedce78
Create the gdbhelper log file only after process has died.
Timo Sirainen <tss@iki.fi>
parents:
3865
diff
changeset
|
41 dup2(fd_out[1], 2) < 0) |
3864 | 42 i_fatal("dup2() failed: %m"); |
43 | |
44 cmd = t_strdup_printf("gdb %s %s", argv[1], dec2str(pid)); | |
45 if (system(cmd) < 0) | |
46 i_fatal("system() failed: %m"); | |
47 | |
48 if (wait(&status) < 0) | |
49 i_fatal("wait() failed: %m"); | |
11075
3b8542d58181
gdbhelper: Check wait() status result a bit more correctly.
Timo Sirainen <tss@iki.fi>
parents:
10582
diff
changeset
|
50 if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) { |
3884
c3dc9cedce78
Create the gdbhelper log file only after process has died.
Timo Sirainen <tss@iki.fi>
parents:
3865
diff
changeset
|
51 char buf[1024]; |
c3dc9cedce78
Create the gdbhelper log file only after process has died.
Timo Sirainen <tss@iki.fi>
parents:
3865
diff
changeset
|
52 ssize_t ret; |
c3dc9cedce78
Create the gdbhelper log file only after process has died.
Timo Sirainen <tss@iki.fi>
parents:
3865
diff
changeset
|
53 |
c3dc9cedce78
Create the gdbhelper log file only after process has died.
Timo Sirainen <tss@iki.fi>
parents:
3865
diff
changeset
|
54 path = t_strdup_printf("/tmp/gdbhelper.%s.%s", |
c3dc9cedce78
Create the gdbhelper log file only after process has died.
Timo Sirainen <tss@iki.fi>
parents:
3865
diff
changeset
|
55 dec2str(time(NULL)), |
c3dc9cedce78
Create the gdbhelper log file only after process has died.
Timo Sirainen <tss@iki.fi>
parents:
3865
diff
changeset
|
56 dec2str(pid)); |
c3dc9cedce78
Create the gdbhelper log file only after process has died.
Timo Sirainen <tss@iki.fi>
parents:
3865
diff
changeset
|
57 fd_log = open(path, O_CREAT | O_WRONLY, 0600); |
c3dc9cedce78
Create the gdbhelper log file only after process has died.
Timo Sirainen <tss@iki.fi>
parents:
3865
diff
changeset
|
58 if (fd_log < 0) |
c3dc9cedce78
Create the gdbhelper log file only after process has died.
Timo Sirainen <tss@iki.fi>
parents:
3865
diff
changeset
|
59 i_fatal("open(%s) failed: %m", path); |
c3dc9cedce78
Create the gdbhelper log file only after process has died.
Timo Sirainen <tss@iki.fi>
parents:
3865
diff
changeset
|
60 |
c3dc9cedce78
Create the gdbhelper log file only after process has died.
Timo Sirainen <tss@iki.fi>
parents:
3865
diff
changeset
|
61 while ((ret = read(fd_out[0], buf, sizeof(buf))) > 0) { |
c3dc9cedce78
Create the gdbhelper log file only after process has died.
Timo Sirainen <tss@iki.fi>
parents:
3865
diff
changeset
|
62 if (write(fd_log, buf, ret) < 0) |
c3dc9cedce78
Create the gdbhelper log file only after process has died.
Timo Sirainen <tss@iki.fi>
parents:
3865
diff
changeset
|
63 i_fatal("write(%s) failed: %m", path); |
c3dc9cedce78
Create the gdbhelper log file only after process has died.
Timo Sirainen <tss@iki.fi>
parents:
3865
diff
changeset
|
64 } |
c3dc9cedce78
Create the gdbhelper log file only after process has died.
Timo Sirainen <tss@iki.fi>
parents:
3865
diff
changeset
|
65 if (ret < 0) |
c3dc9cedce78
Create the gdbhelper log file only after process has died.
Timo Sirainen <tss@iki.fi>
parents:
3865
diff
changeset
|
66 i_fatal("read(pipe) failed: %m"); |
14691
3945a3646c67
Changed i_close_fd() API to set the fd to -1 after closing.
Timo Sirainen <tss@iki.fi>
parents:
14687
diff
changeset
|
67 i_close_fd(&fd_log); |
3864 | 68 } |
69 } | |
70 return 0; | |
71 } |