(Đăng lại trong unix theo đề xuất trong /programming/13718394/what-should-interactive-shells-do-in-orphaned- Process-groups )
Câu hỏi ngắn gọn là, một cái vỏ nên làm gì nếu nó nằm trong nhóm quy trình mồ côi không sở hữu tty? Nhưng tôi khuyên bạn nên đọc câu hỏi dài bởi vì nó thú vị.
Đây là một cách thú vị và thú vị để biến máy tính xách tay của bạn thành một máy sưởi không gian di động, sử dụng lớp vỏ yêu thích của bạn (trừ khi bạn là một trong những người lạ đó):
#include <unistd.h>
int main(void) {
if (fork() == 0) {
execl("/bin/bash", "/bin/bash", NULL);
}
return 0;
}
Điều này gây ra bash để chốt CPU ở mức 100%. zsh và cá cũng làm như vậy, trong khi ksh và tcsh lẩm bẩm điều gì đó về kiểm soát công việc và sau đó keel qua, điều này tốt hơn một chút, nhưng không nhiều. Ồ, và đó là một kẻ phạm tội bất khả tri về nền tảng: OS X và Linux đều bị ảnh hưởng.
Giải thích (có khả năng sai) của tôi là như sau: shell con phát hiện nó không nằm ở phía trước : tcgetpgrp(0) != getpgrp()
. Vì vậy, nó cố gắng để ngăn chặn chính nó : killpg(getpgrp(), SIGTTIN)
. Nhưng nhóm quy trình của nó là mồ côi, bởi vì cha mẹ của nó (chương trình C) là người lãnh đạo và đã chết, và SIGTTIN
được gửi đến một nhóm quy trình mồ côi bị bỏ rơi (nếu không thì không thể bắt đầu lại được). Do đó, lớp vỏ con không dừng lại, nhưng nó vẫn ở trong nền, vì vậy nó sẽ làm lại tất cả ngay lập tức. Rửa sạch và lặp lại.
Câu hỏi của tôi là, làm thế nào một shell dòng lệnh có thể phát hiện ra kịch bản này, và điều gì là đúng cho nó để làm gì? Tôi có hai giải pháp, cả hai đều không lý tưởng:
- Cố gắng báo hiệu quá trình có pid khớp với ID nhóm của chúng tôi. Nếu thất bại
ESRCH
, điều đó có nghĩa là chúng ta có thể mồ côi. - Hãy thử đọc không chặn một byte từ
/dev/tty
. Nếu thất bạiEIO
, điều đó có nghĩa là chúng ta có thể mồ côi.
(Vấn đề của chúng tôi theo dõi vấn đề này là https://github.com/fish-shell/fish-shell/issues/422 )
Cảm ơn những suy nghĩ của bạn!