Tôi đang viết một mini-shell (không, không dành cho trường học: P; vì sự thích thú của riêng tôi) và hầu hết các chức năng cơ bản hiện đang được thực hiện nhưng tôi bị kẹt khi cố gắng xử lý SIGTSTP.waitpid chặn khi nó không nên
Giả sử, khi người dùng nhấn Ctrl+Z
, SIGTSTP sẽ được gửi đến tiến trình Foreground của trình vỏ nếu nó tồn tại và Shell sẽ tiếp tục bình thường.
Sau khi tạo mỗi quá trình (nếu đó là một quá trình Foreground), đoạn code sau đợi:
if(waitpid(pid, &processReturnStatus, WUNTRACED)>0){//wait stopped too
if(WIFEXITED(processReturnStatus) || WIFSIGNALED(processReturnStatus))
removeFromJobList(pid);
}
Và tôi xử lý các tín hiệu như sau:
void sigtstpHandler(int signum)
{
signum++;//Just to remove gcc's warning
pid_t pid = findForegroundProcessID();
if(pid > -1){
kill(-pid, SIGTSTP);//Sending to the whole group
}
}
gì xảy ra được khi tôi nhấn Ctrl+Z
, quy trình con sẽ bị tạm ngưng thực sự (sử dụng ps -all
để xem trạng thái của các quy trình) nhưng vỏ của tôi bị treo tại số waitpid
r trả về ngay cả khi tôi đã thông qua cờ WUNTRACED
mà theo như tôi hiểu là nghĩa vụ phải thực hiện trả lại waitpid
khi quá trình được dừng lại quá.
Vì vậy, tôi có thể làm gì sai? hoặc tôi có hiểu hành vi của waitpid không chính xác không?
Ghi chú:
-findForegroundProcessID() trả về đúng pid; Tôi đã kiểm tra lại điều đó.
-Tôi đang thay đổi nhóm của mỗi quá trình khi ngay sau khi tôi fork
-Xử lý Ctrl+C
đang làm việc tốt
-Nếu tôi sử dụng thiết bị đầu cuối khác để gửi SIGCONT sau khi bị treo vỏ của tôi, quá trình trẻ sơ yếu lý lịch công việc của mình và vỏ gặt nó cuối cùng.
-Tôi đang bắt SIGTSTP mà theo như tôi đọc (và thử nghiệm) có thể bị bắt. -Tôi đã thử sử dụng waitid thay vì waitpid trong trường hợp, sự cố vẫn tiếp diễn. EDIT:
void sigchldHandler(int signum)
{
signum++;//Just to remove the warning
pid_t pid;
while((pid = waitpid(-1, &processReturnStatus, 0)) > 0){
removeFromJobList(pid);
}
if(errno != ECHILD)
unixError("kill error");
}
xử lý SIGCHLD My.
IIUC, bạn đang cố gắng nắm bắt SIGSTP. Bạn không thể bắt SIGSTP hoặc SIGKILL. – wildplasser
Tôi không chắc liệu SIGSTOP có giống SIGSTP hay không, nhưng theo một cuốn sách, SIGSTOP không thể bị bắt nhưng SIGTSTP có thể, trên thực tế tôi chắc chắn tôi đã bắt được nó vì tôi đã in một cái gì đó như một bài kiểm tra – Fingolfin
Rất tiếc, xấu của tôi. Nếu tôi đọc chính xác, SIGTSTP đã được cố ý tạo ra để cho phép nó bị bắt, để cho phép nhóm tiến trình/nhóm thiết bị đầu cuối truyền bá nó giữa các thành viên của nó. Nếu cuốn sách bạn đề cập đến là APUE, bạn có thể sẽ làm điều đó một cách chính xác ... – wildplasser