简体   繁体   中英

Killing parent process through child

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 (god this sounds dark)? 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.

Any hints? Thanks in advance

In "real" shell, commands like exit is a "shell built-in" . They are not external commands that starts another program, but executed internally by the shell.

You can implement those through various means, strcmp, dictionary, etc, but they are essentially just glorified version of what you're currently doing. So, yeah, keep doing what you're doing.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM