00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifdef SOLARIS
00019
00020 #define __EXTENSIONS__
00021 #endif
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #define AUP2_SKIP_WAIT
00034 #include "defs.h"
00035
00036 #ifdef _GNU_SOURCE
00037 #define _GNU_SOURCE_WAS_DEFINED
00038 #undef _GNU_SOURCE
00039 #undef __USE_GNU
00040 #endif
00041 #include <sys/resource.h>
00042 #ifdef _GNU_SOURCE_WAS_DEFINED
00043 #define _GNU_SOURCE
00044 #undef _GNU_SOURCE_WAS_DEFINED
00045 #endif
00046
00047 #include <sys/wait.h>
00048 #include "ux.hpp"
00049
00050 using namespace Ux;
00051
00052
00053
00054
00055 void Process::atexit(void (*fcn)(void))
00056 {
00057 errno = 0;
00058 if (::atexit(fcn) != 0)
00059 throw Error(errno);
00060 }
00061
00062
00063
00064
00065 void Process::chdir(const char *path)
00066 {
00067 if (::chdir(path) == -1)
00068 throw Error(errno);
00069 }
00070
00071
00072
00073
00074 void Process::chdir(int fd)
00075 {
00076 if (::fchdir(fd) == -1)
00077 throw Error(errno);
00078 }
00079
00080
00081
00082
00083 void Process::chroot(const char *path)
00084 {
00085 if (::chroot(path) == -1)
00086 throw Error(errno);
00087 }
00088
00089
00090
00091
00092 clock_t Process::clock(void)
00093 {
00094 clock_t c;
00095
00096 errno = 0;
00097 if ((c = ::clock()) == -1) {
00098 if (errno == 0)
00099 throw Error(EINVAL);
00100 else
00101 throw Error(errno);
00102 }
00103 return c;
00104 }
00105
00106
00107
00108
00109
00110 void Process::execlp(const char *file, const char *arg0, ...)
00111 {
00112 va_list ap;
00113 int count;
00114
00115 va_start(ap, arg0);
00116 for (count = 1; va_arg(ap, char *) != NULL; count++)
00117 ;
00118 va_end(ap);
00119 char **argv = new char*[count + 1];
00120 if (argv == NULL)
00121 throw Error(ENOMEM);
00122 va_start(ap, arg0);
00123 argv[0] = (char *)arg0;
00124 for (count = 1; (argv[count] = va_arg(ap, char *)) != NULL; count++)
00125 ;
00126 va_end(ap);
00127 (void)::execvp(file, argv);
00128 delete [] argv;
00129 throw Error(errno);
00130 }
00131
00132
00133
00134
00135
00136
00137
00138
00139 void Process::execvpe(const char *file, char *const argv[], char *const *envv = NULL)
00140 {
00141 extern char **environ;
00142
00143 char **environ_save = environ;
00144 if (envv != NULL)
00145 environ = (char **)envv;
00146 (void)execvp(file, argv);
00147 environ = environ_save;
00148 throw Error(errno);
00149 }
00150
00151
00152
00153
00154 Process Process::fork(void)
00155 {
00156 pid_t rtn_pid;
00157
00158 if ((rtn_pid = ::fork()) == -1)
00159 throw Error(errno);
00160 return Process(rtn_pid);
00161 }
00162
00163
00164
00165
00166
00167 void Process::getcwd(Dir& d)
00168 {
00169 if (d.get_size() < 0)
00170 throw Error(ENOMEM);
00171
00172 if (::getcwd((char *)(const char *)d, d.get_size()) == NULL)
00173 throw(errno);
00174 }
00175
00176
00177
00178
00179 char* Process::getenv(const char *var)
00180 {
00181 return ::getenv(var);
00182 }
00183
00184
00185
00186
00187 pid_t Process::getpgid(pid_t pid)
00188 {
00189 pid_t rtn_pid;
00190
00191 if ((rtn_pid = ::getpgid(pid)) == -1)
00192 throw Error(errno);
00193 return rtn_pid;
00194 }
00195
00196
00197
00198
00199 void Process::getrlimit(int resource, struct rlimit *rlp)
00200 {
00201 if (::getrlimit(resource, rlp) == -1)
00202 throw Error(errno);
00203 }
00204
00205
00206
00207
00208 void Process::getrusage(int who, struct rusage *r_usage)
00209 {
00210 if (::getrusage(who, r_usage) == -1)
00211 throw Error(errno);
00212 }
00213
00214
00215
00216
00217
00218
00219 pid_t Process::getsid(void)
00220 {
00221 pid_t rtn_pid;
00222
00223 if ((rtn_pid = ::getsid(pid)) == -1)
00224 throw Error(errno);
00225 return rtn_pid;
00226 }
00227
00228
00229
00230
00231 void Process::kill(pid_t pid, int signum)
00232 {
00233 if (::kill(pid, signum) == -1)
00234 throw Error(errno);
00235 }
00236
00237
00238
00239
00240 void Process::nice(int incr)
00241 {
00242 if (::nice(incr) == -1)
00243 throw Error(errno);
00244 }
00245
00246
00247
00248
00249 void Process::pause(void)
00250 {
00251 if (::pause() == -1 && errno != EINTR)
00252 throw Error(errno);
00253 }
00254
00255
00256
00257
00258 void Process::putenv(char *string)
00259 {
00260 if (::putenv(string) != 0)
00261 throw Error(errno);
00262 }
00263
00264
00265
00266
00267 void Process::setegid(gid_t gid)
00268 {
00269 if (::setegid(gid) == -1)
00270 throw Error(errno);
00271 }
00272
00273
00274
00275
00276 void Process::setenv(const char *var, const char *val, int overwrite)
00277 {
00278 #if _XOPEN_VERSION >= 600 || defined(FREEBSD) || defined(LINUX)
00279 if (::setenv(var, val, overwrite) == -1)
00280 throw Error(errno);
00281 #else
00282 throw Error(ENOSYS);
00283 #endif
00284 }
00285
00286
00287
00288
00289 void Process::seteuid(uid_t uid)
00290 {
00291 if (::seteuid(uid) == -1)
00292 throw Error(errno);
00293 }
00294
00295
00296
00297
00298 void Process::setgid(gid_t gid)
00299 {
00300 if (::setgid(gid) == -1)
00301 throw Error(errno);
00302 }
00303
00304
00305
00306
00307 void Process::setpgid(pid_t pid, pid_t pgid)
00308 {
00309 if (::setpgid(pid, pgid) == -1)
00310 throw Error(errno);
00311 }
00312
00313
00314
00315
00316 void Process::setrlimit(int resource, const struct rlimit *rlp)
00317 {
00318 if (::setrlimit(resource, rlp) == -1)
00319 throw Error(errno);
00320 }
00321
00322
00323
00324
00325 pid_t Process::setsid(void)
00326 {
00327 pid_t rtn_pid;
00328
00329 if ((rtn_pid = ::setsid()) == -1)
00330 throw Error(errno);
00331 return rtn_pid;
00332 }
00333
00334
00335
00336
00337 void Process::setuid(uid_t uid)
00338 {
00339 if (::setuid(uid) == -1)
00340 throw Error(errno);
00341 }
00342
00343
00344
00345
00346 void Process::sigaction(int signum, const struct sigaction *act, struct sigaction *oact)
00347 {
00348 if (::sigaction(signum, act, oact) == -1)
00349 throw Error(errno);
00350 }
00351
00352
00353
00354
00355 void Process::sigaltstack(const stack_t *stack, stack_t *ostack)
00356 {
00357 if (::sigaltstack(stack, ostack) == -1)
00358 throw Error(errno);
00359 }
00360
00361
00362
00363
00364 void Process::siginterrupt(int signum, int on)
00365 {
00366 if (::siginterrupt(signum, on) == -1)
00367 throw Error(errno);
00368 }
00369
00370
00371
00372
00373 void Process::sigprocmask(int how, const sigset_t *set, sigset_t *oset)
00374 {
00375 if (::sigprocmask(how, set, oset) == -1)
00376 throw Error(errno);
00377 }
00378
00379
00380
00381
00382 void Process::sigqueue(int signum, const union sigval value)
00383 {
00384 #ifdef _POSIX_REALTIME_SIGNALS
00385 if (::sigqueue(pid, signum, value) == -1)
00386 throw Error(errno);
00387 #else
00388 throw Error(ENOSYS);
00389 #endif
00390 }
00391
00392
00393
00394
00395 void Process::sigsuspend(const sigset_t *sigmask)
00396 {
00397 if (::sigsuspend(sigmask) == -1)
00398 throw Error(errno);
00399 }
00400
00401
00402
00403
00404
00405 int Process::sigtimedwait(const sigset_t *set, siginfo_t *info, const struct timespec *ts)
00406 {
00407 #ifdef _POSIX_REALTIME_SIGNALS
00408 int r;
00409
00410 if ((r = ::sigtimedwait(set, info, ts)) == -1)
00411 throw Error(errno);
00412 return r;
00413 #else
00414 throw Error(ENOSYS);
00415 #endif
00416 }
00417
00418
00419
00420
00421
00422 void Process::sigwait(const sigset_t *set, int *signum)
00423 {
00424 #if _XOPEN_VERSION >= 500
00425 if (::sigwait(set, signum) == -1)
00426 throw Error(errno);
00427 #else
00428 throw Error(ENOSYS);
00429 #endif
00430 }
00431
00432
00433
00434
00435
00436 int Process::sigwaitinfo(const sigset_t *set, siginfo_t *info)
00437 {
00438 #ifdef _POSIX_REALTIME_SIGNALS
00439 int r;
00440
00441 if ((r = ::sigwaitinfo(set, info)) == -1)
00442 throw Error(errno);
00443 return r;
00444 #else
00445 throw Error(ENOSYS);
00446 #endif
00447 }
00448
00449
00450
00451
00452
00453 int Process::system(const char *command)
00454 {
00455 int n;
00456
00457 if ((n = ::system(command)) == -1)
00458 throw Error(errno);
00459 return n;
00460 }
00461
00462
00463
00464
00465 clock_t Process::times(struct tms *buffer)
00466 {
00467 clock_t c;
00468
00469 if ((c = ::times(buffer)) == -1)
00470 throw Error(errno);
00471 return c;
00472 }
00473
00474
00475
00476
00477 void Process::unsetenv(const char *var)
00478 {
00479 #if _XOPEN_VERSION >= 600
00480 if (::unsetenv(var) == -1)
00481 throw Error(errno);
00482 #elif defined(FREEBSD) || defined(LINUX)
00483 ::unsetenv(var);
00484 #else
00485 throw Error(ENOSYS);
00486 #endif
00487 }
00488
00489
00490
00491
00492 void Process::waitid(idtype_t idtype, id_t id, siginfo_t *infop, int options)
00493 {
00494 #ifdef _XOPEN_UNIX
00495 if (::waitid(idtype, id, infop, options) == -1)
00496 throw Error(errno);
00497 #else
00498 throw Error(ENOSYS);
00499 #endif
00500 }
00501
00502
00503
00504
00505
00506 pid_t Process::waitpid(pid_t pid, ExitStatus *statusp, int options = 0)
00507 {
00508 pid_t rtn_pid;
00509 int status;
00510
00511 if ((rtn_pid = ::waitpid(pid, &status, options)) == -1)
00512 throw Error(errno);
00513 if (statusp != NULL)
00514 statusp->set(status);
00515 return rtn_pid;
00516 }
00517