11 #include <sys/types.h> 12 #include <sys/socket.h> 16 #include <sys/ioctl.h> 25 static int socketpair(
int d,
int type,
int protocol,
int sv[2])
27 static int counter = 10;
29 int f1 = socket(PF_UNIX, SOCK_STREAM, protocol);
30 int f2 = socket(PF_UNIX, SOCK_STREAM, protocol);
32 WvString s(
"/tmp/sock%s", ++counter);
33 WvString s2(
"/tmp/sock%sb", counter);
39 bind(f1, a.sockaddr(), a.sockaddr_len());
40 bind(f2, a2.sockaddr(), a2.sockaddr_len());
42 connect(f2, a.sockaddr(), a.sockaddr_len());
44 socklen_t ll = a.sockaddr_len();
45 int f3 = accept(f1, a.sockaddr(), &ll);
59 bool writable,
bool readable,
bool catch_stderr,
60 int stdin_fd,
int stdout_fd,
int stderr_fd,
WvStringList *env)
62 setup(program, argv, writable, readable, catch_stderr,
63 stdin_fd, stdout_fd, stderr_fd, env);
68 bool writable,
bool readable,
bool catch_stderr,
72 int fd0 = 0, fd1 = 1, fd2 = 2;
76 fd1 = stdout_str->
getwfd();
78 fd2 = stderr_str->
getwfd();
79 setup(program, argv, writable, readable, catch_stderr, fd0, fd1, fd2, env);
84 bool writable,
bool readable,
bool catch_stderr,
90 setup(program, argv, writable, readable, catch_stderr,
94 setup(program, argv, writable, readable, catch_stderr, 0, 1, 2, env);
98 void WvPipe::setup(
const char *program,
const char *
const *argv,
99 bool writable,
bool readable,
bool catch_stderr,
100 int stdin_fd,
int stdout_fd,
int stderr_fd,
108 if (!program || !argv)
114 if (socketpair(AF_UNIX, SOCK_STREAM, 0, socks))
120 fcntl(socks[0], F_SETFL, O_RDWR|O_NONBLOCK);
125 WvStringList::Iter it(*env);
126 for (it.rewind(); it.next(); )
128 proc.env.append(*it);
131 pid = proc.fork(&waitfd);
140 else if (stdin_fd == -1)
146 else if (stdout_fd == -1)
152 else if (stderr_fd == -1)
158 fcntl(0, F_SETFD, 0);
159 fcntl(1, F_SETFD, 0);
160 fcntl(2, F_SETFD, 0);
164 flags = fcntl(0, F_GETFL);
165 fcntl(0, F_SETFL, flags & ~O_NONBLOCK);
166 flags = fcntl(1, F_GETFL);
167 fcntl(1, F_SETFL, flags & ~O_NONBLOCK);
168 flags = fcntl(2, F_GETFL);
169 fcntl(2, F_SETFL, flags & ~O_NONBLOCK);
176 if (!writable && !readable && !catch_stderr)
177 fcntl(socks[1], F_SETFD, 0);
183 if (!readable && stdout_fd != 1)
189 ioctl(1, TIOCSCTTY, 1);
192 # warning You should implement TCSETCTTY here. Thanks! 201 execvp(program, (
char *
const *)argv);
208 fcntl(socks[0], F_SETFD, 1);
231 shutdown(
getwfd(), SHUT_WR);
234 proc.wait(1000, wait_children);
245 return !proc.running;
253 int st = proc.estatus;
254 assert (WIFEXITED(st) || WIFSIGNALED(st));
255 return WIFSIGNALED(st);
267 int st = proc.estatus;
268 assert (WIFEXITED(st) || WIFSIGNALED(st));
272 return WEXITSTATUS(st);
286 void WvPipe::ignore_read(
WvStream& s)
289 s.
read(&buf,
sizeof(buf));
A Unix domain socket address is really just a filename.
WvPipe(const char *program, const char *const *argv, bool writable, bool readable, bool catch_stderr, int stdin_fd=0, int stdout_fd=1, int stderr_fd=2, WvStringList *env=NULL)
default pipe constructor; if you just want to use a pipe, use this.
void setfd(int fd)
Sets the file descriptor for both reading and writing.
bool child_killed() const
returns true if child is dead because of a signal.
void kill(int signum)
send the child a signal (signal names are defined in signal.h)
virtual ~WvPipe()
kill the child process and close the stream.
int finish(bool wait_children=true)
wait for child to die.
int exit_status()
returns the exit status: if child_killed()==true, the signal that killed the child.
Unified support for streams, that is, sequences of bytes that may or may not be ready for read/write ...
virtual void close()
Closes the file descriptors.
Base class for streams built on Unix file descriptors.
This is a WvList of WvStrings, and is a really handy way to parse strings.
int wfd
The file descriptor for writing.
int rfd
The file descriptor for reading.
int getrfd() const
Returns the Unix file descriptor for reading from this stream.
virtual void seterr(int _errnum)
Override seterr() from WvError so that it auto-closes the stream.
bool child_exited()
returns true if child is dead.
WvString is an implementation of a simple and efficient printable-string class.
virtual size_t read(void *buf, size_t count)
read a data block on the stream.
int getwfd() const
Returns the Unix file descriptor for writing to this stream.