1 ////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (C) 1996-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 (HAVE_CONFIG_H)
27 #  include "config.h"
28 #endif
29 
30 #include <ctime>
31 #include <cerrno>
32 #include <cstdlib>
33 #include <cstring>
34 
35 #include "fcntl-wrappers.h"
36 #include "lo-utils.h"
37 #include "lo-sysdep.h"
38 #include "oct-syscalls.h"
39 #include "octave-popen2.h"
40 #include "signal-wrappers.h"
41 #include "str-vec.h"
42 #include "unistd-wrappers.h"
43 #include "wait-wrappers.h"
44 
45 #define NOT_SUPPORTED(nm)                       \
46   nm ": not supported on this system"
47 
48 namespace octave
49 {
50   namespace sys
51   {
52     int
dup2(int old_fd,int new_fd)53     dup2 (int old_fd, int new_fd)
54     {
55       std::string msg;
56       return sys::dup2 (old_fd, new_fd, msg);
57     }
58 
59     int
dup2(int old_fd,int new_fd,std::string & msg)60     dup2 (int old_fd, int new_fd, std::string& msg)
61     {
62       msg = "";
63 
64       int status = -1;
65 
66       status = octave_dup2_wrapper (old_fd, new_fd);
67 
68       if (status < 0)
69         msg = std::strerror (errno);
70 
71       return status;
72     }
73 
74     int
execvp(const std::string & file,const string_vector & argv)75     execvp (const std::string& file, const string_vector& argv)
76     {
77       std::string msg;
78       return sys::execvp (file, argv, msg);
79     }
80 
81     int
execvp(const std::string & file,const string_vector & args,std::string & msg)82     execvp (const std::string& file, const string_vector& args,
83             std::string& msg)
84     {
85       msg = "";
86 
87       char **argv = args.c_str_vec ();
88 
89       int status = octave_execvp_wrapper (file.c_str (), argv);
90 
91       string_vector::delete_c_str_vec (argv);
92 
93       if (status < 0)
94         msg = std::strerror (errno);
95 
96       return status;
97     }
98 
99     pid_t
fork(std::string & msg)100     fork (std::string& msg)
101     {
102       pid_t status = -1;
103 
104       if (octave_have_fork ())
105         {
106           status = octave_fork_wrapper ();
107 
108           if (status < 0)
109             msg = std::strerror (errno);
110         }
111       else
112         msg = NOT_SUPPORTED ("fork");
113 
114       return status;
115     }
116 
117     pid_t
vfork(std::string & msg)118     vfork (std::string& msg)
119     {
120       pid_t status = -1;
121 
122       if (octave_have_vfork () || octave_have_fork ())
123         {
124           if (octave_have_vfork ())
125             status = octave_vfork_wrapper ();
126           else
127             status = octave_fork_wrapper ();
128 
129           if (status < 0)
130             msg = std::strerror (errno);
131         }
132       else
133         msg = NOT_SUPPORTED ("vfork");
134 
135       return status;
136     }
137 
138     pid_t
getpgrp(std::string & msg)139     getpgrp (std::string& msg)
140     {
141       pid_t status = octave_getpgrp_wrapper ();
142 
143       if (status < 0)
144         msg = std::strerror (errno);
145 
146       return status;
147     }
148 
149     pid_t
getpid(void)150     getpid (void)
151     {
152       return octave_getpid_wrapper ();
153     }
154 
155     pid_t
getppid(void)156     getppid (void)
157     {
158       return octave_getppid_wrapper ();
159     }
160 
161     gid_t
getgid(void)162     getgid (void)
163     {
164       return octave_getgid_wrapper ();
165     }
166 
167     gid_t
getegid(void)168     getegid (void)
169     {
170       return octave_getegid_wrapper ();
171     }
172 
173     uid_t
getuid(void)174     getuid (void)
175     {
176       return octave_getuid_wrapper ();
177     }
178 
179     uid_t
geteuid(void)180     geteuid (void)
181     {
182       return octave_geteuid_wrapper ();
183     }
184 
185     int
pipe(int * fildes)186     pipe (int *fildes)
187     {
188       std::string msg;
189       return sys::pipe (fildes, msg);
190     }
191 
192     int
pipe(int * fildes,std::string & msg)193     pipe (int *fildes, std::string& msg)
194     {
195       msg = "";
196 
197       int status = -1;
198 
199       status = octave_pipe_wrapper (fildes);
200 
201       if (status < 0)
202         msg = std::strerror (errno);
203 
204       return status;
205     }
206 
207     pid_t
waitpid(pid_t pid,int * status,int options)208     waitpid (pid_t pid, int *status, int options)
209     {
210       std::string msg;
211       return sys::waitpid (pid, status, options, msg);
212     }
213 
214     pid_t
waitpid(pid_t pid,int * status,int options,std::string & msg)215     waitpid (pid_t pid, int *status, int options,
216              std::string& msg)
217     {
218       pid_t retval = -1;
219       msg = "";
220 
221       retval = octave_waitpid_wrapper (pid, status, options);
222 
223       if (retval < 0)
224         msg = std::strerror (errno);
225 
226       return retval;
227     }
228 
229     int
wcontinue(void)230     wcontinue (void)
231     {
232       return octave_wcontinue_wrapper ();
233     }
234 
235     int
wcoredump(int status)236     wcoredump (int status)
237     {
238       return octave_wcoredump_wrapper (status);
239     }
240 
241     bool
wifcontinued(int status)242     wifcontinued (int status)
243     {
244       return octave_wifcontinued_wrapper (status);
245     }
246 
247     bool
wifexited(int status)248     wifexited (int status)
249     {
250       return octave_wifexited_wrapper (status);
251     }
252 
253     bool
wifsignaled(int status)254     wifsignaled (int status)
255     {
256       return octave_wifsignaled_wrapper (status);
257     }
258 
259     bool
wifstopped(int status)260     wifstopped (int status)
261     {
262       return octave_wifstopped_wrapper (status);
263     }
264 
265     int
wexitstatus(int status)266     wexitstatus (int status)
267     {
268       return octave_wexitstatus_wrapper (status);
269     }
270 
271     int
wnohang(void)272     wnohang (void)
273     {
274       return octave_wnohang_wrapper ();
275     }
276 
277     int
wstopsig(int status)278     wstopsig (int status)
279     {
280       return octave_wstopsig_wrapper (status);
281     }
282 
283     int
wtermsig(int status)284     wtermsig (int status)
285     {
286       return octave_wtermsig_wrapper (status);
287     }
288 
289     int
wuntraced(void)290     wuntraced (void)
291     {
292       return octave_wuntraced_wrapper ();
293     }
294 
295     int
kill(pid_t pid,int sig)296     kill (pid_t pid, int sig)
297     {
298       std::string msg;
299       return sys::kill (pid, sig, msg);
300     }
301 
302     int
kill(pid_t pid,int sig,std::string & msg)303     kill (pid_t pid, int sig, std::string& msg)
304     {
305       msg = "";
306 
307       int status = -1;
308 
309       if (octave_have_kill ())
310         {
311           status = octave_kill_wrapper (pid, sig);
312 
313           if (status < 0)
314             msg = std::strerror (errno);
315         }
316       else
317         msg = NOT_SUPPORTED ("kill");
318 
319       return status;
320     }
321 
322     pid_t
popen2(const std::string & cmd,const string_vector & args,bool sync_mode,int * fildes)323     popen2 (const std::string& cmd, const string_vector& args,
324             bool sync_mode, int *fildes)
325     {
326       std::string msg;
327       return sys::popen2 (cmd, args, sync_mode, fildes, msg);
328     }
329 
330     pid_t
popen2(const std::string & cmd,const string_vector & args,bool sync_mode,int * fildes,std::string & msg)331     popen2 (const std::string& cmd, const string_vector& args,
332             bool sync_mode, int *fildes, std::string& msg)
333     {
334       char **argv = args.c_str_vec ();
335       const char *errmsg;
336 
337       pid_t pid = octave_popen2 (cmd.c_str (), argv, sync_mode, fildes,
338                                  &errmsg);
339 
340       string_vector::delete_c_str_vec (argv);
341 
342       if (pid < 0)
343         msg = errmsg;
344 
345       return pid;
346     }
347 
348     int
fcntl(int fd,int cmd,long arg)349     fcntl (int fd, int cmd, long arg)
350     {
351       std::string msg;
352       return sys::fcntl (fd, cmd, arg, msg);
353     }
354 
355     int
fcntl(int fd,int cmd,long arg,std::string & msg)356     fcntl (int fd, int cmd, long arg, std::string& msg)
357     {
358       msg = "";
359 
360       int status = -1;
361 
362       status = octave_fcntl_wrapper (fd, cmd, arg);
363 
364       if (status < 0)
365         msg = std::strerror (errno);
366 
367       return status;
368     }
369   }
370 }
371