]> git.saurik.com Git - apple/security.git/blob - OSX/libsecurity_utilities/lib/unixchild.h
Security-58286.200.222.tar.gz
[apple/security.git] / OSX / libsecurity_utilities / lib / unixchild.h
1 /*
2 * Copyright (c) 2004,2011,2014 Apple Inc. All Rights Reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24
25 //
26 // unixchild - low-level UNIX process child management
27 //
28 #ifndef _H_UNIXCHILD
29 #define _H_UNIXCHILD
30
31 #include <security_utilities/utilities.h>
32 #include <security_utilities/errors.h>
33 #include <security_utilities/globalizer.h>
34 #include <sys/types.h>
35 #include <sys/wait.h>
36 #include <map>
37 #include <list>
38
39
40 namespace Security {
41 namespace UnixPlusPlus {
42
43
44 //
45 // A Child object represents a (potential) fork-child of your process.
46 // It could be a clean fork or a fork/exec; this layer doesn't care.
47 // It is meant to track the UNIX-life of that process.
48 // Subclass Child or use it as a mix-in.
49 //
50 // Child keeps track of all alive children; Child::find<>() can locate them
51 // by pid if you like. Other children are not collected; you've got to do this
52 // yourself.
53 //
54 class Child {
55 public:
56 Child();
57 virtual ~Child();
58
59 enum State {
60 unborn, // never forked
61 alive, // last seen alive
62 dead, // coroner confirms death
63 stopped, // stopped due to trace or job control (not implemented)
64 abandoned, // cut loose (via forget())
65 invalid // system says we're all confused about this child
66 };
67
68 void fork(); // do the forky-forky
69
70 State state() const { return mState; }
71 operator bool () const { return mState == alive; }
72 pid_t pid() const { assert(mState != unborn); return mPid; }
73
74 State check(); // update status on (just) this child and return new state
75 void wait(); // wait for (just) this Child to die
76
77 void kill(int signal); // send signal to child (if alive)
78 void kill(); // bring me its head, NOW
79
80 // status is only available for dead children
81 int waitStatus() const; // raw wait(2) status byte
82 bool succeeded() const { return waitStatus() == 0; }
83 bool bySignal() const; // was killed by a signal
84 int exitCode() const; // exit() code; valid only if !bySignal()
85 int exitSignal() const; // signal that killed child; valid only if bySignal()
86 bool coreDumped() const; // child dumped core when it died
87
88 protected:
89 virtual void childAction() = 0; // called in child after fork()
90 virtual void parentAction(); // called in parent after fork()
91 virtual void dying(); // called when child is confirmed dead
92
93 void abandon(); // cut a living child loose (forget about it)
94
95 private:
96 State mState; // child state
97 pid_t mPid; // pid of child (if born)
98 int mStatus; // exit status (if dead)
99
100 bool checkStatus(int options); // check status of this Child (wait4)
101 void bury(int status); // canonical last rites
102 static Child *findGeneric(pid_t pid); // find living child by pid
103 void tryKill(int signal);
104
105 class Bier: public std::list<Child *> {
106 public:
107 void add(Child *child) { this->push_back(child); }
108 void notify();
109 };
110
111 public:
112 // set sharedChildren(true) in library code to leave other children alone
113 static void sharedChildren(bool s);
114 static bool sharedChildren();
115
116 void reset(); // make Child ready to be born again (forgets all state)
117
118 static void checkChildren(); // update status on living offspring
119
120 template <class Subclass>
121 static Subclass *find(pid_t pid)
122 { return dynamic_cast<Subclass *>(findGeneric(pid)); }
123
124 private:
125 struct Children : public Mutex, public std::map<pid_t, Child *> {
126 Children() : shared(false) { }
127 bool shared;
128 };
129 static ModuleNexus<Children> mChildren;
130 };
131
132
133 } // end namespace UnixPlusPlus
134 } // end namespace Security
135
136 #endif //_H_UNIXCHILD