/* -*- Mode: C; c-file-style: "gnu" -*-
   fd.c -- native methods pertaining to java.io.FileDescriptor
   Created: Chris Toshok <toshok@hungry.com>, 14-Aug-1997
 */
/*
  This file is part of Japhar, the GNU Virtual Machine for Java Bytecodes.
  Japhar is a project of The Hungry Programmers, GNU, and OryxSoft.

  Copyright (C) 1997, 1998, 1999 The Hungry Programmers

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Library General Public
  License as published by the Free Software Foundation; either
  version 2 of the License, or (at your option) any later version.

  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Library General Public License for more details.

  You should have received a copy of the GNU Library General Public
  License along with this library; if not, write to the Free Software
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "jniint.h"
#include <errno.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_SYS_FCNTL_H
#include <sys/fcntl.h>
#else
# ifdef HAVE_FCNTL_H
# include <fcntl.h>
# endif
#endif
static int
get_fd(JNIEnv *env,
       jobject fd_obj)
{
  jfieldID fd_field;
  jclass cls = (*env)->GetObjectClass(env, fd_obj);

  fd_field = (*env)->GetFieldID(env, cls, "fd", "I");

  return (*env)->GetIntField(env, fd_obj, fd_field);
}

/* JDK 1.2 */
JNIEXPORT void JNICALL
Java_java_io_FileDescriptor_initIDs(JNIEnv *env,
				    jclass cls)
{
}

/* JDK1.1 */
JNIEXPORT jboolean JNICALL
Java_java_io_FileDescriptor_valid(JNIEnv *env,
				  jobject obj)
{
  int fd = get_fd(env, obj);

  return (fd != -1);
}

JNIEXPORT void JNICALL
Java_java_io_FileDescriptor_sync(JNIEnv *env,
				 jobject obj)
{
#ifdef HAVE_FSYNC
  int fd = get_fd(env, obj);

  if ( -1 != fd && 0 != fsync(fd) )
      {
	HungryEnv *henv = HVM_ThreadGetEnv();
	HVM_ExceptionThrow(henv, "java/io/SyncFailedException",
			"fsync() failed: %s", strerror(errno));
      }
#else
  HungryEnv *henv = HVM_ThreadGetEnv();
  HVM_ExceptionThrow(henv, "java/io/SyncFailedException",
		  "fsync() unimplemented");
#endif
}

/* JDK1.1 */
JNIEXPORT jobject JNICALL
Java_java_io_FileDescriptor_initSystemFD(JNIEnv *env,
					 jclass cls,
					 jobject fd_obj,
					 jint desc)
{
  jfieldID fd;

  fd = (*env)->GetFieldID(env, cls, "fd", "I");

  /* we need to set all the system fd's to non blocking. */
  /* toshok - actually, we do want them blocking, since the thread
     library is the one that's supposed to take care of blocking
     threads instead of process.  We're not supposed to care about this. */
  /*fcntl(desc, F_SETFL, O_NONBLOCK);*/

  (*env)->SetIntField(env, fd_obj, fd, desc);

  return fd_obj;
}
