Os/spring2019/run-commands

From Maryville College CS Wiki
< Os‎ | spring2019
Jump to: navigation, search

runcommand.h

/* Run a process and wait for it to exit */
void run_command(char **args);

/* Run a two way pipe */
void run_simple_pipe(char **args1, char **args2);

runcommand.c

#include <unistd.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>


void 
run_command(char **args)
{
    int pid;

    /* fork our process */
    pid = fork();

    /* in the child, we exec */
    if(pid == 0) { /* if(!pid) */
        execvp(args[0], args);
	fprintf(stderr, "Could not execute %s.\n", args[0]);
	exit(1);
    }

    /* the parent waits for the death of the child */
    wait(NULL);
}


/* Run a two way pipe */
void 
run_simple_pipe(char **args1, char **args2)
{
   int pid;
   int p[2]; /* our pipe */

   /* create the pipe */
   pipe(p);

   /* fork the left hand side */
   pid = fork();
   if(pid == 0) {
       close(1);  /* close stdout */
       dup(p[1]); /* duplicate the write side to stdout */
       close(p[0]); 
       close(p[1]); /* close extraneous file descriptiors */
       execvp(args1[0], args1);
       fprintf(stderr, "Could not execute %s.\n", args1[0]);
       exit(1);
   }

   /* fork the right hand side */
   pid = fork();
   if(pid == 0) {
       close(0); /* close stdin */
       dup(p[0]); /* duplicate the read end to stdin */
       close(p[0]);
       close(p[1]); /* get rid of extra descriptors */
       execvp(args2[0], args2);
       fprintf(stderr, "Could not execute %s.\n", args2[0]);
       exit(1);
   }

   /* close extra descriptors */
   close(p[0]);
   close(p[1]);

   /* wait on our children */
   wait(NULL);
   wait(NULL);
}

run.c

#include <stdio.h>
#include <stdlib.h>
#include "runcommand.h"

/* Run the command line specified on our own command line */
int main(int argc, char **argv)
{
  /* check the command line */
  if(argc < 2) {
      fprintf(stderr, "Usage: %s <command> <args>", argv[0]);
      exit(1);
  }

  /* execute the process */
  printf("Executing %s\n", argv[1]);
  run_command(argv + 1);
  printf("Finished %s\n", argv[1]);
}

simplepipe.c

#include <stdio.h>
#include <stdlib.h>
#include "runcommand.h"

int main(int argc, char **argv)
{
    int cmd2; /* index of command 2 in argv */

    if(argc < 4) {
       fprintf(stderr, "Usage: %s cmd1 @ cmd2\n", argv[0]);
       exit(1);
    }

    /* process the command line */
    for(int i=1; i<argc; i++) {
        if(argv[i][0] == '@') {
	   cmd2=i+1;
	}
    }
    argv[cmd2-1]=NULL;

    printf("Running Pipeline\n");
    run_simple_pipe(argv+1, argv+cmd2);
    printf("Finished Pipeline\n");
}

Makefile

CFLAGS=-g
ALL=run simplepipe

all: $(ALL)
run: run.c runcommand.o
simplepipe: simplepipe.c runcommand.o
clean:
	rm -f $(ALL) *.o