19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// This file is part of the ustl library, an STL implementation. 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// Copyright (C) 2005 by Mike Sharov <msharov@users.sourceforge.net> 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// This file is free software, distributed under the MIT License. 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// file.cc 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "fstream.h" 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "uassert.h" 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "uexception.h" 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "uutility.h" 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <fcntl.h> 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <unistd.h> 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <errno.h> 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <sys/stat.h> 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <sys/mman.h> 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <sys/ioctl.h> 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if PLATFORM_ANDROID 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <stdio.h> 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectnamespace ustl { 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/// Default constructor. 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectfstream::fstream (void) 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project: ios_base (), 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project m_fd (-1), 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project m_Filename () 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/// Opens \p filename in \p mode. 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectfstream::fstream (const char* filename, openmode mode) 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project: ios_base (), 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project m_fd (-1), 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project m_Filename () 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project open (filename, mode); 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/// Attaches to \p nfd of \p filename. 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectfstream::fstream (int nfd, const char* filename) 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project: ios_base (), 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project m_fd (-1), 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project m_Filename () 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project attach (nfd, filename); 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/// Destructor. Closes if still open, but without throwing. 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectfstream::~fstream (void) throw() 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project clear (goodbit); 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project exceptions (goodbit); 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project close(); 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project assert (!(rdstate() & badbit) && "close failed in the destructor! This may lead to loss of user data. Please call close() manually and either enable exceptions or check the badbit."); 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/// Sets state \p s and throws depending on the exception setting. 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid fstream::set_and_throw (iostate s, const char* op) 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (ios_base::set_and_throw (s)) 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if PLATFORM_ANDROID 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("file_exception\n"); 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#else /* !PLATFORM_ANDROID */ 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw file_exception (op, name()); 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/// Attaches to the given \p nfd. 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid fstream::attach (int nfd, const char* filename) 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project assert (filename && "Don't do that"); 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project clear (goodbit); 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (nfd < 0 && ios_base::set_and_throw (badbit)) 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if PLATFORM_ANDROID 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("file exception\n"); 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#else /* !PLATFORM_ANDROID */ 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw file_exception ("open", filename); 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project close(); 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project m_fd = nfd; 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project m_Filename = filename; 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/// Detaches from the current fd. 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid fstream::detach (void) 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project m_fd = -1; 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project m_Filename.clear(); 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/// Converts openmode bits into libc open flags. 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*static*/ int fstream::om_to_flags (openmode m) 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static const int s_OMFlags [nombits] = { 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 0, // in 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project O_CREAT, // out 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project O_APPEND, // app 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project O_APPEND, // ate 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 0, // binary 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project O_TRUNC, // trunc 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project O_NONBLOCK, // nonblock 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 0, // nocreate 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project O_NOCTTY // noctty 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project }; 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int flags = (m - 1) & O_ACCMODE; // in and out 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (uoff_t i = 0; i < VectorSize(s_OMFlags); ++ i) 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (m & (1 << i)) 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project flags |= s_OMFlags[i]; 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (m & nocreate) 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project flags &= ~O_CREAT; 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (flags); 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/// \brief Opens \p filename in the given mode. 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/// \warning The string at \p filename must exist until the object is closed. 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid fstream::open (const char* filename, openmode mode, mode_t perms) 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int nfd = ::open (filename, om_to_flags(mode), perms); 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project attach (nfd, filename); 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/// Closes the file and throws on error. 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid fstream::close (void) 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (m_fd >= 0 && ::close(m_fd)) 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project set_and_throw (badbit | failbit, "close"); 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project detach(); 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/// Moves the current file position to \p n. 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectoff_t fstream::seek (off_t n, seekdir whence) 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project off_t p = lseek (m_fd, n, whence); 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (p < 0) 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project set_and_throw (failbit, "seek"); 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (p); 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/// Returns the current file position. 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectoff_t fstream::pos (void) const 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (lseek (m_fd, 0, SEEK_CUR)); 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/// Reads \p n bytes into \p p. 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectoff_t fstream::read (void* p, off_t n) 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project off_t br (0); 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (br < n && good()) 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project br += readsome (advance (p, br), n - br); 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (br); 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/// Reads at most \p n bytes into \p p, stopping when it feels like it. 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectoff_t fstream::readsome (void* p, off_t n) 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ssize_t brn; 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project do { brn = ::read (m_fd, p, n); } while (brn < 0 && errno == EINTR); 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (brn > 0) 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (brn); 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (brn < 0 && errno != EAGAIN) 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project set_and_throw (failbit, "read"); 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!brn && ios_base::set_and_throw (eofbit | failbit)) 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if PLATFORM_ANDROID 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("stream_bounds_exception\n"); 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#else /* !PLATFORM_ANDROID */ 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw stream_bounds_exception ("read", name(), pos(), n, 0); 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (0); 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/// Writes \p n bytes from \p p. 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectoff_t fstream::write (const void* p, off_t n) 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project off_t btw (n); 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (btw) { 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const off_t bw (n - btw); 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ssize_t bwn = ::write (m_fd, advance(p,bw), btw); 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (bwn > 0) 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project btw -= bwn; 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project else if (!bwn) { 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (ios_base::set_and_throw (eofbit | failbit)) 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if PLATFORM_ANDROID 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("stream_bounds_exception\n"); 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#else /* !PLATFORM_ANDROID */ 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw stream_bounds_exception ("write", name(), pos() - bw, n, bw); 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (errno != EINTR) { 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (errno != EAGAIN) 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project set_and_throw (failbit, "write"); 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (n - btw); 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/// Returns the file size. 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectoff_t fstream::size (void) const 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project struct stat st; 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project st.st_size = 0; 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project stat (st); 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (st.st_size); 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/// Synchronizes the file's data and status with the disk. 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid fstream::sync (void) 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fsync (m_fd)) 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project set_and_throw (failbit, "sync"); 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/// Get the stat structure. 2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid fstream::stat (struct stat& rs) const 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fstat (m_fd, &rs)) 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if PLATFORM_ANDROID 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("file_exception\n"); 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#else 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw file_exception ("stat", name()); 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/// Calls the given ioctl. Use IOCTLID macro to pass in both \p name and \p request. 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint fstream::ioctl (const char* rname, int request, long argument) 2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int rv = ::ioctl (m_fd, request, argument); 2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (rv < 0) 2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project set_and_throw (failbit, rname); 2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (rv); 2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/// Calls the given fcntl. Use FCNTLID macro to pass in both \p name and \p request. 2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint fstream::fcntl (const char* rname, int request, long argument) 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int rv = ::fcntl (m_fd, request, argument); 2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (rv < 0) 2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project set_and_throw (failbit, rname); 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (rv); 2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/// Memory-maps the file and returns a link to it. 2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectmemlink fstream::mmap (off_t n, off_t offset) 2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void* result = ::mmap (NULL, n, PROT_READ | PROT_WRITE, MAP_SHARED, m_fd, offset); 2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (result == MAP_FAILED) 2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project set_and_throw (failbit, "mmap"); 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (memlink (result, n)); 2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/// Unmaps a memory-mapped area. 2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid fstream::munmap (memlink& l) 2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (::munmap (l.data(), l.size())) 2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project set_and_throw (failbit, "munmap"); 2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project l.unlink(); 2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/// Synchronizes a memory-mapped area. 2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid fstream::msync (memlink& l) 2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (::msync (l.data(), l.size(), MS_ASYNC | MS_INVALIDATE)) 2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project set_and_throw (failbit, "msync"); 2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid fstream::set_nonblock (bool v) 2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int curf = fcntl (FCNTLID (F_GETFL)); 2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (curf < 0) return; 2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (v) curf |= O_NONBLOCK; 2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project else curf &= ~O_NONBLOCK; 2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fcntl (FCNTLID (F_SETFL), curf); 2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} // namespace ustl 2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 283