]>
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
) { }
95 FileDesc() : mFd(invalidFd
), mAtEnd(false) { }
96 FileDesc(int fd
) : mFd(fd
), mAtEnd(false) { }
98 static const mode_t modeMissingOk
= S_IFIFO
; // in mode means "do not throw on ENOENT"
100 // implicit file system open() construction
101 explicit FileDesc(const char *path
, int flag
= O_RDONLY
, mode_t mode
= 0666)
102 : mFd(invalidFd
) { this->open(path
, flag
, mode
); }
103 explicit FileDesc(const std::string
&path
, int flag
= O_RDONLY
, mode_t mode
= 0666)
104 : mFd(invalidFd
) { this->open(path
.c_str(), flag
, mode
); }
107 FileDesc
&operator = (int fd
) { mFd
= fd
; mAtEnd
= false; return *this; }
108 FileDesc
&operator = (const FileDesc
&fd
) { mFd
= fd
.mFd
; mAtEnd
= fd
.mAtEnd
; return *this; }
110 bool isOpen() const { return mFd
!= invalidFd
; }
111 operator bool() const { return isOpen(); }
112 int fd() const { return mFd
; }
113 operator int() const { return fd(); }
115 void clear() { mFd
= invalidFd
; }
116 void close(); // close and clear
118 void open(const char *path
, int flag
= O_RDONLY
, mode_t mode
= 0666);
119 void open(const std::string
&path
, int flag
= O_RDONLY
, mode_t mode
= 0666)
120 { this->open(path
.c_str(), flag
, mode
); }
122 // basic I/O: this defines the "Filedescoid" pseudo-type
123 size_t read(void *addr
, size_t length
);
124 size_t write(const void *addr
, size_t length
);
125 bool atEnd() const { return mAtEnd
; } // valid after zero-length read only
127 // basic I/O with positioning
128 size_t read(void *addr
, size_t length
, size_t position
);
129 size_t write(const void *addr
, size_t length
, size_t position
);
131 // read/write all of a buffer, in pieces of necessary
132 size_t readAll(void *addr
, size_t length
);
133 size_t readAll(std::string
&content
);
134 void writeAll(const void *addr
, size_t length
);
135 void writeAll(char *s
) { writeAll(s
, strlen(s
)); }
136 void writeAll(const char *s
) { writeAll(s
, strlen(s
)); }
137 template <class Data
>
138 void writeAll(const Data
&ds
) { writeAll(ds
.data(), ds
.length()); }
140 void truncate(size_t offset
);
142 // more convenient I/O
143 template <class T
> size_t read(T
&obj
) { return read(&obj
, sizeof(obj
)); }
144 template <class T
> size_t write(const T
&obj
) { return write(&obj
, sizeof(obj
)); }
147 size_t seek(size_t position
, int whence
= SEEK_SET
);
148 size_t position() const;
151 void *mmap(int prot
= PROT_READ
, size_t length
= 0,
152 int flags
= MAP_FILE
| MAP_PRIVATE
, size_t offset
= 0, void *addr
= NULL
);
155 int fcntl(int cmd
, void *arg
= NULL
) const;
156 template <class T
> int fcntl(int cmd
, T arg
) const
157 { return fcntl(cmd
, reinterpret_cast<void *>(arg
)); }
158 int flags() const { return fcntl(F_GETFL
); }
159 void flags(int flags
) const { fcntl(F_SETFL
, flags
); }
160 void setFlag(int flag
, bool on
= true) const;
161 void clearFlag(int flag
) const { setFlag(flag
, false); }
163 int openMode() const { return flags() & O_ACCMODE
; }
164 bool isWritable() const { return openMode() != O_RDONLY
; }
165 bool isReadable() const { return openMode() != O_WRONLY
; }
167 FileDesc
dup() const;
168 FileDesc
dup(int newFd
) const;
170 // lock support (fcntl style)
172 Pos(size_t s
= 0, int wh
= SEEK_SET
, size_t siz
= 0)
173 : start(s
), size(siz
), whence(wh
) { }
179 static Pos
lockAll() { return Pos(0, SEEK_SET
, 0); }
181 void lock(struct flock
&args
); // raw form (fill in yourself)
183 void lock(int type
= F_WRLCK
, const Pos
&pos
= lockAll());
184 bool tryLock(int type
= F_WRLCK
, const Pos
&pos
= lockAll());
185 void unlock(const Pos
&pos
= lockAll()) { lock(F_UNLCK
, pos
); }
188 int ioctl(int cmd
, void *arg
) const;
189 template <class Arg
> Arg
iocget(int cmd
) const
190 { Arg arg
; ioctl(cmd
, &arg
); return arg
; }
191 template <class Arg
> void iocget(int cmd
, Arg
&arg
) const
192 { ioctl(cmd
, &arg
); }
193 template <class Arg
> void iocset(int cmd
, const Arg
&arg
)
194 { ioctl(cmd
, const_cast<Arg
*>(&arg
)); }
197 void setAttr(const char *name
, const void *value
, size_t length
,
198 u_int32_t position
= 0, int options
= 0);
199 void setAttr(const std::string
&name
, const void *value
, size_t length
,
200 u_int32_t position
= 0, int options
= 0)
201 { return setAttr(name
.c_str(), value
, length
, position
, options
); }
202 ssize_t
getAttr(const char *name
, void *value
, size_t length
,
203 u_int32_t position
= 0, int options
= 0);
204 ssize_t
getAttr(const std::string
&name
, void *value
, size_t length
,
205 u_int32_t position
= 0, int options
= 0)
206 { return getAttr(name
.c_str(), value
, length
, position
, options
); }
207 ssize_t
getAttrLength(const char *name
, int options
= 0);
208 ssize_t
getAttrLength(const std::string
&name
, int options
= 0) { return getAttrLength(name
.c_str(), options
); }
209 // removeAttr ignore missing attributes. Pass XATTR_REPLACE to fail in that case
210 void removeAttr(const char *name
, int options
= 0);
211 void removeAttr(const std::string
&name
, int options
= 0)
212 { return removeAttr(name
.c_str(), options
); }
213 size_t listAttr(char *value
, size_t length
, int options
= 0);
215 bool hasExtendedAttribute(const char *forkname
) const;
217 // xattrs with string values (not including trailing null bytes)
218 void setAttr(const std::string
&name
, const std::string
&value
, int options
= 0);
219 std::string
getAttr(const std::string
&name
, int options
= 0);
221 // stat-related utilities. @@@ should cache??
222 typedef struct stat UnixStat
;
223 void fstat(UnixStat
&st
) const;
224 size_t fileSize() const;
225 bool isA(int type
) const;
227 // change various permissions-related features on the open file
228 void chown(uid_t uid
);
229 void chown(uid_t uid
, gid_t gid
);
230 void chgrp(gid_t gid
);
231 void chmod(mode_t mode
);
232 void chflags(u_int flags
);
234 // stdio interactions
235 FILE *fdopen(const char *mode
= NULL
); // fdopen(3)
237 // Is this a regular file? (not a symlink, fifo, etc.)
238 bool isPlainFile(const std::string
&path
);
240 // device characteristics
241 std::string
mediumType();
244 int mFd
; // UNIX file descriptor
247 struct LockArgs
: public flock
{
248 LockArgs(int type
, const Pos
&pos
)
249 { l_start
= pos
.start
; l_len
= pos
.size
; l_type
= type
; l_whence
= pos
.whence
; }
250 IFDEBUG(void debug(int fd
, const char *what
));
254 bool mAtEnd
; // end-of-data indicator (after zero read)
258 bool filehasExtendedAttribute(const char *path
, const char *forkname
);
259 inline bool filehasExtendedAttribute(const std::string
& path
, const char *forkname
) { return filehasExtendedAttribute(path
.c_str(), forkname
); }
263 // A (plain) FileDesc that auto-closes
265 class AutoFileDesc
: public FileDesc
{
268 AutoFileDesc(int fd
) : FileDesc(fd
) { }
270 AutoFileDesc(const char *path
, int flag
= O_RDONLY
, mode_t mode
= 0666)
271 : FileDesc(path
, flag
, mode
) { }
272 AutoFileDesc(const std::string
&path
, int flag
= O_RDONLY
, mode_t mode
= 0666)
273 : FileDesc(path
, flag
, mode
) { }
275 ~AutoFileDesc() { close(); }
284 SigSet() { sigemptyset(&mValue
); }
285 SigSet(const sigset_t
&s
) : mValue(s
) { }
287 SigSet
&operator += (int sig
)
288 { sigaddset(&mValue
, sig
); return *this; }
289 SigSet
&operator -= (int sig
)
290 { sigdelset(&mValue
, sig
); return *this; }
292 bool contains(int sig
)
293 { return sigismember(&mValue
, sig
); }
295 sigset_t
&value() { return mValue
; }
296 operator sigset_t () const { return mValue
; }
302 SigSet
sigMask(SigSet set
, int how
= SIG_SETMASK
);
306 // A ForkMonitor determines whether the current thread is a (fork) child of
307 // the thread that last checked it. Essentially, it checks for pid changes.
309 class StaticForkMonitor
{
311 bool operator () () const
316 } else if (getpid() != mLastPid
) {
324 mutable pid_t mLastPid
;
327 class ForkMonitor
: public StaticForkMonitor
{
329 ForkMonitor() { mLastPid
= getpid(); }
334 // Miscellaneous functions to aid the intrepid UNIX hacker
336 void makedir(const char *path
, int flags
, mode_t mode
= 0777);
338 int ffprintf(const char *path
, int flags
, mode_t mode
, const char *format
, ...);
339 int ffscanf(const char *path
, const char *format
, ...);
342 } // end namespace UnixPlusPlus
343 } // end namespace Security
346 #endif //_H_UNIXPLUSPLUS