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, 6 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

# User Rev Content
1 ab11 1.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