Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

Unix Minishell Question Pastebin: http://pastebin.com/v5uU1XbM (Fork begins on l

ID: 3765365 • Letter: U

Question

Unix Minishell Question

Pastebin: http://pastebin.com/v5uU1XbM (Fork begins on line 117)

How can I get an integer value for the status of a background process? My aim is to eventually mimick the "jobs" command in shell which displays something like this for background processes:

jobs:

[0] Running sleep 20 &

[1] Running sleep 15 &

[2] Done sleep 5 &

As of now I can print everything but the status.

Also if you see anything else I may need to fix, it would be greatly appreciated.Thank you

Explanation / Answer

#include <stdlib.h>

#include <errno.h>

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <unistd.h>

#include <sys/types.h>

#include <sys/time.h>

#include <sys/resource.h>

#include <signal.h>

#include <wait.h>

#define DEFAULT_PROMPT " Log710H2014%>"

#define EXIT_CMD "exit"

#define CD_CMD "cd"

#define JOB_LIST_CMD "aptaches"

#define HOME_ENV_VAR "HOME"

#define NEW_LINE " ************************************************** "

#define BCG_CMD_FLAG "&"

void cd_handler(int argc, char *argv[]);

int lire(char *chaine, int longueur);

char** init_command(int* size,char *str);

int execProg(int *argc, char **argv);

int execProgBg(int *argc, char **argv);

void sigchldHandler(int sig_num);

void aptachesHandler();

void cleanJobList(pid_t *childpid);

struct beanProcess {

    pid_t pid;

    int job_num;

    char *command;

};

void ajoutProcess(struct beanProcess bp);

struct beanProcess beans[20];

int jobCount = 1;

int main() {

    signal(SIGCHLD, sigchldHandler);

    printf(NEW_LINE);

    printf("Bienvenue sur le shell de l'equipe 1");

    printf(NEW_LINE);

    while(1){

        char str[200]="";

        printf(DEFAULT_PROMPT);

        lire(str, 200);

        int commArgsC = 0, bg = 0;

        char** comms = init_command(&commArgsC, str);

        if(commArgsC == 0){

            //printf("Saisie vide, veuillez entrez une commande.");

            continue;

        }

        if(strcmp(comms[commArgsC-1], BCG_CMD_FLAG) == 0){

            bg = 1;

            comms[commArgsC-1] = 0;

        }

        if(strcmp(comms[0], CD_CMD) == 0){

            cd_handler(commArgsC, comms);

            commArgsC = commArgsC -1;

        }

        else if (strcmp(comms[0], JOB_LIST_CMD) == 0){

            aptachesHandler();

        }

        else if (strcmp(comms[0], EXIT_CMD) == 0){

            int beansVide = 1;

            for(int i = 0; i < jobCount -1 ; i++){

                if(beans[i].pid != 0){

                    beansVide = 0;

                }

            }

            if(beansVide){

                exit(0);

            }else{

                printf(" Impossible d'arreter le programme, des processus sont encore en cours d'éxécution ");

            }

        }

        else {

            if(bg){

                execProgBg(&commArgsC, comms);

            }

            else{

                execProg(&commArgsC, comms);

            }

        }

    }

    return 0;

}

void cd_handler(int argc, char *argv[]){

    char buff[512];

    char * directory;

  if(argc < 2){

        directory = getenv(HOME_ENV_VAR);

    }else if (argc == 2){

        directory = argv[1];

    }else{

        exit(1);

    }

    if (chdir(directory) == -1) {

        printf ("Erreur de changement de repertoire actif", strerror (errno));

    }else{

        if (getcwd(buff, sizeof(buff)) == NULL)

            perror("Impossible d'afficher le repertoire courant");

        else

            printf("le repertoire courant est: %s ", buff);

    }

}

char** init_command(int* size, char* str){

    char ** res = NULL;

    char * p    = strtok (str, " ");

    int n_spaces = 0;

    while (p) {

        res = realloc (res, sizeof (char*) * ++n_spaces);

        if (res == NULL){

            exit (-1);

        }

        res[n_spaces-1] = p;

        p = strtok (NULL, " ");

    }

    res = realloc (res, sizeof (char*) * (n_spaces+1));

    res[n_spaces] = 0;

    *size = n_spaces;

    return res;

}

int lire(char *chaine, int longueur)

{

    char *positionEntree = NULL;

    if (fgets(chaine, longueur, stdin) != NULL)

    {

        positionEntree = strchr(chaine, ' ');

        if (positionEntree != NULL)

        {

            *positionEntree = '';

        }

        return 1;

    }

    else

    {

        return 0;

    }

}

int execProg(int *argc, char **argv){

    char path[30] = "/bin/";

    strcat(path,argv[0]);

    printf("Voici le resultat de l'execution de votre commande ");

    pid_t pid;

    pid = fork();

    if (pid < 0) {

        perror("Creation de processus avec fork echouee");

        exit(-1);

    }

    else if (pid == 0) {

        if(execvp(argv[0], argv) == -1){

            perror("execv");

            return EXIT_FAILURE;

        }

    }

    else {

        struct rusage rusg;

        long temp, tempCpu;

        wait (NULL);

       sleep 20 &

       sleep 15 &

        getrusage(RUSAGE_CHILDREN, &rusg);

        printf(" Statistique de la commande %s: ", argv[0]);

        temp = (rusg.ru_utime.tv_sec * 1000) + (rusg.ru_utime.tv_usec / 1000);

        tempCpu = (rusg.ru_stime.tv_sec * 1000) + (rusg.ru_stime.tv_usec / 1000);

        printf(" Le temps wall-clock (ms): %ld", temp);

        printf(" Le temps CPU (ms) %ld", tempCpu);

        printf(" NB interruptions volontaires: %ld", rusg.ru_nvcsw);

        printf(" NB interruptions involontaires: %ld", rusg.ru_nivcsw);

        printf(" NB defaults de pages: %ld", rusg.ru_majflt);

        printf(" NB defaults de pages satifaits du noyau : %ld", rusg.ru_minflt);

    }

    return EXIT_SUCCESS;

}

int execProgBg(int *argc, char **argv){

    pid_t pid;

    pid = fork();

    if (pid < 0) {

        perror("Creation de processus avec fork echouee");

        return EXIT_FAILURE;

    }

    else if (pid == 0) {

        if(execvp(argv[0], argv) == -1){

            perror("execvp");

            return EXIT_FAILURE;

        }

    }

    else {

        printf("[%d] %d", jobCount, pid);

        struct beanProcess bP;

        bP.pid = pid;

        bP.job_num = jobCount;

        bP.command = argv[0];

        ajoutProcess(bP);

    }

    return EXIT_SUCCESS;

}

void sigchldHandler(int sig_num)

{

    int status;

    pid_t childPid;

    childPid = waitpid(-1, &status, WNOHANG);

    cleanJobList(&childPid);

}

void ajoutProcess(struct beanProcess bP){

    beans[jobCount-1] = bP;

    jobCount++;

}

void aptachesHandler(){

    for(int i = 0; i < jobCount-1 ; i++){

        printf("[%d] %d %s ", beans[i].job_num, beans[i].pid, beans[i].command) ;

    }

}

void cleanJobList(pid_t *childpid){

    printf("clean performed on %d", *childpid);

    for(int i = 0; i < jobCount-1 ; i++){

        if(beans[i].pid == *childpid){

            beans[i].pid = 0;

            beans[i].job_num = 0;

            beans[i].command = NULL;

        }

    }

}

Hire Me For All Your Tutoring Needs
Integrity-first tutoring: clear explanations, guidance, and feedback.
Drop an Email at
drjack9650@gmail.com
Chat Now And Get Quote