/* * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved. * * The contents of this file constitute Original Code as defined in and are * subject to the Apple Public Source License Version 1.2 (the 'License'). * You may not use this file except in compliance with the License. Please obtain * a copy of the License at http://www.apple.com/publicsource and read it before * using this file. * * This Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the * specific language governing rights and limitations under the License. */ // // unix++ - C++ layer for basic UNIX facilities // #include "unix++.h" #include namespace Security { namespace UnixPlusPlus { // // Generic UNIX file descriptors // void FileDesc::open(const char *path, int flags, mode_t mode) { checkSetFd(::open(path, flags, mode)); mAtEnd = false; debug("unixio", "open(%s,0x%x,0x%x) = %d", path, flags, mode, mFd); } void FileDesc::close() { if (mFd >= 0) { checkError(::close(mFd)); debug("unixio", "close(%d)", mFd); mFd = invalidFd; } } // // Filedescoid operations // size_t FileDesc::read(void *addr, size_t length) { switch (ssize_t rc = ::read(mFd, addr, length)) { case 0: // end-of-source if (length == 0) { // check for errors, but don't set mAtEnd unless we have to debug("unixio", "%d zero read (ignored)", mFd); return 0; } mAtEnd = true; debug("unixio", "%d end of data", mFd); return 0; case -1: // error if (errno == EAGAIN) return 0; // no data, unknown end-of-source status UnixError::throwMe(); // throw error default: // have data return rc; } } size_t FileDesc::write(const void *addr, size_t length) { ssize_t rc = ::write(mFd, addr, length); if (rc == -1) { if (errno == EAGAIN) return 0; UnixError::throwMe(); } return rc; } // // Seeking // off_t FileDesc::seek(off_t position, int whence) { off_t rc = ::lseek(mFd, position, whence); if (rc == -1) UnixError::throwMe(); return rc; } // // Mmap support // void *FileDesc::mmap(int prot, size_t length, int flags, off_t offset, void *addr) { void *result = ::mmap(addr, length ? length : fileSize(), prot, flags, mFd, offset); if (result == MAP_FAILED) UnixError::throwMe(); return result; } int FileDesc::fcntl(int cmd, int arg) const { int rc = ::fcntl(mFd, cmd, arg); debug("unixio", "%d fcntl(%d,%d) = %d", mFd, cmd, arg, rc); if (rc == -1) UnixError::throwMe(); return rc; } int FileDesc::fcntl(int cmd, void *arg) const { // The BSD UNIX headers require an int argument to fcntl. // This will fail miserably if sizeof(void *) > sizeof(int). For such ports, // fix the problem here. assert(sizeof(void *) <= sizeof(int)); return fcntl(cmd, reinterpret_cast(arg)); } int FileDesc::flags() const { int flags = fcntl(F_GETFL); if (flags == -1) UnixError::throwMe(); return flags; } void FileDesc::flags(int flags) const { if (fcntl(F_SETFL, flags) == -1) UnixError::throwMe(); } void FileDesc::setFlag(int flag, bool on) const { if (flag) { // if there's anything at all to do... int oldFlags = flags(); flags(on ? (oldFlags | flag) : (oldFlags & ~flag)); } } int FileDesc::ioctl(int cmd, void *arg) const { int rc = ::ioctl(mFd, cmd, arg); if (rc == -1) UnixError::throwMe(); return rc; } void FileDesc::fstat(UnixStat &st) const { if (::fstat(mFd, &st)) UnixError::throwMe(); } size_t FileDesc::fileSize() const { struct stat st; fstat(st); return st.st_size; } FILE *FileDesc::fdopen(const char *form) { return ::fdopen(mFd, form); } } // end namespace IPPlusPlus } // end namespace Security