Mercurial > octave-nkf
annotate liboctave/oct-syscalls.cc @ 10454:79a56d0a6a0d ss-3-3-51
version is now 3.3.51
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Wed, 24 Mar 2010 16:27:05 -0400 |
parents | 479cc8a0a846 |
children | fd0a3ac60b0e |
rev | line source |
---|---|
2941 | 1 /* |
2 | |
7017 | 3 Copyright (C) 1996, 1997, 1998, 2000, 2002, 2003, 2005, 2006, 2007 |
4 John W. Eaton | |
2941 | 5 |
6 This file is part of Octave. | |
7 | |
8 Octave is free software; you can redistribute it and/or modify it | |
9 under the terms of the GNU General Public License as published by the | |
7016 | 10 Free Software Foundation; either version 3 of the License, or (at your |
11 option) any later version. | |
2941 | 12 |
13 Octave is distributed in the hope that it will be useful, but WITHOUT | |
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
16 for more details. | |
17 | |
18 You should have received a copy of the GNU General Public License | |
7016 | 19 along with Octave; see the file COPYING. If not, see |
20 <http://www.gnu.org/licenses/>. | |
2941 | 21 |
22 */ | |
23 | |
24 #ifdef HAVE_CONFIG_H | |
25 #include <config.h> | |
26 #endif | |
27 | |
28 #include <cerrno> | |
6482 | 29 #include <cstdlib> |
2941 | 30 |
31 #include <string.h> | |
32 | |
33 #include <sys/types.h> | |
34 #include <unistd.h> | |
35 | |
36 #include <fcntl.h> | |
37 | |
4299 | 38 // We can't use csignal as kill is not in the std namespace, and picky |
39 // compiler runtimes will also exclude it from global scope as well. | |
40 | |
41 #include <signal.h> | |
42 | |
5453 | 43 #include "lo-utils.h" |
6321 | 44 #include "lo-sysdep.h" |
2941 | 45 #include "oct-syscalls.h" |
46 #include "str-vec.h" | |
47 | |
48 #define NOT_SUPPORTED(nm) \ | |
4062 | 49 nm ": not supported on this system" |
2941 | 50 |
51 int | |
52 octave_syscalls::dup2 (int old_fd, int new_fd) | |
53 { | |
3504 | 54 std::string msg; |
2941 | 55 return dup2 (old_fd, new_fd, msg); |
56 } | |
57 | |
58 int | |
3504 | 59 octave_syscalls::dup2 (int old_fd, int new_fd, std::string& msg) |
2941 | 60 { |
3504 | 61 msg = std::string (); |
2941 | 62 |
63 int status = -1; | |
64 | |
65 #if defined (HAVE_DUP2) | |
10411 | 66 status = gnulib::dup2 (old_fd, new_fd); |
2941 | 67 |
68 if (status < 0) | |
10411 | 69 msg = gnulib::strerror (errno); |
2941 | 70 #else |
71 msg = NOT_SUPPORTED ("dup2"); | |
72 #endif | |
73 | |
74 return status; | |
75 } | |
76 | |
77 int | |
3504 | 78 octave_syscalls::execvp (const std::string& file, const string_vector& argv) |
2941 | 79 { |
3504 | 80 std::string msg; |
2941 | 81 return execvp (file, argv, msg); |
82 } | |
83 | |
84 int | |
3504 | 85 octave_syscalls::execvp (const std::string& file, const string_vector& args, |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10259
diff
changeset
|
86 std::string& msg) |
2941 | 87 { |
3504 | 88 msg = std::string (); |
2941 | 89 |
90 int status = -1; | |
91 | |
92 #if defined (HAVE_EXECVP) | |
93 char **argv = args.c_str_vec (); | |
94 | |
95 status = ::execvp (file.c_str (), argv); | |
96 | |
97 string_vector::delete_c_str_vec (argv); | |
98 | |
99 if (status < 0) | |
10411 | 100 msg = gnulib::strerror (errno); |
2941 | 101 #else |
102 msg = NOT_SUPPORTED ("execvp"); | |
103 #endif | |
104 | |
105 return status; | |
106 } | |
107 | |
108 pid_t | |
3504 | 109 octave_syscalls::fork (std::string& msg) |
2941 | 110 { |
111 pid_t status = -1; | |
112 | |
113 #if defined (HAVE_FORK) | |
114 status = ::fork (); | |
115 | |
116 if (status < 0) | |
10411 | 117 msg = gnulib::strerror (errno); |
2941 | 118 #else |
119 msg = NOT_SUPPORTED ("fork"); | |
120 #endif | |
121 | |
122 return status; | |
123 } | |
124 | |
125 pid_t | |
3504 | 126 octave_syscalls::vfork (std::string& msg) |
3147 | 127 { |
128 pid_t status = -1; | |
129 | |
130 #if defined (HAVE_VFORK) || defined (HAVE_FORK) | |
131 #if defined (HAVE_VFORK) | |
132 status = ::vfork (); | |
133 #else | |
3148 | 134 status = ::fork (); |
3147 | 135 #endif |
136 | |
137 if (status < 0) | |
10411 | 138 msg = gnulib::strerror (errno); |
3147 | 139 #else |
140 msg = NOT_SUPPORTED ("vfork"); | |
141 #endif | |
142 | |
143 return status; | |
144 } | |
145 | |
146 pid_t | |
3504 | 147 octave_syscalls::getpgrp (std::string& msg) |
2941 | 148 { |
149 pid_t status = -1; | |
150 | |
151 #if defined (HAVE_GETPGRP) | |
152 status = ::getpgrp (); | |
153 | |
154 if (status < 0) | |
10411 | 155 msg = gnulib::strerror (errno); |
2941 | 156 #else |
157 msg = NOT_SUPPORTED ("getpgrp"); | |
158 #endif | |
159 | |
160 return status; | |
161 } | |
162 | |
163 pid_t | |
164 octave_syscalls::getpid (void) | |
165 { | |
166 #if defined (HAVE_GETPID) | |
167 return ::getpid (); | |
168 #else | |
169 return 0; | |
170 #endif | |
171 } | |
172 | |
173 pid_t | |
174 octave_syscalls::getppid (void) | |
175 { | |
176 #if defined (HAVE_GETPPID) | |
177 return ::getppid (); | |
178 #else | |
179 return 0; | |
180 #endif | |
181 } | |
182 | |
183 gid_t | |
184 octave_syscalls::getgid (void) | |
185 { | |
186 #if defined (HAVE_GETGID) | |
187 return ::getgid (); | |
188 #else | |
189 return 0; | |
190 #endif | |
191 } | |
192 | |
193 gid_t | |
194 octave_syscalls::getegid (void) | |
195 { | |
196 #if defined (HAVE_GETEGID) | |
197 return ::getegid (); | |
198 #else | |
199 return 0; | |
200 #endif | |
201 } | |
202 | |
203 uid_t | |
204 octave_syscalls::getuid (void) | |
205 { | |
206 #if defined (HAVE_GETUID) | |
207 return ::getuid (); | |
208 #else | |
209 return 0; | |
210 #endif | |
211 } | |
212 | |
213 uid_t | |
214 octave_syscalls::geteuid (void) | |
215 { | |
216 #if defined (HAVE_GETEUID) | |
217 return ::geteuid (); | |
218 #else | |
219 return 0; | |
220 #endif | |
221 } | |
222 | |
223 int | |
224 octave_syscalls::pipe (int *fildes) | |
225 { | |
3504 | 226 std::string msg; |
6123 | 227 return pipe (fildes, msg); |
2941 | 228 } |
229 | |
230 int | |
3504 | 231 octave_syscalls::pipe (int *fildes, std::string& msg) |
2941 | 232 { |
3504 | 233 msg = std::string (); |
2941 | 234 |
235 int status = -1; | |
236 | |
237 #if defined (HAVE_PIPE) | |
238 status = ::pipe (fildes); | |
239 | |
240 if (status < 0) | |
10411 | 241 msg = gnulib::strerror (errno); |
2941 | 242 #else |
243 msg = NOT_SUPPORTED ("pipe"); | |
244 #endif | |
245 | |
246 return status; | |
247 } | |
248 | |
249 pid_t | |
5453 | 250 octave_syscalls::waitpid (pid_t pid, int *status, int options) |
2941 | 251 { |
3504 | 252 std::string msg; |
5453 | 253 return waitpid (pid, status, options, msg); |
2941 | 254 } |
255 | |
256 pid_t | |
5453 | 257 octave_syscalls::waitpid (pid_t pid, int *status, int options, |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10259
diff
changeset
|
258 std::string& msg) |
2941 | 259 { |
6060 | 260 pid_t retval = -1; |
3504 | 261 msg = std::string (); |
2941 | 262 |
5453 | 263 #if defined (HAVE_WAITPID) |
6060 | 264 retval = ::octave_waitpid (pid, status, options); |
2941 | 265 |
5453 | 266 if (retval < 0) |
10411 | 267 msg = gnulib::strerror (errno); |
2941 | 268 #else |
269 msg = NOT_SUPPORTED ("waitpid"); | |
270 #endif | |
271 | |
5453 | 272 return retval; |
2941 | 273 } |
274 | |
4294 | 275 int |
276 octave_syscalls::kill (pid_t pid, int sig) | |
277 { | |
278 std::string msg; | |
279 return kill (pid, sig, msg); | |
280 } | |
281 | |
282 int | |
283 octave_syscalls::kill (pid_t pid, int sig, std::string& msg) | |
284 { | |
285 msg = std::string (); | |
286 | |
287 int status = -1; | |
288 | |
289 #if defined (HAVE_KILL) | |
290 status = ::kill (pid, sig); | |
291 | |
292 if (status < 0) | |
10411 | 293 msg = gnulib::strerror (errno); |
4294 | 294 #else |
295 msg = NOT_SUPPORTED ("kill"); | |
296 #endif | |
297 | |
298 return status; | |
299 } | |
300 | |
6321 | 301 pid_t |
302 octave_syscalls::popen2 (const std::string& cmd, const string_vector& args, | |
303 bool sync_mode, int *fildes) | |
304 { | |
305 std::string msg; | |
306 bool interactive = false; | |
307 return popen2 (cmd, args, sync_mode, fildes, msg, interactive); | |
308 } | |
309 | |
310 pid_t | |
311 octave_syscalls::popen2 (const std::string& cmd, const string_vector& args, | |
312 bool sync_mode, int *fildes, std::string& msg) | |
313 { | |
314 bool interactive = false; | |
315 return popen2 (cmd, args, sync_mode, fildes, msg, interactive); | |
316 } | |
317 | |
318 pid_t | |
319 octave_syscalls::popen2 (const std::string& cmd, const string_vector& args, | |
320 bool sync_mode, int *fildes, std::string& msg, bool &interactive) | |
321 { | |
322 #if defined (__WIN32__) && ! defined (__CYGWIN__) | |
323 return ::octave_popen2 (cmd, args, sync_mode, fildes, msg); | |
324 #else | |
325 pid_t pid; | |
326 int child_stdin[2], child_stdout[2]; | |
327 | |
328 if (pipe (child_stdin, msg) == 0) | |
329 { | |
330 if (pipe (child_stdout, msg) == 0) | |
331 { | |
332 pid = fork (msg); | |
333 if (pid < 0) | |
334 msg = "popen2: process creation failed -- " + msg; | |
335 else if (pid == 0) | |
336 { | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10259
diff
changeset
|
337 std::string child_msg; |
6321 | 338 |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10259
diff
changeset
|
339 interactive = false; |
6321 | 340 |
341 // Child process | |
10411 | 342 gnulib::close (child_stdin[1]); |
343 gnulib::close (child_stdout[0]); | |
6321 | 344 |
345 if (dup2 (child_stdin[0], STDIN_FILENO) >= 0) | |
346 { | |
10411 | 347 gnulib::close (child_stdin[0]); |
6321 | 348 if (dup2 (child_stdout[1], STDOUT_FILENO) >= 0) |
349 { | |
10411 | 350 gnulib::close (child_stdout[1]); |
6321 | 351 if (execvp (cmd, args, child_msg) < 0) |
352 child_msg = "popen2 (child): unable to start process -- " + child_msg; | |
353 } | |
354 else | |
355 child_msg = "popen2 (child): file handle duplication failed -- " + child_msg; | |
356 } | |
357 else | |
358 child_msg = "popen2 (child): file handle duplication failed -- " + child_msg; | |
10314
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10259
diff
changeset
|
359 |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10259
diff
changeset
|
360 (*current_liboctave_error_handler)(child_msg.c_str()); |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10259
diff
changeset
|
361 |
07ebe522dac2
untabify liboctave C++ sources
John W. Eaton <jwe@octave.org>
parents:
10259
diff
changeset
|
362 exit(0); |
6321 | 363 } |
364 else | |
365 { | |
366 // Parent process | |
10411 | 367 gnulib::close (child_stdin[0]); |
368 gnulib::close (child_stdout[1]); | |
369 | |
6321 | 370 #if defined (F_SETFL) && defined (O_NONBLOCK) |
10259 | 371 if (! sync_mode && octave_fcntl (child_stdout[0], F_SETFL, O_NONBLOCK, msg) < 0) |
6321 | 372 msg = "popen2: error setting file mode -- " + msg; |
373 else | |
374 #endif | |
375 { | |
376 fildes[0] = child_stdin [1]; | |
377 fildes[1] = child_stdout [0]; | |
378 return pid; | |
379 } | |
380 } | |
10411 | 381 gnulib::close (child_stdout[0]); |
382 gnulib::close (child_stdout[1]); | |
6321 | 383 } |
384 else | |
385 msg = "popen2: pipe creation failed -- " + msg; | |
10411 | 386 |
387 gnulib::close (child_stdin[0]); | |
388 gnulib::close (child_stdin[1]); | |
6321 | 389 } |
390 else | |
391 msg = "popen2: pipe creation failed -- " + msg; | |
392 | |
393 return -1; | |
394 #endif | |
395 } | |
10259 | 396 |
397 int | |
398 octave_fcntl (int fd, int cmd, long arg) | |
399 { | |
400 std::string msg; | |
401 return octave_fcntl (fd, cmd, arg, msg); | |
402 } | |
403 | |
404 int | |
405 octave_fcntl (int fd, int cmd, long arg, std::string& msg) | |
406 { | |
407 msg = std::string (); | |
408 | |
409 int status = -1; | |
410 | |
10411 | 411 status = gnulib::fcntl (fd, cmd, arg); |
10259 | 412 |
413 if (status < 0) | |
10411 | 414 msg = gnulib::strerror (errno); |
10259 | 415 |
416 return status; | |
417 } |