]>
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 FileDesc(const FileDesc
& fd
) : mFd(fd
.mFd
), mAtEnd(fd
.mAtEnd
) { }
101 static const mode_t modeMissingOk
= S_IFIFO
; // in mode means "do not throw on ENOENT"
103 // implicit file system open() construction
104 explicit FileDesc(const char *path
, int flag
= O_RDONLY
, mode_t mode
= 0666)
105 : mFd(invalidFd
) { this->open(path
, flag
, mode
); }
106 explicit FileDesc(const std::string
&path
, int flag
= O_RDONLY
, mode_t mode
= 0666)
107 : mFd(invalidFd
) { this->open(path
.c_str(), flag
, mode
); }
110 FileDesc
&operator = (int fd
) { mFd
= fd
; mAtEnd
= false; return *this; }
111 FileDesc
&operator = (const FileDesc
&fd
) { mFd
= fd
.mFd
; mAtEnd
= fd
.mAtEnd
; return *this; }
113 bool isOpen() const { return mFd
!= invalidFd
; }
114 operator bool() const { return isOpen(); }
115 int fd() const { return mFd
; }
116 operator int() const { return fd(); }
118 void clear() { mFd
= invalidFd
; }
119 void close(); // close and clear
121 void open(const char *path
, int flag
= O_RDONLY
, mode_t mode
= 0666);
122 void open(const std::string
&path
, int flag
= O_RDONLY
, mode_t mode
= 0666)
123 { this->open(path
.c_str(), flag
, mode
); }
125 // basic I/O: this defines the "Filedescoid" pseudo-type
126 size_t read(void *addr
, size_t length
);
127 size_t write(const void *addr
, size_t length
);
128 bool atEnd() const { return mAtEnd
; } // valid after zero-length read only
130 // basic I/O with positioning
131 size_t read(void *addr
, size_t length
, size_t position
);
132 size_t write(const void *addr
, size_t length
, size_t position
);
134 // read/write all of a buffer, in pieces of necessary
135 size_t readAll(void *addr
, size_t length
);
136 size_t readAll(std::string
&content
);
137 void writeAll(const void *addr
, size_t length
);
138 void writeAll(char *s
) { writeAll(s
, strlen(s
)); }
139 void writeAll(const char *s
) { writeAll(s
, strlen(s
)); }
140 template <class Data
>
141 void writeAll(const Data
&ds
) { writeAll(ds
.data(), ds
.length()); }
143 void truncate(size_t offset
);
145 // more convenient I/O
146 template <class T
> size_t read(T
&obj
) { return read(&obj
, sizeof(obj
)); }
147 template <class T
> size_t write(const T
&obj
) { return write(&obj
, sizeof(obj
)); }
150 size_t seek(size_t position
, int whence
= SEEK_SET
);
151 size_t position() const;
154 void *mmap(int prot
= PROT_READ
, size_t length
= 0,
155 int flags
= MAP_FILE
| MAP_PRIVATE
, size_t offset
= 0, void *addr
= NULL
);
158 int fcntl(int cmd
, void *arg
= NULL
) const;
159 template <class T
> int fcntl(int cmd
, T arg
) const
160 { return fcntl(cmd
, reinterpret_cast<void *>(arg
)); }
161 int flags() const { return fcntl(F_GETFL
); }
162 void flags(int flags
) const { fcntl(F_SETFL
, flags
); }
163 void setFlag(int flag
, bool on
= true) const;
164 void clearFlag(int flag
) const { setFlag(flag
, false); }
166 int openMode() const { return flags() & O_ACCMODE
; }
167 bool isWritable() const { return openMode() != O_RDONLY
; }
168 bool isReadable() const { return openMode() != O_WRONLY
; }
170 FileDesc
dup() const;
171 FileDesc
dup(int newFd
) const;
173 // lock support (fcntl style)
175 Pos(size_t s
= 0, int wh
= SEEK_SET
, size_t siz
= 0)
176 : start(s
), size(siz
), whence(wh
) { }
182 static Pos
lockAll() { return Pos(0, SEEK_SET
, 0); }
184 void lock(struct flock
&args
); // raw form (fill in yourself)
186 void lock(int type
= F_WRLCK
, const Pos
&pos
= lockAll());
187 bool tryLock(int type
= F_WRLCK
, const Pos
&pos
= lockAll());
188 void unlock(const Pos
&pos
= lockAll()) { lock(F_UNLCK
, pos
); }
191 int ioctl(int cmd
, void *arg
) const;
192 template <class Arg
> Arg
iocget(int cmd
) const
193 { Arg arg
; ioctl(cmd
, &arg
); return arg
; }
194 template <class Arg
> void iocget(int cmd
, Arg
&arg
) const
195 { ioctl(cmd
, &arg
); }
196 template <class Arg
> void iocset(int cmd
, const Arg
&arg
)
197 { ioctl(cmd
, const_cast<Arg
*>(&arg
)); }
200 void setAttr(const char *name
, const void *value
, size_t length
,
201 u_int32_t position
= 0, int options
= 0);
202 void setAttr(const std::string
&name
, const void *value
, size_t length
,
203 u_int32_t position
= 0, int options
= 0)
204 { return setAttr(name
.c_str(), value
, length
, position
, options
); }
205 ssize_t
getAttr(const char *name
, void *value
, size_t length
,
206 u_int32_t position
= 0, int options
= 0);
207 ssize_t
getAttr(const std::string
&name
, void *value
, size_t length
,
208 u_int32_t position
= 0, int options
= 0)
209 { return getAttr(name
.c_str(), value
, length
, position
, options
); }
210 ssize_t
getAttrLength(const char *name
, int options
= 0);
211 ssize_t
getAttrLength(const std::string
&name
, int options
= 0) { return getAttrLength(name
.c_str(), options
); }
212 // removeAttr ignore missing attributes. Pass XATTR_REPLACE to fail in that case
213 void removeAttr(const char *name
, int options
= 0);
214 void removeAttr(const std::string
&name
, int options
= 0)
215 { return removeAttr(name
.c_str(), options
); }
216 size_t listAttr(char *value
, size_t length
, int options
= 0);
218 bool hasExtendedAttribute(const char *forkname
) const;
220 // xattrs with string values (not including trailing null bytes)
221 void setAttr(const std::string
&name
, const std::string
&value
, int options
= 0);
222 std::string
getAttr(const std::string
&name
, int options
= 0);
224 // stat-related utilities. @@@ should cache??
225 typedef struct stat UnixStat
;
226 void fstat(UnixStat
&st
) const;
227 size_t fileSize() const;
228 bool isA(int type
) const;
230 // change various permissions-related features on the open file
231 void chown(uid_t uid
);
232 void chown(uid_t uid
, gid_t gid
);
233 void chgrp(gid_t gid
);
234 void chmod(mode_t mode
);
235 void chflags(u_int flags
);
237 // stdio interactions
238 FILE *fdopen(const char *mode
= NULL
); // fdopen(3)
240 // Is this a regular file? (not a symlink, fifo, etc.)
241 bool isPlainFile(const std::string
&path
);
243 // device characteristics
244 std::string
mediumType();
247 int mFd
; // UNIX file descriptor
250 struct LockArgs
: public flock
{
251 LockArgs(int type
, const Pos
&pos
)
252 { l_start
= pos
.start
; l_len
= pos
.size
; l_type
= type
; l_whence
= pos
.whence
; }
253 IFDEBUG(void debug(int fd
, const char *what
));
257 bool mAtEnd
; // end-of-data indicator (after zero read)
261 bool filehasExtendedAttribute(const char *path
, const char *forkname
);
262 inline bool filehasExtendedAttribute(const std::string
& path
, const char *forkname
) { return filehasExtendedAttribute(path
.c_str(), forkname
); }
266 // A (plain) FileDesc that auto-closes
268 class AutoFileDesc
: public FileDesc
{
271 AutoFileDesc(int fd
) : FileDesc(fd
) { }
273 AutoFileDesc(const char *path
, int flag
= O_RDONLY
, mode_t mode
= 0666)
274 : FileDesc(path
, flag
, mode
) { }
275 AutoFileDesc(const std::string
&path
, int flag
= O_RDONLY
, mode_t mode
= 0666)
276 : FileDesc(path
, flag
, mode
) { }
277 AutoFileDesc(const AutoFileDesc
& rhs
);
278 ~AutoFileDesc() { closeAndLog(); }
287 SigSet() { sigemptyset(&mValue
); }
288 SigSet(const sigset_t
&s
) : mValue(s
) { }
290 SigSet
&operator += (int sig
)
291 { sigaddset(&mValue
, sig
); return *this; }
292 SigSet
&operator -= (int sig
)
293 { sigdelset(&mValue
, sig
); return *this; }
295 bool contains(int sig
)
296 { return sigismember(&mValue
, sig
); }
298 sigset_t
&value() { return mValue
; }
299 operator sigset_t () const { return mValue
; }
305 SigSet
sigMask(SigSet set
, int how
= SIG_SETMASK
);
309 // A ForkMonitor determines whether the current thread is a (fork) child of
310 // the thread that last checked it. Essentially, it checks for pid changes.
312 class StaticForkMonitor
{
314 bool operator () () const
319 } else if (getpid() != mLastPid
) {
327 mutable pid_t mLastPid
;
330 class ForkMonitor
: public StaticForkMonitor
{
332 ForkMonitor() { mLastPid
= getpid(); }
337 // Miscellaneous functions to aid the intrepid UNIX hacker
339 void makedir(const char *path
, int flags
, mode_t mode
= 0777);
341 int ffprintf(const char *path
, int flags
, mode_t mode
, const char *format
, ...) __attribute__((format(printf
, 4, 5)));
342 int ffscanf(const char *path
, const char *format
, ...) __attribute__((format(scanf
, 2, 3)));
345 } // end namespace UnixPlusPlus
346 } // end namespace Security
349 #endif //_H_UNIXPLUSPLUS