diff options
Diffstat (limited to 'newlib/libc/sys/mmixware/open.c')
-rw-r--r-- | newlib/libc/sys/mmixware/open.c | 237 |
1 files changed, 0 insertions, 237 deletions
diff --git a/newlib/libc/sys/mmixware/open.c b/newlib/libc/sys/mmixware/open.c deleted file mode 100644 index f0b9fbafe..000000000 --- a/newlib/libc/sys/mmixware/open.c +++ /dev/null @@ -1,237 +0,0 @@ -/* open for MMIXware. - - 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 - 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 <stdlib.h> -#include <fcntl.h> -#include <_ansi.h> -#include <sys/types.h> -#include <sys/stat.h> -#include "sys/syscall.h" -#include <errno.h> - -/* Let's keep the filehandle array here, since this is a primary - initializer of it. */ -unsigned char _MMIX_allocated_filehandle[32] = - { - 1, - 1, - 1, - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0 - }; - -int -_open (const char *path, - int flags, ...) -{ - long fileno; - unsigned char mode; - long append_contents = 0; - unsigned long prev_contents_size = 0; - char *prev_contents = NULL; - long ret; - - for (fileno = 0; - fileno < (sizeof (_MMIX_allocated_filehandle) / - sizeof (_MMIX_allocated_filehandle[0])); - fileno++) - if (_MMIX_allocated_filehandle[fileno] == 0) - break; - - if (fileno == (sizeof (_MMIX_allocated_filehandle) / - sizeof (_MMIX_allocated_filehandle[0]))) - { - errno = EMFILE; - return -1; - } - - /* We map this to a fopen call. The flags parameter is stymied because - 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)); - errno = ENOSYS; - return -1; - } - - if ((flags & O_ACCMODE) == O_RDONLY) - mode = BinaryRead; - else if ((flags & (O_WRONLY | O_APPEND)) == (O_WRONLY | O_APPEND)) - { - mode = BinaryReadWrite; - append_contents = 1; - } - else if ((flags & (O_RDWR | O_APPEND)) == (O_RDWR | O_APPEND)) - { - mode = BinaryReadWrite; - append_contents = 1; - } - else if ((flags & (O_WRONLY | O_CREAT)) == (O_WRONLY | O_CREAT) - || (flags & (O_WRONLY | O_TRUNC)) == (O_WRONLY | O_TRUNC)) - mode = BinaryWrite; - else if ((flags & (O_RDWR | O_CREAT)) == (O_RDWR | O_CREAT)) - mode = BinaryReadWrite; - else if (flags & O_RDWR) - mode = BinaryReadWrite; - else - { - errno = EINVAL; - 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) - { - /* It's totally unknown what the error was. We'll just take our - chances and assume ENOENT. */ - errno = ENOENT; - return -1; - } - - if (prev_contents_size != 0) - { - /* 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; -} |