OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [packages/] [language/] [cxx/] [ustl/] [current/] [src/] [fstream.cpp] - Blame information for rev 845

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 786 skrzyp
// This file is part of the uSTL library, an STL implementation.
2
//
3
// Copyright (c) 2005-2009 by Mike Sharov <msharov@users.sourceforge.net>
4
// This file is free software, distributed under the MIT License.
5
 
6
#include "fstream.h"
7
#include "uexception.h"
8
#include "uutility.h"
9
#include <fcntl.h>
10
#include <unistd.h>
11
#include <errno.h>
12
#include <sys/stat.h>
13
#if 0 // both header files does not exist in eCos
14
#include <sys/mman.h>
15
#include <sys/ioctl.h>
16
#endif
17
#include "config.h"
18
 
19
namespace ustl {
20
 
21
/// Default constructor.
22
fstream::fstream (void)
23
: ios_base (),
24
  m_fd (-1),
25
  m_Filename ()
26
{
27
    exceptions (goodbit);
28
}
29
 
30
/// Opens \p filename in \p mode.
31
fstream::fstream (const char* filename, openmode mode)
32
: ios_base (),
33
  m_fd (-1),
34
  m_Filename ()
35
{
36
    exceptions (goodbit);
37
    open (filename, mode);
38
}
39
 
40
/// Attaches to \p nfd of \p filename.
41
fstream::fstream (int nfd, const char* filename)
42
: ios_base (),
43
  m_fd (-1),
44
  m_Filename ()
45
{
46
    exceptions (goodbit);
47
    attach (nfd, filename);
48
}
49
 
50
/// Destructor. Closes if still open, but without throwing.
51
fstream::~fstream (void) throw()
52
{
53
    clear (goodbit);
54
    exceptions (goodbit);
55
    close();
56
    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.");
57
}
58
 
59
/// Sets state \p s and throws depending on the exception setting.
60
void fstream::set_and_throw (iostate s, const char* op)
61
{
62
    if (ios_base::set_and_throw (s))
63
        USTL_THROW(file_exception (op, name()));
64
}
65
 
66
/// Attaches to the given \p nfd.
67
void fstream::attach (int nfd, const char* filename)
68
{
69
    assert (filename && "Don't do that");
70
    m_Filename = filename;
71
    clear (goodbit);
72
    if (nfd < 0)
73
        set_and_throw (badbit, "open");
74
    close();
75
    m_fd = nfd;
76
}
77
 
78
/// Detaches from the current fd.
79
void fstream::detach (void)
80
{
81
    m_fd = -1;
82
    m_Filename.clear();
83
}
84
 
85
/// Converts openmode bits into libc open flags.
86
/*static*/ int fstream::om_to_flags (openmode m)
87
{
88
    static const int s_OMFlags [nombits] = {
89
        0,               // in
90
        O_CREAT,        // out
91
        O_APPEND,       // app
92
        O_APPEND,       // ate
93
        0,               // binary
94
        O_TRUNC,        // trunc
95
        O_NONBLOCK,     // nonblock
96
        0,               // nocreate
97
        O_NOCTTY        // noctty
98
    };
99
    int flags = (m - 1) & O_ACCMODE;    // in and out
100
    for (uoff_t i = 0; i < VectorSize(s_OMFlags); ++ i)
101
        flags |= s_OMFlags[i] & (!(m & (1 << i)) - 1);
102
    if (m & nocreate)
103
        flags &= ~O_CREAT;
104
    return (flags);
105
}
106
 
107
/// \brief Opens \p filename in the given mode.
108
/// \warning The string at \p filename must exist until the object is closed.
109
void fstream::open (const char* filename, openmode mode, mode_t perms)
110
{
111
    int nfd = ::open (filename, om_to_flags(mode), perms);
112
    attach (nfd, filename);
113
}
114
 
115
/// Closes the file and throws on error.
116
void fstream::close (void)
117
{
118
    if (m_fd < 0)
119
        return; // already closed
120
    while (::close(m_fd)) {
121
        if (errno != EINTR) {
122
            set_and_throw (badbit | failbit, "close");
123
            break;
124
        }
125
    }
126
    detach();
127
}
128
 
129
/// Moves the current file position to \p n.
130
off_t fstream::seek (off_t n, seekdir whence)
131
{
132
    off_t p = lseek (m_fd, n, whence);
133
    if (p < 0)
134
        set_and_throw (failbit, "seek");
135
    return (p);
136
}
137
 
138
/// Returns the current file position.
139
off_t fstream::pos (void) const
140
{
141
    return (lseek (m_fd, 0, SEEK_CUR));
142
}
143
 
144
/// Reads \p n bytes into \p p.
145
off_t fstream::read (void* p, off_t n)
146
{
147
    off_t br (0);
148
    while ((br < n) & good())
149
        br += readsome (advance (p, br), n - br);
150
    return (br);
151
}
152
 
153
/// Reads at most \p n bytes into \p p, stopping when it feels like it.
154
off_t fstream::readsome (void* p, off_t n)
155
{
156
    ssize_t brn;
157
    do { brn = ::read (m_fd, p, n); } while ((brn < 0) & (errno == EINTR));
158
    if (brn > 0)
159
        return (brn);
160
    else if ((brn < 0) & (errno != EAGAIN))
161
        set_and_throw (failbit, "read");
162
    else if (!brn && ios_base::set_and_throw (eofbit | failbit))
163
        USTL_THROW(stream_bounds_exception ("read", name(), pos(), n, 0));
164
    return (0);
165
}
166
 
167
/// Writes \p n bytes from \p p.
168
off_t fstream::write (const void* p, off_t n)
169
{
170
    off_t btw (n);
171
    while (btw) {
172
        const off_t bw (n - btw);
173
        ssize_t bwn = ::write (m_fd, advance(p,bw), btw);
174
        if (bwn > 0)
175
            btw -= bwn;
176
        else if (!bwn) {
177
            if (ios_base::set_and_throw (eofbit | failbit))
178
                USTL_THROW(stream_bounds_exception ("write", name(), pos() - bw, n, bw));
179
            break;
180
        } else if (errno != EINTR) {
181
            if (errno != EAGAIN)
182
                set_and_throw (failbit, "write");
183
            break;
184
        }
185
    }
186
    return (n - btw);
187
}
188
 
189
/// Returns the file size.
190
off_t fstream::size (void) const
191
{
192
    struct stat st;
193
    st.st_size = 0;
194
    stat (st);
195
    return (st.st_size);
196
}
197
 
198
/// Synchronizes the file's data and status with the disk.
199
void fstream::sync (void)
200
{
201
    if (fsync (m_fd))
202
        set_and_throw (badbit | failbit, "sync");
203
}
204
 
205
/// Get the stat structure.
206
void fstream::stat (struct stat& rs) const
207
{
208
    if (fstat (m_fd, &rs))
209
        USTL_THROW(file_exception ("stat", name()));
210
}
211
 
212
/// Calls the given ioctl. Use IOCTLID macro to pass in both \p name and \p request.
213
int fstream::ioctl (const char* rname, int request, long argument)
214
{
215
    int rv = ::ioctl (m_fd, request, argument);
216
    if (rv < 0)
217
        set_and_throw (failbit, rname);
218
    return (rv);
219
}
220
 
221
/// Calls the given fcntl. Use FCNTLID macro to pass in both \p name and \p request.
222
int fstream::fcntl (const char* rname, int request, long argument)
223
{
224
    int rv = ::fcntl (m_fd, request, argument);
225
    if (rv < 0)
226
        set_and_throw (failbit, rname);
227
    return (rv);
228
}
229
 
230
#if 0 // memory mapped files are not supported in eCos
231
/// Memory-maps the file and returns a link to it.
232
memlink fstream::mmap (off_t n, off_t offset)
233
{
234
    void* result = ::mmap (NULL, n, PROT_READ | PROT_WRITE, MAP_SHARED, m_fd, offset);
235
    if (result == MAP_FAILED)
236
        set_and_throw (failbit, "mmap");
237
    return (memlink (result, n));
238
}
239
 
240
/// Unmaps a memory-mapped area.
241
void fstream::munmap (memlink& l)
242
{
243
    if (::munmap (l.data(), l.size()))
244
        set_and_throw (failbit, "munmap");
245
    l.unlink();
246
}
247
 
248
/// Synchronizes a memory-mapped area.
249
void fstream::msync (memlink& l)
250
{
251
    if (::msync (l.data(), l.size(), MS_ASYNC | MS_INVALIDATE))
252
        set_and_throw (failbit, "msync");
253
}
254
#endif // #if 0
255
 
256
void fstream::set_nonblock (bool v)
257
{
258
    int curf = max (0, fcntl (FCNTLID (F_GETFL)));
259
    if (v) curf |=  O_NONBLOCK;
260
    else   curf &= ~O_NONBLOCK;
261
    fcntl (FCNTLID (F_SETFL), curf);
262
}
263
 
264
} // namespace ustl

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.