#include #include #include #include #include #include #include #include #include #include void die(const char *ptr, ...) { va_list vlist; va_start(vlist, ptr); char ch; while ((ch = *ptr++) != '\0') { if (ch == '%' && *ptr != '\0') { ch = *ptr++; switch(ch) { case 'd': printf("%d", va_arg(vlist, int)); break; case 'e': printf("%e", va_arg(vlist, double)); break; case 'c': printf("%c", va_arg(vlist, int)); break; case 's': printf("%s", va_arg(vlist, char *)); break; default: va_end(vlist);exit(1); } } else printf("%c", ch); } va_end(vlist); exit(1); } int main() { int pid; int ptm; int pts; char *ptr; char *program_name[2] = { (char*)"/bin/uname", NULL}; char buf[512]; int n; if ((ptm = posix_openpt(O_RDWR)) == -1) { die("posix_openpt error: %s\n", strerror(errno)); } if (grantpt(ptm) == -1) { die("grantpt error: %s\n", strerror(errno)); } if (unlockpt(ptm) == -1) { die("unlockpt error: %s\n", strerror(errno)); } pid = fork(); if (pid < 0) { die("fork error: %s\n", strerror(errno)); } else if (pid == 0) { // child if (setsid() == (pid_t)-1) { die("setsid() error: %s\n", strerror(errno)); } if ((ptr = (char *) ptsname(ptm)) == NULL) { die("ptsname error: %s\n", strerror(errno)); } if ((pts = open(ptr, O_RDWR)) < 0) { die("open of slave failed: %a\n", strerror(errno)); } close(ptm); if (dup2(pts, STDIN_FILENO) != STDIN_FILENO || dup2(pts, STDOUT_FILENO) != STDOUT_FILENO || dup2(pts, STDERR_FILENO) != STDERR_FILENO) { die("error doing dup's : %s\n", strerror(errno)); } if (execve(*program_name, program_name , NULL) == -1) { die("execve error: %s\n", strerror(errno)); } exit(1); } else { // parent if (dup2(ptm, STDIN_FILENO) != STDIN_FILENO) { die("dup2 of parent failed"); } while (1) { n = read(ptm, buf, 511); if (n <= 0) { break; } write(STDOUT_FILENO, buf, n); } } return 0; }