Presentation is loading. Please wait.

Presentation is loading. Please wait.

Mgr inż. Marcin Borkowski UNIX Pipe and FIFO. mgr inż. Marcin Borkowski Waiting for I/O ● Pipes, FIFO's, sockets and stdin usually can not produce data.

Similar presentations


Presentation on theme: "Mgr inż. Marcin Borkowski UNIX Pipe and FIFO. mgr inż. Marcin Borkowski Waiting for I/O ● Pipes, FIFO's, sockets and stdin usually can not produce data."— Presentation transcript:

1 mgr inż. Marcin Borkowski UNIX Pipe and FIFO

2 mgr inż. Marcin Borkowski Waiting for I/O ● Pipes, FIFO's, sockets and stdin usually can not produce data on demand (like regular files), the same problem applies to consuming data. ● Data can be available for reading or writing, when it is not available the process must wait. ● Waiting can be organized in several ways – Functions select, pselect – Function poll (ppoll,epoll) – Signal SIGIO, controlled by fcntl (non-POSIX) – aio (see next chapter)

3 mgr inż. Marcin Borkowski Waiting for I/O ● Function (p)select – fd_set – bit array representing a set of descriptors ● FD_SETSIZE – maximum number of descriptors the array can hold (counting from 0 to FD_SETSIZE-1 ) ● if maximum number of descriptors is constant FD_SETSIZE should be no less that the limit ● if there is no maximum defined, constant imposes additional limit on file descriptors (e.g. on GNU) ● FD_ZERO - clear the set ● FD_SET and FD_CLR – set/clear the descriptor number ● FD_ISSET – checks if descriptor number is in the set

4 mgr inż. Marcin Borkowski Waiting for I/O – Function (p)select arguments: ● nfds – maximum value of descriptor (+1) to check in 3 descriptors sets passed to the function – as descriptors count from zero, this should be the maximum descriptor number plus one ! – if process can easily count the descriptors number the value of FD_SETSIZE should not be used as it adds unnecessary load to the select function ● readfds – set of descriptors process wants to read from – end of file (read 0 bytes) also means available reading (stops select) – not removing such a descriptors is a common error in students' works, this may lead to busy waiting – parameter will be modified after successful call – can be NULL

5 mgr inż. Marcin Borkowski Waiting for I/O ● writefds – set of descriptors process wants to write to – it is unspecified how much data process can write without blocking, it may be a little as 1 byte (usually memory page size buffer is available) – parameter will be modified after successful call – can be NULL ● exceptfds – set of descriptors process expects some extraordinary condition to occur – not i/o errors ! – e.g. out of the band data on socket – parameter will be modified after successful call – can be NULL

6 mgr inż. Marcin Borkowski Waiting for I/O ● timeout – maximum allowed waiting time – can be unlimited when NULL is supplied – can be shortened by signal handling (EINTR) – structure is different in select and pselect ! – can be modified by function but POSIX does not say how - select can not be portably used as timer – is not affecting alarm and setitimer (can not internally use SIGALRM) – can be set to zero to check what descriptors are available immediately ● sigmask – new signal blocking mask used only for duration of pselect call – one atomic function that combines waiting for signal and waiting for input/output ● the same descriptors can be used in all the sets

7 mgr inż. Marcin Borkowski Waiting for I/O – Function (p)select return value: ● on success – total number of bits set in three descriptors sets – zero in case of time-out – sets are modified to contain only descriptors that meet desired criteria, use FD_ISSET to check if given descriptor is in the set ● -1 on failure or EINTR – Descriptors sets are unmodified in case of error or EINTR – See example of select at the end of this chapter

8 mgr inż. Marcin Borkowski Waiting for I/O ● Function poll – pollfd structure holds: ● fd – opened descriptor ● events– requested events, input (POSIX defines more constants) – POLLIN – read (including end of file condition) – POLLOUTI - write – POLLPRI – read priority data ● revents – returned events, output – POLLIN, POLLOUT,POLLPRI – POLLERR,POLLHUP – POLLNVAL - descriptor not opened

9 mgr inż. Marcin Borkowski Waiting for I/O ● Function poll – Each descriptor passed to poll function has its own structure, events requested for this descriptor are bitwise encoded in events – After poll function terminates, encountered events or errors are bitwise encoded into revents of proper descriptor – poll parameters: ● *fds – pointer to array of pollfd stuctures, unlimited size !! ● nfds – size of pollfd array

10 mgr inż. Marcin Borkowski Waiting for I/O – timeout ● if negative poll waits indefinitely ● if zero test immediate data availability, do not wait ● positive value of time-out in milliseconds ● can be interrupted (EINTR) earlier, does not report time left – Regular files immediately report data available for read and write. Socket, pipe or FIFO always reports end of file (ready to read) when the other end of connection is closed. Placing such a descriptor in fds array and calling poll in a loop may lead to busy waiting !

11 mgr inż. Marcin Borkowski Waiting for I/O – Return value: ● -1 failure, check for errors or EINTR ● 0 time-out, no data is available as requested ● positive number indicates how many revents fields are not zero, it may mean errors or data availability ● ppoll function is not POSIX compliant, there is not way to correctly wait for signal and data availability with poll as it can be done with pselect ● epoll linux specific variant of poll designed for large sets of descriptors with relatively small amount of events, efficient but not portable

12 mgr inż. Marcin Borkowski Pipe ● One direction communication channel between related processes: – Parent to children or children to parent – Siblings ● For two-way communication two pipes must be created ● Pipe must be created (f. pipe ) before processes are spawned, pipe connection is a result of fork call ● There can be many writers and many readers on a single pipe

13 mgr inż. Marcin Borkowski Pipe ● Usually process that writes to pipe does not read from pipe and should close the descriptor – It is technically possible for the same single threaded process to read and write from the same pipe (as long as data transferred fits into pipe buffer, otherwise process will block itself) – Closing unused descriptors saves process limit on opened files ● filedes[0] read end of pipe ● filedes[1] write end of pipe

14 mgr inż. Marcin Borkowski Pipe ● Pipe descriptors can be manipulated with fcntl, for example flag O_NONBLOCK can be set ● Data send to pipe is stored in buffer, access is organized in FIFO order ● Pipe has no name in file system ● Pipe is created in opened state, pipe can not be opened !!!

15 mgr inż. Marcin Borkowski Pipe ● Pipe to sub-process (f. popen, pclose ) – Process can start shell command (like f. system ) and redirect it's standard output or input to that command – Useful for filtering ● mode “w” - process sends standard input to the command ● mode “r” - process reads its stdin from the command ● modes are exclusive – Usually the process reads all the data from the pipe i.e. to the end of file marker before closing the pipe – When writing data, closing the pipe marks the end of file

16 mgr inż. Marcin Borkowski Pipe – Data in the stream buffer on stdin can clutter the input from the command – Data in stdout buffer can clutter the output to the command – Call fflush before popen to be sure buffers are clean – popen can be substituted by fork, dup2 and execv functions

17 mgr inż. Marcin Borkowski Pipe – Stream to subprocess started with popen must be closed by function pclose which closes the stream and waits for child process termination – According to POSIX pclose can not return before sub- process terminates – can not be interrupted by signal handling (never reports EINTR) – Main process should not call wait (or waitpid ) that will wait for the command process, it will result in pclose returning ECHLD – pclose returns termination status of the command or code 127 if the shell interpreter is unavailable

18 mgr inż. Marcin Borkowski FIFO ● First In First Out queue ● Similar to pipe but: – has entry in the file system ● path and name ● permissions – can be opened by any process that have permissions to the FIFO file – can be created from the process (f. mkfifo ) or from command line (command mkfifo) – is independent from creating process, can persist between program executions

19 mgr inż. Marcin Borkowski FIFO ● Process can open (f. open ) the FIFO for: – reading, open call will block until some other process opens the same FIFO for writing – writing, open call will block until some other process opens the same FIFO for reading – both, no blocking required. This case is very rare ● If FIFO is opened with O_NONBLOCK for – reading, no blocking but if no process is writing to that pipe, subsequent read call will return end of file – writing, if no process is reading from that FIFO call will fail with ENXIO error

20 mgr inż. Marcin Borkowski FIFO ● Removing ( unlink ) the FIFO file does not affect already attached processes, the queue will be not be available for new connections and will be destroyed after the last connection is closed ● Changing permissions on FIFO file does not affect already opened channels (descriptors or streams) the same rule applies to regular files

21 mgr inż. Marcin Borkowski Pipe and FIFO - Closing Connection – If writing end is closed in all the processes connected to the pipe or FIFO and the connection buffer is empty, reading from this channel will return end of file status (read returns zero as number of bytes read) – If reading end is closed in all the processes connected to the pipe or FIFO writing to the channel results in SIGPIPE signal. If this signal is handled, ignored or blocked write will return the error EPIPE – EPIPE is not critical error and can be properly recognized and handled in students works without terminating the application

22 mgr inż. Marcin Borkowski Atomicity of Pipe and FIFO ● If only one process writes and only one process reads from the pipe or FIFO, the size of sent message does not matter. ● If there are more processes involved on writing side data must not exceed the size of PIPE_BUF and both reader and writer must use the same buffer size for communication ● Transfer (f. write ) of data buffer smaller or equal to PIPE_BUF can not be interrupted in the middle of the process by signal handling routine.

23 mgr inż. Marcin Borkowski Atomicity of Pipe and FIFO ● Having multiple processes: – writing to a pipe/fifo – will work correctly provide you send data in parts no larger than PIPE_BUF – reading from a pipe/fifo – may produce undefined results, POSIX does not adopt the idea of atomic read

24 mgr inż. Marcin Borkowski Atomicity of Pipe and FIFO ● Data transfer of atomic block can be interrupted only before any data is sent (EINTR) ● Most common errors concerning data atomicity on shared pipe: – defining the custom message size and not checking if it fits in PIPE_BUF – using different messages sizes for different types of communication over the same pipe – splitting messages into two or more parts (size, message) – sending last chunk of data in smaller buffer

25 mgr inż. Marcin Borkowski Pipe and FIFO - Examples ● How to wait for I/O ( select ): fd_set in1,in2; FD_ZERO(&in1); FD_SET(STDIN_FILENO, &in1); FD_SET(fd, &in1); in2 = in1; if (TEMP_FAILURE_RETRY(select(fd+1, &in2, NULL, NULL, NULL)) < 0) ERR(); if (FD_ISSET(fd, &in2))... if (FD_ISSET(STDIN_FILENO, &in2))...

26 mgr inż. Marcin Borkowski Pipe and FIFO - Examples ● How to wait for I/O ( poll ): struct pollfd fds[2]; fds[0].fd = fd1; fds[1].fd = fd2; fds[0].events = POLLOUT | POLLWRBAND; fds[1].events = POLLIN | POLLPRI; ret = TEMP_FAILURE_RETRY(poll(fds, 2, 300)); if (ret < 0) ERR(); else if (0 == ret){... } /*timeout*/ else { if (fds[0].revents & POLLERR) ERR(); else if (fds[0].revents & POLLOUT)...... }

27 mgr inż. Marcin Borkowski Pipe and FIFO - Examples ● How to read atomic blocks (pipe,FIFO) with respect to disconnected channel: if (size > PIPE_BUF) ERR(); len = TEMP_FAILURE_RETRY(read(fd, buffer, size)) if (len < 0) ERR(); if (0 == len)... /*disconnected*/

28 mgr inż. Marcin Borkowski Pipe and FIFO - Examples ● How to write atomic blocks (pipe, FIFO) with respect to broken pipe: if (sethandler(SIG_IGN,SIGPIPE)) ERR();... len2 = TEMP_FAILURE_RETRY(write(fds[current], (char*)(&len), sizeof(size_t))); if ((len2 < 0) && (EPIPE == errno)) { if (TEMP_FAILURE_RETRY(close(fds[current]))) ERR(); fds[current] =- 1; children--; } if (len2 < sizeof(size_t)) ERR();


Download ppt "Mgr inż. Marcin Borkowski UNIX Pipe and FIFO. mgr inż. Marcin Borkowski Waiting for I/O ● Pipes, FIFO's, sockets and stdin usually can not produce data."

Similar presentations


Ads by Google