Jump to content


Check out our Community Blogs

Register and join over 40,000 other developers!


Recent Status Updates

View All Updates

Photo
- - - - -

Trying to implement unix-like " | " command [C]

form

  • Please log in to reply
8 replies to this topic

#1 charles-eng

charles-eng

    CC Addict

  • Advanced Member
  • PipPipPipPipPip
  • 103 posts
  • Programming Language:C, Java, Assembly
  • Learning:C++, C#, Python, Transact-SQL

Posted 11 March 2012 - 02:31 PM

Hi, I've just began to get into unix like operating systems. I'm using Fedora and i like it a lot. Now I'm trying to implement the " | " command, but I've got really stuck.

My program, called T gets 2 arguments form the command line: "command1 and its parameters" and "command2 and it's parameters" and the idea is that I then create a child process that will be the first command (the command on the left of ' | ') and the parent will be the second command. The child process wil load the intended process with execl and its output will be redirected to the pipe, the parent process will wait for the child's output and use it as its input. This is my idea but I cant get it to work. Any help on what's wrong with my code would be heavily apreciated.


/* Trying to implement "|"

Example:

 ls -l | wc
 must be written as
 ./T "ls -l" "wc"
 
 */

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

int main(int argc, char *argv[])
{
   int p[2];
   unsigned char i, sizeComm;
   unsigned char *command;
   unsigned char *route;
   unsigned char *param;
   int state;
   pid_t pid;
   
   //buffers
   command=calloc(15,sizeof(unsigned char));
   route=calloc(17,sizeof(unsigned char));
   param=calloc(30,sizeof(unsigned char));
   
   //initializing pipe
   pipe(p);
   
   pid=fork();
   
   if(pid==0)
   {
      //child process is the first command to be executed (command on the left of "|")
      // will send its output to parent process (command on the right of "|")
      close(p[0]);
      //stdout now will be sent to parent process
      dup2(p[1],STDOUT_FILENO);
      
      //Now the command must be parsed
      
      //concatenating name of the command to "/bin/" or else  access denied
      
      for(i=0; ( command[i] = (argv[1])[i] ) != ' '; i++)
         ;
      strcpy(route,"/bin/");
      strcat(route+5,command);
      
      // parsing parameters to be sent to execl
      
      //pointing to the first space after the first command
      sizeComm = strlen(command);
      for(i=0;( param[i] = (argv[1])[i+sizeComm] ) ;i++)
         ;
      
      //Now I just call the first command
      execl(route,command,param,(char*)NULL);
      
      free(command);
      free(route);
      free(param);
      close(p[1]);
   }
   if(pid>0)
   {
      //Parent process is the second command, must wait for its child.
      close(p[1]);
      //stdin is now what the child process sent
      dup2(p[0],STDIN_FILENO);
      
      //parsing the second command
      
      //concatenating name of the command to "/bin/" or else  access denied
      
      for(i=0; ( command[i] = (argv[2])[i] ) != ' '; i++)
         ;
      strcpy(route,"/bin/");
      strcat(route+5,command);
      
      // parameters
      // parsing parameters to be sent to execl
      sizeComm = strlen(command);
      for(i=0;( param[i] = (argv[2])[i+sizeComm] ) ;i++)
         ;
      
      //waiting for the output of command1 before executing command2
      wait(&state);
      execl(route,command,param,(char*)NULL);
      close(p[0]);
      free(command);
      free(route);
      free(param);
   }
   if(pid<0)
   {
      perror("Failiure");
      return -1;
   }
   
   return 0;  
}


  • 0

#2 dargueta

dargueta

    I chown trolls.

  • Moderator
  • 4854 posts
  • Programming Language:C, Java, C++, PHP, Python, JavaScript, Perl, Assembly, Bash, Others
  • Learning:Objective-C

Posted 11 March 2012 - 03:03 PM

What's wrong with it?
  • 0

sudo rm -rf / && echo $'Sanitize your inputs!'


#3 charles-eng

charles-eng

    CC Addict

  • Advanced Member
  • PipPipPipPipPip
  • 103 posts
  • Programming Language:C, Java, Assembly
  • Learning:C++, C#, Python, Transact-SQL

Posted 11 March 2012 - 03:10 PM

What's wrong with it?


The program will compile successfully, but it outputs nothing to the console. As an example ./T "who" "wc -l" should print the same as who | wc -l , buy my program outputs nothing, it just finishes.
  • 0

#4 dargueta

dargueta

    I chown trolls.

  • Moderator
  • 4854 posts
  • Programming Language:C, Java, C++, PHP, Python, JavaScript, Perl, Assembly, Bash, Others
  • Learning:Objective-C

Posted 11 March 2012 - 03:29 PM

You're parsing the parameters to the second program wrong. Use strtok() to break up the argument strings, but do not use it directly on argv. That could result in some bad things happening.
  • 0

sudo rm -rf / && echo $'Sanitize your inputs!'


#5 charles-eng

charles-eng

    CC Addict

  • Advanced Member
  • PipPipPipPipPip
  • 103 posts
  • Programming Language:C, Java, Assembly
  • Learning:C++, C#, Python, Transact-SQL

Posted 11 March 2012 - 03:55 PM

You're parsing the parameters to the second program wrong. Use strtok() to break up the argument strings, but do not use it directly on argv. That could result in some bad things happening.


Ok, I'll use strtok(). Does the rest look ok? I ask that because I'm new at POSIX so I'm not so sure of what I'm doing in my code is ok. I'm trying to code this stuff for the sake of learning.
Thanks.
  • 0

#6 dargueta

dargueta

    I chown trolls.

  • Moderator
  • 4854 posts
  • Programming Language:C, Java, C++, PHP, Python, JavaScript, Perl, Assembly, Bash, Others
  • Learning:Objective-C

Posted 11 March 2012 - 03:58 PM

At a glance, yes. I'm busy at the moment and can't do my own derivation to see where you might be messing up.
  • 0

sudo rm -rf / && echo $'Sanitize your inputs!'


#7 charles-eng

charles-eng

    CC Addict

  • Advanced Member
  • PipPipPipPipPip
  • 103 posts
  • Programming Language:C, Java, Assembly
  • Learning:C++, C#, Python, Transact-SQL

Posted 11 March 2012 - 04:03 PM

At a glance, yes. I'm busy at the moment and can't do my own derivation to see where you might be messing up.

Ok, thanks for your time man, I'll keep working on this.
  • 0

#8 Pieter

Pieter

    CC Lurker

  • New Member
  • Pip
  • 3 posts

Posted 17 March 2012 - 01:43 PM

You're doing the parsing of the command line wrong. See here for basic review and solution.

Regards
Pieter
  • 0

#9 charles-eng

charles-eng

    CC Addict

  • Advanced Member
  • PipPipPipPipPip
  • 103 posts
  • Programming Language:C, Java, Assembly
  • Learning:C++, C#, Python, Transact-SQL

Posted 17 March 2012 - 03:57 PM

You're doing the parsing of the command line wrong. See here for basic review and solution.

Regards
Pieter


Thanks man, I knew the parsing was wrong, but I didn't imagine the problem would be the whitespace...
  • 0





Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download