From 635dfd03a2b940b320b0b9eb60ca645c40207b8f Mon Sep 17 00:00:00 2001 From: Jan Nieuwenhuizen Date: Sun, 3 Jun 2018 18:54:26 +0200 Subject: [PATCH] mescc: Support glibc-1.06.4. * lib/glibc.c: New file. * lib/libc+gnu.c: Include it. --- GNUmakefile | 4 +- build-aux/build-mes.sh | 1 + build-aux/check-mescc.sh | 6 +- include/errno.h | 6 + include/limits.h | 1 + include/signal.h | 11 +- include/stdio.h | 17 +- include/string.h | 3 + include/sys/stat.h | 38 ++-- include/sys/times.h | 4 + include/time.h | 30 ++- include/unistd.h | 4 +- lib/binutils.c | 9 +- lib/gcc.c | 2 +- lib/glibc.c | 32 ++++ lib/libc+gnu.c | 4 +- lib/libc+tcc.c | 28 ++- lib/libc-mini.c | 8 + lib/libc.c | 1 + lib/libg.c | 52 +----- lib/linux+gnu-gcc.c | 179 ------------------ lib/linux+gnu.c | 84 +++++++++ lib/linux+tcc-gcc.c | 140 -------------- lib/{linux+tcc-mes.c => linux+tcc.c} | 55 ++---- lib/linux-gcc.c | 267 ++++----------------------- lib/linux-mes.c | 104 ++--------- lib/linux-mini-gcc.c | 19 +- lib/linux-mini-mes.c | 6 +- lib/linux.c | 108 +++++++++++ lib/m4.c | 69 +++++-- lib/x86-mes/x86.M1 | 1 + scaffold/tests/92-stat.c | 100 ++++++++++ scaffold/tests/93-fread-fwrite.c | 77 ++++++++ 33 files changed, 648 insertions(+), 822 deletions(-) create mode 100644 lib/glibc.c delete mode 100644 lib/linux+gnu-gcc.c create mode 100644 lib/linux+gnu.c delete mode 100644 lib/linux+tcc-gcc.c rename lib/{linux+tcc-mes.c => linux+tcc.c} (50%) create mode 100644 lib/linux.c create mode 100644 scaffold/tests/92-stat.c create mode 100644 scaffold/tests/93-fread-fwrite.c diff --git a/GNUmakefile b/GNUmakefile index 132e8d96..12aa936c 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -42,12 +42,12 @@ install: .config.make: ./configure seed: all-go + build-aux/build-mes-gcc.sh + cd $(TINYCC_SEED) && MES_PREFIX=$(PWD) ./refresh.sh cd $(MES_SEED) && git reset --hard HEAD MES=$(GUILE) GUILE=$(GUILE) SEED=1 build-aux/build-mes.sh cd $(MES_SEED) && MES_PREFIX=$(PWD) ./refresh.sh MES=$(GUILE) GUILE=$(GUILE) SEED=1 build-aux/build-mes.sh - build-aux/build-mes-gcc.sh - cd $(TINYCC_SEED) && MES_PREFIX=$(PWD) ./refresh.sh define HELP_TOP Usage: make [OPTION]... [TARGET]... diff --git a/build-aux/build-mes.sh b/build-aux/build-mes.sh index b3134f91..02d47ba7 100755 --- a/build-aux/build-mes.sh +++ b/build-aux/build-mes.sh @@ -102,6 +102,7 @@ ARCHDIR=1 NOLINK=1 sh build-aux/cc-mes.sh lib/libc-mini ARCHDIR=1 NOLINK=1 sh build-aux/cc-mes.sh lib/libc ARCHDIR=1 NOLINK=1 sh build-aux/cc-mes.sh lib/libgetopt ARCHDIR=1 NOLINK=1 sh build-aux/cc-mes.sh lib/libc+tcc +ARCHDIR=1 NOLINK=1 sh build-aux/cc-mes.sh lib/libc+gnu [ -n "$SEED" ] && exit 0 diff --git a/build-aux/check-mescc.sh b/build-aux/check-mescc.sh index 3ce4a04e..6d7c6099 100755 --- a/build-aux/check-mescc.sh +++ b/build-aux/check-mescc.sh @@ -136,13 +136,13 @@ t 87-sscanf 90-strpbrk 91-fseek +92-stat +93-fread-fwrite " # 90: needs GNU, fails for mescc, passes for tcc broken="$broken 7s-struct-short -90-strpbrk -91-fseek " # gcc not supported @@ -273,7 +273,7 @@ broken="$broken #49_bracket_evaluation ; float LIBC=c+gnu -MESCCLIBS="-l c+tcc" +MESCCLIBS="-l c+gnu" expect=$(echo $broken | wc -w) ARGS="arg1 arg2 arg3 arg4 arg5" diff --git a/include/errno.h b/include/errno.h index 83655d38..1b4a473f 100644 --- a/include/errno.h +++ b/include/errno.h @@ -45,6 +45,12 @@ int errno; #define ENOSYS 38 #define ELOOP 40 +#if !__MESC__ +//extern char const *const sys_errlist[]; +extern char *sys_errlist[]; +extern int sys_nerr; +#endif // !__MESC__ + #endif // ! WITH_GLIBC #endif // __MES_ERRNO_H diff --git a/include/limits.h b/include/limits.h index c1e0f4d3..2f55cd28 100644 --- a/include/limits.h +++ b/include/limits.h @@ -35,6 +35,7 @@ #define MB_CUR_MAX 1 #define LONG_MIN -2147483648 #define LONG_MAX 2147483647 +#define LONG_MAX _POSIX_OPEN_MAX 16 #endif // ! WITH_GLIBC diff --git a/include/signal.h b/include/signal.h index 57b284b6..634e202e 100644 --- a/include/signal.h +++ b/include/signal.h @@ -38,8 +38,17 @@ typedef int pid_t; typedef int uid_t; #endif -typedef int clock_t; +#ifndef __MES_CLOCK_T +#define __MES_CLOCK_T +#undef clock_t +typedef long clock_t; +#endif + +#ifndef __MES_SIGVAL_T +#define __MES_SIGVAL_T +#undef clock_t typedef int sigval_t; +#endif #define NSIG 30 #define SIGHUP 1 diff --git a/include/stdio.h b/include/stdio.h index 9cd6ddec..174b86ac 100644 --- a/include/stdio.h +++ b/include/stdio.h @@ -65,18 +65,20 @@ int g_stdout; #define L_tmpnam 100 #endif -// Hmm -#define stdin 0 -#define stdout 1 -#define stderr 2 +#if !defined (__MES_FILE_T) && ! defined (_FILE_T) +#define __MES_FILE_T +#define _FILE_T +typedef int FILE; +#endif + +#define stdin (FILE*)0 +#define stdout (FILE*)1 +#define stderr (FILE*)2 -// TODO: fseek etc #define SEEK_SET 0 #define SEEK_CUR 1 #define SEEK_END 2 -typedef int FILE; - #ifndef __MES_SIZE_T #define __MES_SIZE_T #undef size_t @@ -92,6 +94,7 @@ int feof (FILE *stream); int ferror (FILE *stream); int fflush (FILE *stream); int fgetc (FILE* stream); +char *fgets (char *s, int size, FILE *stream); int fprintf (FILE *stream, char const *format, ...); int fpurge (FILE *stream); int fputc (int c, FILE *stream); diff --git a/include/string.h b/include/string.h index 8d503d9b..eec1a440 100644 --- a/include/string.h +++ b/include/string.h @@ -60,6 +60,9 @@ int strncmp (char const*, char const*, size_t); char *strrchr (char const *s, int c); char *strstr (char const *haystack, char const *needle); +char *strerror (int errnum); +void perror (char const *message); + #endif // ! WITH_GLIBC #endif // __MES_STRING_H diff --git a/include/sys/stat.h b/include/sys/stat.h index 74998f15..782201f1 100644 --- a/include/sys/stat.h +++ b/include/sys/stat.h @@ -35,26 +35,24 @@ typedef int mode_t; struct stat { - unsigned long st_dev; /* Device. */ - unsigned long st_ino; /* File serial number. */ - unsigned int st_mode; /* File mode. */ - unsigned int st_nlink; /* Link count. */ - unsigned int st_uid; /* User ID of the file's owner. */ - unsigned int st_gid; /* Group ID of the file's group. */ - unsigned long st_rdev; /* Device number, if device. */ - unsigned long __pad1; - long st_size; /* Size of file, in bytes. */ - int st_blksize; /* Optimal block size for I/O. */ - int __pad2; - long st_blocks; /* Number 512-byte blocks allocated. */ - long st_atime; /* Time of last access. */ - unsigned long st_atime_nsec; - long st_mtime; /* Time of last modification. */ - unsigned long st_mtime_nsec; - long st_ctime; /* Time of last status change. */ - unsigned long st_ctime_nsec; - unsigned int __unused4; - unsigned int __unused5; + unsigned long st_dev; + unsigned long st_ino; + unsigned short st_mode; + unsigned short st_nlink; + unsigned short st_uid; + unsigned short st_gid; + unsigned long st_rdev; + long st_size; + unsigned int st_blksize; + unsigned int st_blocks; + long st_atime; + unsigned long st_atime_usec; + long st_mtime; + unsigned long st_mtime_usec; + long st_ctime; + unsigned long st_ctime_usec; + unsigned int __foo0; + unsigned int __foo1; }; int chmod (char const *file_name, mode_t mode); diff --git a/include/sys/times.h b/include/sys/times.h index 60da88b9..c9b54018 100644 --- a/include/sys/times.h +++ b/include/sys/times.h @@ -32,6 +32,10 @@ typedef long clock_t; #endif +#ifndef CLOCKS_PER_SEC +#define CLOCKS_PER_SEC 1000000 +#endif + #ifndef HZ #define HZ 100 #endif diff --git a/include/time.h b/include/time.h index c8bd415f..be948d12 100644 --- a/include/time.h +++ b/include/time.h @@ -24,18 +24,22 @@ #undef __MES_TIME_H #include_next #else // ! WITH_GLIBC + +#ifndef __MES_TIME_T +#define __MES_TIME_T 1 typedef int time_t; +#endif struct tm { - int tm_sec; /* Seconds (0-60) */ - int tm_min; /* Minutes (0-59) */ - int tm_hour; /* Hours (0-23) */ - int tm_mday; /* Day of the month (1-31) */ - int tm_mon; /* Month (0-11) */ - int tm_year; /* Year - 1900 */ - int tm_wday; /* Day of the week (0-6, Sunday = 0) */ - int tm_yday; /* Day in the year (0-365, 1 Jan = 0) */ - int tm_isdst; /* Daylight saving time */ + int tm_sec; + int tm_min; + int tm_hour; + int tm_mday; + int tm_mon; + int tm_year; + int tm_wday; + int tm_yday; + int tm_isdst; }; struct tm *localtime (time_t const *timep); @@ -44,16 +48,8 @@ time_t time (time_t *tloc); #ifndef __MES_STRUCT_TIMESPEC #define __MES_STRUCT_TIMESPEC -// #ifndef __kernel_long_t -// typedef long __kernel_long_t; -// typedef unsigned long __kernel_ulong_t; -// #endif - -// typedef __kernel_long_t __kernel_time_t; - struct timespec { - //__kernel_time_t tv_sec; long tv_sec; long tv_nsec; }; diff --git a/include/unistd.h b/include/unistd.h index bd21b4dd..511adee4 100644 --- a/include/unistd.h +++ b/include/unistd.h @@ -71,9 +71,9 @@ int fork (); char *getcwd (char *buf, size_t size); int isatty (int fd); off_t lseek (int fd, off_t offset, int whence); -int read (int fd, void* buf, size_t n); +ssize_t read (int fd, void *buffer, size_t size); int unlink (char const *file_name); -int write (int fd, char const* s, int n); +ssize_t write (int filedes, void const *buffer, size_t size); #endif // ! WITH_GLIBC #endif // __MES_UNISTD_H diff --git a/lib/binutils.c b/lib/binutils.c index 1510b8d4..393d0bf7 100644 --- a/lib/binutils.c +++ b/lib/binutils.c @@ -111,11 +111,10 @@ getuid (int x) return 0; } -int -perror (int x) +void +perror (char const *message) { - eputs ("perror stub\n"); - return 0; + fprintf (stderr, "%s: %s\n", strerror (errno), message); } void* @@ -160,7 +159,7 @@ strncat (char *to, char const *from, size_t size) if (size == 0) return to; char *p = strchr (to , '\0'); - while (*from && size-- > 1) + while (*from && size-- > 0) *p++ = *from++; *p = 0; return to; diff --git a/lib/gcc.c b/lib/gcc.c index 27ae03e6..679b6068 100644 --- a/lib/gcc.c +++ b/lib/gcc.c @@ -21,7 +21,7 @@ #include #include #include -#include +#include FILE * freopen (char const *file_name, char const *opentype, FILE *stream) diff --git a/lib/glibc.c b/lib/glibc.c new file mode 100644 index 00000000..37ed69e7 --- /dev/null +++ b/lib/glibc.c @@ -0,0 +1,32 @@ +/* -*-comment-start: "//";comment-end:""-*- + * Mes --- Maxwell Equations of Software + * Copyright © 2018 Jan (janneke) Nieuwenhuizen + * + * This file is part of Mes. + * + * Mes is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * Mes is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Mes. If not, see . + */ + +int +__cleanup () +{ + eputs ("__cleanup stub\n"); + return 0; +} + +int +__exit (int status) +{ + exit (status); +} diff --git a/lib/libc+gnu.c b/lib/libc+gnu.c index 31229180..5cd48c23 100644 --- a/lib/libc+gnu.c +++ b/lib/libc+gnu.c @@ -18,9 +18,9 @@ * along with Mes. If not, see . */ -#include #include -#include +#include #include #include #include +#include diff --git a/lib/libc+tcc.c b/lib/libc+tcc.c index 26ed3011..56892b5d 100644 --- a/lib/libc+tcc.c +++ b/lib/libc+tcc.c @@ -35,15 +35,14 @@ #include #include +#include #if __MESC__ -#include #include #else // !__MESC__ -#include #include #endif // !__MESC__ @@ -143,7 +142,7 @@ ferror (FILE *stream) int fflush (FILE *stream) { - return 0; + fsync ((int)stream); } int @@ -189,22 +188,19 @@ FILE* fopen (char const *file_name, char const *opentype) { int fd; - if (opentype[0] == 'a') + int mode = 0600; + if (opentype[0] == 'a' && !access (file_name, O_RDONLY)) { - fd = open (file_name, O_RDONLY); - if (fd > 0) - { - close (fd); - fd = open (file_name, O_RDWR); - lseek (fd, 0, SEEK_END); - return fd; - } + fd = open (file_name, O_RDWR, mode); + lseek (fd, 0, SEEK_END); + } + else if (opentype[0] == 'w' || opentype[0] == 'a') + { + char *plus_p = strchr (opentype, '+'); + int flags = plus_p ? O_RDWR | O_CREAT : O_WRONLY | O_CREAT | O_TRUNC; + fd = open (file_name, flags, mode); } - if (opentype[0] == 'w' || opentype[0] == 'a') - /* 577 is O_WRONLY|O_CREAT|O_TRUNC, 384 is 600 in octal */ - fd = open (file_name, 577 , 384); else - /* Everything else is a read */ fd = open (file_name, 0, 0); return (FILE*)fd; diff --git a/lib/libc-mini.c b/lib/libc-mini.c index 09293ccf..4eb165b1 100644 --- a/lib/libc-mini.c +++ b/lib/libc-mini.c @@ -24,6 +24,14 @@ typedef unsigned long size_t; #endif +#ifndef __MES_SSIZE_T +#define __MES_SSIZE_T +#undef ssize_t +typedef long ssize_t; +#endif + +ssize_t write (int filedes, void const *buffer, size_t size); + size_t strlen (char const* s) { diff --git a/lib/libc.c b/lib/libc.c index 18eff321..62c31ad3 100644 --- a/lib/libc.c +++ b/lib/libc.c @@ -43,6 +43,7 @@ #include #include +#include int g_stdin = 0; diff --git a/lib/libg.c b/lib/libg.c index 2c4a6067..ee463cad 100644 --- a/lib/libg.c +++ b/lib/libg.c @@ -29,6 +29,7 @@ #define malloc _malloc #define printf _printf #define putchar _putchar +#define puts _puts #define setjmp _setjmp #define signal _signal #define strcmp _strcmp @@ -36,7 +37,7 @@ #define sscanf _sscanf #include -#include +#include #include #include #include @@ -44,53 +45,6 @@ int __cleanup () { - eputs ("cleanup stub\n"); + eputs ("__cleanup stub\n"); return 0; } - -int -_dprop () -{ - eputs ("dprop stub\n"); -} - -int -_edprop () -{ - eputs ("edprop stub\n"); -} - -int -_eldprop () -{ - eputs ("eldprop stub\n"); -} - -int -_iprop () -{ - eputs ("iprop stub\n"); -} - -int -_lprop () -{ - eputs ("lprop stub\n"); -} - -int -_ldprop () -{ - eputs ("ldprop stub\n"); -} - -int -_uiprop () -{ - eputs ("uiprop stub\n"); -} -int -_ulprop () -{ - eputs ("ulprop stub\n"); -} diff --git a/lib/linux+gnu-gcc.c b/lib/linux+gnu-gcc.c deleted file mode 100644 index e6cd0df7..00000000 --- a/lib/linux+gnu-gcc.c +++ /dev/null @@ -1,179 +0,0 @@ -/* -*-comment-start: "//";comment-end:""-*- - * Mes --- Maxwell Equations of Software - * Copyright © 2018 Jan (janneke) Nieuwenhuizen - * - * This file is part of Mes. - * - * Mes is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or (at - * your option) any later version. - * - * Mes is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Mes. If not, see . - */ - -#define SYS_link "0x09" -#define SYS_rename "0x26" -#define SYS_mkdir "0x27" -#define SYS_dup "0x29" -#define SYS_pipe "0x2a" -#define SYS_lstat "0x6b" -#define SYS_fstat "0x6c" - -#define SYS_kill 0x25 -#define SYS_nanosleep 0xa2 - -int -link (char const *old_name, char const *new_name) -{ -#if !__TINYC__ - int r; - asm ( - "mov %1,%%ebx\n\t" - "mov %2,%%ecx\n\t" - - "mov $"SYS_link",%%eax\n\t" - "int $0x80\n\t" - - "mov %%eax,%0\n\t" - : "=r" (r) - : "" (old_name), "" (new_name) - : "eax", "ebx", "ecx" - ); - return r; -#endif -} - -int -kill (pid_t pid, int signum) -{ - return _sys_call2 (SYS_kill, pid, signum); -} - -int -rename (char const *old_name, char const *new_name) -{ -#if !__TINYC__ - int r; - asm ( - "mov %1,%%ebx\n\t" - "mov %2,%%ecx\n\t" - - "mov $"SYS_rename",%%eax\n\t" - "int $0x80\n\t" - - "mov %%eax,%0\n\t" - : "=r" (r) - : "" (old_name), "" (new_name) - : "eax", "ebx", "ecx" - ); - return r; -#endif -} - -int -mkdir (char const *s, mode_t mode) -{ -#if !__TINYC__ - int r; - asm ( - "mov %1,%%ebx\n\t" - "mov %2,%%ecx\n\t" - "mov $"SYS_mkdir",%%eax\n\t" - "int $0x80\n\t" - "mov %%eax,%0\n\t" - : "=r" (r) - : "" (s), "" (mode) - : "eax", "ebx", "ecx" - ); - return r; -#endif -} - -int -dup (int old) -{ -#if !__TINYC__ - int r; - asm ( - "mov %0,%%ebx\n\t" - "mov $"SYS_dup",%%eax\n\t" - "int $0x80" - : "=r" (r) - : "" (old) - ); - return r; -#endif -} - -int -pipe (int filedes[2]) -{ -#if !__TINYC__ - int r; - asm ( - "mov %0,%%ebx\n\t" - "mov $"SYS_pipe",%%eax\n\t" - "int $0x80" - : "=r" (r) - : "" (filedes) - ); - return r; -#endif -} - -int -lstat (char const *file_name, struct stat *statbuf) -{ -#if !__TINYC__ - int r; - asm ( - "mov %1,%%ebx\n\t" - "mov %2,%%ecx\n\t" - - "mov $"SYS_lstat",%%eax\n\t" - "int $0x80\n\t" - - "mov %%eax,%0\n\t" - : "=r" (r) - : "" (file_name), "" (statbuf) - : "eax", "ebx", "ecx" - ); - return r; -#endif -} - -int -nanosleep (const struct timespec *requested_time, - struct timespec *remaining) -{ - return _sys_call2 (SYS_execve, (int)requested_time, (int)remaining); -} - -int -fstat (int fd, struct stat *statbuf) -{ -#if !__TINYC__ - int r; - asm ( - "mov %1,%%ebx\n\t" - "mov %2,%%ecx\n\t" - - "mov $"SYS_fstat",%%eax\n\t" - //"mov $"SYS_oldfstat",%%eax\n\t" - "int $0x80\n\t" - - "mov %%eax,%0\n\t" - : "=r" (r) - : "" (fd), "" (statbuf) - : "eax", "ebx", "ecx" - ); - return r; -#endif -} diff --git a/lib/linux+gnu.c b/lib/linux+gnu.c new file mode 100644 index 00000000..3c54feef --- /dev/null +++ b/lib/linux+gnu.c @@ -0,0 +1,84 @@ +/* -*-comment-start: "//";comment-end:""-*- + * Mes --- Maxwell Equations of Software + * Copyright © 2018 Jan (janneke) Nieuwenhuizen + * + * This file is part of Mes. + * + * Mes is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * Mes is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Mes. If not, see . + */ + +#define SYS_link 0x09 +#define SYS_kill 0x25 +#define SYS_rename 0x26 +#define SYS_mkdir 0x27 +#define SYS_dup 0x29 +#define SYS_pipe 0x2a +#define SYS_lstat 0x6b +#define SYS_fstat 0x6c +#define SYS_nanosleep 0xa2 + +int +link (char const *old_name, char const *new_name) +{ + return _sys_call2 (SYS_link, (int)old_name, (int)new_name); +} + +int +kill (pid_t pid, int signum) +{ + return _sys_call2 (SYS_kill, (int)pid, (int)signum); +} + +int +rename (char const *old_name, char const *new_name) +{ + return _sys_call2 (SYS_rename, (int)old_name, (int)new_name); +} + +int +mkdir (char const *file_name, mode_t mode) +{ + return _sys_call2 (SYS_mkdir, (int)file_name, (int)mode); +} + +int +dup (int old) +{ + return _sys_call1 (SYS_dup, (int)old); +} + +int +pipe (int filedes[2]) +{ + return _sys_call1 (SYS_pipe, (int)filedes); +} + +int +lstat (char const *file_name, struct stat *statbuf) +{ + return _sys_call2 (SYS_lstat, (int)file_name, (int)statbuf); +} + +int +nanosleep (const struct timespec *requested_time, + struct timespec *remaining) +{ + return _sys_call2 (SYS_nanosleep, (int)requested_time, (int)remaining); +} + +int +fstat (int fd, struct stat *statbuf) +{ + return _sys_call2 (SYS_fstat, (int)fd, (int)statbuf); +} diff --git a/lib/linux+tcc-gcc.c b/lib/linux+tcc-gcc.c deleted file mode 100644 index d73772ad..00000000 --- a/lib/linux+tcc-gcc.c +++ /dev/null @@ -1,140 +0,0 @@ -/* -*-comment-start: "//";comment-end:""-*- - * Mes --- Maxwell Equations of Software - * Copyright © 2016,2017,2018 Jan (janneke) Nieuwenhuizen - * - * This file is part of Mes. - * - * Mes is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or (at - * your option) any later version. - * - * Mes is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Mes. If not, see . - */ - -#define SYS_close "0x06" -#define SYS_lseek "0x13" -#define SYS_unlink "0x0a" -#define SYS_rmdir "0x28" -#define SYS_stat "0x6a" -#define SYS_getcwd "0xb7" - -int -close (int fd) -{ -#if !__TINYC__ - int r; - asm ( - "mov %0,%%ebx\n\t" - "mov $"SYS_close",%%eax\n\t" - "int $0x80" - : "=r" (r) - : "" (fd) - ); - return r; -#endif -} - -off_t -lseek (int fd, off_t offset, int whence) -{ -#if !__TINYC__ - int r; - asm ( - "mov %1,%%ebx\n\t" - "mov %2,%%ecx\n\t" - "mov %3,%%edx\n\t" - - "mov $"SYS_lseek",%%eax\n\t" - "int $0x80\n\t" - - "mov %%eax,%0\n\t" - : "=r" (r) - : "" (fd), "" (offset), "" (whence) - : "eax", "ebx", "ecx", "edx" - ); - return r; -#endif -} - -int -unlink (char const *file_name) -{ -#if !__TINYC__ - int r; - asm ( - "mov %0,%%ebx\n\t" - "mov $"SYS_unlink",%%eax\n\t" - "int $0x80" - : "=r" (r) - : "" (file_name) - ); - return r; -#endif -} - -int -rmdir (char const *file_name) -{ -#if !__TINYC__ - int r; - asm ( - "mov %0,%%ebx\n\t" - "mov $"SYS_rmdir",%%eax\n\t" - "int $0x80" - : "=r" (r) - : "" (file_name) - ); - return r; -#endif -} - -int -stat (char const *file_name, struct stat *statbuf) -{ -#if !__TINYC__ - int r; - asm ( - "mov %1,%%ebx\n\t" - "mov %2,%%ecx\n\t" - - "mov $"SYS_stat",%%eax\n\t" - "int $0x80\n\t" - - "mov %%eax,%0\n\t" - : "=r" (r) - : "" (file_name), "" (statbuf) - : "eax", "ebx", "ecx" - ); - if (r < 0) - errno = -r; - return r; -#endif -} - -char * -getcwd (char *buf, size_t size) -{ -#if !__TINYC__ - int r; - asm ( - "mov %1,%%ebx\n\t" - "mov %2,%%ecx\n\t" - - "mov $"SYS_getcwd",%%eax\n\t" - "int $0x80\n\t" - - "mov %%eax,%0\n\t" - : "=r" (r) - : "" (buf), "" (size) - : "eax", "ebx", "ecx" - ); - return r; -#endif -} diff --git a/lib/linux+tcc-mes.c b/lib/linux+tcc.c similarity index 50% rename from lib/linux+tcc-mes.c rename to lib/linux+tcc.c index 8013371a..cf69a264 100644 --- a/lib/linux+tcc-mes.c +++ b/lib/linux+tcc.c @@ -1,6 +1,6 @@ /* -*-comment-start: "//";comment-end:""-*- * Mes --- Maxwell Equations of Software - * Copyright © 2017 Jan (janneke) Nieuwenhuizen + * Copyright © 2016,2017,2018 Jan (janneke) Nieuwenhuizen * * This file is part of Mes. * @@ -18,62 +18,45 @@ * along with Mes. If not, see . */ -int errno; +#define SYS_close 0x06 +#define SYS_lseek 0x13 +#define SYS_unlink 0x0a +#define SYS_rmdir 0x28 +#define SYS_stat 0x6a +#define SYS_getcwd 0xb7 int -close (int fd) +close (int filedes) { - asm ("mov____0x8(%ebp),%ebx !8"); + return _sys_call1 (SYS_close, (int)filedes); +} - asm ("mov____$i32,%eax SYS_close"); - asm ("int____$0x80"); +off_t +lseek (int filedes, off_t offset, int whence) +{ + return _sys_call3 (SYS_lseek, (int)filedes, (int)offset, (int)whence); } int unlink (char const *file_name) { - asm ("mov____0x8(%ebp),%ebx !8"); - - asm ("mov____$i32,%eax SYS_unlink"); - asm ("int____$0x80"); + return _sys_call1 (SYS_unlink, (int)file_name); } int rmdir (char const *file_name) { - asm ("mov____0x8(%ebp),%ebx !8"); - - asm ("mov____$i32,%eax SYS_rmdir"); - asm ("int____$0x80"); + return _sys_call1 (SYS_rmdir, (int)file_name); } int stat (char const *file_name, struct stat *statbuf) { - asm ("mov____0x8(%ebp),%ebx !8"); - asm ("mov____0x8(%ebp),%ecx !12"); - - asm ("mov____$i32,%eax SYS_getcwd"); - asm ("int____$0x80"); -} - -off_t -lseek (int fd, off_t offset, int whence) -{ - asm ("mov____0x8(%ebp),%ebx !8"); - asm ("mov____0x8(%ebp),%ecx !12"); - asm ("mov____0x8(%ebp),%edx !16"); - - asm ("mov____$i32,%eax SYS_lseek"); - asm ("int____$0x80"); + return _sys_call2 (SYS_stat, (int)file_name, (int)statbuf); } char * -getcwd (char *buf, size_t size) +getcwd (char *buffer, size_t size) { - asm ("mov____0x8(%ebp),%ebx !8"); - asm ("mov____0x8(%ebp),%ecx !12"); - - asm ("mov____$i32,%eax SYS_getcwd"); - asm ("int____$0x80"); + return _sys_call2 (SYS_getcwd, (int)buffer, (int)size); } diff --git a/lib/linux-gcc.c b/lib/linux-gcc.c index 5ed78460..79de74f3 100644 --- a/lib/linux-gcc.c +++ b/lib/linux-gcc.c @@ -19,25 +19,45 @@ */ #include -#include -#include -#include -#include -#include -#include -#define SYS_fork "0x02" -#define SYS_read "0x03" -#define SYS_open "0x05" -#define SYS_waitpid "0x07" -#define SYS_execve 0x0b -#define SYS_chmod "0x0f" -#define SYS_access "0x21" -#define SYS_brk "0x2d" -#define SYS_ioctl "0x36" -#define SYS_fsync "0x76" +int +_sys_call (int sys_call) +{ +#if !__TINYC__ + int r; + asm ( + "mov %1,%%eax\n\t" + "int $0x80\n\t" + "mov %%eax,%0\n\t" + : "=r" (r) + : "" (sys_call) + : "eax" + ); + if (r < 0) + errno = -r; + return r; +#endif +} -#define xSYS_execve "0x0b" +int +_sys_call1 (int sys_call, int one) +{ +#if !__TINYC__ + int r; + asm ( + "mov %1,%%eax\n\t" + "mov %2,%%ebx\n\t" + "int $0x80\n\t" + "mov %%eax,%0\n\t" + : "=r" (r) + : "" (sys_call), "" (one) + : "eax", "ebx" + ); + if (r < 0) + errno = -r; + return r; +#endif +} int _sys_call2 (int sys_call, int one, int two) @@ -45,10 +65,9 @@ _sys_call2 (int sys_call, int one, int two) #if !__TINYC__ int r; asm ( + "mov %1,%%eax\n\t" "mov %2,%%ebx\n\t" "mov %3,%%ecx\n\t" - - "mov %1,%%eax\n\t" "int $0x80\n\t" "mov %%eax,%0\n\t" : "=r" (r) @@ -70,10 +89,8 @@ _sys_call3 (int sys_call, int one, int two, int three) "mov %2,%%ebx\n\t" "mov %3,%%ecx\n\t" "mov %4,%%edx\n\t" - "mov %1,%%eax\n\t" "int $0x80\n\t" - "mov %%eax,%0\n\t" : "=r" (r) : "" (sys_call), "" (one), "" (two), "" (three) @@ -84,211 +101,3 @@ _sys_call3 (int sys_call, int one, int two, int three) return r; #endif } - -int -fork () -{ -#if !__TINYC__ - int r; - asm ( - "mov $"SYS_fork",%%eax\n\t" - "int $0x80\n\t" - "mov %%eax,%0\n\t" - : "=r" (r) - : //no inputs - : "eax" - ); - return r; -#endif -} - -int -read (int fd, void* buf, size_t n) -{ -#if !__TINYC__ - int r; - asm ( - "mov %1,%%ebx\n\t" - "mov %2,%%ecx\n\t" - "mov %3,%%edx\n\t" - - "mov $"SYS_read",%%eax\n\t" - "int $0x80\n\t" - - "mov %%eax,%0\n\t" - : "=r" (r) - : "" (fd), "" (buf), "" (n) - : "eax", "ebx", "ecx", "edx" - ); - return r; -#endif -} - -int -open (char const *s, int flags, ...) -{ -#if !__TINYC__ - int mode; - asm ( - "mov %%ebp,%%eax\n\t" - "add $0x10,%%eax\n\t" - "mov (%%eax),%%eax\n\t" - "mov %%eax,%0\n\t" - : "=mode" (mode) - : //no inputs "" - ); - int r; - //syscall (SYS_open, mode)); - asm ( - "mov %1,%%ebx\n\t" - "mov %2,%%ecx\n\t" - "mov %3,%%edx\n\t" - - "mov $"SYS_open",%%eax\n\t" - "int $0x80\n\t" - "mov %%eax,%0\n\t" - : "=r" (r) - : "" (s), "" (flags), "" (mode) - : "eax", "ebx", "ecx", "edx" - ); - return r; -#endif -} - -pid_t -waitpid (pid_t pid, int *status_ptr, int options) -{ -#if !__TINYC__ - int r; - asm ( - "mov %1,%%ebx\n\t" - "mov %2,%%ecx\n\t" - "mov %3,%%edx\n\t" - - "mov $"SYS_waitpid",%%eax\n\t" - "int $0x80\n\t" - - "mov %%eax,%0\n\t" - : "=r" (r) - : "" (pid), "" (status_ptr), "" (options) - : "eax", "ebx", "ecx", "edx" - ); - return r; -#endif -} - -int -execve (char const* file_name, char *const argv[], char *const env[]) -{ - return _sys_call3 (SYS_execve, (int)file_name, (int)argv, (int)env); -} - -int -chmod (char const *s, mode_t mode) -{ -#if !__TINYC__ - int r; - asm ( - "mov %1,%%ebx\n\t" - "mov %2,%%ecx\n\t" - - "mov $"SYS_chmod",%%eax\n\t" - "int $0x80\n\t" - "mov %%eax,%0\n\t" - : "=r" (r) - : "" (s), "" (mode) - : "eax", "ebx", "ecx" - ); - return r; -#endif -} - -int -access (char const *s, int mode) -{ -#if !__TINYC__ - int r; - asm ( - "mov %1,%%ebx\n\t" - "mov %2,%%ecx\n\t" - - "mov $"SYS_access",%%eax\n\t" - "int $0x80\n\t" - "mov %%eax,%0\n\t" - : "=r" (r) - : "" (s), "" (mode) - : "eax", "ebx", "ecx" - ); - return r; -#endif -} - -void * -brk (void *p) -{ -#if !__TINYC__ - void *r; - asm ( - "mov %1,%%ebx\n\t" - - "mov $"SYS_brk",%%eax\n\t" - "int $0x80\n\t" - "mov %%eax,%0\n\t" - : "=r" (r) - : "" (p) - : "eax", "ebx" - ); - return r; -#endif -} - -int -ioctl (int fd, unsigned long request, ...) -{ -#if !__TINYC__ - int p; - asm ( - "mov %%ebp,%%eax\n\t" - "add $0x10,%%eax\n\t" - "mov (%%eax),%%eax\n\t" - "mov %%eax,%0\n\t" - : "=p" (p) - : //no inputs "" - ); - int r; - //syscall (SYS_ioctl, fd)); - asm ( - "mov %1,%%ebx\n\t" - "mov %2,%%ecx\n\t" - "mov %3,%%edx\n\t" - - "mov $"SYS_ioctl",%%eax\n\t" - "int $0x80\n\t" - "mov %%eax,%0\n\t" - : "=r" (r) - : "" (fd), "" (request), "" (p) - : "eax", "ebx", "ecx", "edx" - ); - return r; -#endif -} - -int -fsync (int fd) -{ -#if !__TINYC__ - int r; - //syscall (SYS_fsync, fd)); - asm ( - "mov %1,%%ebx\n\t" - - "mov $"SYS_fsync",%%eax\n\t" - "int $0x80\n\t" - "mov %%eax,%0\n\t" - : "=r" (r) - : "" (fd) - : "eax", "ebx" - ); - return r; -#endif -} diff --git a/lib/linux-mes.c b/lib/linux-mes.c index f525381e..2fe00e6f 100644 --- a/lib/linux-mes.c +++ b/lib/linux-mes.c @@ -18,102 +18,38 @@ * along with Mes. If not, see . */ -void -fork () +#include + +int +_sys_call (int sys_call) { - asm ("mov____$i32,%eax SYS_fork"); + asm ("mov____0x8(%ebp),%eax !8"); asm ("int____$0x80"); } -void -read () +int +_sys_call1 (int sys_call, int one) { - asm ("mov____0x8(%ebp),%ebx !8"); - asm ("mov____0x8(%ebp),%ecx !12"); - asm ("mov____0x8(%ebp),%edx !16"); - - asm ("mov____$i32,%eax SYS_read"); + asm ("mov____0x8(%ebp),%eax !8"); + asm ("mov____0x8(%ebp),%ebx !12"); asm ("int____$0x80"); } -void -open () +int +_sys_call2 (int sys_call, int one, int two) { - asm ("mov____0x8(%ebp),%ebx !8"); - asm ("mov____0x8(%ebp),%ecx !12"); - asm ("mov____0x8(%ebp),%edx !16"); - - asm ("mov____$i32,%eax SYS_open"); + asm ("mov____0x8(%ebp),%eax !8"); + asm ("mov____0x8(%ebp),%ebx !12"); + asm ("mov____0x8(%ebp),%ecx !16"); asm ("int____$0x80"); } -void -waitpid () +int +_sys_call3 (int sys_call, int one, int two, int three) { - asm ("mov____0x8(%ebp),%ebx !8"); - asm ("mov____0x8(%ebp),%ecx !12"); - asm ("mov____0x8(%ebp),%edx !16"); - - asm ("mov____$i32,%eax SYS_waitpid"); - asm ("int____$0x80"); -} - -void -execve () -{ - asm ("mov____0x8(%ebp),%ebx !8"); - asm ("mov____0x8(%ebp),%ecx !12"); - asm ("mov____0x8(%ebp),%edx !16"); - - asm ("mov____$i32,%eax SYS_execve"); - asm ("int____$0x80"); -} - -void -chmod () -{ - asm ("mov____0x8(%ebp),%ebx !8"); - asm ("mov____0x8(%ebp),%ecx !12"); - - asm ("mov____$i32,%eax SYS_chmod"); - asm ("int____$0x80"); -} - -void -access () -{ - asm ("mov____0x8(%ebp),%ebx !8"); - asm ("mov____0x8(%ebp),%ecx !12"); - - asm ("mov____$i32,%eax SYS_access"); - asm ("int____$0x80"); -} - -void -brk () -{ - asm ("mov____0x8(%ebp),%ebx !8"); - - asm ("mov____$i32,%eax SYS_brk"); - asm ("int____$0x80"); -} - -void -ioctl () -{ - asm ("mov____0x8(%ebp),%ebx !8"); - asm ("mov____0x8(%ebp),%ecx !12"); - asm ("mov____0x8(%ebp),%edx !16"); - - asm ("mov____$i32,%eax SYS_ioctl"); - asm ("int____$0x80"); -} - -void -fsync () -{ - asm ("mov____0x8(%ebp),%ebx !8"); - - asm ("mov____$i32,%eax SYS_fsync"); + asm ("mov____0x8(%ebp),%eax !8"); + asm ("mov____0x8(%ebp),%ebx !12"); + asm ("mov____0x8(%ebp),%ecx !16"); + asm ("mov____0x8(%ebp),%edx !20"); asm ("int____$0x80"); } diff --git a/lib/linux-mini-gcc.c b/lib/linux-mini-gcc.c index f8386526..da05ccf4 100644 --- a/lib/linux-mini-gcc.c +++ b/lib/linux-mini-gcc.c @@ -26,17 +26,16 @@ exit (int code) { #if !__TINYC__ asm ( + "mov $"SYS_exit",%%eax\n\t" "mov %0,%%ebx\n\t" - "mov $1,%%eax\n\t" "int $0x80\n\t" : // no outputs "=" (r) : "" (code) ); #else // __TINYC__ asm ( - "mov %0,%%ebx\n\t" - "mov $"SYS_exit",%%eax\n\t" + "mov %0,%%ebx\n\t" "int $128\n\t" : // no outputs "=" (r) : "Ir" (code) @@ -46,34 +45,32 @@ exit (int code) exit (0); } -int -write (int fd, char const* s, int n) +ssize_t +write (int filedes, void const *buffer, size_t size) { int r; #if __GNUC__ asm ( + "mov $"SYS_write",%%eax\n\t" "mov %1,%%ebx\n\t" "mov %2,%%ecx\n\t" "mov %3,%%edx\n\t" - - "mov $0x04,%%eax\n\t" "int $0x80\n\t" "mov %%eax,%0\n\t" : "=r" (r) - : "" (fd), "" (s), "" (n) + : "" (filedes), "" (buffer), "" (size) : "eax", "ebx", "ecx", "edx" ); #elif __TINYC__ asm ( + "mov $"SYS_write",%%eax\n\t" "mov %1,%%ebx\n\t" "mov %2,%%ecx\n\t" "mov %3,%%edx\n\t" - - "mov $"SYS_write",%%eax\n\t" "int $128\n\t" "mov %%eax,%0\n\t" : "=r" (r) - : "Ir" (fd), "Ir" (s), "Ir" (n) + : "Ir" (filedes), "Ir" (buffer), "Ir" (size) : "eax", "ebx", "ecx"//, "edx" ); #endif diff --git a/lib/linux-mini-mes.c b/lib/linux-mini-mes.c index 95ba9716..34955216 100644 --- a/lib/linux-mini-mes.c +++ b/lib/linux-mini-mes.c @@ -21,19 +21,17 @@ void exit () { - asm ("mov____0x8(%ebp),%ebx !8"); - asm ("mov____$i32,%eax SYS_exit"); + asm ("mov____0x8(%ebp),%ebx !8"); asm ("int____$0x80"); } void write () { + asm ("mov____$i32,%eax SYS_write"); asm ("mov____0x8(%ebp),%ebx !8"); asm ("mov____0x8(%ebp),%ecx !12"); asm ("mov____0x8(%ebp),%edx !16"); - - asm ("mov____$i32,%eax SYS_write"); asm ("int____$0x80"); } diff --git a/lib/linux.c b/lib/linux.c new file mode 100644 index 00000000..f9dbcd9e --- /dev/null +++ b/lib/linux.c @@ -0,0 +1,108 @@ +/* -*-comment-start: "//";comment-end:""-*- + * Mes --- Maxwell Equations of Software + * Copyright © 2016,2017,2018 Jan (janneke) Nieuwenhuizen + * + * This file is part of Mes. + * + * Mes is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * Mes is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Mes. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include + +#define SYS_fork 0x02 +#define SYS_read 0x03 +#define SYS_open 0x05 +#define SYS_waitpid 0x07 +#define SYS_execve 0x0b +#define SYS_chmod 0x0f +#define SYS_access 0x21 +#define SYS_brk 0x2d +#define SYS_ioctl 0x36 +#define SYS_fsync 0x76 + +int +fork () +{ + return _sys_call (SYS_fork); +} + +ssize_t +read (int filedes, void *buffer, size_t size) +{ + return _sys_call3 (SYS_read, (int)filedes, (int)buffer, (int)size); +} + +int +open (char const *file_name, int flags, ...) +{ + va_list ap; + va_start (ap, flags); + int mask = va_arg (ap, int); + int r = _sys_call3 (SYS_open, (int)file_name, (int)flags, (int)mask); + va_end (ap); + return r; +} + +pid_t +waitpid (pid_t pid, int *status_ptr, int options) +{ + return _sys_call3 (SYS_waitpid, (int)pid, (int)status_ptr, (int)options); +} + +int +execve (char const* file_name, char *const argv[], char *const env[]) +{ + return _sys_call3 (SYS_execve, (int)file_name, (int)argv, (int)env); +} + +int +chmod (char const *file_name, mode_t mask) +{ + return _sys_call2 (SYS_chmod, (int)file_name, (int)mask); +} + +int +access (char const *file_name, int how) +{ + return _sys_call2 (SYS_access, (int)file_name, (int)how); +} + +int +brk (void *addr) +{ + return _sys_call1 (SYS_brk, (int)addr); +} + +int +ioctl (int filedes, unsigned long command, ...) +{ + va_list ap; + va_start (ap, command); + int data = va_arg (ap, int); + int r = _sys_call3 (SYS_ioctl, (int)filedes, (int)command, (int)data); + va_end (ap); + return r; +} + +int +fsync (int filedes) +{ + return _sys_call1 (SYS_fsync, (int)filedes); +} diff --git a/lib/m4.c b/lib/m4.c index da1102bb..f1e4ae7d 100644 --- a/lib/m4.c +++ b/lib/m4.c @@ -167,23 +167,64 @@ signal (int x) return 0; } -int -sys_errlist (int x) -{ - eputs ("sys_errlist stub\n"); - return 0; -} - -int -sys_nerr (int x) -{ - eputs ("sys_nerr stub\n"); - return 0; -} - int system (int x) { eputs ("system stub\n"); return 0; } + +//char const *const sys_errlist[40] = { +char *sys_errlist[] = { + "error 00", + "error 01", + "error 02", + "error 03", + "error 04", + "error 05", + "error 06", + "error 07", + "error 08", + "error 09", + "error 10", + "error 11", + "error 12", + "error 13", + "error 14", + "error 15", + "error 16", + "error 17", + "error 18", + "error 19", + "error 20", + "error 21", + "error 22", + "error 23", + "error 24", + "error 25", + "error 26", + "error 27", + "error 28", + "error 29", + "error 30", + "error 31", + "error 32", + "error 33", + "error 34", + "error 35", + "error 36", + "error 37", + "error 38", + "error 39", +}; + +int sys_nerr = 39; + +char * +strerror (int errnum) +{ + eputs ("strerror errnum="); eputs (itoa (errnum)); eputs ("\n"); + if (errnum > 0 && errnum <= sys_nerr) + return sys_errlist[errnum]; + return "sterror: unknown error"; +} diff --git a/lib/x86-mes/x86.M1 b/lib/x86-mes/x86.M1 index 277c04d8..77e84cc0 100644 --- a/lib/x86-mes/x86.M1 +++ b/lib/x86-mes/x86.M1 @@ -229,5 +229,6 @@ DEFINE SYS_lseek 13000000 DEFINE SYS_access 21000000 DEFINE SYS_brk 2d000000 DEFINE SYS_ioctl 36000000 +DEFINE SYS_stat 6a000000 DEFINE SYS_fsync 76000000 DEFINE SYS_getcwd b7000000 diff --git a/scaffold/tests/92-stat.c b/scaffold/tests/92-stat.c new file mode 100644 index 00000000..d3583884 --- /dev/null +++ b/scaffold/tests/92-stat.c @@ -0,0 +1,100 @@ +/* -*-comment-start: "//";comment-end:""-*- + * Mes --- Maxwell Equations of Software + * Copyright © 2018 Jan (janneke) Nieuwenhuizen + * + * This file is part of Mes. + * + * Mes is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * Mes is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Mes. If not, see . + */ + +#include +#include +#include +#include + + +#if __i386__ +#define stat xstat + +struct stat +{ + unsigned long st_dev; + unsigned long st_ino; + unsigned short st_mode; + unsigned short st_nlink; + unsigned short st_uid; + unsigned short st_gid; + unsigned long st_rdev; + long st_size; + unsigned int st_blksize; + unsigned int st_blocks; + long st_atime; + unsigned long st_atime_usec; + long st_mtime; + unsigned long st_mtime_usec; + long st_ctime; + unsigned long st_ctime_usec; + unsigned int __foo0; + unsigned int __foo1; +}; +#endif + +int +main () +{ + // char buf[20]; + // strcpy (buf, "Hello"); + // eputs ("buf="); eputs (buf); eputs ("\n"); + // strcat (buf, ", "); + // eputs ("buf="); eputs (buf); eputs ("\n"); + // strncat (buf, "world!XXX", 6); + // eputs ("buf="); eputs (buf); eputs ("\n"); + // if (strcmp (buf, "Hello, world!")) + // return 1; + + // char *name = "boo"; + // errno = 0; + // fprintf (stderr, "%s: %s\n", name, strerror (errno)); + int fd = open ("COPYING", 0); + + struct stat sbuf; + + int r = fstat (fd, &sbuf); + if (r < 0) + return 1; + + eputs ("st_dev="); eputs (itoa (sbuf.st_dev)); eputs ("\n"); + eputs ("st_ino="); eputs (itoa (sbuf.st_ino)); eputs ("\n"); + eputs ("st_mode="); eputs (itoa (sbuf.st_mode)); eputs ("\n"); + eputs ("st_nlink="); eputs (itoa (sbuf.st_nlink)); eputs ("\n"); + eputs ("st_uid="); eputs (itoa (sbuf.st_uid)); eputs ("\n"); + eputs ("st_gid="); eputs (itoa (sbuf.st_gid)); eputs ("\n"); + eputs ("st_rdev="); eputs (itoa (sbuf.st_rdev)); eputs ("\n"); + eputs ("st_size="); eputs (itoa (sbuf.st_size)); eputs ("\n"); + + eputs ("st_blksize="); eputs (itoa (sbuf.st_blksize)); eputs ("\n"); + eputs ("st_blocks="); eputs (itoa (sbuf.st_blocks)); eputs ("\n"); + + eputs ("st_atime="); eputs (itoa (sbuf.st_atime)); eputs ("\n"); + //eputs ("st_atime_nsec="); eputs (itoa (sbuf.st_atime_nsec)); eputs ("\n"); + + eputs ("st_mtime="); eputs (itoa (sbuf.st_mtime)); eputs ("\n"); + //eputs ("st_mtime_nsec="); eputs (itoa (sbuf.st_mtime_nsec)); eputs ("\n"); + + eputs ("st_ctime="); eputs (itoa (sbuf.st_ctime)); eputs ("\n"); + //eputs ("st_ctime_nsec="); eputs (itoa (sbuf.st_ctime_nsec)); eputs ("\n"); + + eputs ("size:"); eputs (itoa (sizeof (struct stat))); eputs ("\n"); + return 0; +} diff --git a/scaffold/tests/93-fread-fwrite.c b/scaffold/tests/93-fread-fwrite.c new file mode 100644 index 00000000..43847401 --- /dev/null +++ b/scaffold/tests/93-fread-fwrite.c @@ -0,0 +1,77 @@ +/* -*-comment-start: "//";comment-end:""-*- + * Mes --- Maxwell Equations of Software + * Copyright © 2018 Jan (janneke) Nieuwenhuizen + * + * This file is part of Mes. + * + * Mes is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * Mes is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Mes. If not, see . + */ + +#include +#include +#include +#include +#include +#include + +int +main () +{ + char *temp = "COPYING.tmp"; + char *new = "COPYING.new"; + + unlink (temp); + unlink (new); + + FILE *t = fopen (temp, "wb+"); + FILE *n = fopen (new, "wb"); + + char *header = "!
\n"; + fwrite (header, strlen (header), 1, n); + + char *data = "foo bar baz\n"; + fwrite (data, strlen (data), 1, t); + + fseek (t, 0, SEEK_END); + int size = ftell (t); + fprintf (stderr, " size=>%d\n", size); + fseek (t, 0, SEEK_SET); + char *p = (char*)malloc (size + 1); + fread (p, size, 1, t); + fwrite (p, size, 1, n); + + char header_plus_data[200]; + strcpy (header_plus_data, header); + strcat (header_plus_data, data); + + FILE *test = fopen (new, "r"); + char buf[200]; + fflush (n); + fread (buf, strlen (header_plus_data), 1, test); + eputs ("buf="); eputs (buf); eputs ("\n"); + if (strcmp (buf, header_plus_data)) + return 1; + + if (access (temp, R_OK)) + return 22; + + unlink (temp); + + if (!access (temp, R_OK)) + return 3; + + unlink (new); + + return 0; +}