1
votes

This my project statement but i dont seem to quite understand what linking standard output to the input end of the pipe (read end).I am not asking for the solution but i am confused about what the question means

Project Statement

Project Requirements

This project simulates Unix pipe command. The parent process forks one child and the two processes are connected via a kernel pipe. The parent process takes in two command-line arguments, which are two independent executable programs: p1 and p2. The parent open a kernel pipe and forks a child process. The child inherits the open pipe from parent. The parent process links its standard output to the input end of the pipe and closes the output end, then it replaces itself with p1. The child process links is standard input to the output end of the pipe and closes the input end, then the child replaces itself with p2.

Project Helper

In writing this program, you will learn and use the system calls pipe, dup2, and execlp. Pipe is a very simple inter-process communication design that is supported by all Unix/Linux distributions. Each pipe is coded as an integer array of two file descriptors (int fd[2]). fd[0] is the input end of the pipe, and fd1 is the output end of the pipe. A child process inherits open pipe from its parent. It is prudent to close immediately the unused end of a pipe in a process.

Can some explain what this line means "The parent process links its standard output to the input end of the pipe and closes the output end",as far as i know we cant read from STDOUT_FILENO so invoking a dup2 doesnt make any sense.

1
Ask your instructor for clarifications.a3f
I am not a CS student, just took a friends assignment for learning.sarat b
GIYF unix self-pipewildplasser

1 Answers

1
votes

The linked question image says (material added to question while answer being written — leaving it here too because I can leave some [sic] comments):

This project simulates Unix pipe command. …

The parent process takes in two command-line arguments, which are two independent executable programs: p1 and p2. The parent open [sic] a kernel pipe and forks child process. The child inherits the open pipe from parent.

The parent process links its standard output to the input end of the pipe and closes the output end, then it replaces itself with p1. The child process links is [sic] standard input to the output end of the pipe and closes the input end, then the child replaces itself with p2.

… Each pipe is coded as an integer array of two file descriptors (int fd[2]). fd[0] is the input end of the pipe, and fd[1] is the output end of the pipe. …

The terminology 'input end' and 'output end' is defined.

You're left with connecting a read descriptor (fd[0]) to a write channel (FILENO_STDOUT), which "can be done" but is normally meaningless. The directions of the channels are conventional and ensure interworking between programs. But you could subvert the convention for one set of programs — which makes the code useless in other contexts. Unless the progams p1 and p2 are specially created to read from file descriptor 1 (FILENO_STDOUT) and to write to file descriptor 0 (FILENO_STDIN), the information generated by p1 will not be relayed to p2.

  • The exercise has bugs in it.

You can do exactly as told and demonstrate that it does not work. You can create a working solution which does things in the orthodox way and demonstrate that it does work.


I'd also quibble with the terminology 'pipe command'. On macOS, there is an actual command called pipe(8):

NAME
pipe - Postfix delivery to external command

SYNOPSIS
pipe [generic Postfix daemon options] command_attributes...

DESCRIPTION
The pipe(8) daemon processes requests from the Postfix queue manager to deliver messages to external commands. This program expects to be run from the master(8) process manager.

The | notation is not a command; it is a method of inter-process communication, IPC.

A better description would be:

This project simulates the Unix shell pipe notation p1 | p2.


The question title is 'Can pipe be used to connect 2 file descriptors of the same process?' The question in the title is not actually asked in the body of the question. The answer to the question in the title is "Yes". Indeed, the pipe() system call creates two file descriptors in the same process which are connect such that data written on one of the file descriptors can be read from the other file descriptor. That's the point of the pipe() system call.

If you need to set up the link between a specific pair of file descriptors, you have to call pipe(), then dup2() twice, then close() twice. The pipe() call returns 2 arbitrary file descriptor numbers. The dup2() calls connect the desired numbers to the numbers provided by pipe(); the close() calls disconnect the numbers returned by pipe(). The only gotcha to watch for is if the numbers returned by pipe() collide with the desired numbers. Then you have to be more fiddly — probably two calls to dup() with the descriptors returned by pipe(), two calls to close() on the descriptors returned by pipe(), then two calls to dup2() to map the descriptors from dup() to the desired numbers, and two more calls to close() to close the descriptors from dup(). (Note that dup() chooses the file descriptors for you; dup2() allows you to dictate the file descriptor returned.)

There is still the sick possibility that pipe() returns one of the two descriptors desired; then one of the dup() calls returns the other of the two descriptors. Just add another dup() into the sequence. Don't call close() until you've called dup2().