1 ////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (C) 1993-2021 The Octave Project Developers
4 //
5 // See the file COPYRIGHT.md in the top-level directory of this
6 // distribution or <https://octave.org/copyright/>.
7 //
8 // This file is part of Octave.
9 //
10 // Octave is free software: you can redistribute it and/or modify it
11 // under the terms of the GNU General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // Octave is distributed in the hope that it will be useful, but
16 // WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 // GNU General Public License for more details.
19 //
20 // You should have received a copy of the GNU General Public License
21 // along with Octave; see the file COPYING.  If not, see
22 // <https://www.gnu.org/licenses/>.
23 //
24 ////////////////////////////////////////////////////////////////////////
25 
26 #if ! defined (octave_procstream_h)
27 #define octave_procstream_h 1
28 
29 #include "octave-config.h"
30 
31 #include <iosfwd>
32 #include <string>
33 
34 #include <sys/types.h>
35 
36 #include "oct-procbuf.h"
37 
38 class
39 OCTINTERP_API
40 procstreambase : virtual public std::ios
41 {
42 public:
43 
procstreambase(void)44   procstreambase (void) : m_pb () { pb_init (); }
45 
46   procstreambase (const std::string& name, int mode);
47 
48   procstreambase (const char *name, int mode);
49 
~procstreambase(void)50   ~procstreambase (void) { close (); }
51 
open(const std::string & name,int mode)52   void open (const std::string& name, int mode)
53   {
54     open (name.c_str (), mode);
55   }
56 
57   void open (const char *name, int mode);
58 
is_open(void)59   int is_open (void) const { return m_pb.is_open (); }
60 
61   int close (void);
62 
pid(void)63   pid_t pid (void) const { return m_pb.pid (); }
64 
file_number(void)65   int file_number (void) const { return m_pb.file_number (); }
66 
67 private:
68 
69   octave_procbuf m_pb;
70 
pb_init(void)71   void pb_init (void)
72   {
73     // Explicit initialization of the std::ios object is needed.
74     // FIXME: is there a better way to organize these classes?
75     init (&m_pb);
76   }
77 
78   procstreambase (const procstreambase&);
79 
80   procstreambase& operator = (const procstreambase&);
81 };
82 
83 class
84 OCTINTERP_API
85 iprocstream : public std::istream, public procstreambase
86 {
87 public:
88 
iprocstream(void)89   iprocstream (void) : std::istream (nullptr), procstreambase () { }
90 
91   iprocstream (const std::string& name, int mode = std::ios::in)
istream(nullptr)92     : std::istream (nullptr), procstreambase (name, mode)
93   { }
94 
95   iprocstream (const char *name, int mode = std::ios::in)
istream(nullptr)96     : std::istream (nullptr), procstreambase (name, mode)
97   { }
98 
99   ~iprocstream (void) = default;
100 
101   void open (const std::string& name, int mode = std::ios::in)
102   {
103     procstreambase::open (name, mode);
104   }
105 
106   void open (const char *name, int mode = std::ios::in)
107   {
108     procstreambase::open (name, mode);
109   }
110 
111 private:
112 
113   iprocstream (const iprocstream&);
114 
115   iprocstream& operator = (const iprocstream&);
116 };
117 
118 class
119 OCTINTERP_API
120 oprocstream : public std::ostream, public procstreambase
121 {
122 public:
123 
oprocstream(void)124   oprocstream (void) : std::ostream (nullptr), procstreambase () { }
125 
126   oprocstream (const std::string& name, int mode = std::ios::out)
ostream(nullptr)127     : std::ostream (nullptr), procstreambase (name, mode) { }
128 
129   oprocstream (const char *name, int mode = std::ios::out)
ostream(nullptr)130     : std::ostream (nullptr), procstreambase (name, mode) { }
131 
132   ~oprocstream (void) = default;
133 
134   void open (const std::string& name, int mode = std::ios::out)
135   {
136     procstreambase::open (name, mode);
137   }
138 
139   void open (const char *name, int mode = std::ios::out)
140   {
141     procstreambase::open (name, mode);
142   }
143 
144 private:
145 
146   oprocstream (const oprocstream&);
147 
148   oprocstream& operator = (const oprocstream&);
149 };
150 
151 class
152 OCTINTERP_API
153 procstream : public std::iostream, public procstreambase
154 {
155 public:
156 
procstream(void)157   procstream (void) : std::iostream (nullptr), procstreambase () { }
158 
procstream(const std::string & name,int mode)159   procstream (const std::string& name, int mode)
160     : std::iostream (nullptr), procstreambase (name, mode)
161   { }
162 
procstream(const char * name,int mode)163   procstream (const char *name, int mode)
164     : std::iostream (nullptr), procstreambase (name, mode)
165   { }
166 
167   ~procstream (void) = default;
168 
open(const std::string & name,int mode)169   void open (const std::string& name, int mode)
170   {
171     procstreambase::open (name, mode);
172   }
173 
open(const char * name,int mode)174   void open (const char *name, int mode)
175   {
176     procstreambase::open (name, mode);
177   }
178 
179 private:
180 
181   procstream (const procstream&);
182 
183   procstream& operator = (const procstream&);
184 };
185 
186 #endif
187