/* * Copyright (c) 1996 Gunther Schadow. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef CXX_PROC_H #define CXX_PROC_H #pragma interface #include #include #include #include class ProcInfo { public: enum { now = 0x0001, // start process now (meaningful only in ctor) join = 0x0002, // join process wait if necessary (for dtor) term = 0x0004, // process is to be terminated (meaningful for join) kill = 0x0010, // process is to be killed (meaningful for join) cont = 0x0020, // send stopped process a continue signal dead = 0x0040, // process is dead start = 0x0080, // process is started chld = 0x0100, // process info for child clean = 0x0200, // clean proc info entry if process died user_mask = ( now | join | term | kill | cont ), }; ProcInfo(int flags = 0); ~ProcInfo(); int flags(int f = 0, int m = 0); pid_t pid() const { return _pid; } bool parent() const { return (_flags & start) && !(_flags & chld); } bool child() const { return (_flags & start) && (_flags & chld); } bool started() const { return _flags & start; } bool running() const { return (_flags & start) && !(_flags & dead); } bool exited() const { return _flags & dead & WIFEXITED(_wstatus); } bool stopped() const { return _flags & dead & WIFSTOPPED(_wstatus); } bool signaled() const { return _flags & dead & WIFSIGNALED(_wstatus); } int exitstatus() const { return WEXITSTATUS(_wstatus); } int termsignal() const { return WTERMSIG(_wstatus); } int stopsignal() const { return WSTOPSIG(_wstatus); } private: int _flags; pid_t _pid; int _wstatus; ProcInfo *_next_proc; ProcInfo *_prev_proc; static ProcInfo *_root_proc; static class Signal _sigchld; static int reaper(Signal &s); friend class Proc; }; inline int ProcInfo::flags(int f, int m) { int old=_flags; _flags=_flags&~(m&user_mask)|(f&user_mask); return old; } class Proc { public: Proc(int flags = 0); ~Proc(); void run(); void raise(int sig) { kill(_info->pid(), sig); } int flags(int f = 0, int m = 0) { return _info->flags(f, m); } typedef void (*vinit_t)(va_list); void vrun(vinit_t, ...); public: pid_t pid() const { return _info->pid(); } bool parent() const { return _info->parent(); } bool child() const { return _info->child(); } bool started() const { return _info->started(); } bool running() const { return _info->running(); } bool exited() const { return _info->exited(); } bool stopped() const { return _info->stopped(); } bool signaled() const { return _info->signaled(); } int exitstatus() const { return _info->exitstatus(); } int termsignal() const { return _info->termsignal(); } int stopsignal() const { return _info->stopsignal(); } private: ProcInfo *_info; }; #endif