1
2#include <stdio.h>
3#include <stdlib.h>
4#include <stdarg.h>
5#include <fcntl.h>
6#include <unistd.h>
7#include <string.h>
8#include <errno.h>
9#include <sys/ioctl.h>
10#include <termios.h>
11#include <signal.h>
12
13void die(const char *ptr, ...)
14{
15	va_list vlist;
16	va_start(vlist, ptr);
17	char ch;
18
19	while ((ch = *ptr++) != '\0') {
20		if (ch == '%' && *ptr != '\0') {
21			ch = *ptr++;
22			switch(ch) {
23			case 'd': printf("%d", va_arg(vlist, int)); break;
24			case 'e': printf("%e", va_arg(vlist, double)); break;
25			case 'c': printf("%c", va_arg(vlist, int)); break;
26			case 's': printf("%s", va_arg(vlist, char *)); break;
27			default: va_end(vlist);exit(1);
28
29			}
30
31		} else
32			printf("%c", ch);
33
34
35	}
36
37	va_end(vlist);
38	exit(1);
39}
40
41
42int main()
43{
44	int pid;
45	int ptm;
46	int pts;
47	char *ptr;
48	char *program_name[2] = { (char*)"/bin/uname", NULL};
49	char buf[512];
50	int n;
51
52	if ((ptm = posix_openpt(O_RDWR)) == -1) {
53		die("posix_openpt error: %s\n", strerror(errno));
54	}
55	if (grantpt(ptm) == -1) {
56		die("grantpt error: %s\n", strerror(errno));
57	}
58	if (unlockpt(ptm) == -1) {
59		die("unlockpt error: %s\n", strerror(errno));
60	}
61
62	pid = fork();
63	if (pid < 0) {
64		die("fork error: %s\n", strerror(errno));
65	} else if (pid == 0) { // child
66		if (setsid() == (pid_t)-1) {
67			die("setsid() error: %s\n", strerror(errno));
68		}
69		if ((ptr = (char *) ptsname(ptm)) == NULL) {
70			die("ptsname error: %s\n", strerror(errno));
71		}
72		if ((pts = open(ptr, O_RDWR)) < 0) {
73			die("open of slave failed: %a\n", strerror(errno));
74		}
75		close(ptm);
76
77		if (dup2(pts, STDIN_FILENO) != STDIN_FILENO
78			|| dup2(pts, STDOUT_FILENO) != STDOUT_FILENO
79			|| dup2(pts, STDERR_FILENO) != STDERR_FILENO) {
80			die("error doing dup's : %s\n", strerror(errno));
81		}
82
83		if (execve(*program_name, program_name , NULL) == -1) {
84			die("execve error: %s\n", strerror(errno));
85		}
86		exit(1);
87	} else { // parent
88		if (dup2(ptm, STDIN_FILENO) != STDIN_FILENO) {
89			die("dup2 of parent failed");
90		}
91		while (1) {
92			n = read(ptm, buf, 511);
93			if (n <= 0) {
94				break;
95			}
96			write(STDOUT_FILENO, buf, n);
97		}
98	}
99	return 0;
100}
101
102