Logo Search packages:      
Sourcecode: chromium-browser version File versions  Download package

unixchild.h

/*
 * Copyright (c) 2004 Apple Computer, Inc. All Rights Reserved.
 * 
 * @APPLE_LICENSE_HEADER_START@
 * 
 * This file contains Original Code and/or Modifications of Original Code
 * as defined in and that are subject to the Apple Public Source License
 * Version 2.0 (the 'License'). You may not use this file except in
 * compliance with the License. Please obtain a copy of the License at
 * http://www.opensource.apple.com/apsl/ and read it before using this
 * file.
 * 
 * The Original Code and all software distributed under the License are
 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
 * Please see the License for the specific language governing rights and
 * limitations under the License.
 * 
 * @APPLE_LICENSE_HEADER_END@
 */


//
// unixchild - low-level UNIX process child management
//
#ifndef _H_UNIXCHILD
#define _H_UNIXCHILD

#include <security_utilities/utilities.h>
#include <security_utilities/errors.h>
#include <security_utilities/globalizer.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <map>


namespace Security {
namespace UnixPlusPlus {


//
// A Child object represents a (potential) fork-child of your process.
// It could be a clean fork or a fork/exec; this layer doesn't care.
// It is meant to track the UNIX-life of that process.
// Subclass Child or use it as a mix-in.
//
// Child keeps track of all alive children; Child::find<>() can locate them
// by pid if you like. Other children are not collected; you've got to do this
// yourself.
//
class Child {
public:
      Child();
      virtual ~Child();
      
      enum State {
            unborn,                       // never forked
            alive,                        // last seen alive
            dead,                   // coroner confirms death
            stopped,                // stopped due to trace or job control (not implemented)
            abandoned,              // cut loose (via forget())
            invalid                       // system says we're all confused about this child
      };
      
      void fork();                  // do the forky-forky

      State state() const { return mState; }
      operator bool () const { return mState == alive; }
      pid_t pid() const { assert(mState != unborn); return mPid; }
      
      void kill(int signal);  // send signal to child (if alive)
      void kill();                  // bring me its head, NOW
      
      // status is only available for dead children
      int waitStatus() const; // raw wait(2) status byte
      bool bySignal() const;  // was killed by a signal
      int exitCode() const;   // exit() code; valid only if !bySignal()
      int exitSignal() const; // signal that killed child; valid only if bySignal()
      bool coreDumped() const; // child dumped core when it died

protected:
      virtual void childAction() = 0; // called in child after fork()
      virtual void parentAction();  // called in parent after fork()
      virtual void dying();   // called when child is confirmed dead
      
      void abandon();               // cut a living child loose (forget about it)
      
private:
      State mState;                 // child state
      pid_t mPid;                   // pid of child (if born)
      int mStatus;                  // exit status (if dead)
      
      void bury(int status);  // canonical last rites
      static Child *findGeneric(pid_t pid); // find living child by pid
      void tryKill(int signal);

public:
      static void sharedChildren(bool s);
      static bool sharedChildren();
      
      void reset();

      static void checkChildren();

      template <class Subclass>
      static Subclass *find(pid_t pid)
      { return dynamic_cast<Subclass *>(findGeneric(pid)); }

private:
      struct Children : public Mutex, public std::map<pid_t, Child *> {
            Children() : shared(false) { }
            bool shared;
      };
      static ModuleNexus<Children> mChildren;
};


}     // end namespace UnixPlusPlus
}     // end namespace Security

#endif //_H_UNIXCHILD

Generated by  Doxygen 1.6.0   Back to index