Add access?
[mes.git] / libc / mlibc.c
1 /* -*-comment-start: "//";comment-end:""-*-
2  * Mes --- Maxwell Equations of Software
3  * Copyright © 2016,2017 Jan Nieuwenhuizen <janneke@gnu.org>
4  *
5  * This file is part of Mes.
6  *
7  * Mes is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 3 of the License, or (at
10  * your option) any later version.
11  *
12  * Mes is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with Mes.  If not, see <http://www.gnu.org/licenses/>.
19  */
20
21 int g_stdin = 0;
22
23 #define EOF -1
24 #define STDIN 0
25 #define STDOUT 1
26 #define STDERR 2
27
28 #if __GNUC__ && !POSIX
29
30 #define O_RDONLY 0
31 #define INT_MIN -2147483648
32 #define INT_MAX 2147483647
33
34 typedef long size_t;
35 void *malloc (size_t i);
36 int open (char const *s, int mode);
37 int read (int fd, void* buf, size_t n);
38 int write (int fd, char const* s, int n);
39
40 void
41 exit (int code)
42 {
43   asm (
44        "movl %0,%%ebx\n\t"
45        "movl $1,%%eax\n\t"
46        "int  $0x80"
47        : // no outputs "=" (r)
48        : "" (code)
49        );
50   // not reached
51   exit (0);
52 }
53
54 char const*
55 getenv (char const* p)
56 {
57   return 0;
58 }
59
60 int
61 read (int fd, void* buf, size_t n)
62 {
63   int r;
64   //syscall (SYS_write, fd, s, n));
65   asm (
66        "movl %1,%%ebx\n\t"
67        "movl %2,%%ecx\n\t"
68        "movl %3,%%edx\n\t"
69
70        "movl $0x3,%%eax\n\t"
71        "int  $0x80\n\t"
72
73        "mov %%eax,%0\n\t"
74        : "=r" (r)
75        : "" (fd), "" (buf), "" (n)
76        : "eax", "ebx", "ecx", "edx"
77        );
78   return r;
79 }
80
81 int
82 write (int fd, char const* s, int n)
83 {
84   int r;
85   //syscall (SYS_write, fd, s, n));
86   asm (
87        "mov %1,%%ebx\n\t"
88        "mov %2,%%ecx\n\t"
89        "mov %3,%%edx\n\t"
90
91        "mov $0x4, %%eax\n\t"
92        "int $0x80\n\t"
93        "mov %%eax,%0\n\t"
94        : "=r" (r)
95        : "" (fd), "" (s), "" (n)
96        : "eax", "ebx", "ecx", "edx"
97        );
98   return r;
99 }
100
101 int
102 open (char const *s, int mode)
103 {
104   int r;
105   //syscall (SYS_open, mode));
106   asm (
107        "mov %1,%%ebx\n\t"
108        "mov %2,%%ecx\n\t"
109        "mov $0x5,%%eax\n\t"
110        "int $0x80\n\t"
111        "mov %%eax,%0\n\t"
112        : "=r" (r)
113        : "" (s), "" (mode)
114        : "eax", "ebx", "ecx"
115        );
116   return r;
117 }
118
119 int
120 access (char const *s, int mode)
121 {
122   int r;
123   //syscall (SYS_access, mode));
124   asm (
125        "mov %1,%%ebx\n\t"
126        "mov %2,%%ecx\n\t"
127        "mov $0x21,%%eax\n\t"
128        "int $0x80\n\t"
129        "mov %%eax,%0\n\t"
130        : "=r" (r)
131        : "" (s), "" (mode)
132        : "eax", "ebx", "ecx"
133        );
134   return r;
135 }
136
137 void *
138 brk (void *p)
139 {
140   void *r;
141   asm (
142        "mov %1,%%ebx\n\t"
143
144        "mov $0x2d,%%eax\n\t"
145        "int $0x80\n\t"
146
147        "mov %%eax,%0\n\t"
148        : "=r" (r)
149        : "" (p)
150        : "eax", "ebx"
151        );
152   return r;
153 }
154
155 int
156 fsync (int fd)
157 {
158   int r;
159   //syscall (SYS_fsync, fd));
160   asm (
161        "mov %1,%%ebx\n\t"
162
163        "mov $0x76, %%eax\n\t"
164        "int $0x80\n\t"
165        "mov %%eax,%0\n\t"
166        : "=r" (r)
167        : "" (fd)
168        : "eax", "ebx"
169        );
170   return r;
171 }
172
173 int
174 fputc (int c, int fd)
175 {
176   write (fd, (char*)&c, 1);
177   return 0;
178 }
179
180 int
181 putchar (int c)
182 {
183   write (STDOUT, (char*)&c, 1);
184   return 0;
185 }
186
187 void *g_malloc_base = 0;
188
189 void *
190 malloc (size_t size)
191 {
192   void *p = brk (0);
193   if (!g_malloc_base) g_malloc_base = p;
194   brk (p+size);
195   return p;
196 }
197
198 void *
199 realloc (void *p, size_t size)
200 {
201   (void)p;
202   brk (g_malloc_base + size);
203   return g_malloc_base;
204 }
205
206 void
207 free (void *p)
208 {
209   int *n = (int*)p-1;
210   //munmap ((void*)p, *n);
211 }
212
213 size_t
214 strlen (char const* s)
215 {
216   int i = 0;
217   while (s[i]) i++;
218   return i;
219 }
220
221 int
222 strcmp (char const* a, char const* b)
223 {
224   while (*a && *b && *a == *b) {a++;b++;}
225   return *a - *b;
226 }
227
228 int
229 eputs (char const* s)
230 {
231   int i = strlen (s);
232   write (STDERR, s, i);
233   return 0;
234 }
235
236 int
237 fputs (char const* s, int fd)
238 {
239   int i = strlen (s);
240   write (fd, s, i);
241   return 0;
242 }
243
244 int
245 puts (char const* s)
246 {
247   int i = strlen (s);
248   write (STDOUT, s, i);
249   return 0;
250 }
251
252 void
253 assert_fail (char* s)
254 {
255   eputs ("assert fail: ");
256   eputs (s);
257   eputs ("\n");
258   *((int*)0) = 0;
259 }
260
261 #define assert(x) ((x) ? (void)0 : assert_fail (#x))
262
263 int ungetc_char = -1;
264 char ungetc_buf[2];
265
266 int
267 getchar ()
268 {
269   char c;
270   int i;
271   if (ungetc_char == -1)
272     {
273       int r = read (g_stdin, &c, 1);
274       if (r < 1) return -1;
275       i = c;
276     }
277   else
278     i = ungetc_buf[ungetc_char--];
279
280   if (i < 0) i += 256;
281
282   return i;
283 }
284
285 int
286 ungetc (int c, int fd)
287 {
288   assert (ungetc_char < 2);
289   ungetc_buf[++ungetc_char] = c;
290   return c;
291 }
292
293 int
294 isdigit (int c)
295 {
296   return (c>='0') && (c<='9');
297 }
298 #endif
299
300 char itoa_buf[10];
301
302 char const*
303 itoa (int x)
304 {
305   //static char itoa_buf[10];
306   //char *p = buf+9;
307   char *p = itoa_buf;
308   p += 9;
309   *p-- = 0;
310
311   //int sign = x < 0;
312   int sign;
313   sign = x < 0;
314   if (sign)
315     x = -x;
316
317   do
318     {
319       *p-- = '0' + (x % 10);
320       x = x / 10;
321     } while (x);
322
323   if (sign)
324     *p-- = '-';
325
326   return p+1;
327 }
328
329 #if POSIX
330
331 #define _GNU_SOURCE
332 #include <assert.h>
333 #include <ctype.h>
334 #include <errno.h>
335 #include <fcntl.h>
336 #include <limits.h>
337 #include <stdio.h>
338 #include <stdlib.h>
339 #include <string.h>
340 #include <unistd.h>
341
342 #undef puts
343 #define puts(x) fdputs(x, STDOUT)
344 #define eputs(x) fdputs(x, STDERR)
345 #define fputs fdputs
346 int
347 fdputs (char const* s, int fd)
348 {
349   int i = strlen (s);
350   write (fd, s, i);
351   return 0;
352 }
353
354 #ifdef putc
355 #undef putc
356 #endif
357 #define fputc fdputc
358 int
359 fdputc (int c, int fd)
360 {
361   write (fd, (char*)&c, 1);
362   return 0;
363 }
364
365 int
366 putchar (int c)
367 {
368   write (STDOUT, (char*)&c, 1);
369   return 0;
370 }
371
372 int ungetc_char = -1;
373 char ungetc_buf[2];
374
375 int
376 getchar ()
377 {
378   char c;
379   int i;
380   if (ungetc_char == -1)
381     {
382       int r = read (g_stdin, &c, 1);
383       if (r < 1) return -1;
384       i = c;
385     }
386   else
387     i = ungetc_buf[ungetc_char--];
388
389   if (i < 0) i += 256;
390
391   return i;
392 }
393
394 #define ungetc fdungetc
395 int
396 fdungetc (int c, int fd)
397 {
398   assert (ungetc_char < 2);
399   ungetc_buf[++ungetc_char] = c;
400   return c;
401 }
402 #else
403
404 #define fputs fdputs
405 int
406 fdputs (char const* s, int fd)
407 {
408   int i = strlen (s);
409   write (fd, s, i);
410   return 0;
411 }
412
413 #endif