私の最初のスタックオーバーフローポスト、私はサイトのlurkerですが、私は本当に自分自身のいくつかの質問をし始めたいと思っていました!指定されていない予期しない関数呼び出しを引き起こすC fork()
私は、unistd.hライブラリを使ってfork()システムコールについて学んでいます。私は何を学んでいるのか試してみたい。 UNIXでの簡単なプロセス作成の例については、教科書に従ってきました。私はOSXでこれをやっています。私はシェルを作成するタスクを設定されているので、私はシェルを構築するための完全な答えを与えたくないので、なぜプログラム全体ではなく、この特定のシステムコールについて尋ねています。
コードは完全に正常に動作し、期待される出力が得られます。
これは細かい作業のコードは次のとおりです。
#include <stdio.h>
#include <unistd.h>
int main() {
pid_t pid;
pid = fork();
if(pid == 0){
printf("\nI'm the child\n\n");
}
else if(pid > 0){
printf("\nI'm the parent, child has pid: [%d]\n", pid);
}
else{
printf("ERROR");
}
return 0;
}
私の問題は、私は私のシェルプログラムでこれを入れたとき、それは私が、オンラインフォーク爆弾を発見したものから、原因となっていることです。
このプロセスを作成する関数は、 'test'コマンドで呼び出されます。関数を実行すると、スタンドアロン版と同じ出力が得られますが、次に移動して終了すると、無限ループでそのテスト関数を再度呼び出すように見えます。コンピュータが遅れているので、私はプロセスを殺すことができません。なぜなら、一連のプロセスが作成され、コンピュータを再起動する必要があるからです。私はこれを数回やりました。実行するたびに再起動を実行する必要があるため、テストが不可能になってきています。
私は、終了コマンドを終了することを期待しているwhileループを持っています。コードは以下のように自明でなければなりません。私はwait()システムコールを使うべきだと考えている研究から、これらのコンセプトをテストしようとしていますが、私のコードがこれを引き起こしている理由を理解したいと思います。
完全なプログラム:
main.cの
#include "shell.h"
int main() {
clear();
printf("Jack's Shell\n");
shellLoop();
clear();
return 0;
}
shell.c
#include "shell.h"
void shellLoop(){
char command[MAX_STRING_LEN];
int exit = 1;
while (exit != 0){
printf("\njackdewinter$ ");
scanf("%s", &command);
exit = commandInterpreter(command);
}
}
int commandInterpreter(char * cmd){
char message[MAX_STRING_LEN];
if(strcmp(cmd, "exit") == 0){ /* Best way to test strings (Not just characters.) */
return 0;
}
else if(strcmp(cmd, "info") == 0){
info();
return 1;
}
else if(strcmp(cmd, "pwd") == 0){
shellMessage("Call PWD");
return 1;
}
else if(strcmp(cmd, "cd") == 0){
shellMessage("Call CD");
return 1;
}
else if(strcmp(cmd, "test") == 0){
shellMessage("Test Called.");
test();
return 1;
}
else if(strcmp(cmd, "help") == 0){
shellMessage("Call HELP");
return 1;
}
else{
shellMessage("Incorrect command entered.\nType help for assistance and a list of commands.");
return 1;
}
}
void info(){
shellMessage("This shell was created by Jack Dewinter");
}
void test(){
pid_t pid;
pid = fork();
if(pid == 0){
printf("Child\n");
}
else if(pid > 0){
printf("I'm the parent, child has pid %d\n", pid);
}
else{
printf("ERROR");
}
}
void shellMessage(char * message){ /* Using this for consistent shell messages. */
printf("\n%s\n", message);
}
shell.h
#define MAX_STRING_LEN 80
#define clear() printf("\033[H\033[J") /* Terminal escape codes for clearing the console */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
void shellLoop();
int commandInterpreter(char * cmd);
void info();
void test();
void shellMessage(char * message);
ご協力いただきありがとうございます、ありがとうございます!
これはフォークの爆弾ではなく、単なるバグです。終了したら、子プロセスは 'exit()'する必要があります。私。 'if(pid == 0) 'ブロックの中にあります。結局、フォークされたプロセスは終了するはずです。私が見ていることから、親がそれをいつでも気にする理由はありませんが、それでもやはりそうするべきです。また、コマンドインタープリタとその選択のメニューに戻ることもあります。 – WhozCraig
子供と親の両方があなたのループに戻ります。出口もない。今は2つのプロセスがあります。 stdinに何かを入力すると、それは子供に行きます。しかし、子供が出ると、親はまだ走っていて、stdinからの読み込みを待っています。テストを複数回実行すると、入力待ちのインスタンスが複数存在します。私は爆弾を作成するループが表示されません。 – HardcoreHenry
このコードにバッファオーバーフローがあります。 'scanf("%s "、&command)'を 'scanf("%80s "、&command)'に置き換えるか、代わりに 'fgets'を使うべきです。 –