Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- *
- * NAME:
- * digenv - a program for easy handling of environmental variables
- *
- * SYNTAX:
- * ./digenv [options] PATTERN [FILE...]
- * ./digenv [options] [-e PATTERN | -f FILE] [FILE...]
- *
- * DESCRIPTION:
- * The program digenv is supposed to help the user display the
- * environment variables of the system in an easy way using
- * pipes and built in system calls.
- *
- * OPTIONS:
- * see grep(1)
- *
- * EXAMPLES:
- * ./digenv -i PATH
- *
- * SEE ALSO:
- * grep(1), sort(1), printenv(1), less(1), more(1)
- *
- * NOTES:
- * If any parameter is entered in the wrong way, the program will exit.
- *
- * AUTHOR:
- * Rickard Eriksson - rieri@kth.se
- * Rebecca Ahlstrand - reah@kth.se
- */
- #include <stdlib.h>
- #include <stdio.h>
- #include <unistd.h>
- #include <string.h>
- #include <sys/wait.h>
- #define READ_PIPE (0) /* defines that the integer 0 is bound to READ_PIPE */
- #define WRITE_PIPE (1) /* defines that the integer 1 is bound to WRITE_PIPE */
- pid_t printenvpid; /* holds the pid for the child process printenv */
- pid_t greppid; /* holds the pid for the child process grep */
- pid_t sortpid; /* holds the pid for the child process sort */
- pid_t pagerpid; /* holds the pid for the child process pager */
- int pipe_print[2]; /* variable to hold the file descriptors for the function printenv */
- int pipe_grep[2]; /* variable to hold the file descriptors for the function grep */
- int pipe_sort[2]; /* variable to hold the file descriptors for the function sort */
- int ret; /* variable to hold returns from system calls for error handling */
- /* Function pipe_close(int pipe[])
- *
- * The function takes an int array that contains the file descriptors of a pipe and
- * closes them. There's also error handling if any of the system calls gets an error.
- */
- void pipe_close(int p[]) {
- ret = close(p[READ_PIPE]); /* system call to close to end
- * the READ end of a pipe */
- if (ret < 0) { /* if ret < 0 then there has been
- * an error and the program exits */
- perror("Read pipe closure failed");
- exit(EXIT_FAILURE);
- }
- ret = close(p[WRITE_PIPE]); /* system call to close to end
- * the WRITE end of a pipe */
- if (ret < 0) { /* if ret < 0 then there has been
- * an error and the program exits */
- perror("Write pipe closure failed");
- exit(EXIT_FAILURE);
- }
- }
- /* Function printenv()
- *
- * Writes all the environment variables on the system to the pipe pipe_print.
- * If errors occur there is error handling.
- */
- void printenv() {
- char *args[] = { "printenv", NULL }; /* array that defines which system call to use */
- ret = dup2(pipe_print[WRITE_PIPE], STDOUT_FILENO); /* dup2 copys the file descriptor
- * from stdout to the pipe */
- if (ret < 0) { /* if ret < 0 then there has been
- * an error and the program exits */
- perror("Dup failed");
- exit(EXIT_FAILURE);
- }
- pipe_close(pipe_print); /* closing of pipe after use */
- execvp(args[0], args); /* executes the program defined in args[0] */
- perror("exec failed");
- exit(EXIT_FAILURE);
- }
- /* Function grep(char **arguments)
- *
- * Takes a list of parameters to pass on to the system function grep(1) and
- * uses these on the list passed on from printenv via the pipe pipe_print.
- */
- void grep(char **arguments) {
- ret = dup2(pipe_print[READ_PIPE], STDIN_FILENO); /* dup2 copys the file descriptor
- * from stdin to the pipe */
- if (ret < 0) { /* if ret < 0 then there has been
- * an error and the program exits */
- perror("Dup failed");
- exit(EXIT_FAILURE);
- }
- /* set write end of pipe as stdout for this child process */
- ret = dup2(pipe_grep[WRITE_PIPE], STDOUT_FILENO); /* dup2 copys the file descriptor
- * from stdout to the pipe */
- if (ret < 0) { /* if ret < 0 then there has been
- * an error and the program exits */
- perror("Dup failed");
- exit(EXIT_FAILURE);
- }
- pipe_close(pipe_print); /* closing of pipe after use */
- pipe_close(pipe_grep); /* closing of pipe after use */
- execvp("grep", arguments); /* executes the program defined in args[0] */
- perror("exec failed");
- exit(EXIT_FAILURE);
- }
- /* Function sort(int p[])
- *
- * Sorts a list of environment variables in alphabetical order. The list of variables are
- * either all the variables passed from printenv or the function grep depending on the users
- * choice. int p[] is the pipe that contains the list that is to be sorted.
- */
- void sort(int p[]) {
- char *args[] = { "sort", NULL }; /* array that defines which system call to use */
- ret = dup2(p[READ_PIPE], STDIN_FILENO); /* dup2 copys the file descriptor
- * from stdin to the pipe */
- if (ret < 0) { /* if ret < 0 then there has been
- * an error and the program exits */
- perror("Dup failed");
- exit(EXIT_FAILURE);
- }
- ret = dup2(pipe_sort[WRITE_PIPE], STDOUT_FILENO); /* dup2 copys the file descriptor
- * from stdout to the pipe */
- if (ret < 0) { /* if ret < 0 then there has been
- * an error and the program exits */
- perror("Dup failed");
- exit(EXIT_FAILURE);
- }
- pipe_close(p); /* closing of pipe after use */
- pipe_close(pipe_sort); /* closing of pipe after use */
- execvp(args[0], args); /* executes the program defined in args[0] */
- perror("exec failed");
- exit(EXIT_FAILURE);
- }
- /* Function pager()
- *
- * The function that decides the pager that is to be used when displaying the sorted list.
- * If the environment variable "PAGER" contains a default the program will use it,
- * otherwise the default is to use less().
- */
- void pager() {
- char *args[] = { getenv("PAGER"), NULL };
- if (args[0] == NULL) {
- args[0] = "less";
- }
- ret = dup2(pipe_sort[READ_PIPE], STDIN_FILENO); /* dup2 copys the file descriptor
- * from stdin to the pipe */
- if (ret < 0) { /* if ret < 0 then there has been
- * an error and the program exits */
- perror("Dup failed");
- exit(EXIT_FAILURE);
- }
- pipe_close(pipe_sort); /* closing of pipe after use */
- ret = execvp(args[0], args); /* executes the program defined in args[0] */
- if (ret < 0) { /* if ret < 0 then there has been an error */
- args[0] = "more"; /* if the system can't find less(), then more() is used */
- execvp(args[0], args); /* executes the program defined in args[0] */
- }
- perror("exec failed");
- exit(EXIT_FAILURE);
- }
- /* The main program
- *
- * The program takes two parameters, first the input counter and then the array och inputs.
- * Main.c is the program that creates all the child processes, pipes and handles parts of
- * the error handling. At the end of the program it waits for all the child-processes to
- * finish.
- */
- int main(int argc, char **argv) {
- int status; /* Variable to indicate the status of a child process */
- if (pipe(pipe_print) < 0) { /* opening pipe to printenv, if the returned
- * value < 0 an error has occured */
- perror("pipe failed");
- return EXIT_FAILURE;
- }
- printenvpid = fork(); /* creates a child process for the printenv function */
- if (printenvpid < 0) { /* if this is TRUE, an error has
- * occured and the program is shut down */
- perror("fork failed");
- return EXIT_FAILURE;
- }
- if (printenvpid == 0) { /* if this is TRUE then the program
- * is in the child process */
- printenv(); /* a call to the function printenv() */
- }
- if (argc > 1) { /* if this is TRUE, input to the function
- * grep exists. If FALSE then the program
- * skips the grep() function and goes directly to sort()*/
- if (pipe(pipe_grep) < 0) { /* opening pipe to grep, if the returned
- * value < 0 an error has occured */
- perror("pipe failed");
- return EXIT_FAILURE;
- }
- greppid = fork(); /* creates a child process for the grep function */
- if (greppid < 0) { /* if this is TRUE, an error has
- * occured and the program is shut down */
- perror("fork failed");
- return EXIT_FAILURE;
- }
- if (greppid == 0) { /* if this is TRUE then the program
- * is in the child process */
- grep(argv); /* a call to the function grep() */
- }
- pipe_close(pipe_print); /* closing of pipe after use */
- if (pipe(pipe_sort) < 0) { /* opening pipe to sort, if the returned
- * value < 0 an error has occured */
- perror("pipe failed");
- return EXIT_FAILURE;
- }
- sortpid = fork(); /* creates a child process for the sort function */
- if (sortpid < 0) { /* if this is TRUE, an error has occured
- * and the program is shut down */
- perror("fork failed");
- return EXIT_FAILURE;
- }
- if (sortpid == 0) { /* if this is TRUE then the program
- * is in the child process */
- sort(pipe_grep); /* a call to the function sort() */
- }
- pipe_close(pipe_grep); /* closing of pipe after use */
- ret = waitpid(greppid, &status, 0); /* this makes the program wait for grep
- * to finish to avoid bypassing grep */
- if( ret < 0 || status != 0) { /* if waitpid() fails or the child process
- * returns a status != 0 an error has occured */
- perror( "waitpid() for grep failed" );
- exit( 1 );
- }
- } else { /* this part executes if no parameters to grep is entered */
- if (pipe(pipe_sort) < 0) { /* opening pipe to sort, if the returned
- * value < 0 an error has occured */
- perror("pipe failed");
- return EXIT_FAILURE;
- }
- sortpid = fork(); /* creates a child process for the sort function */
- if (sortpid < 0) { /* if this is TRUE, an error has
- * occured and the program is shut down */
- perror("fork failed");
- return EXIT_FAILURE;
- }
- if (sortpid == 0) { /* if this is TRUE then the program
- * is in the child process */
- sort(pipe_print); /* a call to the function sort() */
- }
- pipe_close(pipe_print); /* closing of pipe after use */
- }
- pagerpid = fork(); /* creates a child process for the pager function */
- if (pagerpid < 0) { /* if this is TRUE, an error has
- * occured and the program is shut down */
- perror("fork failed");
- return EXIT_FAILURE;
- }
- if (pagerpid == 0) { /* if this is TRUE then the program
- * is in the child process */
- pager(); /* a call to the function pager() */
- }
- pipe_close(pipe_sort); /* closing of pipe after use */
- ret = waitpid(printenvpid, &status, 0); /* this makes the program wait for printenv
- * to finish to avoid bypassing printenv */
- if( ret < 0 || status != 0) { /* if waitpid() fails or the child process
- * returns a status != 0 an error has occured */
- perror( "waitpid() for printenv failed" );
- exit( 1 );
- }
- ret = waitpid(sortpid, &status, 0); /* this makes the program wait for sort
- * to finish to avoid bypassing sort */
- if( ret < 0 || status != 0) { /* if waitpid() fails or the child process
- * returns a status != 0 an error has occured */
- perror( "waitpid() for sort failed" );
- exit( 1 );
- }
- ret = waitpid(pagerpid, &status, 0); /* this makes the program wait for pager to
- * finish to avoid bypassing pager */
- if( ret < 0 || status != 0) { /* if waitpid() fails or the child process
- * returns a status != 0 an error has occured */
- perror( "waitpid() for pager failed" );
- exit( 1 );
- }
- exit(0);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement