Open Model Railroad Network (OpenMRN)
Loading...
Searching...
No Matches
Device.cxx
Go to the documentation of this file.
1
34#include "Devtab.hxx"
35
36#include <fcntl.h>
37#include <unistd.h>
38
39#ifdef TARGET_LPC11Cxx
40#define NUM_OPEN_FILES 4
41#else
43#define NUM_OPEN_FILES 20 //12
44#endif
45
46Device *Device::first = NULL;
47
52Device::Device(const char *name)
53 : FileIO(name)
54{
55 mutex.lock();
56 next = first;
57 first = this;
58 prev = NULL;
59 if (next)
60 {
61 next->prev = this;
62 }
63 mutex.unlock();
64}
65
69{
70 mutex.lock();
71 if (first == this)
72 {
73 first = next;
74 }
75 else
76 {
77 prev->next = next;
78 }
79 if (next)
80 {
81 next->prev = prev;
82 }
83 mutex.unlock();
84}
85
93int Device::open(struct _reent *reent, const char *path, int flags, int mode)
94{
95 mutex.lock();
96 int fd = fd_alloc();
97 mutex.unlock();
98 if (fd < 0)
99 {
100 errno = EMFILE;
101 return -1;
102 }
103 files[fd].flags = flags;
104 for (Device *dev = first; dev != NULL; dev = dev->next)
105 {
106 if (dev->name)
107 {
108 if (!strcmp(dev->name, path))
109 {
110 files[fd].dev = dev;
111 files[fd].device = true;
112 int result = files[fd].dev->open(&files[fd], path, flags, mode);
113 if (result < 0)
114 {
115 fd_free(fd);
116 errno = -result;
117 return -1;
118 }
119 return fd;
120 }
121 }
122 }
123 // No device found.
124 fd_free(fd);
125 errno = ENODEV;
126 return -1;
127}
128
134int Device::close(struct _reent *reent, int fd)
135{
136 File* f = file_lookup(fd);
137 if (!f)
138 {
139 /* errno should already be set appropriately */
140 return -1;
141 }
142 if (fd >=0 && fd <= 2)
143 {
144 // stdin, stdout, and stderr never get closed
145 return 0;
146 }
147 files[fd].inshdn = true;
148 int result = f->dev->close(f);
149 if (result < 0)
150 {
151 files[fd].inshdn = false;
152 errno = -result;
153 return -1;
154 }
155 fd_free(fd);
156 return 0;
157}
158
165int Device::stat(struct _reent *reent, const char *path, struct stat *stat)
166{
167 for (Device *dev = first; dev != NULL; dev = dev->next)
168 {
169 if (dev->name)
170 {
171 if (!strcmp(dev->name, path))
172 {
173 memset(stat, 0, sizeof(*stat));
174 stat->st_mode = dev->get_mode();
175 return 0;
176 }
177 }
178 }
179
180 errno = ENOENT;
181 return -1;
182}
Base class for both Device and FileSystem objects.
Definition Devtab.hxx:73
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
friend class Device
Allow access from Device class.
Definition Devtab.hxx:269
virtual int close(File *file)=0
Close a file or device.
static File files[]
File descriptor pool.
Definition Devtab.hxx:261
virtual int open(File *file, const char *path, int flags, int mode)=0
Open a file or device.
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
void lock()
Lock a mutex.
Definition OS.hxx:446
void unlock()
Unlock a mutex.
Definition OS.hxx:453
Device tab structure.
Definition Devtab.hxx:432
static Device * first
first device in linked list
Definition Devtab.hxx:535
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
Device * next
next device in linked list
Definition Devtab.hxx:538
virtual ~Device()
Destructor.
Definition Device.cxx:68
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
Device * prev
previous device in linked list
Definition Devtab.hxx:541
File information.
Definition Devtab.hxx:52
uint8_t inshdn
true if this fd is in shutdown.
Definition Devtab.hxx:65
int flags
open flags
Definition Devtab.hxx:63
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