]>
git.saurik.com Git - apple/security.git/blob - libsecurity_utilities/lib/unix++.h
2 * Copyright (c) 2000-2004 Apple Computer, 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>
41 #include <semaphore.h>
48 namespace UnixPlusPlus
{
52 // Check system call return and throw on error
54 template <class Result
>
55 inline Result
checkError(Result result
)
57 if (result
== Result(-1))
64 // A UNIX standard 'struct iovec' wrapped
66 class IOVec
: public iovec
{
69 IOVec(const void *data
, size_t length
) { set(data
, length
); }
70 IOVec(void *data
, size_t length
) { set(data
, length
); }
72 void set(const void *data
, size_t length
)
73 { iov_base
= reinterpret_cast<char *>(const_cast<void *>(data
)); iov_len
= length
; }
76 void *data() const { return iov_base
; }
77 size_t length() const { return iov_len
; }
82 // Generic file descriptors
86 static const int invalidFd
= -1;
88 void setFd(int fd
) { mFd
= fd
; mAtEnd
= false; }
89 void checkSetFd(int fd
) { checkError(fd
); mFd
= fd
; mAtEnd
= false; }
91 FileDesc(int fd
, bool atEnd
) : mFd(fd
), mAtEnd(atEnd
) { }
94 FileDesc() : mFd(invalidFd
), mAtEnd(false) { }
95 FileDesc(int fd
) : mFd(fd
), mAtEnd(false) { }
97 static const mode_t modeMissingOk
= S_IFIFO
; // in mode means "do not throw on ENOENT"
99 // implicit file system open() construction
100 explicit FileDesc(const char *path
, int flag
= O_RDONLY
, mode_t mode
= 0666)
101 : mFd(invalidFd
) { this->open(path
, flag
, mode
); }
102 explicit FileDesc(const std::string
&path
, int flag
= O_RDONLY
, mode_t mode
= 0666)
103 : mFd(invalidFd
) { this->open(path
.c_str(), flag
, mode
); }
106 FileDesc
&operator = (int fd
) { mFd
= fd
; mAtEnd
= false; return *this; }
107 FileDesc
&operator = (const FileDesc
&fd
) { mFd
= fd
.mFd
; mAtEnd
= fd
.mAtEnd
; return *this; }
109 bool isOpen() const { return mFd
!= invalidFd
; }
110 operator bool() const { return isOpen(); }
111 int fd() const { return mFd
; }
112 operator int() const { return fd(); }
114 void clear() { mFd
= invalidFd
; }
115 void close(); // close and clear
117 void open(const char *path
, int flag
= O_RDONLY
, mode_t mode
= 0666);
118 void open(const std::string
&path
, int flag
= O_RDONLY
, mode_t mode
= 0666)
119 { this->open(path
.c_str(), flag
, mode
); }
121 // basic I/O: this defines the "Filedescoid" pseudo-type
122 size_t read(void *addr
, size_t length
);
123 size_t write(const void *addr
, size_t length
);
124 bool atEnd() const { return mAtEnd
; } // valid after zero-length read only
126 // basic I/O with positioning
127 size_t read(void *addr
, size_t length
, off_t position
);
128 size_t write(const void *addr
, size_t length
, off_t position
);
130 // read/write all of a buffer, in pieces of necessary
131 size_t readAll(void *addr
, size_t length
);
132 size_t readAll(std::string
&content
);
133 void writeAll(const void *addr
, size_t length
);
134 void writeAll(char *s
) { writeAll(s
, strlen(s
)); }
135 void writeAll(const char *s
) { writeAll(s
, strlen(s
)); }
136 template <class Data
>
137 void writeAll(const Data
&ds
) { writeAll(ds
.data(), ds
.length()); }
139 // more convenient I/O
140 template <class T
> size_t read(T
&obj
) { return read(&obj
, sizeof(obj
)); }
141 template <class T
> size_t write(const T
&obj
) { return write(&obj
, sizeof(obj
)); }
144 size_t seek(off_t position
, int whence
= SEEK_SET
);
145 size_t position() const;
148 void *mmap(int prot
= PROT_READ
, size_t length
= 0,
149 int flags
= MAP_FILE
| MAP_PRIVATE
, off_t offset
= 0, void *addr
= NULL
);
152 int fcntl(int cmd
, void *arg
= NULL
) const;
153 template <class T
> int fcntl(int cmd
, T arg
) const
154 { return fcntl(cmd
, reinterpret_cast<void *>(arg
)); }
155 int flags() const { return fcntl(F_GETFL
); }
156 void flags(int flags
) const { fcntl(F_SETFL
, flags
); }
157 void setFlag(int flag
, bool on
= true) const;
158 void clearFlag(int flag
) const { setFlag(flag
, false); }
160 int openMode() const { return flags() & O_ACCMODE
; }
161 bool isWritable() const { return openMode() != O_RDONLY
; }
162 bool isReadable() const { return openMode() != O_WRONLY
; }
164 FileDesc
dup() const;
165 FileDesc
dup(int newFd
) const;
167 // lock support (fcntl style)
169 Pos(off_t s
= 0, int wh
= SEEK_SET
, off_t siz
= 0)
170 : start(s
), size(siz
), whence(wh
) { }
176 static Pos
lockAll() { return Pos(0, SEEK_SET
, 0); }
178 void lock(struct flock
&args
); // raw form (fill in yourself)
180 void lock(int type
= F_WRLCK
, const Pos
&pos
= lockAll());
181 bool tryLock(int type
= F_WRLCK
, const Pos
&pos
= lockAll());
182 void unlock(const Pos
&pos
= lockAll()) { lock(F_UNLCK
, pos
); }
185 int ioctl(int cmd
, void *arg
) const;
186 template <class Arg
> Arg
iocget(int cmd
) const
187 { Arg arg
; ioctl(cmd
, &arg
); return arg
; }
188 template <class Arg
> void iocget(int cmd
, Arg
&arg
) const
189 { ioctl(cmd
, &arg
); }
190 template <class Arg
> void iocset(int cmd
, const Arg
&arg
)
191 { ioctl(cmd
, const_cast<Arg
*>(&arg
)); }
194 void setAttr(const char *name
, const void *value
, size_t length
,
195 u_int32_t position
= 0, int options
= 0);
196 void setAttr(const std::string
&name
, const void *value
, size_t length
,
197 u_int32_t position
= 0, int options
= 0)
198 { return setAttr(name
.c_str(), value
, length
, position
, options
); }
199 ssize_t
getAttr(const char *name
, void *value
, size_t length
,
200 u_int32_t position
= 0, int options
= 0);
201 ssize_t
getAttr(const std::string
&name
, void *value
, size_t length
,
202 u_int32_t position
= 0, int options
= 0)
203 { return getAttr(name
.c_str(), value
, length
, position
, options
); }
204 ssize_t
getAttrLength(const char *name
);
205 ssize_t
getAttrLength(const std::string
&name
) { return getAttrLength(name
.c_str()); }
206 // removeAttr ignore missing attributes. Pass XATTR_REPLACE to fail in that case
207 void removeAttr(const char *name
, int options
= 0);
208 void removeAttr(const std::string
&name
, int options
= 0)
209 { return removeAttr(name
.c_str(), options
); }
210 size_t listAttr(char *value
, size_t length
, int options
= 0);
211 size_t listAttr(const std::string
&name
, size_t length
, int options
= 0)
212 { return listAttr(name
.c_str(), length
, options
); }
214 // xattrs with string values (not including trailing null bytes)
215 void setAttr(const std::string
&name
, const std::string
&value
, int options
= 0);
216 std::string
getAttr(const std::string
&name
, int options
= 0);
218 // stat-related utilities. @@@ should cache??
219 typedef struct stat UnixStat
;
220 void fstat(UnixStat
&st
) const;
221 size_t fileSize() const;
222 bool isA(int type
) const;
224 // change various permissions-related features on the open file
225 void chown(uid_t uid
);
226 void chown(uid_t uid
, gid_t gid
);
227 void chgrp(gid_t gid
);
228 void chmod(mode_t mode
);
229 void chflags(u_int flags
);
231 // stdio interactions
232 FILE *fdopen(const char *mode
= NULL
); // fdopen(3)
235 int mFd
; // UNIX file descriptor
238 struct LockArgs
: public flock
{
239 LockArgs(int type
, const Pos
&pos
)
240 { l_start
= pos
.start
; l_len
= pos
.size
; l_type
= type
; l_whence
= pos
.whence
; }
241 IFDEBUG(void debug(int fd
, const char *what
));
245 bool mAtEnd
; // end-of-data indicator (after zero read)
250 // A (plain) FileDesc that auto-closes
252 class AutoFileDesc
: public FileDesc
{
255 AutoFileDesc(int fd
) : FileDesc(fd
) { }
257 AutoFileDesc(const char *path
, int flag
= O_RDONLY
, mode_t mode
= 0666)
258 : FileDesc(path
, flag
, mode
) { }
259 AutoFileDesc(const std::string
&path
, int flag
= O_RDONLY
, mode_t mode
= 0666)
260 : FileDesc(path
, flag
, mode
) { }
262 ~AutoFileDesc() { close(); }
271 SigSet() { sigemptyset(&mValue
); }
272 SigSet(const sigset_t
&s
) : mValue(s
) { }
274 SigSet
&operator += (int sig
)
275 { sigaddset(&mValue
, sig
); return *this; }
276 SigSet
&operator -= (int sig
)
277 { sigdelset(&mValue
, sig
); return *this; }
279 bool contains(int sig
)
280 { return sigismember(&mValue
, sig
); }
282 sigset_t
&value() { return mValue
; }
283 operator sigset_t () const { return mValue
; }
289 SigSet
sigMask(SigSet set
, int how
= SIG_SETMASK
);
293 // A ForkMonitor determines whether the current thread is a (fork) child of
294 // the thread that last checked it. Essentially, it checks for pid changes.
296 class StaticForkMonitor
{
298 bool operator () () const
303 } else if (getpid() != mLastPid
) {
311 mutable pid_t mLastPid
;
314 class ForkMonitor
: public StaticForkMonitor
{
316 ForkMonitor() { mLastPid
= getpid(); }
321 // Miscellaneous functions to aid the intrepid UNIX hacker
323 void makedir(const char *path
, int flags
, mode_t mode
= 0777);
325 int ffprintf(const char *path
, int flags
, mode_t mode
, const char *format
, ...);
326 int ffscanf(const char *path
, const char *format
, ...);
329 } // end namespace UnixPlusPlus
330 } // end namespace Security
333 #endif //_H_UNIXPLUSPLUS