/*
 * $Header: /p/sss/cvs/OpenVM/src/native/common/sigiomanager.c,v 1.4 2003/10/17 01:34:11 dholmes Exp $
 * sigiomanager.c -- implementation of SIGIO code
 * by Filip Pizlo, 2003
 */

#include "sigiomanager.h"
#include "eventmanager.h"
#include "signalmanager.h"

#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <signal.h>
#include <errno.h>
#include <stdio.h>

static volatile sig_atomic_t triggered=0;

static void sigIOHandler(jint sig,siginfo_t *info) {
    //write(1,"SIGIO!\n",strlen("SIGIO!\n"));
    triggered=1;
    SIGNAL_EVENT();
}

static int fcntlSetFlag(int fd,int flag) {
	int flags=fcntl(fd,F_GETFL,0);
	if (flags<0) {
		return -1;
	}
	return fcntl(fd,F_SETFL,flags|flag);
}

static int fcntlResetFlag(int fd,int flag) {
	int flags=fcntl(fd,F_GETFL,0);
	if (flags<0) {
		return -1;
	}
	return fcntl(fd,F_SETFL,flags&(~flag));
}

jint enableIOSignalManager() {
    if (registerSignalHandler(SIGIO,sigIOHandler)<0) {
        return errno;
    }
    
    if (registerSignalHandler(SIGURG,sigIOHandler)<0) {
        removeSignalHandler(sigIOHandler);
        return errno;
    }
    
    return 0;
}

jint disableIOSignalManager() {
    removeSignalHandler(sigIOHandler);
    return 0;
}

jint enableIOSignal(jint fd) {
    if (fcntlSetFlag(fd, O_ASYNC)<0) {
        printf("enableIOSignal: error setting O_ASYNC flag on %d: %s\n",
               fd, strerror(errno));
        return errno;
    }
/*     printf("enableIOSignal: getpid() == %d\n", getpid()); */
    if (fcntl(fd, F_SETOWN, getpid())<0) {
        printf("enableIOSignal: error fcntl(%d, F_SETOWN, %d): %s\n",fd, getpid(), strerror(errno));
        return errno;
    }
    return 0;
}

jint disableIOSignal(jint fd) {
    if (fcntlResetFlag(fd, O_ASYNC)<0) {
        return errno;
    }
    return 0;
}

jint getKnownSignaledFDs(void *fds) {
    if (triggered) {
        triggered=0;
        //printf("getKnownSignaledFDs: -1\n");
        return -1;
    }
    //printf("getKnownSignaledFDs: 0\n");
    return 0;
    //return -1;
}



