Seg Fault, когда SIGCHLD перехватывается в простой программе оболочки

ОБНОВЛЕНИЕ: Когда я устанавливаю act.sa_flags = SA_RESTART, программа перестает выдавать ошибку сегмента, однако это приводит к тому, что программа «застревает» в этой функции, поскольку она не продвигается вперед с логикой в ​​​​моей программе. Двоеточие указывает на начало нового ввода командной строки. Идеальный результат ниже:

 : ls
 smallsh.c small
 : sleep 5 & //background process
 : ls > junk
 background pid # is complete terminated by signal $ //when background sleep finishes
 :

Однако теперь я получаю следующее:

 : ls
 smallsh.c small
 : sleep 5 & //background process
 : ls > junk
 background pid # is complete terminated by signal $ 
 //cursor is pointing here but no colon appears, i can still write commands
 //and they will work but function believers they are all background processes

ПРЕДЫДУЩАЯ: я пытаюсь закодировать простую оболочку с фоновыми и передними процессами в C. Чтобы создать фоновый процесс, пользователь должен ввести «&» в конце своей команды, поэтому, например, «sleep 3 &» будет фоновый процесс. В моей программе, когда я ввожу «sleep 3 &», процесс успешно запускается, но по завершении, когда вызывается функция обработчика sig, печатается оператор (в котором говорится, что фоновый процесс завершен), а затем происходит ошибка seg программы. Вот пример того, как выглядит вывод:

: спящий режим 3 и фоновый pid 22688: фоновый pid 0 выполнен: завершен сигналом 0 Ошибка сегментации: 11

Мой обработчик сигналов вызывается, когда я пытаюсь запустить фоновый процесс, и я не знаю, почему. Когда я устанавливаю sigaction для использования SIGINT, программа не выдает ошибку seg. Какие-нибудь мысли? Я видел похожий пост здесь (SIGCHLD вызывает ошибку сегментации, не попадая в обработчик), но мне это не помогло.

pid_t spawnPID = -5
int exitMethod; 
int exitStatus = 0;
char bgPID[10];

//Set up signal handler
struct sigaction act;
act.sa_handler = sig_handler;
act.sa_flags = 0;
sigfillset(&(act.sa_mask));

fflush(stdout);


if (bg == 1)
{
 sigaction(SIGCHLD, &act, NULL);
}


switch(spawnPID)
{
    case -1:
    {
        //There was an error forking
        printf("Error forking\n");
        fflush(stdout);
        exitStatus = 1; 
    }
    case 0:   //Child process
    {

        //Check for input/output redirection
        if (numArgs > 1)
        {

            if (!(strncmp(arguments[1], ">", 1)))
            {

                exitStatus = outputRedirect(arguments,numArgs);
            }
            else if (!(strncmp(arguments[1], "<", 1)) || (! 
            (strncmp(arguments[0], "cat", 1))))
            {
                exitStatus = inputRedirect(arguments,numArgs);
            }
            else
            {

            arguments[numArgs] = NULL; //set last value in the array to NULL 


            if (execvp(arguments[0],arguments) == -1)
            {
                printf("Command or file not recognized\n"); //won't run unless there is an error
                fflush(stdout);
                exitStatus = 1;
            }
        }
    }
        else //run other command
        {

            if (execvp(arguments[0],arguments) == -1)
            {
                printf("%s: No such command, file or directory\n", arguments[0]); //won't run unless there is an error
                fflush(stdout);
                exitStatus = 1;
            }

        }
        break;

    }
//Following code is in the parent case of the switch statement

default:



if (bg == 0)  //waitpid is only called in a parent in a foreground process
{
  pid_t exitpid = waitpid(spawnPID,&exitMethod,0); //Wait for one of the     
  //children to be completed
{


 if (WIFEXITED(exitMethod))
 {
   int exitStatus = WEXITSTATUS(exitMethod);
 }


 //Sig Handler function

void sig_handler (int signo)
{
  int status;
  pid_t childPid;
  char bgMessage[50];
  char bgPID[10];
  char exitStatus[10];

  childPid = waitpid(-1, &status, 0);


  sprintf(bgPID,"%d",childPid);
  sprintf(exitStatus,"%d",WEXITSTATUS(status));
  strcat(bgMessage,"background pid ");
  strcat(bgMessage,bgPID);
  strcat(bgMessage," is done: terminated by signal " );
  strcat(bgMessage,exitStatus);
  strcat(bgMessage,"\n");

  // Write out the message
  write(1, bgMessage, sizeof(bgMessage));
}

person user2466886    schedule 19.11.2015    source источник
comment
Пожалуйста, объясните свой код больше. Я не понимаю, как обстоят дела с вопросом.   -  person Whitecat    schedule 19.11.2015
comment
SIGCHLD продолжает сбой сегмента. SIGCHLD — это имя/номер сигнала, поэтому он не может быть ошибкой сегмента. Где именно возникает ошибка seg? Но для начала не вызывайте printf в обработчике сигнала. printf не является безопасным для асинхронного режима.   -  person kaylum    schedule 19.11.2015
comment
Предоставил больше контекста, и да, я обновил свой код, чтобы он не использовал printf, но это не решило проблему.   -  person user2466886    schedule 19.11.2015
comment
Используйте отладчик, чтобы выяснить, какая именно строка кода не работает.   -  person kaylum    schedule 19.11.2015
comment
Ваша программа имеет неопределенное поведение. bgMessage используется неинициализированным. strcat параметры должны быть допустимыми строками (включая пустую строку), тогда как ваш bgMessage содержит мусор.   -  person kaylum    schedule 19.11.2015
comment
Вы можете использовать один безопасный snprintf вместо нескольких небезопасных strcat.   -  person someuser    schedule 19.11.2015