Meine erste Stack Overflow Post, ich bin ein lurker auf der Website, aber ich wollte wirklich anfangen, einige Fragen von meinen eigenen zu stellen!C fork() verursacht unerwartete Funktionsaufrufe, die nicht angegeben werden
Ich lerne über den Systemaufruf fork() mit der Bibliothek unistd.h. Ich möchte testen, was ich lerne. Ich habe ein Lehrbuch als Beispiel für eine einfache Prozesserstellung in UNIX verwendet. Ich mache das unter OSX. Mir wurde eine Aufgabe zum Erstellen einer Shell zugewiesen, ich möchte keine vollständige Antwort auf das Erstellen einer Shell erhalten. Daher frage ich nach diesem spezifischen Systemaufruf, nicht nach dem gesamten Programm.
Der Code läuft von selbst ganz gut und gibt die erwartete Ausgabe.
Dies ist der Code funktioniert gut:
#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;
}
Mein Problem ist, dass, wenn ich dieses Programm in meiner Schale steckte es verursacht, von dem, was ich online, eine Gabel Bombe gefunden.
Die Funktion, die diesen Prozess erzeugt, wird mit dem Befehl 'test' aufgerufen. Wenn ich die Funktion ausführe, gibt es die gleiche Ausgabe wie in der Stand-alone-Version, aber wenn ich dann weitergehe und ausschließe, scheint es diese Testfunktion wieder in einer Endlosschleife aufzurufen. Ich kann dann die Prozesse nicht beenden, weil mein Computer zurückbleibt, klar, weil eine Menge Prozesse erstellt werden und ich meinen Computer neu starten muss. Ich habe das jetzt ein paar Mal gemacht und es wird unmöglich, es zu testen, weil ich jedes Mal neu starten muss, wenn ich es starte.
Ich habe eine while-Schleife, die erwartet, dass ein Beenden-Befehl endet. Der Code sollte selbsterklärend sein, siehe unten. Ich weiß, dass dies eine schlechte Übung ist. Ich versuche nur, diese Konzepte zu testen. Ich glaube, ich sollte den Systemaufruf wait() verwenden, aber ich möchte verstehen, warum mein Code das verursacht.
Das volle Programm:
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);
Jede Hilfe wäre sehr dankbar, danke!
Dies ist keine Gabel Bombe, es ist nur ein Fehler. Der Child-Prozess sollte 'exit()' wenn fertig sein. I.e. innerhalb des 'if (pid == 0)' Blocks. Schließlich sollte dieser gegabelte Prozess enden. Aus dem, was ich sehe, gibt es keinen Grund für den Elternteil, sich darum zu kümmern, ob/wann er es tut, aber es sollte immer noch, oder es wird auch zu dem Befehlsinterpreter und dem Auswahlmenü in seinem Prozess zurückkehren. – WhozCraig
Sowohl Ihr Kind als auch Ihr Elternteil kehren zu Ihrer Schleife zurück. Kein Ausgang. So, jetzt haben Sie zwei Prozesse. Wenn Sie etwas in stdin eingeben, geht es an das Kind. Aber wenn Kind austritt, läuft der Elternteil noch und wartet darauf, von der Standardeingabe zu lesen. Wenn Sie den Test mehrmals ausführen, warten mehrere Instanzen auf die Eingabe. Ich sehe jedoch keine Schleife, die eine Bombe erzeugt ... – HardcoreHenry
In diesem Code gibt es einen Pufferüberlauf. Sie sollten 'scanf ("% s ", & command)' durch 'scanf ("% 80s ", & command)' ersetzen oder stattdessen 'fgets' verwenden. –