diff options
author | Jeff Johnston <jjohnstn@redhat.com> | 2002-02-13 00:01:27 +0000 |
---|---|---|
committer | Jeff Johnston <jjohnstn@redhat.com> | 2002-02-13 00:01:27 +0000 |
commit | 7b61d0c500080f19a0436371f9ac817d649b34e3 (patch) | |
tree | fc410bd06acc0ee5bcfa45f283e1b6d0f824993d | |
parent | 4753a17b28727225c610a611f94549d13b34b387 (diff) | |
download | newlib-7b61d0c500080f19a0436371f9ac817d649b34e3.zip newlib-7b61d0c500080f19a0436371f9ac817d649b34e3.tar.gz newlib-7b61d0c500080f19a0436371f9ac817d649b34e3.tar.bz2 |
2002-02-12 Hans-Peter Nilsson <hp@bitrange.com>
* libc/sys/mmixware/link.c: New.
* libc/sys/mmixware/sys/syscall.h (TRAP1i, I3f): Make asm
volatile.
* libc/sys/mmixware/times.c (_times): Renamed from times.
* libc/sys/mmixware/open.c (_open): Attempt to handle O_APPEND
properly by reading previous contents, not through BinaryReadWrite.
* libc/sys/mmixware/Makefile.am (lib_a_SOURCES): Add link.c
* libc/sys/mmixware/Makefile.in: Regenerate.
-rw-r--r-- | newlib/ChangeLog | 11 | ||||
-rw-r--r-- | newlib/libc/sys/mmixware/Makefile.am | 2 | ||||
-rw-r--r-- | newlib/libc/sys/mmixware/Makefile.in | 8 | ||||
-rw-r--r-- | newlib/libc/sys/mmixware/link.c | 25 | ||||
-rw-r--r-- | newlib/libc/sys/mmixware/open.c | 147 | ||||
-rw-r--r-- | newlib/libc/sys/mmixware/sys/syscall.h | 36 | ||||
-rw-r--r-- | newlib/libc/sys/mmixware/times.c | 4 |
7 files changed, 203 insertions, 30 deletions
diff --git a/newlib/ChangeLog b/newlib/ChangeLog index 16453f4..f837dda 100644 --- a/newlib/ChangeLog +++ b/newlib/ChangeLog @@ -1,3 +1,14 @@ +2002-02-12 Hans-Peter Nilsson <hp@bitrange.com> + + * libc/sys/mmixware/link.c: New. + * libc/sys/mmixware/sys/syscall.h (TRAP1i, I3f): Make asm + volatile. + * libc/sys/mmixware/times.c (_times): Renamed from times. + * libc/sys/mmixware/open.c (_open): Attempt to handle O_APPEND + properly by reading previous contents, not through BinaryReadWrite. + * libc/sys/mmixware/Makefile.am (lib_a_SOURCES): Add link.c + * libc/sys/mmixware/Makefile.in: Regenerate. + 2002-02-10 Corinna Vinschen <corinna@vinschen.de> * libc/include/grp.h: Don't declare group functions when compiling diff --git a/newlib/libc/sys/mmixware/Makefile.am b/newlib/libc/sys/mmixware/Makefile.am index 1e4ed31..054220f 100644 --- a/newlib/libc/sys/mmixware/Makefile.am +++ b/newlib/libc/sys/mmixware/Makefile.am @@ -8,7 +8,7 @@ noinst_LIBRARIES = lib.a lib_a_SOURCES = _exit.c access.c chmod.c chown.c close.c creat.c \ execv.c execve.c fork.c fstat.c getpid.c isatty.c \ - kill.c lseek.c open.c pipe.c read.c \ + kill.c link.c lseek.c open.c pipe.c read.c \ sbrk.c stat.c time.c unlink.c utime.c wait.c write.c \ times.c gettime.c setjmp.S diff --git a/newlib/libc/sys/mmixware/Makefile.in b/newlib/libc/sys/mmixware/Makefile.in index dbd0e66..a009d4e 100644 --- a/newlib/libc/sys/mmixware/Makefile.in +++ b/newlib/libc/sys/mmixware/Makefile.in @@ -86,7 +86,7 @@ noinst_LIBRARIES = lib.a lib_a_SOURCES = _exit.c access.c chmod.c chown.c close.c creat.c \ execv.c execve.c fork.c fstat.c getpid.c isatty.c \ - kill.c lseek.c open.c pipe.c read.c \ + kill.c link.c lseek.c open.c pipe.c read.c \ sbrk.c stat.c time.c unlink.c utime.c wait.c write.c \ times.c gettime.c setjmp.S @@ -104,9 +104,9 @@ CPPFLAGS = @CPPFLAGS@ LIBS = @LIBS@ lib_a_LIBADD = lib_a_OBJECTS = _exit.o access.o chmod.o chown.o close.o creat.o \ -execv.o execve.o fork.o fstat.o getpid.o isatty.o kill.o lseek.o open.o \ -pipe.o read.o sbrk.o stat.o time.o unlink.o utime.o wait.o write.o \ -times.o gettime.o setjmp.o +execv.o execve.o fork.o fstat.o getpid.o isatty.o kill.o link.o lseek.o \ +open.o pipe.o read.o sbrk.o stat.o time.o unlink.o utime.o wait.o \ +write.o times.o gettime.o setjmp.o CFLAGS = @CFLAGS@ COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) diff --git a/newlib/libc/sys/mmixware/link.c b/newlib/libc/sys/mmixware/link.c new file mode 100644 index 0000000..0629163 --- /dev/null +++ b/newlib/libc/sys/mmixware/link.c @@ -0,0 +1,25 @@ +/* link stub for MMIXware. + + Copyright (C) 2002 Hans-Peter Nilsson + + Permission to use, copy, modify, and distribute this software is + freely granted, provided that the above copyright notice, this notice + and the following disclaimer are preserved with no changes. + + THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE. */ + +#include <_ansi.h> +#include <sys/types.h> +#include <sys/stat.h> +#include "sys/syscall.h" +#include <errno.h> + +int +_link () +{ + errno = EMLINK; + return -1; +} diff --git a/newlib/libc/sys/mmixware/open.c b/newlib/libc/sys/mmixware/open.c index 26fbbb9..f0b9fba 100644 --- a/newlib/libc/sys/mmixware/open.c +++ b/newlib/libc/sys/mmixware/open.c @@ -1,6 +1,6 @@ /* open for MMIXware. - Copyright (C) 2001 Hans-Peter Nilsson + Copyright (C) 2001, 2002 Hans-Peter Nilsson Permission to use, copy, modify, and distribute this software is freely granted, provided that the above copyright notice, this notice @@ -11,6 +11,7 @@ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ +#include <stdlib.h> #include <fcntl.h> #include <_ansi.h> #include <sys/types.h> @@ -37,7 +38,9 @@ _open (const char *path, { long fileno; unsigned char mode; - long fffile = 0; + long append_contents = 0; + unsigned long prev_contents_size = 0; + char *prev_contents = NULL; long ret; for (fileno = 0; @@ -55,7 +58,7 @@ _open (const char *path, } /* We map this to a fopen call. The flags parameter is stymied because - we don't support more other than these flags. */ + we don't support other than these flags. */ if (flags & ~(O_RDONLY | O_WRONLY | O_RDWR | O_CREAT | O_APPEND | O_TRUNC)) { UNIMPLEMENTED (("path: %s, flags: %d", path, flags)); @@ -68,12 +71,12 @@ _open (const char *path, else if ((flags & (O_WRONLY | O_APPEND)) == (O_WRONLY | O_APPEND)) { mode = BinaryReadWrite; - fffile = 1; + append_contents = 1; } else if ((flags & (O_RDWR | O_APPEND)) == (O_RDWR | O_APPEND)) { mode = BinaryReadWrite; - fffile = 1; + append_contents = 1; } else if ((flags & (O_WRONLY | O_CREAT)) == (O_WRONLY | O_CREAT) || (flags & (O_WRONLY | O_TRUNC)) == (O_WRONLY | O_TRUNC)) @@ -88,6 +91,99 @@ _open (const char *path, return -1; } + if (append_contents) + { + /* BinaryReadWrite is equal to "w+", so it truncates the file rather + than keeping the contents, as can be imagined if you're looking + for append functionality. The only way we can keep the contents + so we can append to it, is by first reading in and saving the + contents, then re-opening the file as BinaryReadWrite and write + the previous contents. This seems to work for the needs of + simple test-programs. */ + long openexist = TRAP3f (SYS_Fopen, fileno, path, BinaryRead); + if (openexist == 0) + { + /* Yes, this file exists, now opened, so let's read it and keep + the contents. Better have the memory around for this to + work. */ + long seekval = TRAP2f (SYS_Fseek, fileno, -1); + + if (seekval == 0) + { + prev_contents_size = TRAP1f (SYS_Ftell, fileno); + + /* If the file has non-zero size, we have something to + append to. */ + if (prev_contents_size != 0) + { + /* Start reading from the beginning. Ignore the return + value from this call: we'll notice if we can't read + as much as we want. */ + TRAP2f (SYS_Fseek, fileno, 0); + + prev_contents = malloc (prev_contents_size); + if (prev_contents != 0) + { + /* I don't like the thought of trying to read the + whole file all at once, disregarding the size, + because the host system might not support that + and we'd get funky errors. Read in 32k at a + time. */ + char *ptr = prev_contents; + unsigned long read_more = prev_contents_size; + unsigned long chunk_size = 1 << 15; + + while (read_more >= chunk_size) + { + long readval + = TRAP3f (SYS_Fread, fileno, ptr, chunk_size); + + if (readval != 0) + { + free (prev_contents); + TRAP1f (SYS_Fclose, fileno); + errno = EIO; + return -1; + } + read_more -= chunk_size; + ptr += chunk_size; + } + + if (read_more != 0) + { + long readval + = TRAP3f (SYS_Fread, fileno, ptr, read_more); + if (readval != 0) + { + free (prev_contents); + TRAP1f (SYS_Fclose, fileno); + errno = EIO; + return -1; + } + } + } + else + { + /* Malloc of area to copy to failed. The glibc + manpage says its open can return ENOMEM due to + kernel memory failures, so let's do that too + here. */ + errno = ENOMEM; + return -1; + } + } + } + else + { + /* Seek failed. Gotta be some I/O error. */ + errno = EIO; + return -1; + } + + TRAP1f (SYS_Fclose, fileno); + } + } + ret = TRAP3f (SYS_Fopen, fileno, path, mode); if (ret < 0) { @@ -97,12 +193,45 @@ _open (const char *path, return -1; } - _MMIX_allocated_filehandle[fileno] = 1; - - if (fffile) + if (prev_contents_size != 0) { - TRAP2f (SYS_Fseek, fileno, -1); + /* Write out the previous contents, a chunk at a time. Leave the + file pointer at the end of the file. */ + unsigned long write_more = prev_contents_size; + unsigned long chunk_size = 1 << 15; + char *ptr = prev_contents; + + while (write_more >= chunk_size) + { + long writeval + = TRAP3f (SYS_Fwrite, fileno, ptr, chunk_size); + if (writeval != 0) + { + free (prev_contents); + TRAP1f (SYS_Fclose, fileno); + errno = EIO; + return -1; + } + write_more -= chunk_size; + ptr += chunk_size; + } + if (write_more != 0) + { + long writeval + = TRAP3f (SYS_Fwrite, fileno, ptr, write_more); + if (writeval != 0) + { + free (prev_contents); + TRAP1f (SYS_Fclose, fileno); + errno = EIO; + return -1; + } + } + + free (prev_contents); } + _MMIX_allocated_filehandle[fileno] = 1; + return fileno; } diff --git a/newlib/libc/sys/mmixware/sys/syscall.h b/newlib/libc/sys/mmixware/sys/syscall.h index c74a0ac..15a2d1c 100644 --- a/newlib/libc/sys/mmixware/sys/syscall.h +++ b/newlib/libc/sys/mmixware/sys/syscall.h @@ -1,6 +1,6 @@ /* syscall defines for MMIXware. - Copyright (C) 2001 Hans-Peter Nilsson + Copyright (C) 2001, 2002 Hans-Peter Nilsson Permission to use, copy, modify, and distribute this software is freely granted, provided that the above copyright notice, this notice @@ -46,22 +46,30 @@ extern unsigned char _MMIX_allocated_filehandle[N_MMIX_FILEHANDLES]; #define TMPFNO 127 /* Simulator call with one argument. Also used for zero-argument calls; - pass a zero as ARG1. */ -#define TRAP1i(FUN, ARG1) \ - ({ long ret_; \ - __asm__ ("TRAP 0,%1,%2\n\tSET %0,$255" \ - : "=r" (ret_) : "i" (FUN), "i" (ARG1) \ - : "memory"); \ - ret_; \ + pass a zero as ARG1. Make the asm volatile so we can safely ignore the + return-value and only get the benefit from the supposed side-effect + without the asm being optimized away. */ +#define TRAP1i(FUN, ARG1) \ + ({ long ret_; \ + __asm__ __volatile__ \ + ("TRAP 0,%1,%2\n\tSET %0,$255" \ + : "=r" (ret_) : "i" (FUN), "i" (ARG1) \ + : "memory"); \ + ret_; \ }) /* Helper macros to cope with the file-handle parameter to the simulator - being *constant*. We support up to 32 simultaneously open files. */ -#define I3f(FUN, ARG1, N, ARGS) \ - if (ARG1 == N) \ - __asm__ ("SET $255,%3\n\tTRAP 0,%1,%2\n\tSET %0,$255" \ - : "=r" (ret_) : "i" (FUN), "i" (N), "r" (ARGS) \ - : "memory") + being *constant*. We support up to 32 simultaneously open files. Make + the asm volatile so we can safely ignore the return-value and get the + benefit from the supposed side-effect without the asm being optimized + away. */ + +#define I3f(FUN, ARG1, N, ARGS) \ + if (ARG1 == N) \ + __asm__ __volatile__ \ + ("SET $255,%3\n\tTRAP 0,%1,%2\n\tSET %0,$255" \ + : "=r" (ret_) : "i" (FUN), "i" (N), "r" (ARGS) \ + : "memory") /* Using if:s rather than switches to help GCC optimize the rest away. */ #define DO32(FUN, ARG1, ARGS) \ diff --git a/newlib/libc/sys/mmixware/times.c b/newlib/libc/sys/mmixware/times.c index b397f2b..6275ef3 100644 --- a/newlib/libc/sys/mmixware/times.c +++ b/newlib/libc/sys/mmixware/times.c @@ -1,6 +1,6 @@ /* times stub for MMIXware. - Copyright (C) 2001 Hans-Peter Nilsson + Copyright (C) 2001, 2002 Hans-Peter Nilsson Permission to use, copy, modify, and distribute this software is freely granted, provided that the above copyright notice, this notice @@ -18,7 +18,7 @@ #include "sys/times.h" clock_t -times (struct tms *buffer) +_times (struct tms *buffer) { memset (buffer, 0, sizeof (*buffer)); return 0; |