diff options
Diffstat (limited to 'attach.c')
| -rw-r--r-- | attach.c | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/attach.c b/attach.c new file mode 100644 index 0000000..e318b89 --- /dev/null +++ b/attach.c @@ -0,0 +1,75 @@ +#define _GNU_SOURCE +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <fcntl.h> +#include <sys/ioctl.h> +#include <sys/wait.h> + +int main(int argc, char *argv[]) { + int fd; + const char *tty_path; + const char *tty_path_env; + pid_t pid; + + fprintf(stderr, "%i\n", argc); + tty_path_env = getenv("TAKETTY_PTY"); + if (argc <= 1 || (!strcmp(argv[1], "-") && !tty_path_env)) { + fprintf(stderr, "Usage: %s (PATH|-)\n", argv[0]); + fprintf(stderr, "Or set TAKETTY_PTY environment variable\n"); + exit(1); + } + + tty_path = argv[1]; + if (!strcmp(argv[1], "-")) { + tty_path = tty_path_env; + } + + pid = fork(); + if (pid < 0) { + perror("fork"); + exit(1); + } + + if (pid > 0) { + int status; + waitpid(pid, &status, 0); + exit(WIFEXITED(status) ? WEXITSTATUS(status) : 1); + } + + if (setsid() < 0) { + perror("setsid"); + exit(1); + } + + fd = open(tty_path, O_RDWR); + if (fd < 0) { + perror("open tty"); + exit(1); + } + + if (ioctl(fd, TIOCSCTTY, 0) < 0) { + perror("ioctl TIOCSCTTY"); + exit(1); + } + + if (dup2(fd, STDIN_FILENO) < 0 || + dup2(fd, STDOUT_FILENO) < 0 || + dup2(fd, STDERR_FILENO) < 0) { + perror("dup2"); + exit(1); + } + + if (fd > STDERR_FILENO) { + close(fd); + } + + if (argc > 2) { + execvp(argv[2], &argv[2]); + perror("execvp"); + exit(1); + } + + return 0; +} |
