
// natFileChannelImplPosix.cc - Native part of FileChannelImpl class.

/* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004  Free Software Foundation

   This file is part of libgcj.

This software is copyrighted work licensed under the terms of the
Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
details.  */

#include <config.h>
#include <platform.h>

#include <gcj/cni.h>
#include <gcj/javaprims.h>
#include <jvm.h>

#include "posix.h"

#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/param.h>

#include <gnu/gcj/RawData.h>
#include <gnu/java/nio/FileLockImpl.h>
#include <gnu/java/nio/channels/FileChannelImpl.h>
#include <java/io/FileNotFoundException.h>
#include <java/io/IOException.h>
#include <java/io/SyncFailedException.h>
#include <java/io/InterruptedIOException.h>
#include <java/io/EOFException.h>
#include <java/lang/ArrayIndexOutOfBoundsException.h>
#include <java/lang/NullPointerException.h>
#include <java/lang/System.h>
#include <java/lang/String.h>
#include <java/lang/Thread.h>
#include <java/nio/ByteBuffer.h>
#include <java/nio/MappedByteBufferImpl.h>
#include <java/nio/channels/FileChannel.h>
#include <java/nio/channels/FileLock.h>
#include <gnu/java/nio/channels/FileChannelImpl.h>

#ifdef HAVE_SYS_IOCTL_H
#define BSD_COMP /* Get FIONREAD on Solaris2. */
#include <sys/ioctl.h>
#endif

// Pick up FIONREAD on Solaris 2.5.
#ifdef HAVE_SYS_FILIO_H
#include <sys/filio.h>
#endif

#ifdef HAVE_MMAP
#include <sys/mman.h>

// Use overload resolution to find out the argument types.
// E.g. Solaris 2.6 uses different argument types for munmap and msync.
// This is in case _POSIX_C_SOURCES is smaller than 3.

template <typename T_implPtr, typename T_implLen>
static inline int
munmap_adaptor(int (*munmap)(T_implPtr caddr, T_implLen sizet),
		 void* caddr, size_t sizet)
{
  return munmap ((T_implPtr) caddr, (T_implLen) sizet);
}

template <typename T_implPtr, typename T_implLen, typename T_msync>
static inline int
msync_adaptor(int (*msync)(T_implPtr caddr, T_implLen sizet, T_msync msynct),
	      void* caddr, size_t sizet, int msynct)
{
  return msync ((T_implPtr) caddr, (T_implLen) sizet, (T_msync) msynct);
}
#endif

using gnu::gcj::RawData;
using java::io::IOException;
using java::nio::MappedByteBufferImpl;
using java::io::InterruptedIOException;
using java::io::FileNotFoundException;
using java::lang::ArrayIndexOutOfBoundsException;
using gnu::java::nio::channels::FileChannelImpl;

#define NO_FSYNC_MESSAGE "sync unsupported"

void
FileChannelImpl::init(void)
{
  in = new FileChannelImpl((jint) 0, FileChannelImpl::READ);
  out = new FileChannelImpl((jint) 1, FileChannelImpl::WRITE);
  err = new FileChannelImpl((jint) 2, FileChannelImpl::WRITE);
}

#if 0
jboolean
FileChannelImpl::valid (void)
{
  struct stat sb;
  return fd >= 0 && ::fstat (fd, &sb) == 0;
}

void
FileChannelImpl::sync (void)
{
  // Some files don't support fsync.  We don't bother reporting these
  // as errors.
#ifdef HAVE_FSYNC
  if (::fsync (fd) && errno != EROFS && errno != EINVAL)
    throw new SyncFailedException (JvNewStringLatin1 (strerror (errno)));
#else
  throw new SyncFailedException (JvNewStringLatin1 (NO_FSYNC_MESSAGE));
#endif
}
#endif

jint
FileChannelImpl::open (jstring path, jint jflags)
{
  fd = -1;
  char *buf = (char *) _Jv_AllocBytes (_Jv_GetStringUTFLength (path) + 1);
  jsize total = JvGetStringUTFRegion (path, 0, path->length(), buf);
  buf[total] = '\0';
  int flags = 0;
#ifdef O_BINARY
  flags |= O_BINARY;
#endif

  JvAssert ((jflags & READ) || (jflags & WRITE));
  int mode = 0666;
  if ((jflags & READ) && (jflags & WRITE))
    flags |= O_RDWR | O_CREAT;
  else if ((jflags & READ))
    flags |= O_RDONLY;
  else
    {
      flags |= O_WRONLY | O_CREAT;
      if ((jflags & APPEND))
	flags |= O_APPEND;
      else
	flags |= O_TRUNC;

      if ((jflags & EXCL))
	{
	  flags |= O_EXCL;
	  // In this case we are making a temp file.
	  mode = 0600;
	}
    }

  if ((jflags & SYNC))
    flags |= O_SYNC;

  if ((jflags & DSYNC))
    flags |= O_DSYNC;

  int fd = ::open (buf, flags, mode);
  if (fd == -1 && errno == EMFILE)
    {
      // Because finalize () calls close () we might be able to continue.
      ::java::lang::System::gc ();
      ::java::lang::System::runFinalization ();
      fd = ::open (buf, flags, mode);
    }
  if (fd == -1)
    {
      char msg[MAXPATHLEN + 200];
      // We choose the formatting here for JDK compatibility, believe
      // it or not.
      sprintf (msg, "%.*s (%.*s)",
	       MAXPATHLEN + 150, buf,
	       40, strerror (errno));
      throw new ::java::io::FileNotFoundException (JvNewStringLatin1 (msg));
    }

  _Jv_platform_close_on_exec (fd);

  return fd;
}

void
FileChannelImpl::write (jint b)
{
  jbyte d = (jbyte) b;
  int r = 0;
  while (r != 1)
    {
      r = ::write (fd, &d, 1);
      if (r == -1)
        {
	  if (::java::lang::Thread::interrupted())
	    {
	      ::java::io::InterruptedIOException *iioe
		= new ::java::io::InterruptedIOException (JvNewStringLatin1 (strerror (errno)));
	      iioe->bytesTransferred = r == -1 ? 0 : r;
	      throw iioe;
	    }	    
	  if (errno != EINTR)
	    throw new IOException (JvNewStringLatin1 (strerror (errno)));
	}
    }
  pos++;
}

void
FileChannelImpl::write (jbyteArray b, jint offset, jint len)
{
  if (! b)
    throw new ::java::lang::NullPointerException;
  if (offset < 0 || len < 0 || offset + len > JvGetArrayLength (b))
    throw new ArrayIndexOutOfBoundsException;
  jbyte *bytes = elements (b) + offset;

  int written = 0;
  while (len > 0)
    {
      int r = ::write (fd, bytes, len);
      if (r == -1)
        {
	  if (::java::lang::Thread::interrupted())
	    {
	      InterruptedIOException *iioe
		= new InterruptedIOException (JvNewStringLatin1 (strerror (errno)));
	      iioe->bytesTransferred = written;
	      throw iioe;
	    }
	  if (errno != EINTR)
	    throw new IOException (JvNewStringLatin1 (strerror (errno)));
	}

      written += r;
      len -= r;
      bytes += r;
      pos += r;
    }
}

void
FileChannelImpl::implCloseChannel (void)
{
  jint save = fd;
  fd = -1;
  if (::close (save))
    throw new IOException (JvNewStringLatin1 (strerror (errno)));
}

void
FileChannelImpl::implTruncate (jlong size)
{
  struct stat sb;

#ifdef HAVE_FTRUNCATE
  if (::fstat (fd, &sb))
    throw new IOException (JvNewStringLatin1 (strerror (errno)));

  if ((jlong) sb.st_size == size) 
    return;

  // If the file is too short, we extend it.  We can't rely on
  // ftruncate() extending the file.  So we lseek() to 1 byte less
  // than we want, and then we write a single byte at the end.
  if ((jlong) sb.st_size < size)
    {
      if (::lseek (fd, (off_t) (size - 1), SEEK_SET) == -1)
	throw new IOException (JvNewStringLatin1 (strerror (errno)));
      char out = '\0';
      int r = ::write (fd, &out, 1);
      if (r <= 0 || ::lseek (fd, pos, SEEK_SET) == -1)
	throw new IOException (JvNewStringLatin1 (strerror (errno)));
    }
  else
    {
      if (::ftruncate (fd, (off_t) size))
	throw new IOException (JvNewStringLatin1 (strerror (errno)));
      if (pos > size
	  && ::lseek (fd, (off_t) size, SEEK_SET) == -1)
	throw new IOException (JvNewStringLatin1 (strerror (errno)));
      pos = size;
    }
#else /* HAVE_FTRUNCATE */
  throw new IOException (JvNewStringLatin1 ("FileDescriptor.setLength not implemented"));
#endif /* HAVE_FTRUNCATE */
}

void
FileChannelImpl::seek (jlong newPos)
{
  off_t r = ::lseek (fd, (off_t) newPos, SEEK_SET);
  if (r == -1)
    throw new IOException (JvNewStringLatin1 (strerror (errno)));
  pos = r;
}

jlong
FileChannelImpl::size (void)
{
  struct stat sb;
  if (::fstat (fd, &sb))
    throw new IOException (JvNewStringLatin1 (strerror (errno)));
  return sb.st_size;
}

jlong
FileChannelImpl::implPosition (void)
{
  return pos;
}

jint
FileChannelImpl::read (void)
{
  jbyte b;
  int r;
  do
    {
      r = ::read (fd, &b, 1);
      if (r == 0)
	return -1;
      if (r == -1)
	{
	  if (::java::lang::Thread::interrupted())
	    {
	      InterruptedIOException *iioe
		= new InterruptedIOException (JvNewStringLatin1 (strerror (errno)));
	      iioe->bytesTransferred = r == -1 ? 0 : r;
	      throw iioe;
	    }
	  if (errno != EINTR)
	    throw new IOException (JvNewStringLatin1 (strerror (errno)));
	}
    }
  while (r != 1);
  pos++;
  return b & 0xFF;
}

jint
FileChannelImpl::read (jbyteArray buffer, jint offset, jint count)
{
  if (! buffer)
    throw new ::java::lang::NullPointerException;
  jsize bsize = JvGetArrayLength (buffer);
  if (offset < 0 || count < 0 || offset + count > bsize)
    throw new ::java::lang::ArrayIndexOutOfBoundsException;

  // Must return 0 if an attempt is made to read 0 bytes.
  if (count == 0)
    return 0;

  jbyte *bytes = elements (buffer) + offset;
  int r;
  do
    {
      r = ::read (fd, bytes, count);
      if (r == 0)
	return -1;
      if (r == -1)
	{
	  if (::java::lang::Thread::interrupted())
	    {
	      InterruptedIOException *iioe
		= new InterruptedIOException (JvNewStringLatin1 (strerror (errno)));
	      iioe->bytesTransferred = r == -1 ? 0 : r;
	      throw iioe;
	    }
	  if (errno != EINTR)
	    throw new IOException (JvNewStringLatin1 (strerror (errno)));
	}
    }
  while (r <= 0);
  pos += r;
  return r;
}

jint
FileChannelImpl::available (void)
{
#if defined (FIONREAD) || defined (HAVE_SELECT) || defined (HAVE_FSTAT)
  int num = 0;
  int r = 0;
  bool num_set = false;

#if defined (FIONREAD)
  r = ::ioctl (fd, FIONREAD, &num);
  if (r == -1 && errno == ENOTTY)
    {
      // If the ioctl doesn't work, we don't care.
      r = 0;
      num = 0;
    }
  else
    num_set = true;
#elif defined (HAVE_SELECT)
  if (fd < 0)
    {
      errno = EBADF;
      r = -1;
    }
#endif

  if (r == -1)
    {
    posix_error:
      throw new IOException (JvNewStringLatin1 (strerror (errno)));
    }

  // If we didn't get anything, and we have fstat, then see if see if
  // we're reading a regular file.  On many systems, FIONREAD does not
  // work on regular files; select() likewise returns a useless
  // result.  This is run incorrectly when FIONREAD does work on
  // regular files and we are at the end of the file.  However, this
  // case probably isn't very important.
#if defined (HAVE_FSTAT)
  if (! num_set)
    {
      struct stat sb;
      off_t where = 0;
      if (fstat (fd, &sb) != -1
	  && S_ISREG (sb.st_mode)
	  && (where = lseek (fd, 0, SEEK_CUR)) != (off_t) -1)
	{
	  num = (int) (sb.st_size - where);
	  num_set = true;
	}
    }
#endif /* HAVE_FSTAT */

#if defined (HAVE_SELECT)
  if (! num_set)
    {
      fd_set rd;
      FD_ZERO (&rd);
      FD_SET (fd, &rd);
      struct timeval tv;
      tv.tv_sec = 0;
      tv.tv_usec = 0;
      r = _Jv_select (fd + 1, &rd, NULL, NULL, &tv);
      if (r == -1)
	goto posix_error;
      num = r == 0 ? 0 : 1;
    }
#endif /* HAVE_SELECT */

  return (jint) num;
#else
  return 0;
#endif
}

jboolean
FileChannelImpl::lock
(jlong pos, jlong len, jboolean shared, jboolean wait)
{
  struct flock lockdata;

  lockdata.l_type = shared ? F_RDLCK : F_WRLCK;
  lockdata.l_whence = SEEK_SET;
  lockdata.l_start = pos;
  lockdata.l_len = len;

  if (::fcntl (fd, wait ? F_SETLKW : F_SETLK, &lockdata) == -1)
    {
      if (! wait && (errno == EACCES || errno == EAGAIN))
	return false;
      throw new IOException (JvNewStringLatin1 (strerror (errno)));
    }
  return true;
}

void
FileChannelImpl::unlock (jlong pos, jlong len)
{
  struct flock lockdata;

  lockdata.l_type = F_UNLCK;
  lockdata.l_whence = SEEK_SET;
  lockdata.l_start = pos;
  lockdata.l_len = len;

  if (::fcntl (fd, F_SETLK, &lockdata) == -1)
    throw new IOException (JvNewStringLatin1 (strerror (errno)));
}

java::nio::MappedByteBuffer *
FileChannelImpl::mapImpl (jchar mmode, jlong position, jint size)
{
#if defined(HAVE_MMAP)
  int prot, flags;
  if (mmode == 'r')
    {
      prot = PROT_READ;
      flags = MAP_PRIVATE;
    }
  else
    {
      prot = PROT_READ|PROT_WRITE;
      flags = mmode == '+' ? MAP_SHARED : MAP_PRIVATE;
    }
  jint page_size = ::getpagesize();
  jint offset = position & ~(page_size-1);
  jint align = position - offset;
  void* ptr = ::mmap(NULL, size + align, prot, flags, fd, offset);
  MappedByteBufferImpl *buf
    = new MappedByteBufferImpl ((RawData *) ((char *) ptr + align),
				size, mmode == 'r');
  if (ptr == (void *) MAP_FAILED)
    throw new IOException (JvNewStringLatin1 (strerror (errno)));
  buf->implPtr = reinterpret_cast<RawData*> (ptr);
  buf->implLen = size+align;
  return buf;
#else
  throw new IOException (JvNewStringUTF ("mmap not implemented"));
#endif
}

void
MappedByteBufferImpl::unmapImpl ()
{
#if defined(HAVE_MMAP)
  munmap_adaptor(munmap, implPtr, implLen);
#endif
}

void
MappedByteBufferImpl::loadImpl ()
{
}

jboolean
MappedByteBufferImpl::isLoadedImpl ()
{
  return true;
}

void
MappedByteBufferImpl::forceImpl ()
{
#if defined(HAVE_MMAP)
  ::msync_adaptor(msync, implPtr, implLen, MS_SYNC);
#endif
}
