Milán Major

netscape-revival

1 branch
Code

sun-java/runtime/io.c

/*
 * @(#)io.c	1.42 95/11/15
 *
 * Copyright (c) 1994 Sun Microsystems, Inc. All Rights Reserved.
 *
 * Permission to use, copy, modify, and distribute this software
 * and its documentation for NON-COMMERCIAL purposes and without
 * fee is hereby granted provided that this copyright notice
 * appears in all copies. Please refer to the file "copyright.html"
 * for further important copyright and licensing information.
 *
 * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF
 * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
 * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR
 * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
 * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
 */

#include "oobj.h"
#include "interpreter.h"
#include "javaString.h"
#include "fd_md.h"

#include "java_io_FileDescriptor.h"
#include "java_io_FileInputStream.h"
#include "java_io_FileOutputStream.h"
#include "java_io_RandomAccessFile.h"
#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>

#define IO_EXCEPTION "java/io/IOException"


/**************************************************************
 * File Descriptor
 */

struct Hjava_io_FileDescriptor *
java_io_FileDescriptor_initSystemFD(struct Hjava_io_FileDescriptor *this, 
struct Hjava_io_FileDescriptor *fdObj, long fd){

  Classjava_io_FileDescriptor *fdptr = unhand(fdObj);
  if (fdptr == 0) {
    SignalError(0, JAVAPKG "NullPointerException", "null FileDescriptor");
    return 0;
  }

  sysInitFD(fdptr, (int) fd);
  return fdObj;
}

/* To start with we will have this routine in shared code; if needed
it can be moved to system specific io_md.c */
long java_io_FileDescriptor_valid(struct Hjava_io_FileDescriptor *fdObj) {
  Classjava_io_FileDescriptor *fdptr = unhand(fdObj);
  if (fdptr == 0) {
    SignalError(0, JAVAPKG "NullPointerException", "null FileDescriptor");
    return 0;
  }
  return (fdptr->fd)>0;
}

/**************************************************************
 * Input stream
 */

void
java_io_FileInputStream_open(Hjava_io_FileInputStream *this, HString *name)
{
    Classjava_io_FileInputStream *thisptr = unhand(this);
    Classjava_io_FileDescriptor *fdptr = unhand(thisptr->fd);
    char buf[MAXPATHLEN];
    int fd, flags;

    if (fdptr == 0) {
	SignalError(0, JAVAPKG "NullPointerException", "null FileDescriptor");
	return;
    }

    if (name == 0) {
	SignalError(0, JAVAPKG "NullPointerException", 0);
	return;
    }

    javaString2CString(name, buf, sizeof(buf));

    flags = O_RDONLY;
    if ((fd = sysOpenFD(fdptr, buf, flags, 0)) == -1) {
	SignalError(0, IO_EXCEPTION, buf);
	return;
    }
}

long
java_io_FileInputStream_read(Hjava_io_FileInputStream *this)
{
    Classjava_io_FileInputStream *thisptr = unhand(this);
    Classjava_io_FileDescriptor *fdptr = unhand(thisptr->fd);

    unsigned char buf[1];
    int	    cnt;

    if (fdptr == 0) {
	SignalError(0, JAVAPKG "NullPointerException", "null FileDescriptor");
	return 0;
    }

    if ((cnt = sysReadFD(fdptr, (char *) buf, 1)) != 1) {
	if (cnt == 0) {
	    return -1;	    /* EOF */
	}
	if (errno != EINTR)
	    SignalError(0, IO_EXCEPTION, "read error");
    }
    return buf[0];
}

long
java_io_FileInputStream_readBytes(Hjava_io_FileInputStream *this, HArrayOfByte *data, long off, long len)
{
    Classjava_io_FileInputStream *thisptr = unhand(this);
    Classjava_io_FileDescriptor *fdptr = unhand(thisptr->fd);
    char *dataptr;
    uint32_t datalen, n;

    if (fdptr == 0) {
	SignalError(0, JAVAPKG "NullPointerException", "null FileDescriptor");
	return 0;
    }

    if (data == 0) {
	SignalError(0, JAVAPKG "NullPointerException", 0);
	return 0;
    }

    dataptr = unhand(data)->body;
    datalen = obj_length(data);

    if ((off < 0) || ((uint32_t)off > datalen)) {
	SignalError(0, JAVAPKG "ArrayIndexOutOfBoundsException", 0);
	return -1;
    }
    if ((uint32_t)off + len > datalen) {
	len = datalen - off;
    }
    if (len <= 0) {
	return 0;
    }

    n = sysReadFD(fdptr, dataptr + off, len);
    if (n == -1) {
	SignalError(0, IO_EXCEPTION, "read error");
    }

    /* AVH: this is bogus but it stops the pointer from being gc'd */
    if (dataptr == 0) {
	SignalError(0, JAVAPKG "NullPointerException", 0);
    }
    return (n == 0) ? -1 : n;
}

int64_t
java_io_FileInputStream_skip(Hjava_io_FileInputStream *this, int64_t n) 
{
    Classjava_io_FileInputStream *thisptr = unhand(this);
    Classjava_io_FileDescriptor *fdptr = unhand(thisptr->fd);
    off_t cur = 0, end = 0;

     if (fdptr == 0) {
	SignalError(0, JAVAPKG "NullPointerException", "null FileDescriptor");
	return ll_zero_const;
    }

    if ((cur = sysLseekFD(fdptr, 0L, SEEK_CUR)) == -1) {
	SignalError(0, IO_EXCEPTION, 0);
    } else if ((end = sysLseekFD(fdptr, ll2int(n), SEEK_CUR)) == -1) {
	SignalError(0, IO_EXCEPTION, 0);
    }
    return int2ll(end - cur);
}

long
java_io_FileInputStream_available(Hjava_io_FileInputStream *this)
{
    Classjava_io_FileInputStream *thisptr = unhand(this);
    Classjava_io_FileDescriptor *fdptr = unhand(thisptr->fd);
    long bytes;

     if (fdptr == 0) {
	SignalError(0, JAVAPKG "NullPointerException", "null FileDescriptor");
	return 0;
    }

    if (sysAvailableFD(fdptr, &bytes)) {
	return bytes;
    }
    SignalError(0, IO_EXCEPTION, 0);
    return 0;
}

void
java_io_FileInputStream_close(Hjava_io_FileInputStream *this) 
{
    Classjava_io_FileInputStream *thisptr = unhand(this);
    Classjava_io_FileDescriptor *fdptr = unhand(thisptr->fd);

    if (fdptr == 0) {
	SignalError(0, JAVAPKG "NullPointerException", "null FileDescriptor");
	return;
    }

    sysCloseFD(fdptr);
}

/**************************************************************
 * Output stream
 */

void
java_io_FileOutputStream_open(Hjava_io_FileOutputStream *this, HString *name)
{
    Classjava_io_FileOutputStream *thisptr = unhand(this);
    Classjava_io_FileDescriptor *fdptr = unhand(thisptr->fd);
    char buf[MAXPATHLEN];
    int fd, flags;

    if (fdptr == 0) {
	SignalError(0, JAVAPKG "NullPointerException", "null FileDescriptor");
	return;
    }

    if (name == 0) {
	SignalError(0, JAVAPKG "NullPointerException", 0);
	return;
    }

    javaString2CString(name, buf, sizeof(buf));

    flags = O_WRONLY|O_CREAT|O_TRUNC;
    if ((fd = sysOpenFD(fdptr, buf, flags, 0664)) == -1) {
	SignalError(0, IO_EXCEPTION, buf);
	return;
    }
}

void
java_io_FileOutputStream_write(Hjava_io_FileOutputStream *this, long c) 
{
    Classjava_io_FileOutputStream *thisptr = unhand(this);
    Classjava_io_FileDescriptor *fdptr = unhand(thisptr->fd);
    char buf[1];

    if (fdptr == 0) {
	SignalError(0, JAVAPKG "NullPointerException", "null FileDescriptor");
	return;
    }

    buf[0] = (char) c;
    if (sysWriteFD(fdptr, buf, 1) != 1) {
	SignalError(0, IO_EXCEPTION, "write error");
    }
}

void
java_io_FileOutputStream_writeBytes(Hjava_io_FileOutputStream *this, HArrayOfByte *data, long off, long len) 
{
    Classjava_io_FileOutputStream *thisptr = unhand(this);
    Classjava_io_FileDescriptor *fdptr = unhand(thisptr->fd);
    char *dataptr;
    uint32_t datalen, n;

    if (fdptr == 0) {
	SignalError(0, JAVAPKG "NullPointerException", "null FileDescriptor");
	return;
    }

    if (data == 0) {
	SignalError(0, JAVAPKG "NullPointerException", 0);
	return;
    }
    datalen = obj_length(data);
    dataptr = unhand(data)->body;
    if ((off < 0) || (len < 0) || ((uint32_t)off + len > datalen)) {
	SignalError(0, JAVAPKG "ArrayIndexOutOfBoundsException", 0);
	return;
    }
    while (len > 0) {
	n = sysWriteFD(fdptr, dataptr + off, len);
	if (n == -1) {
	    SignalError(0, IO_EXCEPTION, "write error");
	    break;
	}
        off += n;
	len -= n;
    }
}

void
java_io_FileOutputStream_close(Hjava_io_FileOutputStream *this) 
{
    Classjava_io_FileOutputStream *thisptr = unhand(this);
    Classjava_io_FileDescriptor *fdptr = unhand(thisptr->fd);

    if (fdptr == 0) {
	SignalError(0, JAVAPKG "NullPointerException", "null FileDescriptor");
	return;
    }

    sysCloseFD(fdptr);
}

/**************************************************************
 * RandomAccessFile
 */

void
java_io_RandomAccessFile_open(Hjava_io_RandomAccessFile *this, HString *name,
			     long writeable)
{
    Classjava_io_RandomAccessFile *thisptr = unhand(this);
    Classjava_io_FileDescriptor *fdptr = unhand(thisptr->fd);
    char buf[MAXPATHLEN];
    int fd;

    if (fdptr == 0) {
	SignalError(0, JAVAPKG "NullPointerException", "null FileDescriptor");
	return;
    }

    if (name == 0) {
	SignalError(0, JAVAPKG "NullPointerException", 0);
	return;
    }

    javaString2CString(name, buf, sizeof(buf));

    if (writeable) {
	if ((fd = sysOpenFD(fdptr, buf, O_RDWR|O_CREAT, 0664)) == -1) {
	    SignalError(0, IO_EXCEPTION, buf);
	    return;
	}
    }
    else {
	if ((fd = sysOpenFD(fdptr, buf, O_RDONLY, 0)) == -1) {
	    SignalError(0, IO_EXCEPTION, buf);
	    return;
	}
    }
}


long
java_io_RandomAccessFile_read(Hjava_io_RandomAccessFile *this)
{
    Classjava_io_RandomAccessFile *thisptr = unhand(this);
    Classjava_io_FileDescriptor *fdptr = unhand(thisptr->fd);
    unsigned char buf[1];
    int	    cnt;

    if (fdptr == 0) {
	SignalError(0, JAVAPKG "NullPointerException", "null FileDescriptor");
	return 0;
    }

    if ((cnt = sysReadFD(fdptr, (char *) buf, 1)) != 1) {
	if (cnt == 0) {
	    return -1;	    /* EOF */
	}
	SignalError(0, IO_EXCEPTION, "read error");
    }
    return buf[0];
}

long
java_io_RandomAccessFile_readBytes(Hjava_io_RandomAccessFile *this, HArrayOfByte *data, long off, long len)
{
    Classjava_io_RandomAccessFile *thisptr = unhand(this);
    Classjava_io_FileDescriptor *fdptr = unhand(thisptr->fd);
    char *dataptr;
    uint32_t datalen, n;

    if (fdptr == 0) {
	SignalError(0, JAVAPKG "NullPointerException", "null FileDescriptor");
	return 0;
    }

    if (data == 0) {
	SignalError(0, JAVAPKG "NullPointerException", 0);
	return 0;
    }
    datalen = obj_length(data);
    dataptr = unhand(data)->body;

    if ((off < 0) || ((uint32_t)off > datalen)) {
	SignalError(0, JAVAPKG "ArrayIndexOutOfBoundsException", 0);
	return -1;
    }
    if ((uint32_t)off + len > datalen) {
	len = datalen - off;
    }
    if (len <= 0) {
	return 0;
    }

    n = sysReadFD(fdptr, dataptr + off, len);
    if (n == -1) {
	SignalError(0, IO_EXCEPTION, "read error");
    }
    /* AVH: this is bogus but it stops the pointer from being gc'd */
    if (dataptr == 0) {
	SignalError(0, JAVAPKG "NullPointerException", 0);
    }
    return n;
}


void
java_io_RandomAccessFile_write(Hjava_io_RandomAccessFile *this, long c) 
{
    Classjava_io_RandomAccessFile *thisptr = unhand(this);
    Classjava_io_FileDescriptor *fdptr = unhand(thisptr->fd);
    char buf[1];

    if (fdptr == 0) {
	SignalError(0, JAVAPKG "NullPointerException", "null FileDescriptor");
	return;
    }

    buf[0] = (char) c;
    if (sysWriteFD(fdptr, buf, 1) != 1) {
	SignalError(0, IO_EXCEPTION, "write error");
    }
}

void
java_io_RandomAccessFile_writeBytes(Hjava_io_RandomAccessFile *this, HArrayOfByte *data, long off, long len) 
{
    Classjava_io_RandomAccessFile *thisptr = unhand(this);
    Classjava_io_FileDescriptor *fdptr = unhand(thisptr->fd);
    char *dataptr;
    uint32_t datalen, n;

    if (fdptr == 0) {
	SignalError(0, JAVAPKG "NullPointerException", "null FileDescriptor");
	return;
    }

    if (data == 0) {
	SignalError(0, JAVAPKG "NullPointerException", 0);
	return;
    }
    datalen = obj_length(data);
    dataptr = unhand(data)->body;

    if ((off < 0) || (len < 0) || ((uint32_t)off + len > datalen)) {
	SignalError(0, JAVAPKG "ArrayIndexOutOfBoundsException", 0);
	return;
    }

    while (len > 0) {
	n = sysWriteFD(fdptr, dataptr + off, len);
	if (n == -1) {
	    SignalError(0, IO_EXCEPTION, "write error");
	    break;
	}
        off += n;
	len -= n;
    }
}


int64_t
java_io_RandomAccessFile_getFilePointer(Hjava_io_RandomAccessFile *this)
{
    Classjava_io_RandomAccessFile *fileptr = unhand(this);
    Classjava_io_FileDescriptor *thisptr = unhand(fileptr->fd);
    off_t cur = 0;

    if ((cur = sysLseekFD(thisptr, 0L, SEEK_CUR)) == -1) {
	SignalError(0, IO_EXCEPTION, 0);
    }
    return int2ll(cur);
}


void
java_io_RandomAccessFile_seek(Hjava_io_RandomAccessFile *this, int64_t pos) 
{
    Classjava_io_RandomAccessFile *fileptr = unhand(this);
    Classjava_io_FileDescriptor *thisptr = unhand(fileptr->fd);

    if (sysLseekFD(thisptr, ll2int(pos), SEEK_SET) == -1) {
	SignalError(0, IO_EXCEPTION, 0);
    }
}

int64_t
java_io_RandomAccessFile_length(Hjava_io_RandomAccessFile *this)
{
    Classjava_io_RandomAccessFile *fileptr = unhand(this);
    Classjava_io_FileDescriptor *thisptr = unhand(fileptr->fd);
    
    off_t cur = 0, end = 0;

    if ((cur = sysLseekFD(thisptr, 0L, SEEK_CUR)) == -1) {
	SignalError(0, IO_EXCEPTION, 0);
    } else if ((end = sysLseekFD(thisptr, 0L, SEEK_END)) == -1) {
	SignalError(0, IO_EXCEPTION, 0);
    } else if (sysLseekFD(thisptr, cur, SEEK_SET) == -1) {
	SignalError(0, IO_EXCEPTION, 0);
    } 
    return int2ll(end);
}

void
java_io_RandomAccessFile_close(Hjava_io_RandomAccessFile *this) 
{
    Classjava_io_RandomAccessFile *thisptr = unhand(this);
    Classjava_io_FileDescriptor *fdptr = unhand(thisptr->fd);

    if (fdptr == 0) {
	SignalError(0, JAVAPKG "NullPointerException", "null FileDescriptor");
	return;
    }

    sysCloseFD(fdptr);
}