]> git.saurik.com Git - apple/security.git/blob - cdsa/cdsa_utilities/unix++.h
Security-163.tar.gz
[apple/security.git] / cdsa / cdsa_utilities / unix++.h
1 /*
2 * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
3 *
4 * The contents of this file constitute Original Code as defined in and are
5 * subject to the Apple Public Source License Version 1.2 (the 'License').
6 * You may not use this file except in compliance with the License. Please obtain
7 * a copy of the License at http://www.apple.com/publicsource and read it before
8 * using this file.
9 *
10 * This Original Code and all software distributed under the License are
11 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
12 * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
13 * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
14 * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the
15 * specific language governing rights and limitations under the License.
16 */
17
18
19 //
20 // unix++ - C++ layer for basic UNIX facilities
21 //
22 #ifndef _H_UNIXPLUSPLUS
23 #define _H_UNIXPLUSPLUS
24
25 #include <Security/utilities.h>
26 #include <Security/timeflow.h>
27 #include <sys/types.h>
28 #include <sys/ioctl.h>
29 #include <sys/uio.h>
30 #include <sys/stat.h>
31 #include <sys/mman.h>
32 #include <signal.h>
33 #include <fcntl.h>
34 #include <cstdio>
35 #include <cstdarg>
36 #include <map>
37
38
39 namespace Security {
40 namespace UnixPlusPlus {
41
42
43 //
44 // Check system call return and throw on error
45 //
46 inline void checkError(int result)
47 {
48 if (result == -1)
49 UnixError::throwMe();
50 }
51
52
53 //
54 // A UNIX standard 'struct iovec' wrapped
55 //
56 class IOVec : public iovec {
57 public:
58 IOVec() { }
59 IOVec(const void *data, size_t length) { set(data, length); }
60 IOVec(void *data, size_t length) { set(data, length); }
61
62 void set(const void *data, size_t length)
63 { iov_base = reinterpret_cast<char *>(const_cast<void *>(data)); iov_len = length; }
64
65 // data-oid methods
66 void *data() const { return iov_base; }
67 size_t length() const { return iov_len; }
68 };
69
70
71 //
72 // Generic file descriptors
73 //
74 class FileDesc {
75 protected:
76 static const int invalidFd = -1;
77
78 void setFd(int fd) { mFd = fd; mAtEnd = false; }
79 void checkSetFd(int fd) { checkError(fd); mFd = fd; mAtEnd = false; }
80
81 public:
82 FileDesc() : mFd(invalidFd), mAtEnd(false) { }
83 FileDesc(int fd) : mFd(fd), mAtEnd(false) { }
84
85 // implicit file system open() construction
86 FileDesc(const char *path, int flag = O_RDONLY, mode_t mode = 0666) : mFd(invalidFd)
87 { open(path, flag, mode); }
88 FileDesc(const std::string &path, int flag = O_RDONLY, mode_t mode = 0666) : mFd(invalidFd)
89 { open(path.c_str(), flag, mode); }
90
91 // assignment
92 FileDesc &operator = (int fd) { mFd = fd; mAtEnd = false; return *this; }
93 FileDesc &operator = (const FileDesc &fd) { mFd = fd.mFd; mAtEnd = fd.mAtEnd; return *this; }
94
95 bool isOpen() const { return mFd != invalidFd; }
96 operator bool() const { return isOpen(); }
97 int fd() const { return mFd; }
98 operator int() const { return fd(); }
99
100 void clear() { mFd = invalidFd; }
101 void close(); // close and clear
102
103 void open(const char *path, int flag = O_RDONLY, mode_t mode = 0666);
104
105 // basic I/O: this defines the "Filedescoid" pseudo-type
106 size_t read(void *addr, size_t length);
107 size_t write(const void *addr, size_t length);
108 bool atEnd() const { return mAtEnd; } // valid after zero-length read only
109
110 // more convenient I/O
111 template <class T> size_t read(T &obj) { return read(&obj, sizeof(obj)); }
112 template <class T> size_t write(const T &obj) { return write(&obj, sizeof(obj)); }
113
114 // seeking
115 off_t seek(off_t position, int whence = SEEK_SET);
116
117 // mapping support
118 void *mmap(int prot = PROT_READ, size_t length = 0, int flags = MAP_FILE,
119 off_t offset = 0, void *addr = NULL);
120
121 // fcntl support
122 int fcntl(int cmd, int arg = 0) const;
123 int fcntl(int cmd, void *arg) const;
124 int flags() const;
125 void flags(int flags) const;
126 void setFlag(int flag, bool on = true) const;
127 void clearFlag(int flag) const { setFlag(flag, false); }
128
129 int openMode() const { return flags() & O_ACCMODE; }
130 bool isWritable() const { return openMode() != O_RDONLY; }
131 bool isReadable() const { return openMode() != O_WRONLY; }
132
133 // ioctl support
134 int ioctl(int cmd, void *arg) const;
135 template <class Arg> Arg iocget(int cmd) const
136 { Arg arg; ioctl(cmd, &arg); return arg; }
137 template <class Arg> void iocget(int cmd, Arg &arg) const
138 { ioctl(cmd, &arg); }
139 template <class Arg> void iocset(int cmd, const Arg &arg)
140 { ioctl(cmd, const_cast<Arg *>(&arg)); }
141
142 // stat-related utilities. @@@ should cache??
143 typedef struct stat UnixStat;
144 void fstat(UnixStat &st) const;
145 size_t fileSize() const;
146
147 // stdio interactions
148 FILE *fdopen(const char *mode = NULL); // fdopen(3)
149
150 private:
151 int mFd; // UNIX file descriptor
152
153 protected:
154 bool mAtEnd; // end-of-data indicator (after zero read)
155 };
156
157
158 //
159 // A (plain) FileDesc that auto-closes
160 //
161 class AutoFileDesc : public FileDesc {
162 public:
163 AutoFileDesc() { }
164 AutoFileDesc(int fd) : FileDesc(fd) { }
165
166 AutoFileDesc(const char *path, int flag = O_RDONLY, mode_t mode = 0666)
167 : FileDesc(path, flag, mode) { }
168 AutoFileDesc(const std::string &path, int flag = O_RDONLY, mode_t mode = 0666)
169 : FileDesc(path, flag, mode) { }
170
171 ~AutoFileDesc() { close(); }
172 };
173
174
175 //
176 // Signal sets
177 //
178 class SigSet {
179 public:
180 SigSet() { sigemptyset(&mValue); }
181 SigSet(const sigset_t &s) : mValue(s) { }
182
183 SigSet &operator += (int sig)
184 { sigaddset(&mValue, sig); return *this; }
185 SigSet &operator -= (int sig)
186 { sigdelset(&mValue, sig); return *this; }
187
188 bool contains(int sig)
189 { return sigismember(&mValue, sig); }
190
191 sigset_t &value() { return mValue; }
192 operator sigset_t () const { return mValue; }
193
194 private:
195 sigset_t mValue;
196 };
197
198 SigSet sigMask(SigSet set, int how = SIG_SETMASK);
199
200
201 //
202 // A ForkMonitor determines whether the current thread is a (fork) child of
203 // the thread that last checked it. Essentially, it checks for pid changes.
204 //
205 class StaticForkMonitor {
206 public:
207 bool operator () () const
208 {
209 if (mLastPid == 0) {
210 mLastPid = getpid();
211 return false;
212 } else if (getpid() != mLastPid) {
213 mLastPid = getpid();
214 return true;
215 }
216 return false;
217 }
218
219 protected:
220 mutable pid_t mLastPid;
221 };
222
223 class ForkMonitor : public StaticForkMonitor {
224 public:
225 ForkMonitor() { mLastPid = getpid(); }
226 };
227
228
229 } // end namespace UnixPlusPlus
230 } // end namespace Security
231
232
233 #endif //_H_UNIXPLUSPLUS