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