Я пытаюсь построить свою раковину. Вот один из сценариев: я ввожу команду «sleep 10», работающую на переднем плане, и нажимаю Ctrl-z, чтобы остановить ее и перевести в фоновый режим. После того, как я поставил команду "ls &" в фоновом режиме, теперь есть два задания в фоновом режиме, я добавил kill () -SIGCONT, чтобы возобновить "sleep 10", но ничего не происходит. есть идеи?
#include <errno.h>
#include <stdbool.h>
#include <stdio.h>
#include <readline/readline.h>
#include <readline/history.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <signal.h>
#include <sys/wait.h>
#include <termios.h>
#include <unistd.h>
#include <dirent.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <signal.h>
#include <sys/signal.h>
#include <sys/mman.h>
sigset_t mask_all, mask_one, prev_one;
pid_t pid = 0;
void handler()
{
//int olderrno = errno;
sigset_t mask_all, prev_all;
sigfillset(&mask_all);
pid_t pid;
int status;
while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
sigprocmask(SIG_BLOCK, &mask_all, &prev_all);
if(pid == -1)
printf("handler-pid: %d has been reaped\n, no need again", pid);
else
printf("handler-pid: %d has been reaped\n", pid);
sigprocmask(SIG_SETMASK, &prev_all, NULL);
}
}
void send_signal(int signum)
{
kill(pid, signum);
}
void init_signals()
{
signal(SIGCHLD, handler);
signal(SIGTSTP, send_signal);
}
void start_foreground_job(char** argv)
{
//signal(SIGCHLD, SIG_DFL);
sigprocmask(SIG_BLOCK, &mask_one, &prev_one);
pid = fork();
if(pid==0)
{
sigprocmask(SIG_SETMASK, &prev_one, NULL);
printf("This is child %d\n", pid);
setpgid(0,0);
signal(SIGTSTP, SIG_DFL);
if((execve(argv[0], argv, NULL))<0)//envp
{
fprintf(stderr, "%s: Command not found.\n", argv[0]);
exit(0);
}
}
sigprocmask(SIG_SETMASK, &prev_one, NULL);
pause();
//printf("pid: %d was stopped\n", p);
}
void start_background_job(char** argv)
{
//signal(SIGCHLD, handler);
sigprocmask(SIG_BLOCK, &mask_one, &prev_one);
if( fork() ==0)
{
//printf("%d\n", getpid());
sigprocmask(SIG_SETMASK, &prev_one, NULL);
printf("This is child %d\n", getpid());
setpgid(0,0);
signal(SIGTSTP, SIG_DFL);
if((execve(argv[0], argv, NULL))<0)
{
fprintf(stderr, "%s: Command not found.\n", argv[0]);// discard all changed!!!
exit(0);
}
}
//sigprocmask(SIG_BLOCK, &mask_all, NULL);
sigprocmask(SIG_SETMASK, &prev_one, NULL);
}
int main()
{
init_signals();
sigfillset(&mask_all);
sigemptyset(&mask_one);
sigaddset(&mask_one, SIGCHLD);
pid_t stdin_PGID;
setpgid(0,0);
/* Get the PGIDs for stdin. */
stdin_PGID = tcgetpgrp(STDIN_FILENO);
if (stdin_PGID == -1) {
printf("Could not get PGID for stdin.n");
return(EXIT_FAILURE);
}
else if (tcsetpgrp(STDIN_FILENO, stdin_PGID) == -1) {
printf("Could not set PGID.n");
return(EXIT_FAILURE);
}
printf("The PGID has been changed to %d %d \n", stdin_PGID,getpgid(getpid()));
printf("my prompt> \n");
char* argv1[] = {"/bin/sleep", "5", NULL};
start_foreground_job(argv1);
printf("my prompt> \n");
char* argv2[] = {"/bin/ls", NULL};
start_background_job(argv2);
printf("stopped child %d\n", pid);
kill(pid,SIGCONT);
sleep(1);
}