aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff Johnston <jjohnstn@redhat.com>2002-02-13 00:01:27 +0000
committerJeff Johnston <jjohnstn@redhat.com>2002-02-13 00:01:27 +0000
commit7b61d0c500080f19a0436371f9ac817d649b34e3 (patch)
treefc410bd06acc0ee5bcfa45f283e1b6d0f824993d
parent4753a17b28727225c610a611f94549d13b34b387 (diff)
downloadnewlib-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/ChangeLog11
-rw-r--r--newlib/libc/sys/mmixware/Makefile.am2
-rw-r--r--newlib/libc/sys/mmixware/Makefile.in8
-rw-r--r--newlib/libc/sys/mmixware/link.c25
-rw-r--r--newlib/libc/sys/mmixware/open.c147
-rw-r--r--newlib/libc/sys/mmixware/sys/syscall.h36
-rw-r--r--newlib/libc/sys/mmixware/times.c4
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;