Open Model Railroad Network (OpenMRN)
Loading...
Searching...
No Matches
Fileio.cxx
Go to the documentation of this file.
1
34#include "Devtab.hxx"
35
36#include <cstdarg>
37#include <fcntl.h>
38#include <reent.h>
39#include <unistd.h>
40#include <sys/select.h>
41
43
48{
49 for (unsigned int i = 0; i < numOpenFiles; i++)
50 {
51 if (files[i].inuse == false)
52 {
53 files[i].inuse = true;
54 files[i].inshdn = false;
55 files[i].device = true;
56 files[i].dir = false;
57 files[i].dirty = false;
58 files[i].priv = nullptr;
59 files[i].dev = nullptr;
60 files[i].offset = 0;
61 files[i].flags = 0;
62 return i;
63 }
64 }
65 return -1;
66}
67
71void FileIO::fd_free(int fd)
72{
73 files[fd].inuse = false;
74}
75
83{
84 if (fd < 0 || fd >= (int)numOpenFiles)
85 {
86 errno = EBADF;
87 return nullptr;
88 }
89 if (files[fd].inuse == 0 || files[fd].inshdn == 1)
90 {
91 errno = EBADF;
92 return nullptr;
93 }
94 return &files[fd];
95}
96
102{
103 HASSERT(file >= files && file <= (files + numOpenFiles) && file->inuse);
104
105 return (file - files);
106}
107
115ssize_t FileIO::read(struct _reent *reent, int fd, void *buf, size_t count)
116{
117 File* f = file_lookup(fd);
118 if (!f)
119 {
120 /* errno should already be set appropriately */
121 return -1;
122 }
123 ssize_t result = f->dev->read(f, buf, count);
124 if (result < 0)
125 {
126 errno = -result;
127 return -1;
128 }
129 return result;
130}
131
139ssize_t FileIO::write(struct _reent *reent, int fd, const void *buf, size_t count)
140{
141 File* f = file_lookup(fd);
142 if (!f)
143 {
144 /* errno should already be set appropriately */
145 return -1;
146 }
147 ssize_t result = f->dev->write(f, buf, count);
148 if (result < 0)
149 {
150 errno = -result;
151 return -1;
152 }
153 return result;
154}
155
163_off_t FileIO::lseek(struct _reent *reent, int fd, _off_t offset, int whence)
164{
165 File* f = file_lookup(fd);
166 if (!f)
167 {
168 /* errno should already be set appropriately */
169 return (_off_t) -1;
170 }
171 off_t result = f->dev->lseek(f, offset, whence);
172 if (result < 0)
173 {
174 errno = -result;
175 return -1;
176 }
177 return result;
178}
179
186int FileIO::fstat(struct _reent *reent, int fd, struct stat *stat)
187{
188 File* f = file_lookup(fd);
189 if (!f)
190 {
191 /* errno should already be set appropriately */
192 return -1;
193 }
194 ssize_t result = f->dev->fstat(f, stat);
195 if (result < 0)
196 {
197 errno = -result;
198 return -1;
199 }
200 return result;
201}
202
209int FileIO::ioctl(int fd, unsigned long int key, unsigned long data)
210{
211 File* f = file_lookup(fd);
212 if (!f)
213 {
214 /* errno should already be set appropriately */
215 return -1;
216 }
217 int result = f->dev->ioctl(f, key, data);
218 if (result < 0)
219 {
220 errno = -result;
221 return -1;
222 }
223 return result;
224}
225
233int FileIO::fcntl(int fd, int cmd, unsigned long data)
234{
235 File *file = file_lookup(fd);
236
237 if (!file)
238 {
239 errno = EBADF;
240 return -1;
241 }
242
243 switch (cmd)
244 {
245 case F_GETFL:
246 return file->flags;
247 case F_SETFL:
248 /* on this platform, we ignore O_ASYNC, O_DIRECT, and O_NOATIME */
249 data &= (O_APPEND | O_NONBLOCK);
250 file->flags &= ~(O_APPEND | O_NONBLOCK);
251 file->flags |= data;
252 /* fall through */
253 default:
254 {
255 File* f = file_lookup(fd);
256 if (!f)
257 {
258 /* errno should already be set appropriately */
259 return -1;
260 }
261 int result = f->dev->fcntl(f, cmd, data);
262 if (result < 0)
263 {
264 errno = -result;
265 return -1;
266 }
267 return result;
268 }
269 }
270}
271
279off_t FileIO::lseek(File* f, off_t offset, int whence)
280{
281 switch (whence)
282 {
283 case SEEK_SET:
284 f->offset = offset;
285 return offset;
286 case SEEK_CUR:
287 f->offset += offset;
288 return f->offset;
289 }
290 return (off_t)-EINVAL;
291}
292
299int FileIO::ioctl(File *, unsigned long int, unsigned long) {
300 return -EINVAL;
301}
302
310int FileIO::fcntl(File *file, int cmd, unsigned long data)
311{
312 if (cmd == F_SETFL)
313 {
314 return 0;
315 }
316 else
317 {
318 return -EINVAL;
319 }
320}
321
322extern "C" {
323
331int _open_r(struct _reent *reent, const char *path, int flags, int mode)
332{
333 int result = Device::open(reent, path, flags, mode);
334 if (result < 0 && errno == ENODEV)
335 {
336 return FileSystem::open(reent, path, flags, mode);
337 }
338
339 return result;
340}
341
347int _close_r(struct _reent *reent, int fd)
348{
349 return FileIO::is_device(fd) ? Device::close(reent, fd) :
350 FileSystem::close(reent, fd);
351}
352
360ssize_t _read_r(struct _reent *reent, int fd, void *buf, size_t count)
361{
362 return FileIO::read(reent, fd, buf, count);
363}
364
372ssize_t _write_r(struct _reent *reent, int fd, const void *buf, size_t count)
373{
374 return FileIO::write(reent, fd, buf, count);
375}
376
383int _stat_r(struct _reent *reent, const char *path, struct stat *stat)
384{
385 int result = Device::stat(reent, path, stat);
386 if (result < 0 && errno == ENOENT)
387 {
388 return FileSystem::stat(reent, path, stat);
389 }
390
391 return result;
392}
393
400int _fstat_r(struct _reent *reent, int fd, struct stat *stat)
401{
402 return FileIO::fstat(reent, fd, stat);
403}
404
410int _isatty_r(struct _reent *reent, int fd)
411{
412 return 1;
413}
414
420int _unlink_r(struct _reent *reent, const char *path)
421{
422 return FileSystem::unlink(reent, path);
423}
424
432_off_t _lseek_r(struct _reent *reent, int fd, _off_t offset, int whence)
433{
434 return FileIO::lseek(reent, fd, offset, whence);
435}
436
441int fsync(int fd)
442{
443 return FileSystem::fsync(fd);
444}
445
452int ioctl(int fd, unsigned long int key, ...)
453{
454 va_list ap;
455 va_start(ap, key);
456
457 int result = FileIO::ioctl(fd, key, va_arg(ap, unsigned long));
458
459 va_end(ap);
460 return result;
461}
462
473int select(int nfds, fd_set *readfds, fd_set *writefds,
474 fd_set *exceptfds, struct timeval *timeout)
475{
476 long long time_value = -1;
477 if (timeout) {
478 time_value = timeout->tv_sec;
479 time_value *= 1000000;
480 time_value += timeout->tv_usec;
481 time_value *= 1000;
482 }
484 return Device::select(nfds, readfds, writefds, exceptfds, time_value);
485}
486
494int fcntl(int fd, int cmd, ...)
495{
496 va_list ap;
497 va_start(ap, cmd);
498
499 int result = FileIO::fcntl(fd, cmd, va_arg(ap, unsigned long));
500
501 va_end(ap);
502 return result;
503}
504
505}
int _isatty_r(struct _reent *reent, int fd)
Get the tty information of a file or device.
Definition Fileio.cxx:410
_off_t _lseek_r(struct _reent *reent, int fd, _off_t offset, int whence)
Change the offset index of a file or device.
Definition Fileio.cxx:432
int _fstat_r(struct _reent *reent, int fd, struct stat *stat)
Get the status information of a file or device.
Definition Fileio.cxx:400
ssize_t _write_r(struct _reent *reent, int fd, const void *buf, size_t count)
Write to a file or device.
Definition Fileio.cxx:372
ssize_t _read_r(struct _reent *reent, int fd, void *buf, size_t count)
Read from a file or device.
Definition Fileio.cxx:360
int fsync(int fd)
Synchronize (flush) a file to disk.
Definition Fileio.cxx:441
int _close_r(struct _reent *reent, int fd)
Close a file or device.
Definition Fileio.cxx:347
int fcntl(int fd, int cmd,...)
Manipulate a file descriptor.
Definition Fileio.cxx:494
int ioctl(int fd, unsigned long int key,...)
Request and ioctl transaction.
Definition Fileio.cxx:452
int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout)
POSIX select().
Definition Fileio.cxx:473
int _stat_r(struct _reent *reent, const char *path, struct stat *stat)
Get the status information of a file or device.
Definition Fileio.cxx:383
int _unlink_r(struct _reent *reent, const char *path)
remove a file.
Definition Fileio.cxx:420
int _open_r(struct _reent *reent, const char *path, int flags, int mode)
Open a file or device.
Definition Fileio.cxx:331
static void fd_free(int fd)
Free up a file descriptor.
Definition Fileio.cxx:71
static File * file_lookup(int fd)
Looks up a reference to a File corresponding to a given file descriptor.
Definition Fileio.cxx:82
static int fstat(struct _reent *reent, int fd, struct stat *stat)
Get the status information of a file or device.
Definition Fileio.cxx:186
static int fcntl(int fd, int cmd, unsigned long data)
Manipulate a file descriptor.
Definition Fileio.cxx:233
static const unsigned int numOpenFiles
Definition Devtab.hxx:258
static ssize_t read(struct _reent *reent, int fd, void *buf, size_t count)
Read from a file or device.
Definition Fileio.cxx:115
static bool is_device(int fd)
Test if the file descriptor belongs to a device.
Definition Devtab.hxx:134
static _off_t lseek(struct _reent *reent, int fd, _off_t offset, int whence)
Change the offset index of a file or device.
Definition Fileio.cxx:163
static File files[]
File descriptor pool.
Definition Devtab.hxx:261
static ssize_t write(struct _reent *reent, int fd, const void *buf, size_t count)
Write to a file or device.
Definition Fileio.cxx:139
static int fd_lookup(File *file)
Looks up a file descriptor corresponding to a given File reference.
Definition Fileio.cxx:101
static int ioctl(int fd, unsigned long int key, unsigned long data)
Request and ioctl transaction.
Definition Fileio.cxx:209
static int fd_alloc(void)
Allocate a free file descriptor.
Definition Fileio.cxx:47
static OSMutex mutex
mutual exclusion for fileio
Definition Devtab.hxx:264
static int open(struct _reent *reent, const char *path, int flags, int mode)
Open a file or device.
static int fsync(int fd)
Synchronize (flush) a file to disk.
static int close(struct _reent *reent, int fd)
Close a file or device.
static int stat(struct _reent *reent, const char *path, struct stat *stat)
Get the status information of a file or device.
static int unlink(struct _reent *reent, const char *path)
Remove a file.
This class provides a mutex API.
Definition OS.hxx:427
#define HASSERT(x)
Checks that the value of expression x is true, else terminates the current process.
Definition macros.h:138
static int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, long long timeout)
POSIX select().
Definition Select.cxx:96
static void select_clear()
Clears the current thread's select bits.
Definition Select.cxx:78
static int stat(struct _reent *reent, const char *path, struct stat *stat)
Get the status information of a file or device.
Definition Device.cxx:165
static int close(struct _reent *reent, int fd)
Close a file or device.
Definition Device.cxx:134
static int open(struct _reent *reent, const char *path, int flags, int mode)
Open a file or device.
Definition Device.cxx:93
File information.
Definition Devtab.hxx:52
uint8_t dirty
true if this file is dirty and needs flush
Definition Devtab.hxx:68
uint8_t inshdn
true if this fd is in shutdown.
Definition Devtab.hxx:65
off_t offset
current offset within file
Definition Devtab.hxx:62
int flags
open flags
Definition Devtab.hxx:63
uint8_t dir
true if this is a directory, else false
Definition Devtab.hxx:67
void * priv
file reference specific data "pointer"
Definition Devtab.hxx:57
uint8_t device
true if this is a device, false if file system
Definition Devtab.hxx:66
FileIO * dev
file operations
Definition Devtab.hxx:53
uint8_t inuse
true if this is an open fd.
Definition Devtab.hxx:64