initial revision
[ucgine.git] / lib / gloss / ucg_gloss_stubs.c
1 /*
2  * Copyright 2015, Olivier MATZ <zer0@droids-corp.org>
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  *     * Redistributions of source code must retain the above copyright
8  *       notice, this list of conditions and the following disclaimer.
9  *     * Redistributions in binary form must reproduce the above copyright
10  *       notice, this list of conditions and the following disclaimer in the
11  *       documentation and/or other materials provided with the distribution.
12  *     * Neither the name of the University of California, Berkeley nor the
13  *       names of its contributors may be used to endorse or promote products
14  *       derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
17  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19  * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
20  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27
28 #include <sys/types.h>
29 #include <sys/stat.h>
30 #include <sys/queue.h>
31 #include <stdio.h>
32 #include <unistd.h>
33 #include <stdint.h>
34 #include <reent.h>
35 #include <errno.h>
36
37 #include <ucg_gloss_chardev.h>
38
39 /* provide a dummy environment */
40 char *__env[1] = { 0 };
41 char **environ = __env;
42
43 /* provide a definition of errno if not already provided */
44 int errno;
45
46 /* defined by the linker, used by _sbrk */
47 extern char _ebss;
48
49 /* open a device, return its file descriptor */
50 int
51 _open_r(struct _reent *reent, const char *file, int flags, int mode)
52 {
53         const struct ucg_chardev *dev;
54
55         dev = ucg_chardev_lookup_from_name(file);
56         if (dev == NULL) {
57                 reent->_errno = ENODEV;
58                 return -1;
59         }
60
61         if (dev->open_r)
62                 dev->open_r(reent, file, flags, mode);
63
64         return dev->fd;
65 }
66
67 /* close a device */
68 int
69 _close_r(struct _reent *reent, int fd)
70 {
71         const struct ucg_chardev *dev;
72
73         dev = ucg_chardev_lookup_from_fd(fd);
74         if (dev == NULL) {
75                 reent->_errno = EBADF;
76                 return -1;
77         }
78
79         /* call the close() handler if defined */
80         if (dev->close_r)
81                 return dev->close_r(reent, fd);
82
83         return 0;
84 }
85
86 /* read a device. */
87 _ssize_t
88 _read_r(struct _reent *reent, int fd, void *ptr, size_t len)
89 {
90         const struct ucg_chardev *dev;
91
92         dev = ucg_chardev_lookup_from_fd(fd);
93         if (dev == NULL) {
94                 reent->_errno = EBADF;
95                 return -1;
96         }
97
98         if (dev->read_r)
99                 return dev->read_r(reent, fd, ptr, len);
100
101         reent->_errno = ENODEV;
102         return -1;
103 }
104
105 /* write to a device */
106 _ssize_t
107 _write_r(struct _reent *reent, int fd, const void *ptr, size_t len)
108 {
109         const struct ucg_chardev *dev;
110
111         dev = ucg_chardev_lookup_from_fd(fd);
112         if (dev == NULL) {
113                 reent->_errno = EBADF;
114                 return -1;
115         }
116
117         if (dev->write_r)
118                 return dev->write_r(reent, fd, ptr, len);
119
120         reent->_errno = ENODEV;
121         return -1;
122 }
123
124 /* exit: print error code and loop forever */
125 void
126 _exit(int rc)
127 {
128         printf("exit %d\n", rc);
129         while (1);
130 }
131
132 /* set owner: not implemented */
133 int
134 _chown_r(struct _reent *reent,
135          __attribute__((unused)) const char *path,
136          __attribute__((unused)) uid_t owner,
137          __attribute__((unused)) gid_t group)
138 {
139         reent->_errno = ENOSYS;
140         return -1;
141 }
142
143 /* execve: not implemented */
144 int
145 _execve_r(struct _reent *reent,
146           __attribute__((unused)) const char *name,
147           __attribute__((unused)) char *const *argv,
148           __attribute__((unused)) char *const *env)
149 {
150         reent->_errno = ENOSYS;
151         return -1;
152 }
153
154 /* fork: not implemented */
155 int
156 _fork_r(struct _reent *reent)
157 {
158         reent->_errno = ENOSYS;
159         return -1;
160 }
161
162 /* fstat: not implemented, all devices are character devices */
163 int
164 _fstat_r(__attribute__((unused)) struct _reent *reent,
165          __attribute__((unused)) int fildes,
166          struct stat *st)
167 {
168         st->st_mode = S_IFCHR;
169         return 0;
170 }
171
172 /* getpid: not implemented */
173 int
174 _getpid_r(struct _reent *reent)
175 {
176         reent->_errno = ENOSYS;
177         return -1;
178 }
179
180 struct timeval;
181
182 /* gettimeofday: not implemented */
183 int
184 _gettimeofday_r(struct _reent *reent,
185                 __attribute__((unused)) struct timeval *ptimeval,
186                 __attribute__((unused)) void *ptimezone)
187 {
188         reent->_errno = ENOSYS;
189         return -1;
190 }
191
192 /* isatty; not implemented */
193 int
194 _isatty_r(struct _reent *reent, __attribute__((unused)) int file)
195 {
196         reent->_errno = ENOTTY;
197         return 0;
198 }
199
200 /* kill a process: not implemented */
201 int
202 _kill_r(struct _reent *reent,
203         __attribute__((unused)) int pid,
204         __attribute__((unused)) int sig)
205 {
206         reent->_errno = ENOSYS;
207         return -1;
208 }
209
210 /* link: not implemented */
211 int
212 _link_r(struct _reent *reent,
213         __attribute__((unused)) const char *existing,
214         __attribute__((unused)) const char *new)
215 {
216         reent->_errno = EMLINK;
217         return -1;
218 }
219
220 /* lseek: not implemented */
221 _off_t
222 _lseek_r(__attribute__((unused)) struct _reent *reent,
223          __attribute__((unused)) int file,
224          __attribute__((unused)) _off_t ptr,
225          __attribute__((unused)) int dir)
226 {
227         return 0;
228 }
229
230 /* readlink: not implemented */
231 int
232 _readlink_r(struct _reent *reent,
233             __attribute__((unused)) const char *path,
234             __attribute__((unused)) char *buf,
235             __attribute__((unused)) size_t bufsize)
236 {
237         reent->_errno = ENOSYS;
238         return -1;
239 }
240
241 /* simple sbrk */
242 void *
243 _sbrk_r(__attribute__((unused)) struct _reent *reent, ptrdiff_t incr)
244 {
245         static char *heap_end = NULL;
246         char *prev_heap_end;
247
248         if (heap_end == NULL)
249                 heap_end = &_ebss;
250
251         prev_heap_end = heap_end;
252         heap_end += incr;
253         return (caddr_t)prev_heap_end;
254 }
255
256 /* stat: not implemented, all devices are character devices */
257 int
258 _stat_r(__attribute__((unused)) struct _reent *reent,
259         __attribute__((unused)) const char *file,
260         struct stat *st)
261 {
262         st->st_mode = S_IFCHR;
263         return 0;
264 }
265
266 /* symlink: not implemented */
267 int
268 _symlink_r(struct _reent *reent,
269            __attribute__((unused)) const char *path1,
270            __attribute__((unused)) const char *path2)
271 {
272         reent->_errno = ENOSYS;
273         return -1;
274 }
275
276 /* times: not timplemented */
277 clock_t
278 _times_r(struct _reent *reent,
279          __attribute__((unused)) struct tms *buf)
280 {
281         reent->_errno = ENOSYS;
282         return -1;
283 }
284
285 /* unlink: not implemented */
286 int
287 _unlink_r(struct _reent *reent,
288           __attribute__((unused)) const char *name)
289 {
290         reent->_errno = EMLINK;
291         return -1;
292 }
293
294 /* wait: not implemented */
295 int
296 _wait_r(struct _reent *reent, __attribute__((unused)) int *status)
297 {
298         reent->_errno = ENOSYS;
299         return -1;
300 }
301