How to make a history command

Viewed 64

I am having trouble creating a child process, and I'm not sure if I have the execvp argument right. Is there a way to fix it so it'll pass correctly?

int execute(char* input) { 
int i = 0;
char* shell_argv[MAX_CMD_LINE_ARGS];
memset(shell_argv, 0, MAX_CMD_LINE_ARGS * sizeof(char));

//passing pointer of input and element list 128
int shell_argc = parse(input, shell_argv);

int status = 0;
pid_t pid = fork();

if (pid < 0) { 
  fprintf(stderr, "Fork() failed\n"); }  // send to stderr

else if (pid == 0) { // child
    // fill in code for execvp(...)   <- this is what I'm having trouble with
  if (execvp(shell_argv[0], shell_argv) == -1 && strcmp(input, "history") != 0) {
    printf("Invalid command\n");
  }
} else { // parent -----  don't wait if you are creating a daemon (background) process
    while (wait(&status) != pid) { }
  }
return 0;
}
1 Answers

There are some errors in your code:

  1. shell_argv is an array of char*, memset length shoud be MAX_CMD_LINE_ARGS * sizeof(char*); or use a simple way char *shell_argv[MAX_CMD_LINE_ARGS] = {0};
  2. I can't find a standard function parse(), maybe you implemented it by your self. I have made a workround to run the code.
  3. memory for the element in shell_argv should be free at the end of founction.

The input argument of execvp is correct. Here is all the code for your reference.

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/wait.h>
#include <stdlib.h>
#define MAX_CMD_LINE_ARGS 255

int parse(char *input, char** shell_argv){
    shell_argv[0] = strdup("date");
    shell_argv[1] = strdup("+%s");
}
int execute(char *input)
{
    int i = 0;
    char *shell_argv[MAX_CMD_LINE_ARGS];
    memset(shell_argv, 0, MAX_CMD_LINE_ARGS * sizeof(char*));

    // passing pointer of input and element list 128
    int shell_argc = parse(input, shell_argv);

    int status = 0;
    pid_t pid = fork();

    if (pid < 0)
    {
        fprintf(stderr, "Fork() failed\n");
    } // send to stderr

    else if (pid == 0)
    {   // child
        // fill in code for execvp(...)   <- this is what I'm having trouble with
        if (execvp(shell_argv[0], shell_argv) == -1 && strcmp(input, "history") != 0)
        {
            printf("Invalid command\n");
        }
    }
    else
    { // parent -----  don't wait if you are creating a daemon (background) process
        while (wait(&status) != pid)
        {
        }
    }
    for(int i=0;i<MAX_CMD_LINE_ARGS;i++){
        if(shell_argv[i] != NULL){
            free(shell_argv[i]);
        }
    }
    return 0;
}

int main(){
    execute("date +%s");
    return 0;
}

Test result:

gxie@ubuntu20:~/test $ gcc main.c
gxie@ubuntu20:~/test $ ./a.out
1663837441
Related