Last active
March 6, 2023 01:25
-
-
Save felipec/8a820f3dbf67a5861491553e211400fb to your computer and use it in GitHub Desktop.
zsh pty test
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#define _XOPEN_SOURCE 600 | |
#include <stdlib.h> | |
#include <fcntl.h> | |
#include <unistd.h> | |
#include <sys/select.h> | |
#include <sys/wait.h> | |
#include <sys/ioctl.h> | |
#include <stdio.h> | |
#include <string.h> | |
// #define SUDO | |
#ifdef SUDO | |
char *child_argv[] = { "zsh", "-c", "sudo touch /tmp/sudo", NULL }; | |
#else | |
char *child_argv[] = { "zsh", "-c", "touch /tmp/fork &", NULL }; | |
#endif | |
int main(int argc, char *argv[]) | |
{ | |
int ret, master, slave; | |
#ifdef SUDO | |
const char *pwd; | |
pwd = getenv("PASSWORD"); | |
if (!pwd) { | |
fprintf(stderr, "Missing PASSWORD env variable\n"); | |
exit(1); | |
} | |
#endif | |
if (argc >= 1) child_argv[0] = argv[1]; | |
master = posix_openpt(O_RDWR | O_NOCTTY); | |
unlockpt(master); | |
#ifdef TIOCGPTPEER | |
slave = ioctl(master, TIOCGPTPEER, O_RDWR | O_NOCTTY); | |
#else | |
slave = open(ptsname(master), O_RDWR | O_NOCTTY); | |
#endif | |
pid_t pid = fork(); | |
if (pid) { | |
fd_set rfds; | |
int status; | |
close(slave); | |
FD_ZERO(&rfds); | |
FD_SET(master, &rfds); | |
select(master + 1, &rfds, NULL, NULL, NULL); | |
if (FD_ISSET(master, &rfds)) { | |
char input[0x1000]; | |
ret = read(master, input, sizeof(input)); | |
if (ret > 0) | |
fprintf(stdout, "out: %.*s\n", ret, input); | |
} | |
#ifdef SUDO | |
write(master, pwd, strlen(pwd)); | |
write(master, "\n", 1); | |
#endif | |
waitpid(pid, &status, 0); | |
return (WEXITSTATUS(status)); | |
} else { | |
setsid(); | |
ioctl(slave, TIOCSCTTY, NULL); | |
signal(SIGHUP, SIG_IGN); | |
close(master); | |
dup2(slave, 0); | |
dup2(slave, 1); | |
dup2(slave, 2); | |
close(slave); | |
execvp(child_argv[0], child_argv); | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment