|
Lines 42-47
Link Here
|
| 42 |
#include <sys/queue.h> |
42 |
#include <sys/queue.h> |
| 43 |
|
43 |
|
| 44 |
#include <errno.h> |
44 |
#include <errno.h> |
|
|
45 |
#include <fcntl.h> |
| 45 |
#include <grp.h> |
46 |
#include <grp.h> |
| 46 |
#include <login_cap.h> |
47 |
#include <login_cap.h> |
| 47 |
#include <paths.h> |
48 |
#include <paths.h> |
|
Lines 433-438
do_exec_no_pty(Session *s, const char *c
Link Here
|
| 433 |
#ifdef USE_PIPES |
434 |
#ifdef USE_PIPES |
| 434 |
int pin[2], pout[2], perr[2]; |
435 |
int pin[2], pout[2], perr[2]; |
| 435 |
|
436 |
|
|
|
437 |
if (s == NULL) |
| 438 |
fatal("do_exec_no_pty: no session"); |
| 439 |
|
| 436 |
/* Allocate pipes for communicating with the program. */ |
440 |
/* Allocate pipes for communicating with the program. */ |
| 437 |
if (pipe(pin) < 0) { |
441 |
if (pipe(pin) < 0) { |
| 438 |
error("%s: pipe in: %.100s", __func__, strerror(errno)); |
442 |
error("%s: pipe in: %.100s", __func__, strerror(errno)); |
|
Lines 444-476
do_exec_no_pty(Session *s, const char *c
Link Here
|
| 444 |
close(pin[1]); |
448 |
close(pin[1]); |
| 445 |
return -1; |
449 |
return -1; |
| 446 |
} |
450 |
} |
| 447 |
if (pipe(perr) < 0) { |
451 |
if (s->is_subsystem) { |
| 448 |
error("%s: pipe err: %.100s", __func__, strerror(errno)); |
452 |
if ((perr[1] = open(_PATH_DEVNULL, O_WRONLY)) == -1) { |
| 449 |
close(pin[0]); |
453 |
error("%s: open(%s): %s", __func__, _PATH_DEVNULL, |
| 450 |
close(pin[1]); |
454 |
strerror(errno)); |
| 451 |
close(pout[0]); |
455 |
close(pin[0]); |
| 452 |
close(pout[1]); |
456 |
close(pin[1]); |
| 453 |
return -1; |
457 |
close(pout[0]); |
|
|
458 |
close(pout[1]); |
| 459 |
return -1; |
| 460 |
} |
| 461 |
perr[0] = -1; |
| 462 |
} else { |
| 463 |
if (pipe(perr) < 0) { |
| 464 |
error("%s: pipe err: %.100s", __func__, |
| 465 |
strerror(errno)); |
| 466 |
close(pin[0]); |
| 467 |
close(pin[1]); |
| 468 |
close(pout[0]); |
| 469 |
close(pout[1]); |
| 470 |
return -1; |
| 471 |
} |
| 454 |
} |
472 |
} |
| 455 |
#else |
473 |
#else |
| 456 |
int inout[2], err[2]; |
474 |
int inout[2], err[2]; |
| 457 |
|
475 |
|
|
|
476 |
if (s == NULL) |
| 477 |
fatal("do_exec_no_pty: no session"); |
| 478 |
|
| 458 |
/* Uses socket pairs to communicate with the program. */ |
479 |
/* Uses socket pairs to communicate with the program. */ |
| 459 |
if (socketpair(AF_UNIX, SOCK_STREAM, 0, inout) < 0) { |
480 |
if (socketpair(AF_UNIX, SOCK_STREAM, 0, inout) < 0) { |
| 460 |
error("%s: socketpair #1: %.100s", __func__, strerror(errno)); |
481 |
error("%s: socketpair #1: %.100s", __func__, strerror(errno)); |
| 461 |
return -1; |
482 |
return -1; |
| 462 |
} |
483 |
} |
| 463 |
if (socketpair(AF_UNIX, SOCK_STREAM, 0, err) < 0) { |
484 |
if (s->is_subsystem) { |
| 464 |
error("%s: socketpair #2: %.100s", __func__, strerror(errno)); |
485 |
if ((err[0] = open(_PATH_DEVNULL, O_WRONLY)) == -1) { |
| 465 |
close(inout[0]); |
486 |
error("%s: open(%s): %s", __func__, _PATH_DEVNULL, |
| 466 |
close(inout[1]); |
487 |
strerror(errno)); |
| 467 |
return -1; |
488 |
close(inout[0]); |
|
|
489 |
close(inout[1]); |
| 490 |
return -1; |
| 491 |
} |
| 492 |
err[1] = -1; |
| 493 |
} else { |
| 494 |
if (socketpair(AF_UNIX, SOCK_STREAM, 0, err) < 0) { |
| 495 |
error("%s: socketpair #2: %.100s", __func__, |
| 496 |
strerror(errno)); |
| 497 |
close(inout[0]); |
| 498 |
close(inout[1]); |
| 499 |
return -1; |
| 500 |
} |
| 468 |
} |
501 |
} |
| 469 |
#endif |
502 |
#endif |
| 470 |
|
503 |
|
| 471 |
if (s == NULL) |
|
|
| 472 |
fatal("do_exec_no_pty: no session"); |
| 473 |
|
| 474 |
session_proctitle(s); |
504 |
session_proctitle(s); |
| 475 |
|
505 |
|
| 476 |
/* Fork the child. */ |
506 |
/* Fork the child. */ |
|
Lines 482-494
do_exec_no_pty(Session *s, const char *c
Link Here
|
| 482 |
close(pin[1]); |
512 |
close(pin[1]); |
| 483 |
close(pout[0]); |
513 |
close(pout[0]); |
| 484 |
close(pout[1]); |
514 |
close(pout[1]); |
| 485 |
close(perr[0]); |
515 |
if (perr[0] != -1) |
|
|
516 |
close(perr[0]); |
| 486 |
close(perr[1]); |
517 |
close(perr[1]); |
| 487 |
#else |
518 |
#else |
| 488 |
close(inout[0]); |
519 |
close(inout[0]); |
| 489 |
close(inout[1]); |
520 |
close(inout[1]); |
| 490 |
close(err[0]); |
521 |
close(err[0]); |
| 491 |
close(err[1]); |
522 |
if (err[1] != -1) |
|
|
523 |
close(err[1]); |
| 492 |
#endif |
524 |
#endif |
| 493 |
return -1; |
525 |
return -1; |
| 494 |
case 0: |
526 |
case 0: |
|
Lines 522-528
do_exec_no_pty(Session *s, const char *c
Link Here
|
| 522 |
close(pout[1]); |
554 |
close(pout[1]); |
| 523 |
|
555 |
|
| 524 |
/* Redirect stderr. */ |
556 |
/* Redirect stderr. */ |
| 525 |
close(perr[0]); |
557 |
if (perr[0] != -1) |
|
|
558 |
close(perr[0]); |
| 526 |
if (dup2(perr[1], 2) < 0) |
559 |
if (dup2(perr[1], 2) < 0) |
| 527 |
perror("dup2 stderr"); |
560 |
perror("dup2 stderr"); |
| 528 |
close(perr[1]); |
561 |
close(perr[1]); |
|
Lines 533-539
do_exec_no_pty(Session *s, const char *c
Link Here
|
| 533 |
* seem to depend on it. |
566 |
* seem to depend on it. |
| 534 |
*/ |
567 |
*/ |
| 535 |
close(inout[1]); |
568 |
close(inout[1]); |
| 536 |
close(err[1]); |
569 |
if (err[1] != -1) |
|
|
570 |
close(err[1]); |
| 537 |
if (dup2(inout[0], 0) < 0) /* stdin */ |
571 |
if (dup2(inout[0], 0) < 0) /* stdin */ |
| 538 |
perror("dup2 stdin"); |
572 |
perror("dup2 stdin"); |
| 539 |
if (dup2(inout[0], 1) < 0) /* stdout (same as stdin) */ |
573 |
if (dup2(inout[0], 1) < 0) /* stdout (same as stdin) */ |
|
Lines 562-571
do_exec_no_pty(Session *s, const char *c
Link Here
|
| 562 |
close(perr[1]); |
596 |
close(perr[1]); |
| 563 |
|
597 |
|
| 564 |
if (compat20) { |
598 |
if (compat20) { |
| 565 |
if (s->is_subsystem) { |
|
|
| 566 |
close(perr[0]); |
| 567 |
perr[0] = -1; |
| 568 |
} |
| 569 |
session_set_fds(s, pin[1], pout[0], perr[0], 0); |
599 |
session_set_fds(s, pin[1], pout[0], perr[0], 0); |
| 570 |
} else { |
600 |
} else { |
| 571 |
/* Enter the interactive session. */ |
601 |
/* Enter the interactive session. */ |
|
Lines 582-591
do_exec_no_pty(Session *s, const char *c
Link Here
|
| 582 |
* handle the case that fdin and fdout are the same. |
612 |
* handle the case that fdin and fdout are the same. |
| 583 |
*/ |
613 |
*/ |
| 584 |
if (compat20) { |
614 |
if (compat20) { |
| 585 |
session_set_fds(s, inout[1], inout[1], |
615 |
session_set_fds(s, inout[1], inout[1], err[1], 0); |
| 586 |
s->is_subsystem ? -1 : err[1], 0); |
|
|
| 587 |
if (s->is_subsystem) |
| 588 |
close(err[1]); |
| 589 |
} else { |
616 |
} else { |
| 590 |
server_loop(pid, inout[1], inout[1], err[1]); |
617 |
server_loop(pid, inout[1], inout[1], err[1]); |
| 591 |
/* server_loop has closed inout[1] and err[1]. */ |
618 |
/* server_loop has closed inout[1] and err[1]. */ |