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.
This commit is contained in:
parent
4753a17b28
commit
7b61d0c500
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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) \
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue