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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
|
--- konsole/konsole/TEPty.cpp 22 Nov 2002 13:17:57 -0000 1.75
+++ konsole/konsole/TEPty.cpp 24 Aug 2003 21:44:00 -0000
@@ -65,6 +65,9 @@
#include <config.h>
#endif
+// Get the Q_OS_* defines
+#include <qglobal.h>
+
#ifdef __sgi
#define __svr4__
#endif
@@ -88,6 +91,10 @@
#include <sys/types.h>
#endif
+#ifdef Q_OS_FREEBSD
+#include <sys/param.h>
+#endif
+
#include <stdlib.h>
#include <stdio.h>
@@ -198,9 +205,30 @@ public:
FILE* syslog_file = NULL; //stdout;
-#define PTY_FILENO 3
+#define DEFAULT_PTY_FILENO 3
+int PTY_FILENO = -1; // None allocated yet.
+
#define BASE_CHOWN "konsole_grantpty"
+void TEPtyInit()
+{
+/*
+** FreeBSD can't dup2(fd,3) because fd 3 is already in use by
+** some weird pipe. So instead, we get a new throwaway fd
+** that's not in use by anyone.
+*/
+#ifdef Q_OS_FREEBSD
+ PTY_FILENO = open("/dev/null",O_RDWR);
+ if (PTY_FILENO == -1) {
+ perror("konsole:open PTY");
+ /* This won't work either, but hey .. */
+ PTY_FILENO = DEFAULT_PTY_FILENO;
+ }
+#else
+ PTY_FILENO = DEFAULT_PTY_FILENO;
+#endif
+}
+
int chownpty(int fd, bool grant)
// param fd: the fd of a master pty.
// param grant: true to grant, false to revoke
@@ -212,6 +240,8 @@ int chownpty(int fd, bool grant)
newsa.sa_flags = 0;
sigaction(SIGCHLD, &newsa, &oldsa);
+ if (PTY_FILENO == -1) TEPtyInit();
+
pid_t pid = fork();
if (pid < 0)
{
@@ -225,7 +255,12 @@ int chownpty(int fd, bool grant)
/* We pass the master pseudo terminal as file descriptor PTY_FILENO. */
if (fd != PTY_FILENO && dup2(fd, PTY_FILENO) < 0) exit(1);
QString path = locate("exe", BASE_CHOWN);
- execle(path.ascii(), BASE_CHOWN, grant?"--grant":"--revoke", NULL, NULL);
+ /*
+ ** Because konsole_grantpty now can't expect the fd
+ ** to be constant, we need an additional parameter.
+ */
+ QString fdnumber = QString::number(PTY_FILENO);
+ execle(path.ascii(), BASE_CHOWN, grant?"--grant":"--revoke", fdnumber.ascii(), NULL, NULL);
exit(1); // should not be reached
}
@@ -486,6 +521,16 @@ int TEPty::makePty(bool _addutmp)
// open and set all standard files to slave tty
int tt = m_SlaveFd; // Already opened?
+#ifdef Q_OS_FREEBSD
+ /*
+ ** It seems to be possible for SlaveFd to be closed in error
+ ** somewhere along the line. So check it for "liveness".
+ */
+ struct stat sb;
+ if (fstat(tt,&sb)!=0)
+ tt=-1; // Apparently not alive.
+#endif
+
if (tt < 0)
tt = open(ttynam, O_RDWR);
@@ -524,14 +569,57 @@ int TEPty::makePty(bool _addutmp)
}
strncpy(l_struct.ut_name, str_ptr, UT_NAMESIZE);
+#ifdef Q_OS_FREEBSD
+ /* FreeBSD until august 22, 2003 returned ENOMEM for too-long
+ ** hostnames. Then sanity prevailed (?) and the error was changed
+ ** to NAMETOOLONG, but this breaks konsole .. again.
+ **
+ ** Instead of bailing out with long hostnames, put in partial
+ ** hostnames (the first UT_HOSTSIZE characters) instead.
+ */
+ char hostnamebuffer[MAXHOSTNAMELEN+1];
+ memset(hostnamebuffer,0,MAXHOSTNAMELEN+1);
+ if (gethostname(hostnamebuffer, MAXHOSTNAMELEN) == -1)
+ {
+ if ( (errno==ENOMEM) || (errno==ENAMETOOLONG) ) {
+ /* ignore it, but very odd */
+ }
+ else {
+ /* Not much chance of this being visible anywhere ... */
+ perror("konsole:gethostname");
+ abort();
+ }
+ }
+ /* Copy hostname, possibly only partially */
+ memset(l_struct.ut_host,0,UT_HOSTSIZE);
+ strncpy(l_struct.ut_host,hostnamebuffer,UT_HOSTSIZE);
+ l_struct.ut_host[UT_HOSTSIZE]=0;
+#else
+ /* Non-FreeBSD systems */
if (gethostname(l_struct.ut_host, UT_HOSTSIZE) == -1) {
- if (errno != ENOMEM)
+ if (errno != ENOMEM)
abort();
l_struct.ut_host[UT_HOSTSIZE]=0;
}
+#endif
if (! (str_ptr=ttyname(tt)) ) {
+#ifdef Q_OS_FREEBSD
+ /*
+ ** In FreeBSD, the ttyname() call always returns NULL
+ ** for the kinds of devices (ptys) we have opened,
+ ** so don't abort, use a foolish default value instead.
+ ** The call to login() probably won't work _anyway_,
+ ** since normally users can't update the wtmp file.
+ **
+ ** If we were real sticklers for accuracy, we'd copy the
+ ** code from konsole_grantpty that does it's darndest to
+ ** file out the right tty name.
+ */
+ str_ptr = const_cast<char *>("/dev/konsole");
+#else
abort();
+#endif
}
if (strncmp(str_ptr, "/dev/", 5) == 0)
str_ptr += 5;
@@ -607,7 +695,7 @@ void TEPty::startPgm(const char* pgm, QV
// #define CERASE 0177
// #endif
-#if defined (__FreeBSD__) || defined (__NetBSD__) || defined (__OpenBSD__) || defined (__bsdi__) || defined(__APPLE__)
+#if defined (Q_OS_FREEBSD) || defined (__NetBSD__) || defined (__OpenBSD__) || defined (__bsdi__) || defined(__APPLE__)
ioctl(0,TIOCGETA,(char *)&ttmode);
#else
# if defined (_HPUX_SOURCE) || defined(__Lynx__)
@@ -621,7 +709,7 @@ void TEPty::startPgm(const char* pgm, QV
ttmode.c_cc[VINTR] = CTRL('C');
ttmode.c_cc[VQUIT] = CTRL('\\');
ttmode.c_cc[VERASE] = 0177;
-#if defined (__FreeBSD__) || defined (__NetBSD__) || defined (__OpenBSD__) || defined (__bsdi__) || defined(__APPLE__)
+#if defined (Q_OS_FREEBSD) || defined (__NetBSD__) || defined (__OpenBSD__) || defined (__bsdi__) || defined(__APPLE__)
ioctl(0,TIOCSETA,(char *)&ttmode);
#else
# ifdef _HPUX_SOURCE
|