bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2006-2018 Dovecot authors, see the included COPYING file */
85f0f2bc9aab01b74835d12ee0a12a2b38349938Timo Sirainen
85f0f2bc9aab01b74835d12ee0a12a2b38349938Timo Sirainen#include "lib.h"
85f0f2bc9aab01b74835d12ee0a12a2b38349938Timo Sirainen
85f0f2bc9aab01b74835d12ee0a12a2b38349938Timo Sirainen#include <string.h>
85f0f2bc9aab01b74835d12ee0a12a2b38349938Timo Sirainen#include <fcntl.h>
85f0f2bc9aab01b74835d12ee0a12a2b38349938Timo Sirainen#include <unistd.h>
85f0f2bc9aab01b74835d12ee0a12a2b38349938Timo Sirainen#include <time.h>
85f0f2bc9aab01b74835d12ee0a12a2b38349938Timo Sirainen#include <sys/wait.h>
85f0f2bc9aab01b74835d12ee0a12a2b38349938Timo Sirainen
85f0f2bc9aab01b74835d12ee0a12a2b38349938Timo Sirainenint main(int argc, char *argv[])
85f0f2bc9aab01b74835d12ee0a12a2b38349938Timo Sirainen{
85f0f2bc9aab01b74835d12ee0a12a2b38349938Timo Sirainen pid_t pid = fork();
85f0f2bc9aab01b74835d12ee0a12a2b38349938Timo Sirainen const char *path, *cmd;
2a97481b6131ef21baf95c17f2d729515574b9b9Timo Sirainen int fd_in[2], fd_out[2], fd_log, status;
85f0f2bc9aab01b74835d12ee0a12a2b38349938Timo Sirainen
85f0f2bc9aab01b74835d12ee0a12a2b38349938Timo Sirainen if (argc < 2)
85f0f2bc9aab01b74835d12ee0a12a2b38349938Timo Sirainen i_fatal("Usage: gdbhelper <program> [<args>]");
85f0f2bc9aab01b74835d12ee0a12a2b38349938Timo Sirainen
85f0f2bc9aab01b74835d12ee0a12a2b38349938Timo Sirainen switch (pid) {
85f0f2bc9aab01b74835d12ee0a12a2b38349938Timo Sirainen case 1:
85f0f2bc9aab01b74835d12ee0a12a2b38349938Timo Sirainen i_fatal("fork() failed: %m");
85f0f2bc9aab01b74835d12ee0a12a2b38349938Timo Sirainen case 0:
85f0f2bc9aab01b74835d12ee0a12a2b38349938Timo Sirainen /* child */
85f0f2bc9aab01b74835d12ee0a12a2b38349938Timo Sirainen (void)execvp(argv[1], argv+1);
85f0f2bc9aab01b74835d12ee0a12a2b38349938Timo Sirainen i_fatal("execvp(%s) failed: %m", argv[1]);
85f0f2bc9aab01b74835d12ee0a12a2b38349938Timo Sirainen default:
2a97481b6131ef21baf95c17f2d729515574b9b9Timo Sirainen if (pipe(fd_in) < 0 || pipe(fd_out) < 0)
85f0f2bc9aab01b74835d12ee0a12a2b38349938Timo Sirainen i_fatal("pipe() failed: %m");
85f0f2bc9aab01b74835d12ee0a12a2b38349938Timo Sirainen cmd = "handle SIGPIPE nostop\n"
85f0f2bc9aab01b74835d12ee0a12a2b38349938Timo Sirainen "handle SIGALRM nostop\n"
3356d08585f283681b473dd6cc6cbfddd716ffd7Timo Sirainen "handle SIG32 nostop\n"
85f0f2bc9aab01b74835d12ee0a12a2b38349938Timo Sirainen "cont\n"
3c72cd5812078a437fdf87d4a49de427950d547dTimo Sirainen "bt full\n"
85f0f2bc9aab01b74835d12ee0a12a2b38349938Timo Sirainen "quit\n";
85f0f2bc9aab01b74835d12ee0a12a2b38349938Timo Sirainen if (write(fd_in[1], cmd, strlen(cmd)) < 0)
85f0f2bc9aab01b74835d12ee0a12a2b38349938Timo Sirainen i_fatal("write() failed: %m");
85f0f2bc9aab01b74835d12ee0a12a2b38349938Timo Sirainen
85f0f2bc9aab01b74835d12ee0a12a2b38349938Timo Sirainen if (dup2(fd_in[0], 0) < 0 ||
2a97481b6131ef21baf95c17f2d729515574b9b9Timo Sirainen dup2(fd_out[1], 1) < 0 ||
2a97481b6131ef21baf95c17f2d729515574b9b9Timo Sirainen dup2(fd_out[1], 2) < 0)
85f0f2bc9aab01b74835d12ee0a12a2b38349938Timo Sirainen i_fatal("dup2() failed: %m");
85f0f2bc9aab01b74835d12ee0a12a2b38349938Timo Sirainen
85f0f2bc9aab01b74835d12ee0a12a2b38349938Timo Sirainen cmd = t_strdup_printf("gdb %s %s", argv[1], dec2str(pid));
85f0f2bc9aab01b74835d12ee0a12a2b38349938Timo Sirainen if (system(cmd) < 0)
85f0f2bc9aab01b74835d12ee0a12a2b38349938Timo Sirainen i_fatal("system() failed: %m");
85f0f2bc9aab01b74835d12ee0a12a2b38349938Timo Sirainen
85f0f2bc9aab01b74835d12ee0a12a2b38349938Timo Sirainen if (wait(&status) < 0)
85f0f2bc9aab01b74835d12ee0a12a2b38349938Timo Sirainen i_fatal("wait() failed: %m");
f57e8837e1675791f9e4a6e270004ac613b9d506Timo Sirainen if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
2a97481b6131ef21baf95c17f2d729515574b9b9Timo Sirainen char buf[1024];
2a97481b6131ef21baf95c17f2d729515574b9b9Timo Sirainen ssize_t ret;
2a97481b6131ef21baf95c17f2d729515574b9b9Timo Sirainen
2a97481b6131ef21baf95c17f2d729515574b9b9Timo Sirainen path = t_strdup_printf("/tmp/gdbhelper.%s.%s",
2a97481b6131ef21baf95c17f2d729515574b9b9Timo Sirainen dec2str(time(NULL)),
2a97481b6131ef21baf95c17f2d729515574b9b9Timo Sirainen dec2str(pid));
2a97481b6131ef21baf95c17f2d729515574b9b9Timo Sirainen fd_log = open(path, O_CREAT | O_WRONLY, 0600);
2a97481b6131ef21baf95c17f2d729515574b9b9Timo Sirainen if (fd_log < 0)
2a97481b6131ef21baf95c17f2d729515574b9b9Timo Sirainen i_fatal("open(%s) failed: %m", path);
2a97481b6131ef21baf95c17f2d729515574b9b9Timo Sirainen
2a97481b6131ef21baf95c17f2d729515574b9b9Timo Sirainen while ((ret = read(fd_out[0], buf, sizeof(buf))) > 0) {
2a97481b6131ef21baf95c17f2d729515574b9b9Timo Sirainen if (write(fd_log, buf, ret) < 0)
2a97481b6131ef21baf95c17f2d729515574b9b9Timo Sirainen i_fatal("write(%s) failed: %m", path);
2a97481b6131ef21baf95c17f2d729515574b9b9Timo Sirainen }
2a97481b6131ef21baf95c17f2d729515574b9b9Timo Sirainen if (ret < 0)
2a97481b6131ef21baf95c17f2d729515574b9b9Timo Sirainen i_fatal("read(pipe) failed: %m");
4307c886579381dbb1897ea1388ae6978c96f560Timo Sirainen i_close_fd(&fd_log);
85f0f2bc9aab01b74835d12ee0a12a2b38349938Timo Sirainen }
85f0f2bc9aab01b74835d12ee0a12a2b38349938Timo Sirainen }
85f0f2bc9aab01b74835d12ee0a12a2b38349938Timo Sirainen return 0;
85f0f2bc9aab01b74835d12ee0a12a2b38349938Timo Sirainen}