C: piping and the redirect operator


 
Thread Tools Search this Thread
Top Forums Programming C: piping and the redirect operator
# 1  
Old 10-28-2009
C: piping and the redirect operator

Hi there,

So im having a bit of trouble here finishing up a program that involves the use of piping various unix commands in c. To be exact, I am struggling with how to make the redirect operator work.

Essentially the program it self will run a bunch of piped commands in c. For example you can give it the input:

ls -l | sort -n -r | head -n 3

and it should work as if you typed it into the terminal. My problem arises when I try to do:
ls -l | sort -n -r | head -n 3 > output.txt

My inital attempt was to search the string to see if the redirect operator existed. If so, then it would simply take some special branch where it could execute it, if not it would continue as if it did not exist. However my implementation to try this is shaky at best, so any explanation, help of what I should be doing would be greatly appreciated.

Code is attached below.

Code:
#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;

  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, "|");
  

  /* My initial idea of how to tackle redirection
  char * srch;
  srch = strchr(cmd, '>');
  int reDir;

  while(cmd != NULL) {
  if (srch != NULL){
    printf("redirect operator found\n");
    reDir = 1;
          
  }
  srch = strchr(srch+1, '>');
  }
  */
  
  
  
  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;
  
  //  if(reDir){
  //argue = getargs(sepCmd[k]);
  //open(argue[count], O_RDWR);
    
  //if(!fork()){
  //  close(fd[0]);
  //  close(fd[1]);
  //  dup2(fd[k-1][0], STDOUT_FILENO);
  //  execl("/bin/>", argue[count]);}
  //}
  //else{
     
  close(fd[k-1][1]);
  if(!fork()) {
	  dup2(fd[k-1][0], STDIN_FILENO);
	  argue = getargs(sepCmd[k]);
	  execvp(argue[0], argue);
	  perror(argue[0]);
	  exit(0);
  }
  // }
  while(waitpid(-1, NULL, 0) != -1);
}

# 2  
Old 10-28-2009
The professor's code is working without the redirection. To add redirection at the end, all you need to do is
Code:
locate the ">" position with: srch = strchr(cmd, '>');
terminate the cmd at that position: *srch++ = '\0'
advance srch to skip the ">" and blanks: while (*srch == ' ') ++srch;

before parsing the command line. Then open/create srch for writing and dup2 the fd with:
Code:
if (srch) dup2(open(srch, O_RDWR|O_CREAT), STDOUT_FILENO);

before execvp in the last child
# 3  
Old 10-29-2009
Hi there,

This is the Original Poster (I had made the initial post on my partner's account). Anyways thank you for the reply! The code worked like a charm for the most part. Now it seems to only work when the redirect operator is present in the user inputted commands. Im guessing this is due to my placing of the first chunk of code you had posted. In my code that snipped is currently placed right before:

Code:
while (pch != NULL && count < 256) {

This is the location you had intended?

Thanks in advance

---------- Post updated 10-29-09 at 10:57 AM ---------- Previous update was 10-28-09 at 11:51 PM ----------

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

Last edited by opt!kal; 10-29-2009 at 02:29 AM..
Login or Register to Ask a Question

Previous Thread | Next Thread

10 More Discussions You Might Find Interesting

1. Ubuntu

Piping with grep

Hi everybody, I have a big file with blast results (if you know what this means, otherwise look at it just as a text file with a specific form). I am trying to extract some ids from within this file, which have certain parameters. For example, some Of my IDs have the term 'No hit results'... (6 Replies)
Discussion started by: frymor
6 Replies

2. Ubuntu

Piping with grep

Hi everybody, I have a big file with blast results (if you know what this means, otherwise look at it just as a text file with a specific form). I am trying to extract some ids from within this file, which have certain parameters. For example, some Of my IDs have the term 'No hit results'... (1 Reply)
Discussion started by: frymor
1 Replies

3. UNIX for Dummies Questions & Answers

Piping GREP

Hi, I need to use a double grep so to speak. I need to grep for a particular item say BOB and then for each successful result I need to grep for another item say SMITH. I tried grep "BOB" filename | grep "SMITH" but it does not seem to work. I can achieve my desired result using an... (12 Replies)
Discussion started by: mojoman
12 Replies

4. Shell Programming and Scripting

Piping in Perl

Hi All, I am trying to perform the below csh code in Perl, but i am unfamiliar with Perl. Can anybody give me some advice on it ? Csh Code: cat filename |grep AAA| grep BBB| awk '{print("already_appended")' (11 Replies)
Discussion started by: Raynon
11 Replies

5. Programming

Piping Question

I have a piping question, I am trying to implement piping on my own shell and am having some trouble...esentially I am trying to make something to do command|command|command. I can get it to work fine if the last pipe command is not forked, but executes in the shell and then exits..but I need it... (2 Replies)
Discussion started by: mtobin1987
2 Replies

6. Shell Programming and Scripting

Piping to ex from a script

Is anyone piping commands to ex from scripts? I.E. echo '%s/change this/to that/\nwq' | ex file.name I've been using it for years with AIX, Solaris, SGI, with variations ksh and Mandriva and others with pdksh. I've just started using CentOS with ksh and it no longer works. I've tried single... (2 Replies)
Discussion started by: mph
2 Replies

7. UNIX for Dummies Questions & Answers

Piping in UNIX

All, I am a UNIX novice with a question that I hope you can help me with. I have a UNIX application called "Tole" that formats and displays specific information about customers. I can display the information for up to 30 customers by seperating customer IDs using commas in this format: Tole -c... (3 Replies)
Discussion started by: simo007
3 Replies

8. Programming

Help with piping program

Hi, I am trying to write a program that will pipe any number of programs together like in the linux shell. As an example, the below code tries to execute "cat data | grep int | cut -b 1-10." The problem is that the programs never get executed for some reason. It seems like the first program... (3 Replies)
Discussion started by: PuppyHusher
3 Replies

9. Shell Programming and Scripting

piping

I am using pipes (specifically piping out) in Perl to put an array from one file into an array in a different file. I can't figure out how to transfer the array. I kow how to open the pipe : open (FILEHANDLE, "| file") or die~ but how do I transfer the array. I think it has something to do with... (1 Reply)
Discussion started by: lnatz
1 Replies

10. Shell Programming and Scripting

Help (Piping ls, tr, cut)

I have to: pipe ls, tr, and cut to output the size (in bytes) and name of all of the files/dirs in the current directory (including any hidden ones), with the size at the beginning of the line, followed by a single tab character, followed by the the filename. I don't know what the point of... (2 Replies)
Discussion started by: scan
2 Replies
Login or Register to Ask a Question