更新: act.sa_flags = SA_RESTART を設定すると、プログラムは seg faulting を停止しますが、プログラムのロジックを進めないため、プログラムがその関数で「スタック」します。コロンは、新しいコマンド ライン入力の開始を示します。理想的な出力は次のとおりです。
: 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
バックグラウンド プロセスを実行しようとするとシグナル ハンドラが呼び出されますが、その理由がわかりません。SIGINT を使用するように sigaction を設定すると、プログラムはエラーをセグメント化しません。何かご意見は?ここで同様の投稿を見ました ( 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));
}