
struct fddescriptor { int fd; };

typedef struct fddescriptor Classjava_io_FileDescriptor;

int sysSocketInitializeFD(Classjava_io_FileDescriptor *fdptr, int infd);
long sysSocketAvailableFD(Classjava_io_FileDescriptor *fdobj, long *pbytes);
int sysTimeoutFD(Classjava_io_FileDescriptor *fdobj, long timeout);    
int sysConnectFD(Classjava_io_FileDescriptor *fdobj, 
		 struct sockaddr *him, int len);
int sysListenFD(Classjava_io_FileDescriptor *fdobj, long count);
int sysAcceptFD(Classjava_io_FileDescriptor *fdobj, 
		struct sockaddr *him, int *len);
int sysCloseFD(Classjava_io_FileDescriptor *fdobj);
int sysRecvFD(Classjava_io_FileDescriptor *fdobj, char *buf, int nbytes, 
	      int flags);
int sysSendFD(Classjava_io_FileDescriptor *fdobj, char *buf, int nbytes, 
	      int flags);
ssize_t sysSendtoFD(Classjava_io_FileDescriptor *fdobj, char *buf, int len, 
		    int flags, struct sockaddr *to, int tolen);
ssize_t sysRecvfromFD(Classjava_io_FileDescriptor *fdobj, char *buf, 
		      int nbytes, int flags, 
		      struct sockaddr *from, int *fromlen);

int JVM_InitializeSocketLibrary(){ 
  return 0;
}

int JVM_SendTo(int fd, char *buffer, int bufferlen, int opt, struct sockaddr *in, int inlen) {
  Classjava_io_FileDescriptor file_descriptor; 
  file_descriptor.fd = fd;

  return sysSendtoFD(&file_descriptor, buffer, bufferlen, opt,
		     in, inlen);
}

int JVM_Timeout(int fd, int timeout) {
  Classjava_io_FileDescriptor file_descriptor; 
  file_descriptor.fd = fd;
  
  return sysTimeoutFD(&file_descriptor, timeout);
}

int JVM_RecvFrom(int fd, char *buffer, int bufferLen, int opt, struct sockaddr *in, int *inlen) {
  Classjava_io_FileDescriptor file_descriptor; 
  file_descriptor.fd = fd;

  return sysRecvfromFD(&file_descriptor, buffer, bufferLen, opt,
		     in, inlen);
}

int JVM_Socket(int family, int type, int opt) {
  Classjava_io_FileDescriptor file_descriptor; 
  int sd;
  file_descriptor.fd = 0;
 
  if ((sd = socket(family, type, opt)) != -1) {
    if (sysSocketInitializeFD(&file_descriptor, sd) == -1) {
	return -1; // Check "the return value"
    }
  }
  
  return sd+1;
}

int JVM_Close(int fd) {
    Classjava_io_FileDescriptor file_descriptor; 
    file_descriptor.fd = fd;

    return sysCloseFD(&file_descriptor);  
}

int JVM_Read(int fd, char *buffer, int len) {
  Classjava_io_FileDescriptor file_descriptor; 
  file_descriptor.fd = fd;
 
  return sysRecvFD(&file_descriptor, buffer, len, 0);
}

int JVM_Send(int fd, char *buffer, int len, int opt) {
  Classjava_io_FileDescriptor file_descriptor; 
  file_descriptor.fd = fd;
 
  return sysSendFD(&file_descriptor, buffer, len, opt);
} 

int JVM_Connect(int fd, struct sockaddr *in, int inlen) {
  Classjava_io_FileDescriptor file_descriptor; 
  file_descriptor.fd = fd;

  return sysConnectFD(&file_descriptor, in, inlen);
}

int JVM_Listen(int fd, int aux) {
  Classjava_io_FileDescriptor file_descriptor; 
  file_descriptor.fd = fd;

  return sysListenFD(&file_descriptor, aux);
}

int JVM_Accept(int fd, struct sockaddr *in, jint *inlen) {
  Classjava_io_FileDescriptor file_descriptor; 
  int sd;
  file_descriptor.fd = fd;

  sd = sysAcceptFD(&file_descriptor, in, (int *)inlen);
  
  file_descriptor.fd = 0;

  if (sysSocketInitializeFD(&file_descriptor, sd) == -1) {
    return -1; // Check "the return value"
  }
  
  return sd+1;
}

int JVM_SocketAvailable(int fd, jint *count) {
  Classjava_io_FileDescriptor file_descriptor; 
  file_descriptor.fd = fd;

  return sysSocketAvailableFD(&file_descriptor, count);
}

int JVM_SocketClose(int fd) {
   Classjava_io_FileDescriptor file_descriptor; 
    file_descriptor.fd = fd;

    return sysCloseFD(&file_descriptor);  
}
