ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/i-scream/projects/cms/source/host/c++/socket++-1.10/pipestream.C
Revision: 1.1
Committed: Mon Feb 26 15:01:39 2001 UTC (23 years, 9 months ago) by ab11
Content type: text/plain
Branch: MAIN
CVS Tags: PROJECT_COMPLETION
Log Message:
Networking class. Assumed to be bug free.

File Contents

# Content
1 // pipestream.C -*- C++ -*- socket library
2 // Copyright (C) 1992,1993,1994 Gnanasekaran Swaminathan <gs4t@virginia.edu>
3 //
4 // Permission is granted to use at your own risk and distribute this software
5 // in source and binary forms provided the above copyright
6 // notice and this paragraph are preserved on all copies.
7 // This software is provided "as is" with no express or implied warranty.
8 //
9 // Version: 17Oct95 1.10
10
11
12 #include <config.h>
13
14 #include <pipestream.h>
15 #include <unistd.h>
16 #include <sys/socket.h>
17
18 // environ is not given a declaration in sun's <unistd.h>
19 extern char** environ;
20
21 // child closes s2 and uses s1
22 // parent closes s1 and uses s2
23
24 enum domain { af_unix = 1 };
25
26 iopipestream* iopipestream::head = 0;
27
28 static sockbuf* createpipestream (const char* cmd, int mode)
29 {
30 int sockets[2];
31 if ( ::socketpair (af_unix, sockbuf::sock_stream, 0, sockets) == -1 ) {
32 sock_error ("pipestream", "socketpair");
33 return 0;
34 }
35
36 pid_t pid = vfork ();
37 if (pid == -1) {
38 sock_error ("pipestream", "fork");
39 return 0;
40 }
41
42 if (pid == 0) {
43 // child process
44 if (::close (sockets[1]) == -1)
45 sock_error ("pipestream", "child close 1");
46 if ((mode & ios::in) && ::dup2 (sockets[0], 1) == -1) {
47 sock_error ("pipestream", "child dup2 1");
48 _exit (0x70);
49 }
50 if ((mode & ios::out) && ::dup2 (sockets[0], 0) == -1) {
51 sock_error ("pipestream", "child dup2 0");
52 _exit (0x71);
53 }
54 if (::close (sockets[0]) == -1)
55 sock_error ("pipestream", "child close 0");
56 const char* argv[4];
57 argv[0] = "/bin/sh";
58 argv[1] = "-c";
59 argv[2] = cmd;
60 argv[3] = 0;
61 execve ("/bin/sh", (char**) argv, environ);
62 sock_error ("pipestream", "execve");
63 _exit (0x7f);
64 }
65 // parent process
66 sockbuf* s = new sockbuf (sockets[1]);
67 if (::close (sockets[0]) == -1)
68 sock_error ("pipestream", "parent close 0");
69 if ( !(mode & ios::out) ) s->shutdown (sockbuf::shut_write);
70 if ( !(mode & ios::in) ) s->shutdown (sockbuf::shut_read);
71 return s;
72 }
73
74 ipipestream::ipipestream (const char* cmd)
75 : ios (0)
76 {
77 init (createpipestream (cmd, ios::in));
78 }
79
80 opipestream::opipestream (const char* cmd)
81 : ios (0)
82 {
83 init (createpipestream (cmd, ios::out));
84 }
85
86 iopipestream::iopipestream (const char* cmd)
87 : ios (0), cpid(-1), next (0)
88 {
89 init (createpipestream (cmd, ios::in|ios::out));
90 }
91
92 iopipestream::iopipestream(sockbuf::type ty, int proto)
93 : ios (0), cpid(-1), next (head)
94 {
95 if ( ::socketpair(af_unix, ty, proto, sp) == -1 ) {
96 error ("iopipestream-socketpair ");
97 return;
98 }
99
100 head = this;
101 }
102
103 pid_t iopipestream::fork()
104 {
105 pid_t pid = :: vfork ();
106 if ( pid == -1 ) {
107 sock_error ("iopipestream", "fork");
108 return pid;
109 } else if (pid > 0) {
110 // parent process
111 while (head) {
112 head->cpid = pid;
113 head->init (new sockbuf (head->sp[0]));
114 if (::close (head->sp[1]) == -1)
115 sock_error ("iopipestream", "parent close 0");
116 head = head->next;
117 }
118
119 } else {
120 // child process
121 while (head) {
122 head->cpid = 0;
123 head->init (new sockbuf (head->sp[1]));
124 if (::close (head->sp[0]) == -1)
125 sock_error ("iopipestream", "child close 0");
126 head = head->next;
127 }
128 }
129 return pid;
130 }
131