Hi there,

So im working on this assignment where the user is supposed to input a variety of UNIX commands and they must behave as if one typed it into the terminal. My current problem lies with when a user tries to redirect the inputted commands to some file. Currently it only works when a user has the redirect symbol along with one command:

ls -l > temp.txt

However if I try to input:
ls -l | sort -n

or even:

ls -l | sort -n > temp.txt

I just segfault. I know the problem most likely lies in how I wrote the redirect option, but I cant seem to figure out how to make it so that the two above commands work.

Any Help would be greatly appreciated!

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <fcntl.h>

/*get args function*/

#define MAXARGS 256
char ** getargs(char * cmd) {
	// assumes that cmd ends with NULL
	char** argsarray;
	int nargs = 0;
	int nlen = strlen(cmd);
	int i = 0;
	argsarray = (char**) malloc(sizeof(char*) * MAXARGS);
	argsarray[0] = strtok(cmd," ");
	i = 0;
	while (argsarray[i] != NULL){
		i++;
		argsarray[i] = strtok(NULL," ");
	}
	return argsarray;
}


int main(void){

  pid_t childpid;
  int fd[256][2];
  char cmd[256];
  char * sepCmd[256];
  char * pch;
  char * srch;

  printf("Please enter a command sequence: \n");
  gets(cmd);
  //scanf("%s", cmd);
  printf("You have entered: %s \n", cmd);
  

  printf("Attempting to split up command: \n");
  pch = strtok (cmd, "|");
  
//This is where I think it goes wrong
  srch = strchr(cmd, '>');
  *srch++ = '\0'
  while (*srch == ' ') ++srch;

  int count = 0;  
    while (pch != NULL && count < 256) {
      printf("%s\n", pch);
      sepCmd[count] = pch;
      printf("The value in this array value is: %s\n", sepCmd[count]);
      pch = strtok (NULL, "|");
      count++;
  }
  
  char ** argue;
  int k;
  
  /* Block that deals with the first command given by the user */
  k = 0;
  pipe(fd[k]);
  if(!fork()) {
	  	dup2(fd[k][1], STDOUT_FILENO);
		close(fd[k][0]);
		argue = getargs(sepCmd[k]);
		execvp(argue[0], argue);
		perror(argue[0]);
		exit(0);
  }

  /*Loop that will control all other comands except the last*/
  for(k = 1; k <= count - 2; k++) {
	  close(fd[k-1][1]);
	  pipe(fd[k]);
	  
	  if(!fork()) {
		  close(fd[k][0]);
		  dup2(fd[k-1][0], STDIN_FILENO);
		  dup2(fd[k][1], STDOUT_FILENO);
		  argue = getargs(sepCmd[k]);
		  execvp(argue[0], argue);
		  perror(argue[0]);
		  exit(0);
	  }
  }
  
  
  /*Block that will take care of the last command in the sequence*/
  k = count - 1;
  
  close(fd[k-1][1]);
  if(!fork()) {
	  dup2(fd[k-1][0], STDIN_FILENO);
	  argue = getargs(sepCmd[k]);
          if (srch) dup2(open(srch, O_RDWR|O_CREAT), STDOUT_FILENO);
	  execvp(argue[0], argue);
	  perror(argue[0]);
	  exit(0);
  }
  while(waitpid(-1, NULL, 0) != -1);
}

So a little update,

I changed gets to fgets and it seems like it will take any amount of comannds piped together, but only if it ends with a redirection operator or else I get errors like:

<COMMAND>: invalid option -- '

where COMMAND is the last command in the sequence

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.