-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathinit.c
133 lines (120 loc) · 2.83 KB
/
init.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
/*
* Initialize & Finalize
*
* Copyright (c) 2002 IWAMURO Motonori
* All rights reserved.
*/
#if HAVE_CONFIG_H
# include <config.h>
#endif
#include <stdio.h>
#if HAVE_STDLIB_H
# include <stdlib.h>
#endif
#include <stdarg.h>
#if HAVE_UNISTD_H
# include <unistd.h>
#endif
#if HAVE_TERMIOS_H
# include <termios.h>
#endif
#if HAVE_SYS_IOCTL_H
# include <sys/ioctl.h>
#endif
#ifdef HAVE_LIBUTIL_H
# include <libutil.h>
#endif
#ifdef HAVE_UTIL_H
# include <util.h>
#endif
#if HAVE_PTY_H
# include <pty.h>
#endif
#if defined(HAVE_STROPTS_H) && !defined(linux)
# include <fcntl.h>
# include <stropts.h>
#endif
#include "init.h"
static int initialized = 0;
static struct termios init_term;
#ifndef HAVE_CFMAKERAW
int cfmakeraw(struct termios *term_p)
{
term_p->c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
term_p->c_oflag &= ~OPOST;
term_p->c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
term_p->c_cflag &= ~(CSIZE|PARENB);
term_p->c_cflag |= CS8;
term_p->c_cc[VMIN] = 1;
term_p->c_cc[VTIME] = 0;
return 0;
}
#endif
void
init(int *mfd_p, int *sfd_p)
{
struct termios term;
struct winsize win;
#ifndef HAVE_LIBUTIL
char *slave;
extern char *ptsname();
#endif
if (!isatty(STDIN_FILENO))
fatal("Is not a tty.");
if (tcgetattr(STDIN_FILENO, &term) < 0)
fatal("tcgetattr()");
if (ioctl(STDIN_FILENO, TIOCGWINSZ, &win) < 0)
fatal("ioctl TIOCGWINSZ");
#ifdef HAVE_LIBUTIL
if (openpty(mfd_p, sfd_p, NULL, &term, &win) < 0)
fatal("openpty()");
#else
if ((*mfd_p = open("/dev/ptmx", O_RDWR|O_NOCTTY)) < 0
|| grantpt(*mfd_p) < 0
|| unlockpt(*mfd_p) < 0)
fatal("open master pts");
if ((slave = ptsname(*mfd_p)) == NULL
|| (*sfd_p = open(slave, O_RDWR)) < 0)
fatal("open slave pts");
#if defined(HAVE_STROPTS_H) && !defined(linux)
ioctl(*sfd_p, I_PUSH, "ptem");
ioctl(*sfd_p, I_PUSH, "ldterm");
#endif
#endif /* HAVE_LIBUTIL */
init_tty(*mfd_p, &term, &win);
}
void
init_tty(int mfd, struct termios *term_p, struct winsize *win_p)
{
struct termios term;
struct winsize win;
if (term_p == NULL && tcgetattr(STDIN_FILENO, term_p = &term) < 0)
fatal("tcgetattr()");
if (win_p == NULL && ioctl(STDIN_FILENO, TIOCGWINSZ, win_p = &win) < 0)
fatal("ioctl TIOCGWINSZ");
ioctl(mfd, TIOCSWINSZ, win_p); /* Ummm... Why don't set window size? */
init_term = *term_p;
cfmakeraw(term_p);
/* term_p->c_lflag &= ~ECHO; (script.c in FreeBSD) */
if (tcsetattr(STDIN_FILENO, TCSAFLUSH, term_p) < 0)
fatal("tcsetattr()");
initialized = 1;
}
void
reset_tty(void)
{
if (initialized)
tcsetattr(STDIN_FILENO, TCSAFLUSH, &init_term);
}
void
fatal(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
fputs("Error: ", stderr);
vfprintf(stderr, fmt, ap);
fputs("\nAbort.\n", stderr);
va_end(ap);
reset_tty();
exit(1);
}