📄 pipes.h
字号:
/* Copyright (C) 1999 - 2004 Chris VineThis program is distributed under the General Public Licence, version 2.For particulars of this and relevant disclaimers see the fileCOPYING distributed with the source files.*/#ifndef PIPES_H#define PIPES_H#include "prog_defs.h"#include <unistd.h>/*This class provides a simplified front end to unix write() and read()of fifo pipes. The constructor of the class may be passed anenumerator to indicate whether the pipe is to read in non-blockingmode.The write(char*) method taking a string must have a string less thanPIPE_BUF characters in length, or it will fail. With the write(char*,int) method, taking an array and int arguments, the value of int(indicating the number of chars in the array to be written) shouldusually be less than PIPE_BUF, as POSIX write() guarantees that if itis less than PIPE_BUF, either all will be written or, if the pipe istoo full, none will be written. This prevents data interleaving if anumber of independent writes to the fifo are made.The pipe is set to read in non-blocking mode if the constructor orPipe_fifo is passed the value Pipe_fifo::non_block. If constructedin this way, the pipe can also be set to write in non-block mode (eg to minimise the impact on another program running in a child processto which the child process has exec()ed when monitoring its stdinor stderr) by calling make_write_non_block(). However use this verysparingly -- when set in this way write() will always try to writesomething. The atomic guarantees mentioned in the preceding paragraphdo not apply and data can be interleaved or lost.PIPE_BUF is defined in limits.h, and is at least 512 bytes, and usually 4096 bytes,but may be calculated from other files included by limits.h.Where a pipe is used to communicate between parent and child after acall to fork(), the pipe will normally be used unidirectionally unlessguards or semaphores are used to prevent a process reading dataintended for the other. However, because each process inherits itsown duplicate of the file descriptors, this cannot be enforced withoutclosing the read or write file descriptor for the process for whichthe reading or writing is to be prohibited. This can be done by theprocess concerned calling the methods Pipe_fifo::make_writeonly() orPipe_fifo::make_readonly() after the fork. If an attempt is made toread or write to a descriptor closed in this way, thePipe_fifo::read() or Pipe_fifo::write() method will ensure that noread or write will take place, and instead a -1 will be returned.The methods Pipe_fifo::connect_to_stdin(), Pipe_fifo::connect_to_stdout()and Pipe_fifo::connect_to_stderr() are available to be used in the childprocess before it exec()s another program so as to connect the pipe tothat program's stdin, stdout or stderr. The same pipe may be used to connect toboth stdout and stderr. Pipe_fifo::connect_to_stdin() cannot be usedby a process after that process has calledPipe_fifo::make_writeonly(), and Pipe_fifo::connect_to_stdout() andPipe_fifo::connect_to_stderr() cannot be used after the process hascalled Pipe_fifo::make_readonly(). If that is attempted the methodswill return -1; otherwise they will return 0. Furthermore, theyshould only be used after the process creating the pipe has forked.If the connection to stdin, stdout or stderr is to be made before thefork, this must be done by hand using dup2(), Pipe_fifo::get_write_fd()/Pipe_fifo::get_read_fd() and Pipe_fifo::make_read_only()/Pipe_fifo::make_write_only().If Pipe_fifo::connect_to_stdin() is called by a method,Pipe_fifo::make_readonly() will also be called, and ifPipe_fifo::connect_to_stdout() or Pipe_fifo::connect_to_stderr() arecalled, Pipe_fifo::make_writeonly() will also be called. This will isolate the use of the pipe by the child process to stdin, stdout orstderr, as appropriate.It uses no static members, so is thread safe as between different objects,but its methods are not thread safe as regards any one object in the sensethat the read() and write() methods check the value of read_fd and write_fdrespectively (and get_read_fd() and get_write_fd() return them), andmake_writeonly(), make_readonly(), close(), connect_to_stdin(), open(),connect_to_stdout() and connect_to_stderr() change those values. Likewisethe read() and write() methods access read_blocking_mode andwrite_blocking_mode respectively, and these are changed by open() andmake_write_non_block(). Provided there is no concurrent use of read(),write(), get_read_fd() or get_write_fd() in one thread with a call of amethod which changes read_fd, write_fd, read_blocking_mode orwrite_blocking_mode as described above in another thread then no mutexis required to ensure thread safety.*/class Pipe_fifo {public: enum Fifo_mode{block, non_block};private: int read_fd; int write_fd; Fifo_mode read_blocking_mode; Fifo_mode write_blocking_mode;public: int open(Fifo_mode); void close(void); ssize_t read(char*, size_t); // returns -2 if read file descriptor invalid, and // otherwise it returns the result of unix read() int read(void); // returns -2 if read file descriptor invalid, 0 or -1 // if unix read() returns either of those, and otherwise // returns the char at the front of the pipe ssize_t write(const char*); // if the write is non-blocking (see above) the string // must not be longer than PIPE_BUF (defined // in limits.h) and it returns -2 that is violated // or if the write file descriptor, otherwise it returns // the result of unix write() ssize_t write(const char*, size_t); // returns -2 if read file descriptor invalid, and // otherwise it returns the result of unix write() int write(char item) {return write(&item, 1);} // returns -2 if read file descriptor invalid, 1 if // char written, else result of unix write() void make_writeonly(void); void make_readonly(void); int make_write_non_block(void); int get_read_fd(void) const {return read_fd;} int get_write_fd(void) const {return write_fd;} int connect_to_stdin(void); int connect_to_stdout(void); int connect_to_stderr(void); Pipe_fifo(Fifo_mode); Pipe_fifo(void); ~Pipe_fifo(void) {close();}};// this class enables synchronisation between processes after fork()ing// the process to wait on the other one calls wait() at the point// where it wishes to wait, and the other process calls release()// when it wants to enable the other process to continue// it is one-shot only - once it has released, it cannot re-block againclass Sync_pipe: private Pipe_fifo {public: void release(void) {make_writeonly(); make_readonly();} void wait(void); Sync_pipe(void): Pipe_fifo(block) {}};#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -