]> sourceware.org Git - newlib-cygwin.git/blame - winsup/cygwin/tty.cc
* Merge in cygwin-64bit-branch.
[newlib-cygwin.git] / winsup / cygwin / tty.cc
CommitLineData
1fd5e000
CF
1/* tty.cc
2
cc01c77f 3 Copyright 1997, 1998, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2008, 2009,
61522196 4 2010, 2011, 2012 Red Hat, Inc.
1fd5e000
CF
5
6This file is part of Cygwin.
7
8This software is a copyrighted work licensed under the terms of the
9Cygwin license. Please consult the file "CYGWIN_LICENSE" for
10details. */
11
4c8d72de 12#include "winsup.h"
ade47a34 13#include "miscfuncs.h"
1fd5e000
CF
14#include <unistd.h>
15#include <utmp.h>
f0338f54 16#include <sys/cygwin.h>
bccd5e0d 17#include "cygerrno.h"
6b91b8d5 18#include "security.h"
47063f00 19#include "path.h"
7ac61736 20#include "fhandler.h"
e2ebe117 21#include "dtable.h"
0381fec6 22#include "cygheap.h"
e2ebe117 23#include "pinfo.h"
29ac7f89 24#include "shared_info.h"
1fd5e000 25
c75b5b2d 26HANDLE NO_COPY tty_list::mutex = NULL;
1fd5e000 27
d5f3e0ba
YS
28extern "C" int
29getpt (void)
30{
31 return open ("/dev/ptmx", O_RDWR | O_NOCTTY);
32}
33
70e476d2
CV
34extern "C" int
35posix_openpt (int oflags)
36{
37 return open ("/dev/ptmx", oflags);
38}
39
c367dfd0 40extern "C" int
8db71e01 41grantpt (int fd)
1fd5e000 42{
36b63207
CF
43 cygheap_fdget cfd (fd);
44 return cfd < 0 ? -1 : 0;
1fd5e000
CF
45}
46
c367dfd0 47extern "C" int
8db71e01 48unlockpt (int fd)
1fd5e000 49{
36b63207
CF
50 cygheap_fdget cfd (fd);
51 return cfd < 0 ? -1 : 0;
1fd5e000
CF
52}
53
34a1d63d
CV
54extern "C" int
55revoke (char *ttyname)
56{
57 set_errno (ENOSYS);
58 return -1;
59}
60
c367dfd0 61extern "C" int
1fd5e000
CF
62ttyslot (void)
63{
c75b5b2d 64 if (myself->ctty <= 0 || iscons_dev (myself->ctty))
1fd5e000 65 return -1;
44d2fc0a 66 return device::minor (myself->ctty);
1fd5e000
CF
67}
68
69void __stdcall
71d59a92
CF
70tty_list::init_session ()
71{
495571e5 72 char mutex_name[MAX_PATH];
71d59a92 73 char *name = shared_name (mutex_name, "tty_list::mutex", 0);
c75b5b2d
CF
74
75 /* tty_list::mutex is used while searching for a tty slot */
71d59a92
CF
76 if (!(mutex = CreateMutex (&sec_all_nih, FALSE, name)))
77 api_fatal ("can't create tty_list::mutex '%s', %E", name);
78 ProtectHandle (mutex);
79}
80
81void __stdcall
82tty::init_session ()
1fd5e000 83{
8cb359d9 84 if (!myself->cygstarted && NOTSTATE (myself, PID_CYGPARENT))
083abe54 85 cygheap->fdtab.get_debugger_info ();
1fd5e000
CF
86}
87
1fd5e000 88int __stdcall
44d2fc0a 89tty_list::attach (int n)
1fd5e000 90{
44d2fc0a
CF
91 int res;
92 if (iscons_dev (n))
93 res = -1;
94 else if (n != -1)
95 res = connect (device::minor (n));
44d2fc0a
CF
96 else
97 res = -1;
98 return res;
1fd5e000
CF
99}
100
1fd5e000 101int
71d59a92 102tty_list::connect (int ttynum)
1fd5e000
CF
103{
104 if (ttynum < 0 || ttynum >= NTTYS)
105 {
106 termios_printf ("ttynum (%d) out of range", ttynum);
107 return -1;
108 }
109 if (!ttys[ttynum].exists ())
110 {
23771fa1 111 termios_printf ("pty %d was not allocated", ttynum);
be96a30c 112 set_errno (ENXIO);
1fd5e000
CF
113 return -1;
114 }
115
116 return ttynum;
117}
118
119void
2f9ae2ed 120tty_list::init ()
1fd5e000
CF
121{
122 for (int i = 0; i < NTTYS; i++)
123 {
124 ttys[i].init ();
38d732a1 125 ttys[i].setntty (DEV_PTYS_MAJOR, i);
1fd5e000
CF
126 }
127}
128
c75b5b2d 129/* Search for a free tty and allocate it.
1fd5e000 130 Return tty number or -1 if error.
1fd5e000
CF
131 */
132int
23771fa1 133tty_list::allocate (HANDLE& r, HANDLE& w)
1fd5e000 134{
71d59a92 135 lock_ttys here;
c75b5b2d 136 int freetty = -1;
641654f7 137
c75b5b2d 138 tty *t = NULL;
1fd5e000 139 for (int i = 0; i < NTTYS; i++)
23771fa1 140 if (ttys[i].not_allocated (r, w))
c75b5b2d
CF
141 {
142 t = ttys + i;
143 t->init ();
144 t->setsid (-1);
145 freetty = i;
146 break;
147 }
1fd5e000 148
23771fa1
CF
149 if (freetty >= 0)
150 termios_printf ("pty%d allocated", freetty);
c75b5b2d 151 else
bfa76897 152 {
23771fa1
CF
153 system_printf ("No pty allocated");
154 r = w = NULL;
bfa76897 155 }
23771fa1 156
1fd5e000
CF
157 return freetty;
158}
159
3c4f2024 160bool
23771fa1 161tty::not_allocated (HANDLE& r, HANDLE& w)
3c4f2024
CF
162{
163 /* Attempt to open the from-master side of the tty. If it is accessible
23771fa1
CF
164 then it exists although we may not have privileges to actually use it. */
165 char pipename[sizeof("ptyNNNN-from-master")];
61522196 166 __small_sprintf (pipename, "pty%d-from-master", get_minor ());
9f65451e
CF
167 /* fhandler_pipe::create returns 0 when creation succeeds */
168 return fhandler_pipe::create (&sec_none, &r, &w,
169 fhandler_pty_common::pipesize, pipename,
170 0) == 0;
23771fa1 171}
3c4f2024 172
23771fa1
CF
173bool
174tty::exists ()
175{
176 HANDLE r, w;
177 bool res;
178 if (!not_allocated (r, w))
179 res = true;
3c4f2024 180
23771fa1 181 else
3c4f2024 182 {
23771fa1
CF
183 /* Handles are left open when not_allocated finds a non-open "tty" */
184 CloseHandle (r);
185 CloseHandle (w);
186 res = false;
3c4f2024 187 }
23771fa1
CF
188 debug_printf ("exists %d", res);
189 return res;
3c4f2024
CF
190}
191
2e008fb9 192bool
cc01c77f 193tty::slave_alive ()
1fd5e000
CF
194{
195 HANDLE ev;
cc01c77f 196 if ((ev = open_inuse (READ_CONTROL)))
1fd5e000
CF
197 CloseHandle (ev);
198 return ev != NULL;
199}
200
e3778517 201HANDLE
cc01c77f 202tty::open_mutex (const char *mutex, ACCESS_MASK access)
8bdfa78a 203{
cc01c77f 204 char buf[MAX_PATH];
61522196 205 shared_name (buf, mutex, get_minor ());
cc01c77f 206 return OpenMutex (access, TRUE, buf);
e3778517 207}
8bdfa78a 208
e3778517 209HANDLE
cc01c77f 210tty::open_inuse (ACCESS_MASK access)
8bdfa78a 211{
495571e5 212 char buf[MAX_PATH];
61522196 213 shared_name (buf, TTY_SLAVE_ALIVE, get_minor ());
cc01c77f 214 return OpenEvent (access, FALSE, buf);
8bdfa78a
PH
215}
216
1fd5e000 217HANDLE
cc01c77f 218tty::create_inuse (PSECURITY_ATTRIBUTES sa)
1fd5e000
CF
219{
220 HANDLE h;
495571e5 221 char buf[MAX_PATH];
1fd5e000 222
61522196 223 shared_name (buf, TTY_SLAVE_ALIVE, get_minor ());
cc01c77f 224 h = CreateEvent (sa, TRUE, FALSE, buf);
0cd9f74f 225 termios_printf ("%s %p", buf, h);
1fd5e000 226 if (!h)
61522196 227 termios_printf ("couldn't open inuse event %s, %E", buf);
1fd5e000
CF
228 return h;
229}
230
231void
2f9ae2ed 232tty::init ()
1fd5e000 233{
b98ebf54 234 output_stopped = 0;
1fd5e000
CF
235 setsid (0);
236 pgid = 0;
c75b5b2d 237 was_opened = false;
dad3ae73 238 master_pid = 0;
c75b5b2d 239 is_console = false;
1fd5e000
CF
240}
241
242HANDLE
cc01c77f 243tty::get_event (const char *fmt, PSECURITY_ATTRIBUTES sa, BOOL manual_reset)
1fd5e000
CF
244{
245 HANDLE hev;
495571e5 246 char buf[MAX_PATH];
1fd5e000 247
61522196 248 shared_name (buf, fmt, get_minor ());
cc01c77f
CV
249 if (!sa)
250 sa = &sec_all;
251 if (!(hev = CreateEvent (sa, manual_reset, FALSE, buf)))
1fd5e000
CF
252 {
253 termios_printf ("couldn't create %s", buf);
254 set_errno (ENOENT); /* FIXME this can't be the right errno */
255 return NULL;
256 }
257
258 termios_printf ("created event %s", buf);
259 return hev;
260}
71d59a92
CF
261
262lock_ttys::lock_ttys (DWORD howlong): release_me (true)
263{
264 if (WaitForSingleObject (tty_list::mutex, howlong) == WAIT_FAILED)
265 {
266 termios_printf ("WFSO for mutex %p failed, %E", tty_list::mutex);
267 release_me = false;
268 }
269}
270
271void
272lock_ttys::release ()
273{
274 ReleaseMutex (tty_list::mutex);
275}
44d2fc0a
CF
276
277const char *
278tty_min::ttyname ()
279{
280 device d;
281 d.parse (ntty);
282 return d.name;
283}
This page took 0.483097 seconds and 5 git commands to generate.