Deleted Added
full compact
tty.c (46686) tty.c (47061)
1/*-
2 * Copyright (c) 1999 Brian Somers <brian@Awfulhak.org>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 9 unchanged lines hidden (view full) ---

18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
1/*-
2 * Copyright (c) 1999 Brian Somers <brian@Awfulhak.org>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 9 unchanged lines hidden (view full) ---

18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
26 * $Id:$
26 * $Id: tty.c,v 1.1 1999/05/08 11:07:50 brian Exp $
27 */
28
29#include <sys/param.h>
30#include <sys/socket.h>
31#include <netinet/in.h>
32#include <arpa/inet.h>
33#include <netdb.h>
34#include <netinet/in_systm.h>

--- 8 unchanged lines hidden (view full) ---

43
44#include <errno.h>
45#include <fcntl.h>
46#include <paths.h>
47#include <stdio.h>
48#include <stdlib.h>
49#include <string.h>
50#include <sys/wait.h>
27 */
28
29#include <sys/param.h>
30#include <sys/socket.h>
31#include <netinet/in.h>
32#include <arpa/inet.h>
33#include <netdb.h>
34#include <netinet/in_systm.h>

--- 8 unchanged lines hidden (view full) ---

43
44#include <errno.h>
45#include <fcntl.h>
46#include <paths.h>
47#include <stdio.h>
48#include <stdlib.h>
49#include <string.h>
50#include <sys/wait.h>
51#include <sys/uio.h>
51#include <termios.h>
52#include <unistd.h>
53
54#include "layer.h"
55#include "defs.h"
56#include "mbuf.h"
57#include "log.h"
58#include "id.h"

--- 22 unchanged lines hidden (view full) ---

81#include "bundle.h"
82#include "prompt.h"
83#include "auth.h"
84#include "chap.h"
85#include "cbcp.h"
86#include "datalink.h"
87#include "tty.h"
88
52#include <termios.h>
53#include <unistd.h>
54
55#include "layer.h"
56#include "defs.h"
57#include "mbuf.h"
58#include "log.h"
59#include "id.h"

--- 22 unchanged lines hidden (view full) ---

82#include "bundle.h"
83#include "prompt.h"
84#include "auth.h"
85#include "chap.h"
86#include "cbcp.h"
87#include "datalink.h"
88#include "tty.h"
89
89#define Online(p) ((p)->mbits & TIOCM_CD)
90#define Online(dev) ((dev)->mbits & TIOCM_CD)
90
91
92struct ttydevice {
93 struct device dev; /* What struct physical knows about */
94 struct pppTimer Timer; /* CD checks */
95 int mbits; /* Current DCD status */
96 struct termios ios; /* To be able to reset from raw mode */
97};
98
99#define device2tty(d) ((d)->type == TTY_DEVICE ? (struct ttydevice *)d : NULL)
100
91static int
92tty_Lock(struct physical *p, int tunno)
93{
94 int res;
95 FILE *lockfile;
96 char fn[MAXPATHLEN];
97
98 if (*p->name.full != '/')

--- 43 unchanged lines hidden (view full) ---

142
143 if (p->type != PHYS_DIRECT && ID0uu_unlock(p->name.base) == -1)
144 log_Printf(LogALERT, "%s: Can't uu_unlock %s\n", p->link.name, fn);
145}
146
147static void
148tty_SetupDevice(struct physical *p)
149{
101static int
102tty_Lock(struct physical *p, int tunno)
103{
104 int res;
105 FILE *lockfile;
106 char fn[MAXPATHLEN];
107
108 if (*p->name.full != '/')

--- 43 unchanged lines hidden (view full) ---

152
153 if (p->type != PHYS_DIRECT && ID0uu_unlock(p->name.base) == -1)
154 log_Printf(LogALERT, "%s: Can't uu_unlock %s\n", p->link.name, fn);
155}
156
157static void
158tty_SetupDevice(struct physical *p)
159{
160 struct ttydevice *dev = device2tty(p->handler);
150 struct termios rstio;
151 int oldflag;
152
153 tcgetattr(p->fd, &rstio);
161 struct termios rstio;
162 int oldflag;
163
164 tcgetattr(p->fd, &rstio);
154 p->ios = rstio;
165 dev->ios = rstio;
155
156 log_Printf(LogDEBUG, "%s: tty_SetupDevice: physical (get): fd = %d,"
157 " iflag = %lx, oflag = %lx, cflag = %lx\n", p->link.name, p->fd,
158 (u_long)rstio.c_iflag, (u_long)rstio.c_oflag,
159 (u_long)rstio.c_cflag);
160
161 cfmakeraw(&rstio);
162 if (p->cfg.rts_cts)

--- 14 unchanged lines hidden (view full) ---

177 log_Printf(LogWARN, "%s: %s: Unable to set speed to %d\n",
178 p->link.name, p->name.full, p->cfg.speed);
179 }
180 tcsetattr(p->fd, TCSADRAIN, &rstio);
181 log_Printf(LogDEBUG, "%s: physical (put): iflag = %lx, oflag = %lx, "
182 "cflag = %lx\n", p->link.name, (u_long)rstio.c_iflag,
183 (u_long)rstio.c_oflag, (u_long)rstio.c_cflag);
184
166
167 log_Printf(LogDEBUG, "%s: tty_SetupDevice: physical (get): fd = %d,"
168 " iflag = %lx, oflag = %lx, cflag = %lx\n", p->link.name, p->fd,
169 (u_long)rstio.c_iflag, (u_long)rstio.c_oflag,
170 (u_long)rstio.c_cflag);
171
172 cfmakeraw(&rstio);
173 if (p->cfg.rts_cts)

--- 14 unchanged lines hidden (view full) ---

188 log_Printf(LogWARN, "%s: %s: Unable to set speed to %d\n",
189 p->link.name, p->name.full, p->cfg.speed);
190 }
191 tcsetattr(p->fd, TCSADRAIN, &rstio);
192 log_Printf(LogDEBUG, "%s: physical (put): iflag = %lx, oflag = %lx, "
193 "cflag = %lx\n", p->link.name, (u_long)rstio.c_iflag,
194 (u_long)rstio.c_oflag, (u_long)rstio.c_cflag);
195
185 if (ioctl(p->fd, TIOCMGET, &p->mbits) == -1) {
196 if (ioctl(p->fd, TIOCMGET, &dev->mbits) == -1) {
186 if (p->type != PHYS_DIRECT) {
187 log_Printf(LogWARN, "%s: Open: Cannot get physical status: %s\n",
188 p->link.name, strerror(errno));
189 physical_Close(p);
190 return;
191 } else
197 if (p->type != PHYS_DIRECT) {
198 log_Printf(LogWARN, "%s: Open: Cannot get physical status: %s\n",
199 p->link.name, strerror(errno));
200 physical_Close(p);
201 return;
202 } else
192 p->mbits = TIOCM_CD;
203 dev->mbits = TIOCM_CD;
193 }
194 log_Printf(LogDEBUG, "%s: Open: physical control = %o\n",
204 }
205 log_Printf(LogDEBUG, "%s: Open: physical control = %o\n",
195 p->link.name, p->mbits);
206 p->link.name, dev->mbits);
196
197 oldflag = fcntl(p->fd, F_GETFL, 0);
198 if (oldflag < 0) {
199 log_Printf(LogWARN, "%s: Open: Cannot get physical flags: %s\n",
200 p->link.name, strerror(errno));
201 physical_Close(p);
202 return;
203 } else
204 fcntl(p->fd, F_SETFL, oldflag & ~O_NONBLOCK);
205
207
208 oldflag = fcntl(p->fd, F_GETFL, 0);
209 if (oldflag < 0) {
210 log_Printf(LogWARN, "%s: Open: Cannot get physical flags: %s\n",
211 p->link.name, strerror(errno));
212 physical_Close(p);
213 return;
214 } else
215 fcntl(p->fd, F_SETFL, oldflag & ~O_NONBLOCK);
216
206 physical_SetupStack(p, 0);
217 physical_SetupStack(p, PHYSICAL_NOFORCE);
207}
208
218}
219
209static int
210tty_Open(struct physical *p)
211{
212 if (*p->name.full == '/') {
213 p->mbits = 0;
214 if (tty_Lock(p, p->dl->bundle->unit) != -1) {
215 p->fd = ID0open(p->name.full, O_RDWR | O_NONBLOCK);
216 if (p->fd < 0) {
217 log_Printf(LogPHASE, "%s: Open(\"%s\"): %s\n",
218 p->link.name, p->name.full, strerror(errno));
219 tty_Unlock(p);
220 } else if (!isatty(p->fd)) {
221 log_Printf(LogPHASE, "%s: Open(\"%s\"): Not a tty\n",
222 p->link.name, p->name.full);
223 close(p->fd);
224 p->fd = -1;
225 tty_Unlock(p);
226 } else {
227 log_Printf(LogDEBUG, "%s: Opened %s\n", p->link.name, p->name.full);
228 tty_SetupDevice(p);
229 }
230 }
231 }
232
233 return p->fd >= 0;
234}
235
236int
237tty_OpenStdin(struct physical *p)
238{
239 if (isatty(STDIN_FILENO)) {
240 p->mbits = 0;
241 log_Printf(LogDEBUG, "%s: tty_Open: stdin is a tty\n", p->link.name);
242 physical_SetDevice(p, ttyname(STDIN_FILENO));
243 if (tty_Lock(p, p->dl->bundle->unit) == -1)
244 close(STDIN_FILENO);
245 else {
246 p->fd = STDIN_FILENO;
247 tty_SetupDevice(p);
248 }
249 }
250
251 return p->fd >= 0;
252}
253
254/*
255 * tty_Timeout() watches the DCD signal and mentions it if it's status
256 * changes.
257 */
258static void
259tty_Timeout(void *data)
260{
261 struct physical *p = data;
220/*
221 * tty_Timeout() watches the DCD signal and mentions it if it's status
222 * changes.
223 */
224static void
225tty_Timeout(void *data)
226{
227 struct physical *p = data;
228 struct ttydevice *dev = device2tty(p->handler);
262 int ombits, change;
263
229 int ombits, change;
230
264 timer_Stop(&p->Timer);
265 p->Timer.load = SECTICKS; /* Once a second please */
266 timer_Start(&p->Timer);
267 ombits = p->mbits;
231 timer_Stop(&dev->Timer);
232 dev->Timer.load = SECTICKS; /* Once a second please */
233 timer_Start(&dev->Timer);
234 ombits = dev->mbits;
268
269 if (p->fd >= 0) {
235
236 if (p->fd >= 0) {
270 if (ioctl(p->fd, TIOCMGET, &p->mbits) < 0) {
237 if (ioctl(p->fd, TIOCMGET, &dev->mbits) < 0) {
271 log_Printf(LogPHASE, "%s: ioctl error (%s)!\n", p->link.name,
272 strerror(errno));
273 datalink_Down(p->dl, CLOSE_NORMAL);
238 log_Printf(LogPHASE, "%s: ioctl error (%s)!\n", p->link.name,
239 strerror(errno));
240 datalink_Down(p->dl, CLOSE_NORMAL);
274 timer_Stop(&p->Timer);
241 timer_Stop(&dev->Timer);
275 return;
276 }
277 } else
242 return;
243 }
244 } else
278 p->mbits = 0;
245 dev->mbits = 0;
279
280 if (ombits == -1) {
281 /* First time looking for carrier */
246
247 if (ombits == -1) {
248 /* First time looking for carrier */
282 if (Online(p))
249 if (Online(dev))
283 log_Printf(LogDEBUG, "%s: %s: CD detected\n", p->link.name, p->name.full);
284 else if (p->cfg.cd.required) {
285 log_Printf(LogPHASE, "%s: %s: Required CD not detected\n",
286 p->link.name, p->name.full);
287 datalink_Down(p->dl, CLOSE_NORMAL);
288 } else {
289 log_Printf(LogPHASE, "%s: %s doesn't support CD\n",
290 p->link.name, p->name.full);
250 log_Printf(LogDEBUG, "%s: %s: CD detected\n", p->link.name, p->name.full);
251 else if (p->cfg.cd.required) {
252 log_Printf(LogPHASE, "%s: %s: Required CD not detected\n",
253 p->link.name, p->name.full);
254 datalink_Down(p->dl, CLOSE_NORMAL);
255 } else {
256 log_Printf(LogPHASE, "%s: %s doesn't support CD\n",
257 p->link.name, p->name.full);
291 timer_Stop(&p->Timer);
292 p->mbits = TIOCM_CD;
258 timer_Stop(&dev->Timer);
259 dev->mbits = TIOCM_CD;
293 }
294 } else {
260 }
261 } else {
295 change = ombits ^ p->mbits;
262 change = ombits ^ dev->mbits;
296 if (change & TIOCM_CD) {
263 if (change & TIOCM_CD) {
297 if (p->mbits & TIOCM_CD)
264 if (dev->mbits & TIOCM_CD)
298 log_Printf(LogDEBUG, "%s: offline -> online\n", p->link.name);
299 else {
300 log_Printf(LogDEBUG, "%s: online -> offline\n", p->link.name);
301 log_Printf(LogPHASE, "%s: Carrier lost\n", p->link.name);
302 datalink_Down(p->dl, CLOSE_NORMAL);
265 log_Printf(LogDEBUG, "%s: offline -> online\n", p->link.name);
266 else {
267 log_Printf(LogDEBUG, "%s: online -> offline\n", p->link.name);
268 log_Printf(LogPHASE, "%s: Carrier lost\n", p->link.name);
269 datalink_Down(p->dl, CLOSE_NORMAL);
303 timer_Stop(&p->Timer);
270 timer_Stop(&dev->Timer);
304 }
305 } else
306 log_Printf(LogDEBUG, "%s: Still %sline\n", p->link.name,
271 }
272 } else
273 log_Printf(LogDEBUG, "%s: Still %sline\n", p->link.name,
307 Online(p) ? "on" : "off");
274 Online(dev) ? "on" : "off");
308 }
309}
310
311static void
312tty_StartTimer(struct physical *p)
313{
275 }
276}
277
278static void
279tty_StartTimer(struct physical *p)
280{
314 timer_Stop(&p->Timer);
315 p->Timer.load = SECTICKS * p->cfg.cd.delay;
316 p->Timer.func = tty_Timeout;
317 p->Timer.name = "tty CD";
318 p->Timer.arg = p;
281 struct ttydevice *dev = device2tty(p->handler);
282
283 timer_Stop(&dev->Timer);
284 dev->Timer.load = SECTICKS * p->cfg.cd.delay;
285 dev->Timer.func = tty_Timeout;
286 dev->Timer.name = "tty CD";
287 dev->Timer.arg = p;
319 log_Printf(LogDEBUG, "%s: Using tty_Timeout [%p]\n",
320 p->link.name, tty_Timeout);
288 log_Printf(LogDEBUG, "%s: Using tty_Timeout [%p]\n",
289 p->link.name, tty_Timeout);
321 p->mbits = -1; /* So we know it's the first time */
322 timer_Start(&p->Timer);
290 dev->mbits = -1; /* So we know it's the first time */
291 timer_Start(&dev->Timer);
323}
324
325static int
326tty_Raw(struct physical *p)
327{
292}
293
294static int
295tty_Raw(struct physical *p)
296{
297 struct ttydevice *dev = device2tty(p->handler);
328 struct termios rstio;
329 int oldflag;
330
331 if (physical_IsSync(p))
332 return 1;
333
334 log_Printf(LogDEBUG, "%s: Entering physical_Raw\n", p->link.name);
335
298 struct termios rstio;
299 int oldflag;
300
301 if (physical_IsSync(p))
302 return 1;
303
304 log_Printf(LogDEBUG, "%s: Entering physical_Raw\n", p->link.name);
305
336 if (p->type != PHYS_DIRECT && p->fd >= 0 && !Online(p))
306 if (p->type != PHYS_DIRECT && p->fd >= 0 && !Online(dev))
337 log_Printf(LogDEBUG, "%s: Raw: descriptor = %d, mbits = %x\n",
307 log_Printf(LogDEBUG, "%s: Raw: descriptor = %d, mbits = %x\n",
338 p->link.name, p->fd, p->mbits);
308 p->link.name, p->fd, dev->mbits);
339
340 tcgetattr(p->fd, &rstio);
341 cfmakeraw(&rstio);
342 if (p->cfg.rts_cts)
343 rstio.c_cflag |= CLOCAL | CCTS_OFLOW | CRTS_IFLOW;
344 else
345 rstio.c_cflag |= CLOCAL;
346
347 if (p->type != PHYS_DEDICATED)
348 rstio.c_cflag |= HUPCL;
349
350 tcsetattr(p->fd, TCSANOW, &rstio);
351
352 oldflag = fcntl(p->fd, F_GETFL, 0);
353 if (oldflag < 0)
354 return 0;
355 fcntl(p->fd, F_SETFL, oldflag | O_NONBLOCK);
356
309
310 tcgetattr(p->fd, &rstio);
311 cfmakeraw(&rstio);
312 if (p->cfg.rts_cts)
313 rstio.c_cflag |= CLOCAL | CCTS_OFLOW | CRTS_IFLOW;
314 else
315 rstio.c_cflag |= CLOCAL;
316
317 if (p->type != PHYS_DEDICATED)
318 rstio.c_cflag |= HUPCL;
319
320 tcsetattr(p->fd, TCSANOW, &rstio);
321
322 oldflag = fcntl(p->fd, F_GETFL, 0);
323 if (oldflag < 0)
324 return 0;
325 fcntl(p->fd, F_SETFL, oldflag | O_NONBLOCK);
326
357 if (ioctl(p->fd, TIOCMGET, &p->mbits) == 0)
327 if (ioctl(p->fd, TIOCMGET, &dev->mbits) == 0)
358 tty_StartTimer(p);
359
360 return 1;
361}
362
363static void
364tty_Offline(struct physical *p)
365{
328 tty_StartTimer(p);
329
330 return 1;
331}
332
333static void
334tty_Offline(struct physical *p)
335{
336 struct ttydevice *dev = device2tty(p->handler);
337
366 if (p->fd >= 0) {
338 if (p->fd >= 0) {
367 timer_Stop(&p->Timer);
368 p->mbits &= ~TIOCM_DTR;
369 if (Online(p)) {
339 timer_Stop(&dev->Timer);
340 dev->mbits &= ~TIOCM_DTR;
341 if (Online(dev)) {
370 struct termios tio;
371
372 tcgetattr(p->fd, &tio);
373 if (cfsetspeed(&tio, B0) == -1)
374 log_Printf(LogWARN, "%s: Unable to set physical to speed 0\n",
375 p->link.name);
376 else
377 tcsetattr(p->fd, TCSANOW, &tio);
378 }
379 }
380}
381
382static void
383tty_Cooked(struct physical *p)
384{
342 struct termios tio;
343
344 tcgetattr(p->fd, &tio);
345 if (cfsetspeed(&tio, B0) == -1)
346 log_Printf(LogWARN, "%s: Unable to set physical to speed 0\n",
347 p->link.name);
348 else
349 tcsetattr(p->fd, TCSANOW, &tio);
350 }
351 }
352}
353
354static void
355tty_Cooked(struct physical *p)
356{
357 struct ttydevice *dev = device2tty(p->handler);
385 int oldflag;
386
387 tcflush(p->fd, TCIOFLUSH);
388 if (!physical_IsSync(p)) {
358 int oldflag;
359
360 tcflush(p->fd, TCIOFLUSH);
361 if (!physical_IsSync(p)) {
389 tcsetattr(p->fd, TCSAFLUSH, &p->ios);
362 tcsetattr(p->fd, TCSAFLUSH, &dev->ios);
390 oldflag = fcntl(p->fd, F_GETFL, 0);
391 if (oldflag == 0)
392 fcntl(p->fd, F_SETFL, oldflag & ~O_NONBLOCK);
393 }
394}
395
396static void
363 oldflag = fcntl(p->fd, F_GETFL, 0);
364 if (oldflag == 0)
365 fcntl(p->fd, F_SETFL, oldflag & ~O_NONBLOCK);
366 }
367}
368
369static void
397tty_Close(struct physical *p)
370tty_StopTimer(struct physical *p)
398{
371{
399 tty_Unlock(p);
372 struct ttydevice *dev = device2tty(p->handler);
373
374 timer_Stop(&dev->Timer);
400}
401
402static void
375}
376
377static void
403tty_Restored(struct physical *p)
378tty_Free(struct physical *p)
404{
379{
405 if (p->Timer.state != TIMER_STOPPED) {
406 p->Timer.state = TIMER_STOPPED; /* Special - see physical2iov() */
407 tty_StartTimer(p);
408 }
380 struct ttydevice *dev = device2tty(p->handler);
381
382 tty_Unlock(p);
383 free(dev);
409}
410
411static int
412tty_Speed(struct physical *p)
413{
414 struct termios rstio;
415
416 if (tcgetattr(p->fd, &rstio) == -1)
417 return 0;
418
419 return SpeedToInt(cfgetispeed(&rstio));
420}
421
422static const char *
423tty_OpenInfo(struct physical *p)
424{
384}
385
386static int
387tty_Speed(struct physical *p)
388{
389 struct termios rstio;
390
391 if (tcgetattr(p->fd, &rstio) == -1)
392 return 0;
393
394 return SpeedToInt(cfgetispeed(&rstio));
395}
396
397static const char *
398tty_OpenInfo(struct physical *p)
399{
400 struct ttydevice *dev = device2tty(p->handler);
425 static char buf[13];
426
401 static char buf[13];
402
427 if (Online(p))
403 if (Online(dev))
428 strcpy(buf, "with");
429 else
430 strcpy(buf, "no");
431 strcat(buf, " carrier");
432 return buf;
433}
434
404 strcpy(buf, "with");
405 else
406 strcpy(buf, "no");
407 strcat(buf, " carrier");
408 return buf;
409}
410
435const struct device ttydevice = {
411static void
412tty_device2iov(struct physical *p, struct iovec *iov, int *niov,
413 int maxiov, pid_t newpid)
414{
415 struct ttydevice *dev = p ? device2tty(p->handler) : NULL;
416
417 iov[*niov].iov_base = p ? p->handler : malloc(sizeof(struct ttydevice));
418 iov[*niov].iov_len = sizeof(struct ttydevice);
419 (*niov)++;
420
421 if (dev->Timer.state != TIMER_STOPPED) {
422 timer_Stop(&dev->Timer);
423 dev->Timer.state = TIMER_RUNNING;
424 }
425}
426
427static struct device basettydevice = {
436 TTY_DEVICE,
437 "tty",
428 TTY_DEVICE,
429 "tty",
438 tty_Open,
439 tty_Raw,
440 tty_Offline,
441 tty_Cooked,
430 tty_Raw,
431 tty_Offline,
432 tty_Cooked,
442 tty_Close,
443 tty_Restored,
433 tty_StopTimer,
434 tty_Free,
435 NULL,
436 NULL,
437 tty_device2iov,
444 tty_Speed,
445 tty_OpenInfo
446};
438 tty_Speed,
439 tty_OpenInfo
440};
441
442struct device *
443tty_iov2device(int type, struct physical *p, struct iovec *iov, int *niov,
444 int maxiov)
445{
446 if (type == TTY_DEVICE) {
447 struct ttydevice *dev;
448
449 /* It's one of ours ! Let's create the device */
450
451 dev = (struct ttydevice *)iov[(*niov)++].iov_base;
452 /* Refresh function pointers etc */
453 memcpy(&dev->dev, &basettydevice, sizeof dev->dev);
454
455 physical_SetupStack(p, PHYSICAL_NOFORCE);
456 if (dev->Timer.state != TIMER_STOPPED) {
457 dev->Timer.state = TIMER_STOPPED;
458 tty_StartTimer(p);
459 }
460 return &dev->dev;
461 }
462
463 return NULL;
464}
465
466struct device *
467tty_Create(struct physical *p)
468{
469 if (p->fd >= 0 && isatty(p->fd)) {
470 if (*p->name.full == '\0') {
471 log_Printf(LogDEBUG, "%s: Input is a tty\n", p->link.name);
472 physical_SetDevice(p, ttyname(p->fd));
473 if (tty_Lock(p, p->dl->bundle->unit) == -1) {
474 close(p->fd);
475 p->fd = -1;
476 } else {
477 struct ttydevice *dev = malloc(sizeof *dev);
478
479 if (dev != NULL)
480 tty_SetupDevice(p);
481
482 return &dev->dev;
483 }
484 } else if (tty_Lock(p, p->dl->bundle->unit) != -1) {
485 struct ttydevice *dev = malloc(sizeof *dev);
486 log_Printf(LogDEBUG, "%s: Opened %s\n", p->link.name, p->name.full);
487
488 if (dev != NULL)
489 tty_SetupDevice(p);
490
491 return &dev->dev;
492 }
493 }
494
495 return NULL;
496}