The Open Source Swiss Army Knife

/code/c/unix_c/pipes/
/code/c/unix_c/pipes/ + sub-categories
http://www.sirfsup.com/
web directory content
    
      

Not logged in
Chat Register Login
return to:  http:/www.sirfsup.com      /code   /c   /unix_c   /pipes 
Permalink: pipes.txt
Title: add
article options : please login   |  raw source view  

here we are again in operating systems
in chapter 7 of Unix Systems Programming: pipes

PIPES

--unnammed pipes
--named pipes
--popen
--token ring

pipes occur at the kernel level, not at the user level, so that the data
transferred are transferred through the kernel

commandline pipes redirect from stdout to another special files' stdin

pipes are half-duplex models, only, please read the section in
http://www.cim.mcgill.ca/~franco/OpSys-304-427/lecture-notes/node28.html
where he says
"The reason for the last black dot (appropriately called
``bullet'' by typographers), is that the kernel uses just one internal buffer
for temporary storage of the flowing data, hence what goes in one direction
overwrites whatever is a naive programmer tries to send backward. So, just to
stress the concept once more: pipes make half-duplex, i.e. one-way,
communication channels."

unnamed pipes

int fd[2];
pipe(fd) - unnamed pipe, If the pipe is created succesfully, then its
readable end is fildes[0], while fildes[1] is the writable one.
pipes (when no longer usable) are destroyed --- cannot be used at system level

named pipes

FIFO: named pipes; unlike pipe(fd) persist


#include <sys/stat.h>
mkfifo(const char * path, mode_t mode)

appear in dir listings with first char == p

if nothing is available for reading on a pipe, read will hang
so, need to write to pipe before reading from it.


#define FIFO_PERMS (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)
if (mkfifo("myfifo", FIFO_PERMS) == -1)

perror("failed to create myfifo");


mkfifo is also a shell command

<url:namedpipes/parentchildfifo.c:parentchildfifo.c>
opens a pipe and calls two functions dofifochild and dofifoparent

<url:namedpipes/dofifochild.c:dofifochild.c>: this tries to open fifo, checking signal ( errno == EINTR)

else creates an id string
uses snprintf to copy into a buffer

first opens pipe with
fd = open(fifoname, O_RDONLY)) == -1 && (errno == EINTR)) ;

which is same code as opening any file

open pipe before fork only in order that child can use that pipe
doesn't apply to mkfifo as the pipe exists as a file

program note: in printf %.s means means take value from the value string from printf valarg array at end of printf statement

popen

FILE *popen(char command, char type);

Opens a stream-oriented pipe between the current process and program command,
taking care of all the dirty jobs: forking, duplicating file descriptors,
executing command, etc

see http://www.cim.mcgill.ca/~franco/OpSys-304-427/lecture-notes/node28.html
at the very bottom

client and server model

server: waits for requests for clients
client: requests service from server
a client can be both client and server

the two programs here are an example of IPC communication where the 2 processes are on the same machine

<url:pipeserver.c:pipeserver.c>: requires fifoname on CLI. creates if doesn't exist, opens for reading, does copyfile to STDOUT_FILENO.

<url:pipeclient.c:pipeclient.c>: requires filename from CLI. time(NULL).

snprintf: like sprintf; the printf variants which writes to a buffer.
strncpy: takes the format spec and writes to buffer, but limits output to "n" size, which protects from buffer overflows.

note PIPE_BUF is a standard constant proably in unistd.h

note pipes always make what they write strings by appending a '\0'

when writing to buff will wait if size of buffer > SIZE_BUF

writing to a pipe

PIPE_BUF is always > 256 but usually larger

atomic: sth which can't be split up; no interruptions writing to pipe if concurrently writing by two processes at the same time

a write of at most PIPE_BUF bytes to a pipe or FIFO is atomic

not true of reads nor of writes to the terminal, which means, if pipe has a,b,c,d,e,f,g and process reads 3 bytes and at the same time another process reads 3 bytes means almost anything can happen. Any combination of those bytes is possible.

not good when important data structures (ie kernel data structures) are being changed -- context switch time is too often cause daily crash.

token ring

"The projects of this chapter explore pipes, forks and redirection in the context of a ring or process."

this is an example of using pipes to communicate between parent and process.
in this case is a ring of processes which must read/write in a circle to pipes in their neighbors

for how many processes?
pipe (fd); // creates fd table entries for fd[3] and fd[4] but we can't know their array number entries
dup2(fd[0], STDIN_FILENO); //
dup2(fd[1], STDOUT_FILENO);
close(fd[0]); // close writing end
close(fd[1]); // close reading end
pipe(fd);

// close the reading end in the parent and the writing end in the child, if
// you want to send data from the parent to the child;

this does

dup fd#3 -> fd#0 (read)
dup fd#4 -> fd#1 (write)

flow: create 2 pipes, then fork.... so child has same file descriptor table as its parent process, so they can read/write the same pipes.

this has a two-directional flow of communication, all processes A and B can read/write those pipes

he doesn't want process b to read from pipeA. he makes it unidirectional flow only.

to add another process to the loop, process B or process A calls pipe and then forks and the reduction process is the same as before. at this point parent breaks out

if (childpid == fork()) == -1)

......

if (childpid)

break;


end chapter 7 in USP


Leave a Reply
Your Name:     anonymous
Your Email:
Website:  
Comments:

The author will be notified of your reply.
return to top