diff options
author | Thijs Schreijer <thijs@thijsschreijer.nl> | 2025-04-09 13:15:38 +0200 |
---|---|---|
committer | Thijs Schreijer <thijs@thijsschreijer.nl> | 2025-04-09 13:25:58 +0200 |
commit | 2dd41df8144efeda71739dc2c0d1e62e00a6225a (patch) | |
tree | 88b0e2119a2c4b67c126349214a53b3ef8782c2b /src/term.c | |
parent | 96fb7f1608e00d6f8ceb2a5d9a90483e92fe4e3a (diff) | |
download | luasystem-detach.tar.gz luasystem-detach.tar.bz2 luasystem-detach.zip |
fix review commentsdetach
Diffstat (limited to '')
-rw-r--r-- | src/term.c | 69 |
1 files changed, 34 insertions, 35 deletions
@@ -652,41 +652,55 @@ static int lst_tcsetattr(lua_State *L) | |||
652 | #ifndef _WIN32 | 652 | #ifndef _WIN32 |
653 | /* | 653 | /* |
654 | reopen FDs for independent file descriptions. | 654 | reopen FDs for independent file descriptions. |
655 | fd should be either 1 or 2 (stdout or stderr) | ||
656 | */ | 655 | */ |
657 | static int reopen_fd(lua_State *L, int fd, int flags) { | 656 | static void reopen_fd(lua_State *L, int fd, int flags) { |
658 | char path[64]; | 657 | char path[64]; |
659 | int newfd = -1; | 658 | int newfd = -1; |
660 | 659 | ||
660 | if (fd != STDOUT_FILENO && fd != STDERR_FILENO) { | ||
661 | luaL_error(L, "Invalid file descriptor: %d. Only stdout (1) and stderr (2) are supported.", fd); | ||
662 | } | ||
663 | |||
664 | const char *fallback_path = (fd == STDOUT_FILENO) ? "/dev/stdout" : | ||
665 | (fd == STDERR_FILENO) ? "/dev/stderr" : NULL; | ||
666 | |||
661 | // If fd is a terminal, reopen its actual device (e.g. /dev/ttys003) | 667 | // If fd is a terminal, reopen its actual device (e.g. /dev/ttys003) |
662 | // Works on all POSIX platforms that have terminals (macOS, Linux, BSD, etc.) | 668 | // Works on all POSIX platforms that have terminals (macOS, Linux, BSD, etc.) |
663 | if (isatty(fd)) { | 669 | if (isatty(fd)) { |
664 | const char *tty = ttyname(fd); | 670 | const char *tty = ttyname(fd); |
665 | if (tty) { | 671 | if (tty) { |
666 | newfd = open(tty, flags); | 672 | newfd = open(tty, flags); |
667 | if (newfd >= 0) return newfd; | ||
668 | } | 673 | } |
669 | } | 674 | } |
670 | 675 | ||
671 | // For non-tty: try /dev/fd/N — POSIX-compliant and standard on macOS, Linux, BSD. | 676 | if (newfd < 0) { |
672 | // This gives a new file description even if the target is a file or pipe. | 677 | // For non-tty: try /dev/fd/N — POSIX-compliant and standard on macOS, Linux, BSD. |
673 | snprintf(path, sizeof(path), "/dev/fd/%d", fd); | 678 | // This gives a new file description even if the target is a file or pipe. |
674 | newfd = open(path, flags); | 679 | snprintf(path, sizeof(path), "/dev/fd/%d", fd); |
675 | if (newfd >= 0) return newfd; | 680 | newfd = open(path, flags); |
681 | } | ||
676 | 682 | ||
677 | // Fallback: for platforms/environments where /dev/fd/N doesn't exist. | 683 | if (newfd < 0) { |
678 | // /dev/stdout and /dev/stderr are standard on Linux, but may not create new descriptions. | 684 | // Fallback: for platforms/environments where /dev/fd/N doesn't exist. |
679 | const char *fallback_path = (fd == 1) ? "/dev/stdout" : | 685 | // /dev/stdout and /dev/stderr are standard on Linux, but may not create new descriptions. |
680 | (fd == 2) ? "/dev/stderr" : NULL; | 686 | if (fallback_path) { |
687 | newfd = open(fallback_path, flags); | ||
688 | } | ||
689 | } | ||
681 | 690 | ||
682 | if (fallback_path) { | 691 | if (newfd < 0) { |
683 | newfd = open(fallback_path, flags); | 692 | // All attempts failed — raise error with detailed info (call will not return) |
684 | if (newfd >= 0) return newfd; | 693 | luaL_error(L, "Failed to reopen fd %d: tried ttyname(), /dev/fd/%d, and fallback %s: %s", |
694 | fd, fd, fallback_path ? fallback_path : "(none)", strerror(errno)); | ||
685 | } | 695 | } |
686 | 696 | ||
687 | // All attempts failed — raise error with detailed info | 697 | // Replace the original fd with the new one |
688 | return luaL_error(L, "Failed to reopen fd %d: tried ttyname(), /dev/fd/%d, and fallback %s: %s", | 698 | if (dup2(newfd, fd) < 0) { |
689 | fd, fd, fallback_path ? fallback_path : "(none)", strerror(errno)); | 699 | close(newfd); |
700 | luaL_error(L, "dup2 failed for fd %d: %s", fd, strerror(errno)); | ||
701 | } | ||
702 | |||
703 | close(newfd); // Close the new fd, as dup2 has replaced the original fd with it | ||
690 | } | 704 | } |
691 | #endif | 705 | #endif |
692 | 706 | ||
@@ -720,23 +734,8 @@ static int lst_detachfds(lua_State *L) { | |||
720 | 734 | ||
721 | #ifndef _WIN32 | 735 | #ifndef _WIN32 |
722 | // Reopen stdout and stderr with new file descriptions | 736 | // Reopen stdout and stderr with new file descriptions |
723 | int fd_out = reopen_fd(L, 1, O_WRONLY); | 737 | reopen_fd(L, STDOUT_FILENO, O_WRONLY); |
724 | int fd_err = reopen_fd(L, 2, O_WRONLY); | 738 | reopen_fd(L, STDERR_FILENO, O_WRONLY); |
725 | |||
726 | // Replace fd 1 and 2 in-place using dup2 | ||
727 | if (dup2(fd_out, 1) < 0) { | ||
728 | close(fd_out); | ||
729 | return luaL_error(L, "dup2 failed for stdout: %s", strerror(errno)); | ||
730 | } | ||
731 | if (dup2(fd_err, 2) < 0) { | ||
732 | close(fd_err); | ||
733 | return luaL_error(L, "dup2 failed for stderr: %s", strerror(errno)); | ||
734 | } | ||
735 | |||
736 | // Clean up temporary file descriptors — fd 1 and 2 now own them | ||
737 | close(fd_out); | ||
738 | close(fd_err); | ||
739 | |||
740 | #endif | 739 | #endif |
741 | 740 | ||
742 | lua_pushboolean(L, 1); | 741 | lua_pushboolean(L, 1); |