The UNIX and Linux Forums  


Go Back   The UNIX and Linux Forums > Top Forums > High Level Programming
.
google unix.com



High Level Programming Post questions about C, C++, Java, SQL, and other programming languages here.

More UNIX and Linux Forum Topics You Might Find Helpful
Thread Thread Starter Forum Replies Last Post
new operator Nagapandi High Level Programming 4 02-02-2009 12:04 AM
SED * operator sinpeak Shell Programming and Scripting 7 12-24-2008 10:07 AM
Or operator with if babom HP-UX 1 10-03-2007 04:56 PM
Help (Piping ls, tr, cut) scan Shell Programming and Scripting 2 02-11-2006 08:40 AM
And operator rcarnesiii Shell Programming and Scripting 4 08-04-2005 03:04 AM

Reply
English Japanese Spanish French German Portuguese Italian Dutch Swedish Russian Norwegian Hungarian Hebrew Danish Bulgarian Greek Powered by Powered by Google
 
LinkBack Thread Tools Search this Thread Rate Thread Display Modes
  #1 (permalink)  
Old 4 Weeks Ago
taiL taiL is offline
Registered User
  
 

Join Date: Sep 2009
Posts: 11
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 (permalink)  
Old 4 Weeks Ago
binlib binlib is offline
Registered User
  
 

Join Date: Aug 2009
Location: New Jersey
Posts: 63
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 (permalink)  
Old 4 Weeks Ago
opt!kal opt!kal is offline
Registered User
  
 

Join Date: Oct 2009
Posts: 1
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; 4 Weeks Ago at 01:29 AM..
Reply

Bookmarks

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On




All times are GMT -4. The time now is 01:48 PM.


Powered by: vBulletin, Copyright ©2000 - 2006, Jelsoft Enterprises Limited. Language Translations Powered by .
vBCredits v1.4 Copyright ©2007 - 2008, PixelFX Studios
The UNIX and Linux Forums Content Copyright ©1993-2009. All Rights Reserved.Ad Management by RedTyger

Content Relevant URLs by vBSEO 3.2.0