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} |
|