]>
git.saurik.com Git - apple/security.git/blob - OSX/libsecurity_utilities/lib/unix++.h
2 * Copyright (c) 2000-2004,2011-2012,2014 Apple Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
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
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.
21 * @APPLE_LICENSE_HEADER_END@
26 // unix++ - C++ layer for basic UNIX facilities
28 #ifndef _H_UNIXPLUSPLUS
29 #define _H_UNIXPLUSPLUS
31 #include <security_utilities/utilities.h>
32 #include <security_utilities/errors.h>
33 #include <security_utilities/timeflow.h>
34 #include <sys/types.h>
35 #include <sys/ioctl.h>
39 #include <sys/xattr.h>
42 #include <semaphore.h>
49 namespace UnixPlusPlus
{
53 // Check system call return and throw on error
55 template <class Result
>
56 inline Result
checkError(Result result
)
58 if (result
== Result(-1))
65 // A UNIX standard 'struct iovec' wrapped
67 class IOVec
: public iovec
{
70 IOVec(const void *data
, size_t length
) { set(data
, length
); }
71 IOVec(void *data
, size_t length
) { set(data
, length
); }
73 void set(const void *data
, size_t length
)
74 { iov_base
= reinterpret_cast<char *>(const_cast<void *>(data
)); iov_len
= length
; }
77 void *data() const { return iov_base
; }
78 size_t length() const { return iov_len
; }
83 // Generic file descriptors
87 static const int invalidFd
= -1;
89 void setFd(int fd
) { mFd
= fd
; mAtEnd
= false; }
90 void checkSetFd(int fd
) { checkError(fd
); mFd
= fd
; mAtEnd
= false; }
92 FileDesc(int fd
, bool atEnd
) : mFd(fd
), mAtEnd(atEnd
) { }
93 void closeAndLog(); // close and clear without throwing
96 FileDesc() : mFd(invalidFd
), mAtEnd(false) { }
97 FileDesc(int fd
) : mFd(fd
), mAtEnd(false) { }
99 static const mode_t modeMissingOk
= S_IFIFO
; // in mode means "do not throw on ENOENT"
101 // implicit file system open() construction
102 explicit FileDesc(const char *path
, int flag
= O_RDONLY
, mode_t mode
= 0666)
103 : mFd(invalidFd
) { this->open(path
, flag
, mode
); }
104 explicit FileDesc(const std::string
&path
, int flag
= O_RDONLY
, mode_t mode
= 0666)
105 : mFd(invalidFd
) { this->open(path
.c_str(), flag
, mode
); }
108 FileDesc
&operator = (int fd
) { mFd
= fd
; mAtEnd
= false; return *this; }
109 FileDesc
&operator = (const FileDesc
&fd
) { mFd
= fd
.mFd
; mAtEnd
= fd
.mAtEnd
; return *this; }
111 bool isOpen() const { return mFd
!= invalidFd
; }
112 operator bool() const { return isOpen(); }
113 int fd() const { return mFd
; }
114 operator int() const { return fd(); }
116 void clear() { mFd
= invalidFd
; }
117 void close(); // close and clear
119 void open(const char *path
, int flag
= O_RDONLY
, mode_t mode
= 0666);
120 void open(const std::string
&path
, int flag
= O_RDONLY
, mode_t mode
= 0666)
121 { this->open(path
.c_str(), flag
, mode
); }
123 // basic I/O: this defines the "Filedescoid" pseudo-type
124 size_t read(void *addr
, size_t length
);
125 size_t write(const void *addr
, size_t length
);
126 bool atEnd() const { return mAtEnd
; } // valid after zero-length read only
128 // basic I/O with positioning
129 size_t read(void *addr
, size_t length
, size_t position
);
130 size_t write(const void *addr
, size_t length
, size_t position
);
132 // read/write all of a buffer, in pieces of necessary
133 size_t readAll(void *addr
, size_t length
);
134 size_t readAll(std::string
&content
);
135 void writeAll(const void *addr
, size_t length
);
136 void writeAll(char *s
) { writeAll(s
, strlen(s
)); }
137 void writeAll(const char *s
) { writeAll(s
, strlen(s
)); }
138 template <class Data
>
139 void writeAll(const Data
&ds
) { writeAll(ds
.data(), ds
.length()); }
141 void truncate(size_t offset
);
143 // more convenient I/O
144 template <class T
> size_t read(T
&obj
) { return read(&obj
, sizeof(obj
)); }
145 template <class T
> size_t write(const T
&obj
) { return write(&obj
, sizeof(obj
)); }
148 size_t seek(size_t position
, int whence
= SEEK_SET
);
149 size_t position() const;
152 void *mmap(int prot
= PROT_READ
, size_t length
= 0,
153 int flags
= MAP_FILE
| MAP_PRIVATE
, size_t offset
= 0, void *addr
= NULL
);
156 int fcntl(int cmd
, void *arg
= NULL
) const;
157 template <class T
> int fcntl(int cmd
, T arg
) const
158 { return fcntl(cmd
, reinterpret_cast<void *>(arg
)); }
159 int flags() const { return fcntl(F_GETFL
); }
160 void flags(int flags
) const { fcntl(F_SETFL
, flags
); }
161 void setFlag(int flag
, bool on
= true) const;
162 void clearFlag(int flag
) const { setFlag(flag
, false); }
164 int openMode() const { return flags() & O_ACCMODE
; }
165 bool isWritable() const { return openMode() != O_RDONLY
; }
166 bool isReadable() const { return openMode() != O_WRONLY
; }
168 FileDesc
dup() const;
169 FileDesc
dup(int newFd
) const;
171 // lock support (fcntl style)
173 Pos(size_t s
= 0, int wh
= SEEK_SET
, size_t siz
= 0)
174 : start(s
), size(siz
), whence(wh
) { }
180 static Pos
lockAll() { return Pos(0, SEEK_SET
, 0); }
182 void lock(struct flock
&args
); // raw form (fill in yourself)
184 void lock(int type
= F_WRLCK
, const Pos
&pos
= lockAll());
185 bool tryLock(int type
= F_WRLCK
, const Pos
&pos
= lockAll());
186 void unlock(const Pos
&pos
= lockAll()) { lock(F_UNLCK
, pos
); }
189 int ioctl(int cmd
, void *arg
) const;
190 template <class Arg
> Arg
iocget(int cmd
) const
191 { Arg arg
; ioctl(cmd
, &arg
); return arg
; }
192 template <class Arg
> void iocget(int cmd
, Arg
&arg
) const
193 { ioctl(cmd
, &arg
); }
194 template <class Arg
> void iocset(int cmd
, const Arg
&arg
)
195 { ioctl(cmd
, const_cast<Arg
*>(&arg
)); }
198 void setAttr(const char *name
, const void *value
, size_t length
,
199 u_int32_t position
= 0, int options
= 0);
200 void setAttr(const std::string
&name
, const void *value
, size_t length
,
201 u_int32_t position
= 0, int options
= 0)
202 { return setAttr(name
.c_str(), value
, length
, position
, options
); }
203 ssize_t
getAttr(const char *name
, void *value
, size_t length
,
204 u_int32_t position
= 0, int options
= 0);
205 ssize_t
getAttr(const std::string
&name
, void *value
, size_t length
,
206 u_int32_t position
= 0, int options
= 0)
207 { return getAttr(name
.c_str(), value
, length
, position
, options
); }
208 ssize_t
getAttrLength(const char *name
, int options
= 0);
209 ssize_t
getAttrLength(const std::string
&name
, int options
= 0) { return getAttrLength(name
.c_str(), options
); }
210 // removeAttr ignore missing attributes. Pass XATTR_REPLACE to fail in that case
211 void removeAttr(const char *name
, int options
= 0);
212 void removeAttr(const std::string
&name
, int options
= 0)
213 { return removeAttr(name
.c_str(), options
); }
214 size_t listAttr(char *value
, size_t length
, int options
= 0);
216 bool hasExtendedAttribute(const char *forkname
) const;
218 // xattrs with string values (not including trailing null bytes)
219 void setAttr(const std::string
&name
, const std::string
&value
, int options
= 0);
220 std::string
getAttr(const std::string
&name
, int options
= 0);
222 // stat-related utilities. @@@ should cache??
223 typedef struct stat UnixStat
;
224 void fstat(UnixStat
&st
) const;
225 size_t fileSize() const;
226 bool isA(int type
) const;
228 // change various permissions-related features on the open file
229 void chown(uid_t uid
);
230 void chown(uid_t uid
, gid_t gid
);
231 void chgrp(gid_t gid
);
232 void chmod(mode_t mode
);
233 void chflags(u_int flags
);
235 // stdio interactions
236 FILE *fdopen(const char *mode
= NULL
); // fdopen(3)
238 // Is this a regular file? (not a symlink, fifo, etc.)
239 bool isPlainFile(const std::string
&path
);
241 // device characteristics
242 std::string
mediumType();
245 int mFd
; // UNIX file descriptor
248 struct LockArgs
: public flock
{
249 LockArgs(int type
, const Pos
&pos
)
250 { l_start
= pos
.start
; l_len
= pos
.size
; l_type
= type
; l_whence
= pos
.whence
; }
251 IFDEBUG(void debug(int fd
, const char *what
));
255 bool mAtEnd
; // end-of-data indicator (after zero read)
259 bool filehasExtendedAttribute(const char *path
, const char *forkname
);
260 inline bool filehasExtendedAttribute(const std::string
& path
, const char *forkname
) { return filehasExtendedAttribute(path
.c_str(), forkname
); }
264 // A (plain) FileDesc that auto-closes
266 class AutoFileDesc
: public FileDesc
{
269 AutoFileDesc(int fd
) : FileDesc(fd
) { }
271 AutoFileDesc(const char *path
, int flag
= O_RDONLY
, mode_t mode
= 0666)
272 : FileDesc(path
, flag
, mode
) { }
273 AutoFileDesc(const std::string
&path
, int flag
= O_RDONLY
, mode_t mode
= 0666)
274 : FileDesc(path
, flag
, mode
) { }
275 AutoFileDesc(const AutoFileDesc
& rhs
);
276 ~AutoFileDesc() { closeAndLog(); }
285 SigSet() { sigemptyset(&mValue
); }
286 SigSet(const sigset_t
&s
) : mValue(s
) { }
288 SigSet
&operator += (int sig
)
289 { sigaddset(&mValue
, sig
); return *this; }
290 SigSet
&operator -= (int sig
)
291 { sigdelset(&mValue
, sig
); return *this; }
293 bool contains(int sig
)
294 { return sigismember(&mValue
, sig
); }
296 sigset_t
&value() { return mValue
; }
297 operator sigset_t () const { return mValue
; }
303 SigSet
sigMask(SigSet set
, int how
= SIG_SETMASK
);
307 // A ForkMonitor determines whether the current thread is a (fork) child of
308 // the thread that last checked it. Essentially, it checks for pid changes.
310 class StaticForkMonitor
{
312 bool operator () () const
317 } else if (getpid() != mLastPid
) {
325 mutable pid_t mLastPid
;
328 class ForkMonitor
: public StaticForkMonitor
{
330 ForkMonitor() { mLastPid
= getpid(); }
335 // Miscellaneous functions to aid the intrepid UNIX hacker
337 void makedir(const char *path
, int flags
, mode_t mode
= 0777);
339 int ffprintf(const char *path
, int flags
, mode_t mode
, const char *format
, ...) __attribute__((format(printf
, 4, 5)));
340 int ffscanf(const char *path
, const char *format
, ...) __attribute__((format(scanf
, 2, 3)));
343 } // end namespace UnixPlusPlus
344 } // end namespace Security
347 #endif //_H_UNIXPLUSPLUS