I was tasked with implementing this myshell program which mirrors Linux shell. This is in the scope of an introductory Operating Systems course at my university. They provided us the basic shell code and asked us to tamper with it.
One of the exercises is to implement an exit command which terminated the custom shell. I did this using strcmp. However I feel this is a very hacky solution - feels like cheating.
Here's the source code:
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
int main(int argc, char* argv[]){
char buf[1024];
char* args[256];
pid_t pid;
for( ; ; ){
char* command;
fprintf(stdout, "$ ");
if((command = fgets(buf, sizeof(buf), stdin)) == NULL){
break;
}
command[strlen(buf) -1] = '\0';
//saving commands to a memory file so I can
//print them out later on with tail (through
//myhistory)
FILE* f = fopen("mem.txt", "a");
fwrite(command, sizeof(char), strlen(command), f);
fputc('\n', f);
fclose(f);
int i = 0;
do{
if(i == 0) args[i] = strtok(command, " ");
else args[i] = strtok(NULL, " ");
i++;
}while(args[i-1] != NULL);
//hacky exit command I'm trying to improve on
if(!strcmp(args[0], "exit")) exit(EXIT_SUCCESS);
if((pid = fork()) == -1){
fprintf(stderr, "%s: cant fork command: %s",
argv[0], strerror(errno));
continue;
} else if (pid == 0){
execvp(args[0], args);
fprintf(stderr, "%s: couldn't exec %s: %s\n",
argv[0], buf, strerror(errno));
exit(EXIT_FAILURE);
}
if((pid = waitpid(pid, NULL, 0)) < 0)
fprintf(stderr, "%s: waitpid error: %s\n",
argv[0], strerror(errno));
}
exit(EXIT_SUCCESS);
}
I wrote the exit command like this:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <signal.h>
int main(){
kill(getpid(), 0);
}
however this doesn't help since I'm just killing the child. How could I kill the parent through the child? Yes, I'm aware I could pass the parent PID to the exit command and terminate it that way, but something tells me there's a cleaner solution that doesn't require hard coding control flow logic.