dmbcalado / Pipex

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Pipex (grade : 125)


https://user-images.githubusercontent.com/76601369/110706242-77158d00-81ef-11eb-8085-5da6f0988553.jpg

This project has to goal to understand and use forks, pipes and redirections.

In the mandatory part, the task given is to have a program that would perform the same task as in bash of the following command :

< inputfile cmd1 | cmd 2 > outputfile

with the following call:

./pipex inputfile cmd1 cmd 2 outputfile

Where :

  •  inputfile  -> the name of the file to take as input.
  • outputfile -> the name of the file to take or create as output.
  • cmd 1       -> the first command to execute, with any flag or argument required.
  • cmd 2       -> the second command to execute, and again, with any flag or argument required.

example :

$> ./pipex inputfile.txt "grep world" wc outputfile.txt

should perform the same as:

$> < inputfile.txt grep world | wc > outputfile.txt

That is, it should take input file descriptor as the input for the command grep world, take the output as the input to the wc command, and send the output to the to the output file descriptor.

But in order to do so, we need to be able to both run the commands, and to modify its inputs and outputs. This is where the execve() function comes, as the function that will execute our commands, and dup2() function will redirect the input and output of both the process and each file descriptor needed. But this raises a small issue, the exec family functions kill the program. Also, this raises the problem that we cant send the output of one command to another as straight forward as it may sound.

This requires an introduction to two concepts:

Forks and pipes. Creating the fork is the solution to the execve() function killing the program, since by creating a fork we are creating a new process (the child process), and by so we can kill the child process. The pipe will solve how to transfer information to one command to the other since by using dup2 we can set the fd of input of the first child as the inputfile file descriptor, and the output to the write (1) entrance of the pipe.

On the second child, we set the input as the read (0) entrance of the pipe and the output is the file descriptor of the outputfile.

I've created an ilustration to visualize what was said:


The bonus part of the work was to not also be able to run:

< inputfile cmd1 | (...) cmdN > outputfile

with the following call:

./pipex inputfile cmd1 (...) cmdN outputfile

and if called, to perform the same task as an heredoc, that is take the input of the terminal as the input to the command till the EOF is given or CNTRL D. They specify the usage to only one particular case:

<< key cmd1 | (...) cmdN >> outputfile

with the following call:

./pipex heredoc key cmd1 (...) cmdN outputfile\

So the task now is to perform the same task as an heredoc and to append the output of the commands ran on the heredoc in the outputfile.

The logic used was quite similar to the one described above, to append was just to change the flag 0_TRUNC to 0_APPEND, and the heredoc could be both a pipe or a hidden file as a file descriptor.

As my grade i got 125, getting full grade on both mandatory and bonus parts.


About


Languages

Language:C 93.1%Language:Makefile 6.9%