00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifdef HAVE_CONFIG_H
00024 #include <config.h>
00025 #endif
00026
00027 #include <cerrno>
00028 #include <cstdlib>
00029
00030 #include <string.h>
00031
00032 #include <sys/types.h>
00033 #include <unistd.h>
00034
00035 #include <fcntl.h>
00036
00037
00038
00039
00040 #include <signal.h>
00041
00042 #include "lo-utils.h"
00043 #include "lo-sysdep.h"
00044 #include "oct-syscalls.h"
00045 #include "str-vec.h"
00046
00047 #define NOT_SUPPORTED(nm) \
00048 nm ": not supported on this system"
00049
00050 int
00051 octave_syscalls::dup2 (int old_fd, int new_fd)
00052 {
00053 std::string msg;
00054 return dup2 (old_fd, new_fd, msg);
00055 }
00056
00057 int
00058 octave_syscalls::dup2 (int old_fd, int new_fd, std::string& msg)
00059 {
00060 msg = std::string ();
00061
00062 int status = -1;
00063
00064 #if defined (HAVE_DUP2)
00065 status = gnulib::dup2 (old_fd, new_fd);
00066
00067 if (status < 0)
00068 msg = gnulib::strerror (errno);
00069 #else
00070 msg = NOT_SUPPORTED ("dup2");
00071 #endif
00072
00073 return status;
00074 }
00075
00076 int
00077 octave_syscalls::execvp (const std::string& file, const string_vector& argv)
00078 {
00079 std::string msg;
00080 return execvp (file, argv, msg);
00081 }
00082
00083 int
00084 octave_syscalls::execvp (const std::string& file, const string_vector& args,
00085 std::string& msg)
00086 {
00087 msg = std::string ();
00088
00089 int status = -1;
00090
00091 #if defined (HAVE_EXECVP)
00092 char **argv = args.c_str_vec ();
00093
00094 status = ::execvp (file.c_str (), argv);
00095
00096 string_vector::delete_c_str_vec (argv);
00097
00098 if (status < 0)
00099 msg = gnulib::strerror (errno);
00100 #else
00101 msg = NOT_SUPPORTED ("execvp");
00102 #endif
00103
00104 return status;
00105 }
00106
00107 pid_t
00108 octave_syscalls::fork (std::string& msg)
00109 {
00110 pid_t status = -1;
00111
00112 #if defined (HAVE_FORK)
00113 status = ::fork ();
00114
00115 if (status < 0)
00116 msg = gnulib::strerror (errno);
00117 #else
00118 msg = NOT_SUPPORTED ("fork");
00119 #endif
00120
00121 return status;
00122 }
00123
00124 pid_t
00125 octave_syscalls::vfork (std::string& msg)
00126 {
00127 pid_t status = -1;
00128
00129 #if defined (HAVE_VFORK) || defined (HAVE_FORK)
00130 #if defined (HAVE_VFORK)
00131 status = ::vfork ();
00132 #else
00133 status = ::fork ();
00134 #endif
00135
00136 if (status < 0)
00137 msg = gnulib::strerror (errno);
00138 #else
00139 msg = NOT_SUPPORTED ("vfork");
00140 #endif
00141
00142 return status;
00143 }
00144
00145 pid_t
00146 octave_syscalls::getpgrp (std::string& msg)
00147 {
00148 pid_t status = -1;
00149
00150 #if defined (HAVE_GETPGRP)
00151 status = ::getpgrp ();
00152
00153 if (status < 0)
00154 msg = gnulib::strerror (errno);
00155 #else
00156 msg = NOT_SUPPORTED ("getpgrp");
00157 #endif
00158
00159 return status;
00160 }
00161
00162 pid_t
00163 octave_syscalls::getpid (void)
00164 {
00165 #if defined (HAVE_GETPID)
00166 return ::getpid ();
00167 #else
00168 return 0;
00169 #endif
00170 }
00171
00172 pid_t
00173 octave_syscalls::getppid (void)
00174 {
00175 #if defined (HAVE_GETPPID)
00176 return ::getppid ();
00177 #else
00178 return 0;
00179 #endif
00180 }
00181
00182 gid_t
00183 octave_syscalls::getgid (void)
00184 {
00185 #if defined (HAVE_GETGID)
00186 return ::getgid ();
00187 #else
00188 return 0;
00189 #endif
00190 }
00191
00192 gid_t
00193 octave_syscalls::getegid (void)
00194 {
00195 #if defined (HAVE_GETEGID)
00196 return ::getegid ();
00197 #else
00198 return 0;
00199 #endif
00200 }
00201
00202 uid_t
00203 octave_syscalls::getuid (void)
00204 {
00205 #if defined (HAVE_GETUID)
00206 return ::getuid ();
00207 #else
00208 return 0;
00209 #endif
00210 }
00211
00212 uid_t
00213 octave_syscalls::geteuid (void)
00214 {
00215 #if defined (HAVE_GETEUID)
00216 return ::geteuid ();
00217 #else
00218 return 0;
00219 #endif
00220 }
00221
00222 int
00223 octave_syscalls::pipe (int *fildes)
00224 {
00225 std::string msg;
00226 return pipe (fildes, msg);
00227 }
00228
00229 int
00230 octave_syscalls::pipe (int *fildes, std::string& msg)
00231 {
00232 msg = std::string ();
00233
00234 int status = -1;
00235
00236 #if defined (HAVE_PIPE)
00237 status = ::pipe (fildes);
00238
00239 if (status < 0)
00240 msg = gnulib::strerror (errno);
00241 #else
00242 msg = NOT_SUPPORTED ("pipe");
00243 #endif
00244
00245 return status;
00246 }
00247
00248 pid_t
00249 octave_syscalls::waitpid (pid_t pid, int *status, int options)
00250 {
00251 std::string msg;
00252 return waitpid (pid, status, options, msg);
00253 }
00254
00255 pid_t
00256 octave_syscalls::waitpid (pid_t pid, int *status, int options,
00257 std::string& msg)
00258 {
00259 pid_t retval = -1;
00260 msg = std::string ();
00261
00262 #if defined (HAVE_WAITPID)
00263 retval = ::octave_waitpid (pid, status, options);
00264
00265 if (retval < 0)
00266 msg = gnulib::strerror (errno);
00267 #else
00268 msg = NOT_SUPPORTED ("waitpid");
00269 #endif
00270
00271 return retval;
00272 }
00273
00274 int
00275 octave_syscalls::kill (pid_t pid, int sig)
00276 {
00277 std::string msg;
00278 return kill (pid, sig, msg);
00279 }
00280
00281 int
00282 octave_syscalls::kill (pid_t pid, int sig, std::string& msg)
00283 {
00284 msg = std::string ();
00285
00286 int status = -1;
00287
00288 #if defined (HAVE_KILL)
00289 status = ::kill (pid, sig);
00290
00291 if (status < 0)
00292 msg = gnulib::strerror (errno);
00293 #else
00294 msg = NOT_SUPPORTED ("kill");
00295 #endif
00296
00297 return status;
00298 }
00299
00300 pid_t
00301 octave_syscalls::popen2 (const std::string& cmd, const string_vector& args,
00302 bool sync_mode, int *fildes)
00303 {
00304 std::string msg;
00305 bool interactive = false;
00306 return popen2 (cmd, args, sync_mode, fildes, msg, interactive);
00307 }
00308
00309 pid_t
00310 octave_syscalls::popen2 (const std::string& cmd, const string_vector& args,
00311 bool sync_mode, int *fildes, std::string& msg)
00312 {
00313 bool interactive = false;
00314 return popen2 (cmd, args, sync_mode, fildes, msg, interactive);
00315 }
00316
00317 pid_t
00318 octave_syscalls::popen2 (const std::string& cmd, const string_vector& args,
00319 bool sync_mode, int *fildes, std::string& msg, bool &interactive)
00320 {
00321 #if defined (__WIN32__) && ! defined (__CYGWIN__)
00322 return ::octave_popen2 (cmd, args, sync_mode, fildes, msg);
00323 #else
00324 pid_t pid;
00325 int child_stdin[2], child_stdout[2];
00326
00327 if (pipe (child_stdin, msg) == 0)
00328 {
00329 if (pipe (child_stdout, msg) == 0)
00330 {
00331 pid = fork (msg);
00332 if (pid < 0)
00333 msg = "popen2: process creation failed -- " + msg;
00334 else if (pid == 0)
00335 {
00336 std::string child_msg;
00337
00338 interactive = false;
00339
00340
00341 gnulib::close (child_stdin[1]);
00342 gnulib::close (child_stdout[0]);
00343
00344 if (dup2 (child_stdin[0], STDIN_FILENO) >= 0)
00345 {
00346 gnulib::close (child_stdin[0]);
00347 if (dup2 (child_stdout[1], STDOUT_FILENO) >= 0)
00348 {
00349 gnulib::close (child_stdout[1]);
00350 if (execvp (cmd, args, child_msg) < 0)
00351 child_msg = "popen2 (child): unable to start process -- " + child_msg;
00352 }
00353 else
00354 child_msg = "popen2 (child): file handle duplication failed -- " + child_msg;
00355 }
00356 else
00357 child_msg = "popen2 (child): file handle duplication failed -- " + child_msg;
00358
00359 (*current_liboctave_error_handler)(child_msg.c_str());
00360
00361 exit(0);
00362 }
00363 else
00364 {
00365
00366 gnulib::close (child_stdin[0]);
00367 gnulib::close (child_stdout[1]);
00368
00369 #if defined (F_SETFL) && defined (O_NONBLOCK)
00370 if (! sync_mode && octave_fcntl (child_stdout[0], F_SETFL, O_NONBLOCK, msg) < 0)
00371 msg = "popen2: error setting file mode -- " + msg;
00372 else
00373 #endif
00374 {
00375 fildes[0] = child_stdin [1];
00376 fildes[1] = child_stdout [0];
00377 return pid;
00378 }
00379 }
00380 gnulib::close (child_stdout[0]);
00381 gnulib::close (child_stdout[1]);
00382 }
00383 else
00384 msg = "popen2: pipe creation failed -- " + msg;
00385
00386 gnulib::close (child_stdin[0]);
00387 gnulib::close (child_stdin[1]);
00388 }
00389 else
00390 msg = "popen2: pipe creation failed -- " + msg;
00391
00392 return -1;
00393 #endif
00394 }
00395
00396 int
00397 octave_fcntl (int fd, int cmd, long arg)
00398 {
00399 std::string msg;
00400 return octave_fcntl (fd, cmd, arg, msg);
00401 }
00402
00403 int
00404 octave_fcntl (int fd, int cmd, long arg, std::string& msg)
00405 {
00406 msg = std::string ();
00407
00408 int status = -1;
00409
00410 status = gnulib::fcntl (fd, cmd, arg);
00411
00412 if (status < 0)
00413 msg = gnulib::strerror (errno);
00414
00415 return status;
00416 }