My first Stack Overflow post, I'm a lurker on the site but I really wanted to start asking some questions of my own!
I'm learning about the fork() system call, using the unistd.h library. I want to test out what I'm learning. I have followed a textbook for an example on a simple process creation in UNIX. I am doing this on OSX. I have been set a task to create a shell, I do not want to be given a complete answer to building a shell, hence why I'm asking about this specific system call, not the entire program.
The code runs completely fine on its own and gives the expected output.
This is the code working fine:
#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;
}
My issue is that when I put this in my shell program it is causing, from what I have found online, a fork bomb.
The function that creates this process is called with the command 'test'. When I run the function, it gives the same output as in the stand alone version however when I then move on and exit out, it seems to be calling that test function again in an infinite loop. I then can't kill the processes because my computer lags out, clearly because a bunch of processes are being created and I have to restart my computer. I've done this a few times now and it is becoming impossible to test because of the need to perform restarts every time I run it.
I have a while loop that is expecting an exit command to end. The code should be self explanatory, shown below. I know a lot of this is bad practise, I am just trying to test out these concepts, from research I believe I should be using the wait() system call but I want to understand why my code is causing this to happen.
The full program:
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);
Any help would be greatly appreciated, thanks!