… | |
… | |
406 | |
406 | |
407 | bool get (); |
407 | bool get (); |
408 | void login (int cmd_pid, bool login_shell, const char *hostname); |
408 | void login (int cmd_pid, bool login_shell, const char *hostname); |
409 | }; |
409 | }; |
410 | |
410 | |
|
|
411 | #if PTYTTY_REENTRANT |
|
|
412 | # define NEED_TOKEN do { char ch; read (lock_fd, &ch, 1); } while (0) |
|
|
413 | # define GIVE_TOKEN do { char ch; write (lock_fd, &ch, 1); } while (0) |
|
|
414 | #else |
|
|
415 | # define NEED_TOKEN (void)0 |
|
|
416 | # define GIVE_TOKEN (void)0 |
|
|
417 | #endif |
|
|
418 | |
411 | bool |
419 | bool |
412 | ptytty_proxy::get () |
420 | ptytty_proxy::get () |
413 | { |
421 | { |
|
|
422 | NEED_TOKEN; |
|
|
423 | |
414 | command cmd; |
424 | command cmd; |
415 | |
425 | |
416 | cmd.type = command::get; |
426 | cmd.type = command::get; |
417 | |
427 | |
418 | write (sock_fd, &cmd, sizeof (cmd)); |
428 | write (sock_fd, &cmd, sizeof (cmd)); |
419 | |
429 | |
420 | if (read (sock_fd, &id, sizeof (id)) != sizeof (id)) |
430 | if (read (sock_fd, &id, sizeof (id)) != sizeof (id)) |
421 | ptytty_fatal ("protocol error while creating pty using helper process, aborting.\n"); |
431 | ptytty_fatal ("protocol error while creating pty using helper process, aborting.\n"); |
422 | |
432 | |
423 | if (!id) |
433 | if (!id) |
|
|
434 | { |
|
|
435 | GIVE_TOKEN; |
424 | return false; |
436 | return false; |
|
|
437 | } |
425 | |
438 | |
426 | if ((pty = recv_fd (sock_fd)) < 0 |
439 | if ((pty = recv_fd (sock_fd)) < 0 |
427 | || (tty = recv_fd (sock_fd)) < 0) |
440 | || (tty = recv_fd (sock_fd)) < 0) |
428 | ptytty_fatal ("protocol error while reading pty/tty fds from helper process, aborting.\n"); |
441 | ptytty_fatal ("protocol error while reading pty/tty fds from helper process, aborting.\n"); |
429 | |
442 | |
|
|
443 | GIVE_TOKEN; |
430 | return true; |
444 | return true; |
431 | } |
445 | } |
432 | |
446 | |
433 | void |
447 | void |
434 | ptytty_proxy::login (int cmd_pid, bool login_shell, const char *hostname) |
448 | ptytty_proxy::login (int cmd_pid, bool login_shell, const char *hostname) |
435 | { |
449 | { |
|
|
450 | NEED_TOKEN; |
|
|
451 | |
436 | command cmd; |
452 | command cmd; |
437 | |
453 | |
438 | cmd.type = command::login; |
454 | cmd.type = command::login; |
439 | cmd.id = id; |
455 | cmd.id = id; |
440 | cmd.cmd_pid = cmd_pid; |
456 | cmd.cmd_pid = cmd_pid; |
441 | cmd.login_shell = login_shell; |
457 | cmd.login_shell = login_shell; |
442 | strncpy (cmd.hostname, hostname, sizeof (cmd.hostname)); |
458 | strncpy (cmd.hostname, hostname, sizeof (cmd.hostname)); |
443 | |
459 | |
444 | write (sock_fd, &cmd, sizeof (cmd)); |
460 | write (sock_fd, &cmd, sizeof (cmd)); |
|
|
461 | |
|
|
462 | GIVE_TOKEN; |
445 | } |
463 | } |
446 | |
464 | |
447 | ptytty_proxy::~ptytty_proxy () |
465 | ptytty_proxy::~ptytty_proxy () |
448 | { |
466 | { |
449 | if (id) |
467 | if (id) |
450 | { |
468 | { |
|
|
469 | NEED_TOKEN; |
|
|
470 | |
451 | command cmd; |
471 | command cmd; |
452 | |
472 | |
453 | cmd.type = command::destroy; |
473 | cmd.type = command::destroy; |
454 | cmd.id = id; |
474 | cmd.id = id; |
455 | |
475 | |
456 | write (sock_fd, &cmd, sizeof (cmd)); |
476 | write (sock_fd, &cmd, sizeof (cmd)); |
|
|
477 | |
|
|
478 | GIVE_TOKEN; |
457 | } |
479 | } |
458 | } |
480 | } |
459 | |
481 | |
460 | static |
482 | static |
461 | void serve () |
483 | void serve () |
462 | { |
484 | { |
463 | command cmd; |
485 | command cmd; |
464 | vector<ptytty *> ptys; |
486 | vector<ptytty *> ptys; |
465 | |
487 | |
|
|
488 | for (;;) |
|
|
489 | { |
|
|
490 | GIVE_TOKEN; |
|
|
491 | |
466 | while (read (sock_fd, &cmd, sizeof (command)) == sizeof (command)) |
492 | if (read (sock_fd, &cmd, sizeof (command)) != sizeof (command)) |
467 | { |
493 | break; |
|
|
494 | |
468 | if (cmd.type == command::get) |
495 | if (cmd.type == command::get) |
469 | { |
496 | { |
470 | // -> id ptyfd ttyfd |
497 | // -> id ptyfd ttyfd |
471 | cmd.id = new ptytty_unix; |
498 | cmd.id = new ptytty_unix; |
472 | |
499 | |
… | |
… | |
505 | ptys.erase (pty); |
532 | ptys.erase (pty); |
506 | } |
533 | } |
507 | } |
534 | } |
508 | else |
535 | else |
509 | break; |
536 | break; |
|
|
537 | |
|
|
538 | NEED_TOKEN; |
510 | } |
539 | } |
511 | |
540 | |
512 | // destroy all ptys |
541 | // destroy all ptys |
513 | for (vector<ptytty *>::iterator i = ptys.end (); i-- > ptys.begin (); ) |
542 | for (vector<ptytty *>::iterator i = ptys.end (); i-- > ptys.begin (); ) |
514 | delete *i; |
543 | delete *i; |