how to write a utility which can be use in pipe?

how to write a utility which can be use in pipe?

am 11.10.2005 17:50:26 von wyhang

just for example, I want a utility named "a" and I can use it like
below:

ls | a

then a can process every output of 'ls' command and output to terminal.

if a is programmed by C language, how should I implement it?

thank you~

Re: how to write a utility which can be use in pipe?

am 11.10.2005 20:58:06 von Enrique Perez-Terron

On Tue, 11 Oct 2005 17:50:26 +0200, wyhang@gmail.com wrote:

> just for example, I want a utility named "a" and I can use it like
> below:
>
> ls | a
>
> then a can process every output of 'ls' command and output to terminal.
>
> if a is programmed by C language, how should I implement it?

If you use the unbuffered "read()" system call, use the file descriptor
zero:

read(0, somebuffer, sizeofthebuffer);

To learn more about the "read" system call, use the command

man 2 read


If you use the buffered functions, some of them do not need that
you specify what file to read, they work with standard input (stdin).
Others require that you specify the file, then specify "stdin" as
the file. Do not open the file, assume it is already open when the
program starts.

#include

int main(int argc, char *argv[])
{
char buffer[1024];
while (fgets(buffer, sizeof(buffer), stdin) {
/* do something with the contents of buffer */
printf("%s", buffer);
}
return 0;
}

man 3 scanf
man 3 fgets
man 3 stdio

I suggest that further questions about C programming are posted in a
newgroup dedicated to C.

-Enrique

Re: how to write a utility which can be use in pipe?

am 12.10.2005 03:45:06 von wyhang

oh, thanks, my friends:)

in fact, what I feel confused is just how the 'pipe' work, indeed I'm
more incline to implement with Perl:)

Re: how to write a utility which can be use in pipe?

am 12.10.2005 20:02:43 von Juha Laiho

"wyhang@gmail.com" said:
>in fact, what I feel confused is just how the 'pipe' work, indeed I'm
>more incline to implement with Perl:)

A program doesn't need to be concerned it's reading from a pipe (or
writing to one, for that matter). From the perspective of the
program, the input coming from a pipe looks the same as it would
when coming from the keyboard.
--
Wolf a.k.a. Juha Laiho Espoo, Finland
(GC 3.0) GIT d- s+: a C++ ULSH++++$ P++@ L+++ E- W+$@ N++ !K w !O !M V
PS(+) PE Y+ PGP(+) t- 5 !X R !tv b+ !DI D G e+ h---- r+++ y++++
"...cancel my subscription to the resurrection!" (Jim Morrison)

Re: how to write a utility which can be use in pipe?

am 12.10.2005 22:14:26 von Enrique Perez-Terron

On Wed, 12 Oct 2005 03:45:06 +0200, wyhang@gmail.com wrote:

> oh, thanks, my friends:)
>
> in fact, what I feel confused is just how the 'pipe' work, indeed I'm
> more incline to implement with Perl:)

The pipe works this way:

You are (e.g.) typing into a terminal, and there is a program, the shell,
that reads your input and execute your commands.

You type

command-one args | command-two args

The shell breaks up this text and finds there are two commands separated
by the character "|". The shell...

- asks the operating system (kernel) to create a pipe. A pipe is a
combination of two open-file-descriptors, one open for reading and
one open for writing. Such descriptors behave like other files,
but are not associated with a disk file. Instead, the kernel
"promises" to pass on everything written on the writable end of the
pipe to the readable end.

- receives two numbers in response to the kernel call above. These numbers
are to be used in read and write calls to specify the two ends of the
pipe. Such numbers are called "open file descriptors". However,
when we say a process possess an open file descriptor N, it realy means
the process has an agreement with the kernel about the use of that number
in system calls like read and write.

- creates two sub-proceses. These processes inherit the open file descriptors
from the parent process. The processes execute code that is part of the
shell's code. The parent process disconnects from the pipe, leaving
the pipe entirely to the two child processes.

Now the two processes, while still running shell code do the following:

- The first process asks the kernel to close whatever file was open
as file descriptor 1, and rearrange the file descriptors so that
the writable end of the pipe can be referenced as descritpor 1
rather than by the number the parent process got from the kernel.
This process also disconnects from the readable end of the pipe.

- The second process runs a similar set of commands as the first process,
but wants the readable end of the pipe to become accessible as
file descriptor zero. This is what is conventionally called
the "standard input". It disconnects itself from the writable end.

Finally,

- The first process discards all its executable code and loads the
first command, "command-one". At this point command-one begins
executing, and it has already the pipe open as its "standard output",
i.e., its open-file-descriptor 1.

- The second process discards all its executable code and loads the
second command, "command-two". As command-two begins executing,
it already has an open file with descriptor zero, which it can read.

When command-one writes data to the pipe, the kernel keeps it in a buffer.
If the process writes too much, the kernel suspends the process until
there is room in the buffer. When command-two reads data off the pipe,
the kernel feeds it whatever it has buffered in that pipe. If the process
reads again when the buffer is empty, the kernel suspends the process
until there is some data available.

Contrast this picture with the execution of commands without a pipe.

In the most usual situation, the shell has three open files with
descriptors 0, 1, and 2. All three are associated with the terminal.
These descriptors constitute the standard input, output, and error.

Now the shell creates a subprocess to run the command in question.
The subprocess inherits all open file descriptors the parent has.
Then it loads the command's executable code and starts running it.
In this way, when the command in question starts executing there is
already three open files, 0, 1, and 2.

(In the pipe case, there is also a file descriptor 2, the standard
error. This descriptor is simply not changed in any way, so all
three processes can write to the standard error.)

- Enrique

Re: how to write a utility which can be use in pipe?

am 13.10.2005 04:31:27 von wyhang

thank you, Enrique, your words are really valuable:)