mescc: Support glibc-1.06.4.

* lib/glibc.c: New file.
* lib/libc+gnu.c: Include it.
This commit is contained in:
Jan Nieuwenhuizen 2018-06-03 18:54:26 +02:00
parent de964f3e1f
commit 635dfd03a2
No known key found for this signature in database
GPG key ID: F3C1A0D9C1D65273
33 changed files with 648 additions and 822 deletions

View file

@ -42,12 +42,12 @@ install:
.config.make: ./configure .config.make: ./configure
seed: all-go seed: all-go
build-aux/build-mes-gcc.sh
cd $(TINYCC_SEED) && MES_PREFIX=$(PWD) ./refresh.sh
cd $(MES_SEED) && git reset --hard HEAD cd $(MES_SEED) && git reset --hard HEAD
MES=$(GUILE) GUILE=$(GUILE) SEED=1 build-aux/build-mes.sh MES=$(GUILE) GUILE=$(GUILE) SEED=1 build-aux/build-mes.sh
cd $(MES_SEED) && MES_PREFIX=$(PWD) ./refresh.sh cd $(MES_SEED) && MES_PREFIX=$(PWD) ./refresh.sh
MES=$(GUILE) GUILE=$(GUILE) SEED=1 build-aux/build-mes.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 define HELP_TOP
Usage: make [OPTION]... [TARGET]... Usage: make [OPTION]... [TARGET]...

View file

@ -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/libc
ARCHDIR=1 NOLINK=1 sh build-aux/cc-mes.sh lib/libgetopt 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+tcc
ARCHDIR=1 NOLINK=1 sh build-aux/cc-mes.sh lib/libc+gnu
[ -n "$SEED" ] && exit 0 [ -n "$SEED" ] && exit 0

View file

@ -136,13 +136,13 @@ t
87-sscanf 87-sscanf
90-strpbrk 90-strpbrk
91-fseek 91-fseek
92-stat
93-fread-fwrite
" "
# 90: needs GNU, fails for mescc, passes for tcc # 90: needs GNU, fails for mescc, passes for tcc
broken="$broken broken="$broken
7s-struct-short 7s-struct-short
90-strpbrk
91-fseek
" "
# gcc not supported # gcc not supported
@ -273,7 +273,7 @@ broken="$broken
#49_bracket_evaluation ; float #49_bracket_evaluation ; float
LIBC=c+gnu LIBC=c+gnu
MESCCLIBS="-l c+tcc" MESCCLIBS="-l c+gnu"
expect=$(echo $broken | wc -w) expect=$(echo $broken | wc -w)
ARGS="arg1 arg2 arg3 arg4 arg5" ARGS="arg1 arg2 arg3 arg4 arg5"

View file

@ -45,6 +45,12 @@ int errno;
#define ENOSYS 38 #define ENOSYS 38
#define ELOOP 40 #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 // ! WITH_GLIBC
#endif // __MES_ERRNO_H #endif // __MES_ERRNO_H

View file

@ -35,6 +35,7 @@
#define MB_CUR_MAX 1 #define MB_CUR_MAX 1
#define LONG_MIN -2147483648 #define LONG_MIN -2147483648
#define LONG_MAX 2147483647 #define LONG_MAX 2147483647
#define LONG_MAX _POSIX_OPEN_MAX 16
#endif // ! WITH_GLIBC #endif // ! WITH_GLIBC

View file

@ -38,8 +38,17 @@ typedef int pid_t;
typedef int uid_t; typedef int uid_t;
#endif #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; typedef int sigval_t;
#endif
#define NSIG 30 #define NSIG 30
#define SIGHUP 1 #define SIGHUP 1

View file

@ -65,18 +65,20 @@ int g_stdout;
#define L_tmpnam 100 #define L_tmpnam 100
#endif #endif
// Hmm #if !defined (__MES_FILE_T) && ! defined (_FILE_T)
#define stdin 0 #define __MES_FILE_T
#define stdout 1 #define _FILE_T
#define stderr 2 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_SET 0
#define SEEK_CUR 1 #define SEEK_CUR 1
#define SEEK_END 2 #define SEEK_END 2
typedef int FILE;
#ifndef __MES_SIZE_T #ifndef __MES_SIZE_T
#define __MES_SIZE_T #define __MES_SIZE_T
#undef size_t #undef size_t
@ -92,6 +94,7 @@ int feof (FILE *stream);
int ferror (FILE *stream); int ferror (FILE *stream);
int fflush (FILE *stream); int fflush (FILE *stream);
int fgetc (FILE* stream); int fgetc (FILE* stream);
char *fgets (char *s, int size, FILE *stream);
int fprintf (FILE *stream, char const *format, ...); int fprintf (FILE *stream, char const *format, ...);
int fpurge (FILE *stream); int fpurge (FILE *stream);
int fputc (int c, FILE *stream); int fputc (int c, FILE *stream);

View file

@ -60,6 +60,9 @@ int strncmp (char const*, char const*, size_t);
char *strrchr (char const *s, int c); char *strrchr (char const *s, int c);
char *strstr (char const *haystack, char const *needle); char *strstr (char const *haystack, char const *needle);
char *strerror (int errnum);
void perror (char const *message);
#endif // ! WITH_GLIBC #endif // ! WITH_GLIBC
#endif // __MES_STRING_H #endif // __MES_STRING_H

View file

@ -35,26 +35,24 @@ typedef int mode_t;
struct stat struct stat
{ {
unsigned long st_dev; /* Device. */ unsigned long st_dev;
unsigned long st_ino; /* File serial number. */ unsigned long st_ino;
unsigned int st_mode; /* File mode. */ unsigned short st_mode;
unsigned int st_nlink; /* Link count. */ unsigned short st_nlink;
unsigned int st_uid; /* User ID of the file's owner. */ unsigned short st_uid;
unsigned int st_gid; /* Group ID of the file's group. */ unsigned short st_gid;
unsigned long st_rdev; /* Device number, if device. */ unsigned long st_rdev;
unsigned long __pad1; long st_size;
long st_size; /* Size of file, in bytes. */ unsigned int st_blksize;
int st_blksize; /* Optimal block size for I/O. */ unsigned int st_blocks;
int __pad2; long st_atime;
long st_blocks; /* Number 512-byte blocks allocated. */ unsigned long st_atime_usec;
long st_atime; /* Time of last access. */ long st_mtime;
unsigned long st_atime_nsec; unsigned long st_mtime_usec;
long st_mtime; /* Time of last modification. */ long st_ctime;
unsigned long st_mtime_nsec; unsigned long st_ctime_usec;
long st_ctime; /* Time of last status change. */ unsigned int __foo0;
unsigned long st_ctime_nsec; unsigned int __foo1;
unsigned int __unused4;
unsigned int __unused5;
}; };
int chmod (char const *file_name, mode_t mode); int chmod (char const *file_name, mode_t mode);

View file

@ -32,6 +32,10 @@
typedef long clock_t; typedef long clock_t;
#endif #endif
#ifndef CLOCKS_PER_SEC
#define CLOCKS_PER_SEC 1000000
#endif
#ifndef HZ #ifndef HZ
#define HZ 100 #define HZ 100
#endif #endif

View file

@ -24,18 +24,22 @@
#undef __MES_TIME_H #undef __MES_TIME_H
#include_next <time.h> #include_next <time.h>
#else // ! WITH_GLIBC #else // ! WITH_GLIBC
#ifndef __MES_TIME_T
#define __MES_TIME_T 1
typedef int time_t; typedef int time_t;
#endif
struct tm { struct tm {
int tm_sec; /* Seconds (0-60) */ int tm_sec;
int tm_min; /* Minutes (0-59) */ int tm_min;
int tm_hour; /* Hours (0-23) */ int tm_hour;
int tm_mday; /* Day of the month (1-31) */ int tm_mday;
int tm_mon; /* Month (0-11) */ int tm_mon;
int tm_year; /* Year - 1900 */ int tm_year;
int tm_wday; /* Day of the week (0-6, Sunday = 0) */ int tm_wday;
int tm_yday; /* Day in the year (0-365, 1 Jan = 0) */ int tm_yday;
int tm_isdst; /* Daylight saving time */ int tm_isdst;
}; };
struct tm *localtime (time_t const *timep); struct tm *localtime (time_t const *timep);
@ -44,16 +48,8 @@ time_t time (time_t *tloc);
#ifndef __MES_STRUCT_TIMESPEC #ifndef __MES_STRUCT_TIMESPEC
#define __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 struct timespec
{ {
//__kernel_time_t tv_sec;
long tv_sec; long tv_sec;
long tv_nsec; long tv_nsec;
}; };

View file

@ -71,9 +71,9 @@ int fork ();
char *getcwd (char *buf, size_t size); char *getcwd (char *buf, size_t size);
int isatty (int fd); int isatty (int fd);
off_t lseek (int fd, off_t offset, int whence); 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 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 // ! WITH_GLIBC
#endif // __MES_UNISTD_H #endif // __MES_UNISTD_H

View file

@ -111,11 +111,10 @@ getuid (int x)
return 0; return 0;
} }
int void
perror (int x) perror (char const *message)
{ {
eputs ("perror stub\n"); fprintf (stderr, "%s: %s\n", strerror (errno), message);
return 0;
} }
void* void*
@ -160,7 +159,7 @@ strncat (char *to, char const *from, size_t size)
if (size == 0) if (size == 0)
return to; return to;
char *p = strchr (to , '\0'); char *p = strchr (to , '\0');
while (*from && size-- > 1) while (*from && size-- > 0)
*p++ = *from++; *p++ = *from++;
*p = 0; *p = 0;
return to; return to;

View file

@ -21,7 +21,7 @@
#include <libmes.h> #include <libmes.h>
#include <stdint.h> #include <stdint.h>
#include <time.h> #include <time.h>
#include <sys/time.h> #include <sys/times.h>
FILE * FILE *
freopen (char const *file_name, char const *opentype, FILE *stream) freopen (char const *file_name, char const *opentype, FILE *stream)

32
lib/glibc.c Normal file
View file

@ -0,0 +1,32 @@
/* -*-comment-start: "//";comment-end:""-*-
* Mes --- Maxwell Equations of Software
* Copyright © 2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
*
* 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 <http://www.gnu.org/licenses/>.
*/
int
__cleanup ()
{
eputs ("__cleanup stub\n");
return 0;
}
int
__exit (int status)
{
exit (status);
}

View file

@ -18,9 +18,9 @@
* along with Mes. If not, see <http://www.gnu.org/licenses/>. * along with Mes. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <sys/time.h>
#include <libc+tcc.c> #include <libc+tcc.c>
#include <linux+gnu-gcc.c> #include <linux+gnu.c>
#include <m4.c> #include <m4.c>
#include <binutils.c> #include <binutils.c>
#include <gcc.c> #include <gcc.c>
#include <glibc.c>

View file

@ -35,15 +35,14 @@
#include <unistd.h> #include <unistd.h>
#include <libc.c> #include <libc.c>
#include <linux+tcc.c>
#if __MESC__ #if __MESC__
#include <linux+tcc-mes.c>
#include <libc+tcc-mes.c> #include <libc+tcc-mes.c>
#else // !__MESC__ #else // !__MESC__
#include <linux+tcc-gcc.c>
#include <libc+tcc-gcc.c> #include <libc+tcc-gcc.c>
#endif // !__MESC__ #endif // !__MESC__
@ -143,7 +142,7 @@ ferror (FILE *stream)
int int
fflush (FILE *stream) fflush (FILE *stream)
{ {
return 0; fsync ((int)stream);
} }
int int
@ -189,22 +188,19 @@ FILE*
fopen (char const *file_name, char const *opentype) fopen (char const *file_name, char const *opentype)
{ {
int fd; int fd;
if (opentype[0] == 'a') int mode = 0600;
if (opentype[0] == 'a' && !access (file_name, O_RDONLY))
{ {
fd = open (file_name, O_RDONLY); fd = open (file_name, O_RDWR, mode);
if (fd > 0) lseek (fd, 0, SEEK_END);
{ }
close (fd); else if (opentype[0] == 'w' || opentype[0] == 'a')
fd = open (file_name, O_RDWR); {
lseek (fd, 0, SEEK_END); char *plus_p = strchr (opentype, '+');
return fd; 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 else
/* Everything else is a read */
fd = open (file_name, 0, 0); fd = open (file_name, 0, 0);
return (FILE*)fd; return (FILE*)fd;

View file

@ -24,6 +24,14 @@
typedef unsigned long size_t; typedef unsigned long size_t;
#endif #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 size_t
strlen (char const* s) strlen (char const* s)
{ {

View file

@ -43,6 +43,7 @@
#include <libc-mini.c> #include <libc-mini.c>
#include <libmes.c> #include <libmes.c>
#include <linux.c>
int g_stdin = 0; int g_stdin = 0;

View file

@ -29,6 +29,7 @@
#define malloc _malloc #define malloc _malloc
#define printf _printf #define printf _printf
#define putchar _putchar #define putchar _putchar
#define puts _puts
#define setjmp _setjmp #define setjmp _setjmp
#define signal _signal #define signal _signal
#define strcmp _strcmp #define strcmp _strcmp
@ -36,7 +37,7 @@
#define sscanf _sscanf #define sscanf _sscanf
#include <libc+tcc.c> #include <libc+tcc.c>
#include <linux+gnu-gcc.c> #include <linux+gnu.c>
#include <m4.c> #include <m4.c>
#include <binutils.c> #include <binutils.c>
#include <gcc.c> #include <gcc.c>
@ -44,53 +45,6 @@
int int
__cleanup () __cleanup ()
{ {
eputs ("cleanup stub\n"); eputs ("__cleanup stub\n");
return 0; 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");
}

View file

@ -1,179 +0,0 @@
/* -*-comment-start: "//";comment-end:""-*-
* Mes --- Maxwell Equations of Software
* Copyright © 2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#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
}

84
lib/linux+gnu.c Normal file
View file

@ -0,0 +1,84 @@
/* -*-comment-start: "//";comment-end:""-*-
* Mes --- Maxwell Equations of Software
* Copyright © 2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#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);
}

View file

@ -1,140 +0,0 @@
/* -*-comment-start: "//";comment-end:""-*-
* Mes --- Maxwell Equations of Software
* Copyright © 2016,2017,2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#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
}

View file

@ -1,6 +1,6 @@
/* -*-comment-start: "//";comment-end:""-*- /* -*-comment-start: "//";comment-end:""-*-
* Mes --- Maxwell Equations of Software * Mes --- Maxwell Equations of Software
* Copyright © 2017 Jan (janneke) Nieuwenhuizen <janneke@gnu.org> * Copyright © 2016,2017,2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
* *
* This file is part of Mes. * This file is part of Mes.
* *
@ -18,62 +18,45 @@
* along with Mes. If not, see <http://www.gnu.org/licenses/>. * along with Mes. If not, see <http://www.gnu.org/licenses/>.
*/ */
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 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"); off_t
asm ("int____$0x80"); lseek (int filedes, off_t offset, int whence)
{
return _sys_call3 (SYS_lseek, (int)filedes, (int)offset, (int)whence);
} }
int int
unlink (char const *file_name) unlink (char const *file_name)
{ {
asm ("mov____0x8(%ebp),%ebx !8"); return _sys_call1 (SYS_unlink, (int)file_name);
asm ("mov____$i32,%eax SYS_unlink");
asm ("int____$0x80");
} }
int int
rmdir (char const *file_name) rmdir (char const *file_name)
{ {
asm ("mov____0x8(%ebp),%ebx !8"); return _sys_call1 (SYS_rmdir, (int)file_name);
asm ("mov____$i32,%eax SYS_rmdir");
asm ("int____$0x80");
} }
int int
stat (char const *file_name, struct stat *statbuf) stat (char const *file_name, struct stat *statbuf)
{ {
asm ("mov____0x8(%ebp),%ebx !8"); return _sys_call2 (SYS_stat, (int)file_name, (int)statbuf);
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");
} }
char * char *
getcwd (char *buf, size_t size) getcwd (char *buffer, size_t size)
{ {
asm ("mov____0x8(%ebp),%ebx !8"); return _sys_call2 (SYS_getcwd, (int)buffer, (int)size);
asm ("mov____0x8(%ebp),%ecx !12");
asm ("mov____$i32,%eax SYS_getcwd");
asm ("int____$0x80");
} }

View file

@ -19,25 +19,45 @@
*/ */
#include <errno.h> #include <errno.h>
#include <stdio.h>
#include <libmes.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/wait.h>
#define SYS_fork "0x02" int
#define SYS_read "0x03" _sys_call (int sys_call)
#define SYS_open "0x05" {
#define SYS_waitpid "0x07" #if !__TINYC__
#define SYS_execve 0x0b int r;
#define SYS_chmod "0x0f" asm (
#define SYS_access "0x21" "mov %1,%%eax\n\t"
#define SYS_brk "0x2d" "int $0x80\n\t"
#define SYS_ioctl "0x36" "mov %%eax,%0\n\t"
#define SYS_fsync "0x76" : "=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 int
_sys_call2 (int sys_call, int one, int two) _sys_call2 (int sys_call, int one, int two)
@ -45,10 +65,9 @@ _sys_call2 (int sys_call, int one, int two)
#if !__TINYC__ #if !__TINYC__
int r; int r;
asm ( asm (
"mov %1,%%eax\n\t"
"mov %2,%%ebx\n\t" "mov %2,%%ebx\n\t"
"mov %3,%%ecx\n\t" "mov %3,%%ecx\n\t"
"mov %1,%%eax\n\t"
"int $0x80\n\t" "int $0x80\n\t"
"mov %%eax,%0\n\t" "mov %%eax,%0\n\t"
: "=r" (r) : "=r" (r)
@ -70,10 +89,8 @@ _sys_call3 (int sys_call, int one, int two, int three)
"mov %2,%%ebx\n\t" "mov %2,%%ebx\n\t"
"mov %3,%%ecx\n\t" "mov %3,%%ecx\n\t"
"mov %4,%%edx\n\t" "mov %4,%%edx\n\t"
"mov %1,%%eax\n\t" "mov %1,%%eax\n\t"
"int $0x80\n\t" "int $0x80\n\t"
"mov %%eax,%0\n\t" "mov %%eax,%0\n\t"
: "=r" (r) : "=r" (r)
: "" (sys_call), "" (one), "" (two), "" (three) : "" (sys_call), "" (one), "" (two), "" (three)
@ -84,211 +101,3 @@ _sys_call3 (int sys_call, int one, int two, int three)
return r; return r;
#endif #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
}

View file

@ -18,102 +18,38 @@
* along with Mes. If not, see <http://www.gnu.org/licenses/>. * along with Mes. If not, see <http://www.gnu.org/licenses/>.
*/ */
void #include <errno.h>
fork ()
int
_sys_call (int sys_call)
{ {
asm ("mov____$i32,%eax SYS_fork"); asm ("mov____0x8(%ebp),%eax !8");
asm ("int____$0x80"); asm ("int____$0x80");
} }
void int
read () _sys_call1 (int sys_call, int one)
{ {
asm ("mov____0x8(%ebp),%ebx !8"); asm ("mov____0x8(%ebp),%eax !8");
asm ("mov____0x8(%ebp),%ecx !12"); asm ("mov____0x8(%ebp),%ebx !12");
asm ("mov____0x8(%ebp),%edx !16");
asm ("mov____$i32,%eax SYS_read");
asm ("int____$0x80"); asm ("int____$0x80");
} }
void int
open () _sys_call2 (int sys_call, int one, int two)
{ {
asm ("mov____0x8(%ebp),%ebx !8"); asm ("mov____0x8(%ebp),%eax !8");
asm ("mov____0x8(%ebp),%ecx !12"); asm ("mov____0x8(%ebp),%ebx !12");
asm ("mov____0x8(%ebp),%edx !16"); asm ("mov____0x8(%ebp),%ecx !16");
asm ("mov____$i32,%eax SYS_open");
asm ("int____$0x80"); asm ("int____$0x80");
} }
void int
waitpid () _sys_call3 (int sys_call, int one, int two, int three)
{ {
asm ("mov____0x8(%ebp),%ebx !8"); asm ("mov____0x8(%ebp),%eax !8");
asm ("mov____0x8(%ebp),%ecx !12"); asm ("mov____0x8(%ebp),%ebx !12");
asm ("mov____0x8(%ebp),%edx !16"); asm ("mov____0x8(%ebp),%ecx !16");
asm ("mov____0x8(%ebp),%edx !20");
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 ("int____$0x80"); asm ("int____$0x80");
} }

View file

@ -26,17 +26,16 @@ exit (int code)
{ {
#if !__TINYC__ #if !__TINYC__
asm ( asm (
"mov $"SYS_exit",%%eax\n\t"
"mov %0,%%ebx\n\t" "mov %0,%%ebx\n\t"
"mov $1,%%eax\n\t"
"int $0x80\n\t" "int $0x80\n\t"
: // no outputs "=" (r) : // no outputs "=" (r)
: "" (code) : "" (code)
); );
#else // __TINYC__ #else // __TINYC__
asm ( asm (
"mov %0,%%ebx\n\t"
"mov $"SYS_exit",%%eax\n\t" "mov $"SYS_exit",%%eax\n\t"
"mov %0,%%ebx\n\t"
"int $128\n\t" "int $128\n\t"
: // no outputs "=" (r) : // no outputs "=" (r)
: "Ir" (code) : "Ir" (code)
@ -46,34 +45,32 @@ exit (int code)
exit (0); exit (0);
} }
int ssize_t
write (int fd, char const* s, int n) write (int filedes, void const *buffer, size_t size)
{ {
int r; int r;
#if __GNUC__ #if __GNUC__
asm ( asm (
"mov $"SYS_write",%%eax\n\t"
"mov %1,%%ebx\n\t" "mov %1,%%ebx\n\t"
"mov %2,%%ecx\n\t" "mov %2,%%ecx\n\t"
"mov %3,%%edx\n\t" "mov %3,%%edx\n\t"
"mov $0x04,%%eax\n\t"
"int $0x80\n\t" "int $0x80\n\t"
"mov %%eax,%0\n\t" "mov %%eax,%0\n\t"
: "=r" (r) : "=r" (r)
: "" (fd), "" (s), "" (n) : "" (filedes), "" (buffer), "" (size)
: "eax", "ebx", "ecx", "edx" : "eax", "ebx", "ecx", "edx"
); );
#elif __TINYC__ #elif __TINYC__
asm ( asm (
"mov $"SYS_write",%%eax\n\t"
"mov %1,%%ebx\n\t" "mov %1,%%ebx\n\t"
"mov %2,%%ecx\n\t" "mov %2,%%ecx\n\t"
"mov %3,%%edx\n\t" "mov %3,%%edx\n\t"
"mov $"SYS_write",%%eax\n\t"
"int $128\n\t" "int $128\n\t"
"mov %%eax,%0\n\t" "mov %%eax,%0\n\t"
: "=r" (r) : "=r" (r)
: "Ir" (fd), "Ir" (s), "Ir" (n) : "Ir" (filedes), "Ir" (buffer), "Ir" (size)
: "eax", "ebx", "ecx"//, "edx" : "eax", "ebx", "ecx"//, "edx"
); );
#endif #endif

View file

@ -21,19 +21,17 @@
void void
exit () exit ()
{ {
asm ("mov____0x8(%ebp),%ebx !8");
asm ("mov____$i32,%eax SYS_exit"); asm ("mov____$i32,%eax SYS_exit");
asm ("mov____0x8(%ebp),%ebx !8");
asm ("int____$0x80"); asm ("int____$0x80");
} }
void void
write () write ()
{ {
asm ("mov____$i32,%eax SYS_write");
asm ("mov____0x8(%ebp),%ebx !8"); asm ("mov____0x8(%ebp),%ebx !8");
asm ("mov____0x8(%ebp),%ecx !12"); asm ("mov____0x8(%ebp),%ecx !12");
asm ("mov____0x8(%ebp),%edx !16"); asm ("mov____0x8(%ebp),%edx !16");
asm ("mov____$i32,%eax SYS_write");
asm ("int____$0x80"); asm ("int____$0x80");
} }

108
lib/linux.c Normal file
View file

@ -0,0 +1,108 @@
/* -*-comment-start: "//";comment-end:""-*-
* Mes --- Maxwell Equations of Software
* Copyright © 2016,2017,2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#include <stdarg.h>
#include <stdio.h>
#include <libmes.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/wait.h>
#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);
}

View file

@ -167,23 +167,64 @@ signal (int x)
return 0; 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 int
system (int x) system (int x)
{ {
eputs ("system stub\n"); eputs ("system stub\n");
return 0; 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";
}

View file

@ -229,5 +229,6 @@ DEFINE SYS_lseek 13000000
DEFINE SYS_access 21000000 DEFINE SYS_access 21000000
DEFINE SYS_brk 2d000000 DEFINE SYS_brk 2d000000
DEFINE SYS_ioctl 36000000 DEFINE SYS_ioctl 36000000
DEFINE SYS_stat 6a000000
DEFINE SYS_fsync 76000000 DEFINE SYS_fsync 76000000
DEFINE SYS_getcwd b7000000 DEFINE SYS_getcwd b7000000

100
scaffold/tests/92-stat.c Normal file
View file

@ -0,0 +1,100 @@
/* -*-comment-start: "//";comment-end:""-*-
* Mes --- Maxwell Equations of Software
* Copyright © 2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#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;
}

View file

@ -0,0 +1,77 @@
/* -*-comment-start: "//";comment-end:""-*-
* Mes --- Maxwell Equations of Software
* Copyright © 2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#include <libmes.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
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 = "!<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;
}