예제 #1
0
Val   _lib7_P_ProcEnv_getgroups   (Task* task,  Val arg)   {
    //=========================
    //
    // Mythryl type:  Void -> List(Int)
    //
    // Return supplementary group access list ids.
    //
    // This fn gets bound as   get_group_ids   in:
    //
    //     src/lib/std/src/posix-1003.1b/posix-id.pkg


    gid gidset[ NGROUPS_MAX ];

    Val	result;

    int ngrps =  getgroups( NGROUPS_MAX, gidset );

    if (ngrps != -1) {
	//
	result = mkList (task, ngrps, gidset);

    } else {

	gid* gp;

	// If the error was not due to too small buffer size,
	// raise exception.
	//
	if (errno != EINVAL)   return RAISE_SYSERR(task, -1);

        // Find out how many groups there
        // are and allocate enough space:
        //
	ngrps = getgroups( 0, gidset );
	//
	gp = (gid*) MALLOC( ngrps * (sizeof (gid)) );
	//
	if (gp == 0) {
	    errno = ENOMEM;
	    return RAISE_SYSERR(task, -1);
	}

	ngrps = getgroups (ngrps, gp);

	if (ngrps == -1)   result = RAISE_SYSERR(task, -1);
	else		   result = mkList (task, ngrps, gp);
        
	FREE ((void *)gp);
    }

    return result;
}
예제 #2
0
파일: waitpid.c 프로젝트: xyproto/smlnj
/* _ml_P_Process_waitpid : int * word -> int * int * int
 *
 * Wait for child processes to stop or terminate
 */
ml_val_t _ml_P_Process_waitpid (ml_state_t *msp, ml_val_t arg)
{
    int       pid;
    int       status, how, val;
    ml_val_t  r;

    pid = waitpid(REC_SELINT(arg, 0), &status, REC_SELWORD(arg, 1));
    if (pid < 0)
	return RAISE_SYSERR(msp, pid);

    if (WIFEXITED(status)) {
	how = 0;
	val = WEXITSTATUS(status);
    }
    else if (WIFSIGNALED(status)) {
	how = 1;
	val = WTERMSIG(status);
    }
    else if (WIFSTOPPED(status)) {
	how = 2;
	val = WSTOPSIG(status);
    }
    else
	return RAISE_ERROR(msp, "unknown child status");

    REC_ALLOC3(msp, r, INT_CtoML(pid), INT_CtoML(how), INT_CtoML(val));

    return r;

} /* end of _ml_P_Process_waitpid */
예제 #3
0
/* _lib7_Sock_recvbuffrom
 *   : (socket * rw_unt8_vector.Rw_Vector * int * int * Bool * Bool) -> (int * addr)
 *
 * The arguments are: socket, data buffer, start position, number of
 * bytes, OOB flag and peek flag.  The result is number of bytes read and
 * the source address.
 *
 * This function gets imported into the Mythryl world via:
 *     src/lib/std/src/socket/socket-guts.pkg
 */
lib7_val_t _lib7_Sock_recvbuffrom (lib7_state_t *lib7_state, lib7_val_t arg)
{
    char	addrBuf[MAX_SOCK_ADDR_SZB];
    int		addrLen = MAX_SOCK_ADDR_SZB;
    int		socket = REC_SELINT(arg, 0);
    lib7_val_t	buf = REC_SEL(arg, 1);
    int		nbytes = REC_SELINT(arg, 3);
    char	*start = STR_LIB7toC(buf) + REC_SELINT(arg, 2);
    int		flag = 0;
    int		n;

    if (REC_SEL(arg, 4) == LIB7_true) flag |= MSG_OOB;
    if (REC_SEL(arg, 5) == LIB7_true) flag |= MSG_PEEK;

/*  do { */	/* Backed out 2010-02-26 CrT: See discussion at bottom of src/runtime/c-libs/lib7-socket/connect.c	*/

        n = recvfrom (socket, start, nbytes, flag, (struct sockaddr *)addrBuf, &addrLen);

/*  } while (n < 0 && errno == EINTR);	*/	/* Restart if interrupted by a SIGALRM or SIGCHLD or whatever.	*/

    if (n < 0)
        return RAISE_SYSERR(lib7_state, status);
    else {
	lib7_val_t	data = LIB7_CData (lib7_state, addrBuf, addrLen);
	lib7_val_t	addr, res;

	SEQHDR_ALLOC (lib7_state, addr, DESC_word8vec, data, addrLen);
	REC_ALLOC2(lib7_state, res, INT_CtoLib7(n), addr);
	return res;
    }

} /* end of _lib7_Sock_recvbuffrom */
예제 #4
0
Val   _lib7_P_SysDB_getgrnam   (Task* task,  Val arg)   {
    //======================
    //
    // Mythryl type:   String -> (String, Unt, List(String))
    //
    // Get group file entry by name.
    //
    // This fn gets bound as   getgrname'   in:
    //
    //     src/lib/std/src/posix-1003.1b/posix-etc.pkg


    struct group*  info =  getgrnam( HEAP_STRING_AS_C_STRING( arg ));

    if (info == NULL)   return RAISE_SYSERR(task, -1);
  
    Val  gr_name =  make_ascii_string_from_c_string( task, info->gr_name );

    Val               gr_gid;
    WORD_ALLOC (task, gr_gid, (Val_Sized_Unt)(info->gr_gid));

    Val gr_mem =  make_ascii_strings_from_vector_of_c_strings( task, info->gr_mem );

    Val              result;
    REC_ALLOC3(task, result, gr_name, gr_gid, gr_mem);
    return           result;
}
예제 #5
0
파일: getNREAD.c 프로젝트: jes5199/mythryl
/* _lib7_Sock_getNREAD : socket -> int
 *
 * This function gets imported into the Mythryl world via:
 *     src/lib/std/src/socket/socket-guts.pkg
 */
lib7_val_t _lib7_Sock_getNREAD (lib7_state_t *lib7_state, lib7_val_t arg)
{
    int		n, status;

    status = ioctl (INT_LIB7toC(arg), FIONREAD, (char *)&n);

    if (status < 0)
        return RAISE_SYSERR(lib7_state, status);
    else
	return INT_CtoLib7(n);

} /* end of _lib7_Sock_getNREAD */
예제 #6
0
Val   _lib7_P_ProcEnv_sysconf   (Task* task,  Val arg)   {
    //=======================
    //
    // Mythryl type:   String -> Unt
    //
    // Get configurable system variables
    //
    // This fn gets bound as   sysconf   in:
    //
    //     src/lib/std/src/posix-1003.1b/posix-process.pkg


    name_val_t* attribute =  _lib7_posix_nv_lookup(HEAP_STRING_AS_C_STRING(arg), values, NUMELMS);
    //
    if (!attribute) {
        //
        errno = EINVAL;
        return RAISE_SYSERR(task, -1);
    }
 
    long val;
    errno = 0;
    //
    while (((val = sysconf(attribute->val)) == -1) && (errno == EINTR)) {
        errno = 0;
        continue;
    }


    if (val >= 0) {
	//
        Val               result;
        WORD_ALLOC (task, result, val);
        return            result;
    }

    if (errno == 0)   return RAISE_ERROR(task, "unsupported POSIX feature");
    else              return RAISE_SYSERR(task, -1);
}
예제 #7
0
/* _lib7_win32_IO_close: one_word_unt -> Void
 * close a handle
 */
Val _lib7_win32_IO_close(Task *task, Val arg)
{
    HANDLE h = (HANDLE) WORD_LIB7toC(arg);

    if (CloseHandle(h)) {
      return HEAP_VOID;
    }

#ifdef WIN32_DEBUG
    debug_say("_lib7_win32_IO_close: failing\n");
#endif

    return RAISE_SYSERR(task,-1);
}
예제 #8
0
Val   _lib7_P_Process_waitpid   (Task* task,  Val arg)   {
    //=======================
    //
    // Mythryl type:  (Int, Unt) -> (Int, Int, Int)
    //
    // Wait for child processes to stop or terminate.
    //
    // This fn gets bound as   waitpid'   in:
    //
    //     src/lib/std/src/posix-1003.1b/posix-process.pkg

    int status;
    int how;
    int val;

    int  pid;

/*  do { */						// Backed out 2010-02-26 CrT: See discussion at bottom of src/c/lib/socket/connect.c

        pid = waitpid(GET_TUPLE_SLOT_AS_INT(arg, 0), &status, TUPLE_GETWORD(arg, 1));

/*  } while (pid < 0 && errno == EINTR);	*/	// Restart if interrupted by a SIGALRM or SIGCHLD or whatever.

    if (pid < 0)   return RAISE_SYSERR(task, pid);

    if (WIFEXITED(status)) {
	//
	how = 0;
	val = WEXITSTATUS(status);

    } else if (WIFSIGNALED(status)) {

	how = 1;
	val = WTERMSIG(status);

    } else if (WIFSTOPPED(status)) {

	how = 2;
	val = WSTOPSIG(status);

    } else {

        return RAISE_ERROR(task, "unknown child status");
    }

    Val              result;
    REC_ALLOC3(task, result, TAGGED_INT_FROM_C_INT(pid), TAGGED_INT_FROM_C_INT(how), TAGGED_INT_FROM_C_INT(val));
    return           result;
}
예제 #9
0
파일: recv.c 프로젝트: jes5199/mythryl
/* _lib7_Sock_recv : (Socket, Int, Bool, Bool) -> unt8_vector::Vector
 *
 * The arguments are: socket, number of bytes, OOB flag and peek flag; the
 * result is the vector of bytes received.
 *
 * This function gets imported into the Mythryl world via:
 *     src/lib/std/src/socket/socket-guts.pkg
 */
lib7_val_t _lib7_Sock_recv (lib7_state_t *lib7_state, lib7_val_t arg)
{
    lib7_val_t	vec;
    lib7_val_t	result;
    int		n;

    int		socket = REC_SELINT(arg, 0);
    int		nbytes = REC_SELINT(arg, 1);
    lib7_val_t	oob    = REC_SEL(   arg, 2);
    lib7_val_t	peek   = REC_SEL(   arg, 3);

    int		flag = 0;

    if (oob  == LIB7_true) flag |= MSG_OOB;
    if (peek == LIB7_true) flag |= MSG_PEEK;

    /* Allocate the vector.
     * Note that this might cause a GC:
     */
    vec = LIB7_AllocRaw32 (lib7_state, BYTES_TO_WORDS(nbytes));

    print_if("recv.c/before: socket d=%d nbytes d=%d oob=%s peek=%s\n",socket,nbytes,(oob == LIB7_true)?"TRUE":"FALSE",(peek == LIB7_true)?"TRUE":"FALSE");
    errno = 0;

/*  do { */	/* Backed out 2010-02-26 CrT: See discussion at bottom of src/runtime/c-libs/lib7-socket/connect.c	*/

        n = recv (socket, PTR_LIB7toC(char, vec), nbytes, flag);

/*  } while (n < 0 && errno == EINTR);	*/	/* Restart if interrupted by a SIGALRM or SIGCHLD or whatever.	*/

    print_if(   "recv.c/after: n d=%d errno d=%d (%s)\n", n, errno, errno ? strerror(errno) : "");
    hexdump_if( "recv.c/after: Received data: ", PTR_LIB7toC(unsigned char, vec), n );

    if (n < 0)
        return RAISE_SYSERR(lib7_state, status);
    else if (n == 0)
	return LIB7_string0;

    if (n < nbytes) {
      /* we need to shrink the vector */
	LIB7_ShrinkRaw32 (lib7_state, vec, BYTES_TO_WORDS(n));
    }

    SEQHDR_ALLOC (lib7_state, result, DESC_string, vec, n);

    return result;
}
예제 #10
0
/* _lib7_win32_PS_get_environment_variable : String -> String option
 *                                         var
 *
 */
Val _lib7_win32_PS_get_environment_variable(Task *task, Val arg)
{
#define GEV_BUF_SZ 4096
  char buf[GEV_BUF_SZ];
  int ret = GetEnvironmentVariable(HEAP_STRING_AS_C_STRING(arg),buf,GEV_BUF_SZ);
  Val ml_s,res = OPTION_NULL;

  if (ret > GEV_BUF_SZ) {
    return RAISE_SYSERR(task,-1);
  }
  if (ret > 0) {
    ml_s = make_ascii_string_from_c_string(task,buf);
    OPTION_THE(task,res,ml_s);
  }
  return res;
#undef GEV_BUF_SZ
}
예제 #11
0
/* _lib7_win32_PS_get_environment_variable : String -> String option
 *                                         var
 *
 */
lib7_val_t _lib7_win32_PS_get_environment_variable(lib7_state_t *lib7_state, lib7_val_t arg)
{
#define GEV_BUF_SZ 4096
  char buf[GEV_BUF_SZ];
  int ret = GetEnvironmentVariable(STR_LIB7toC(arg),buf,GEV_BUF_SZ);
  lib7_val_t ml_s,res = OPTION_NONE;

  if (ret > GEV_BUF_SZ) {
    return RAISE_SYSERR(lib7_state,-1);
  }
  if (ret > 0) {
    ml_s = LIB7_CString(lib7_state,buf);
    OPTION_SOME(lib7_state,res,ml_s);
  }
  return res;
#undef GEV_BUF_SZ
}
예제 #12
0
파일: getsockname.c 프로젝트: xyproto/smlnj
/* _ml_Sock_getsockname : sock -> addr
 */
ml_val_t _ml_Sock_getsockname (ml_state_t *msp, ml_val_t arg)
{
    int		sock = INT_MLtoC(arg);
    char	addrBuf[MAX_SOCK_ADDR_SZB];
    socklen_t	addrLen = MAX_SOCK_ADDR_SZB;
    int		sts;

    sts = getsockname (sock, (struct sockaddr *)addrBuf, &addrLen);

    if (sts == -1)
	return RAISE_SYSERR(msp, sts);
    else {
	ml_val_t	data = ML_CData (msp, addrBuf, addrLen);
	ml_val_t	addr;
	SEQHDR_ALLOC (msp, addr, DESC_word8vec, data, addrLen);
	return addr;
    }

} /* end of _ml_Sock_getsockname */
예제 #13
0
파일: ctlRCVBUF.c 프로젝트: xyproto/smlnj
/* _ml_Sock_ctlRCVBUF : (sock * int option) -> int
 */
ml_val_t _ml_Sock_ctlRCVBUF (ml_state_t *msp, ml_val_t arg)
{
    int		sock = REC_SELINT(arg, 0);
    ml_val_t	ctl = REC_SEL(arg, 1);
    int		sz, sts;

    if (ctl == OPTION_NONE) {
	socklen_t	optSz = sizeof(int);
	sts = getsockopt (sock, SOL_SOCKET, SO_RCVBUF, (sockoptval_t)&sz, &optSz);
	ASSERT((sts < 0) || (optSz == sizeof(int)));
    }
    else {
	sz = INT_MLtoC(OPTION_get(ctl));
	sts = setsockopt (sock, SOL_SOCKET, SO_RCVBUF, (sockoptval_t)&sz, sizeof(int));
    }

    if (sts < 0)
	return RAISE_SYSERR(msp, sts);
    else
	return INT_CtoML(sz);

} /* end of _ml_Sock_ctlRCVBUF */
예제 #14
0
Val   _lib7_P_FileSys_readdir   (Task* task,  Val arg)   {
    //=======================
    //
    // Mythryl type:   Ckit_Dirstream -> String
    //
    // Return the next filename from the directory stream.
    //
    // This fn gets bound as   readdir'   in:
    //
    //     src/lib/std/src/posix-1003.1b/posix-file.pkg
    //     src/lib/std/src/posix-1003.1b/posix-file-system-64.pkg

    struct dirent* dirent;
    
    while (TRUE) {
	errno = 0;

	dirent = readdir(PTR_CAST(DIR*, arg));

	if (dirent == NULL) {
	    if (errno != 0)  return RAISE_SYSERR(task, -1);     // Error occurred.
	    else	     return ZERO_LENGTH_STRING__GLOBAL;	// End of stream.
	} else {
	    char	*cp = dirent->d_name;

// SML/NJ drops "." and ".." at this point,
//           but that is alien to posix culture,
//           so I've commented it out:			-- 2008-02-23 CrT
//

//	    if ((cp[0] == '.')
//	    && ((cp[1] == '\0') || ((cp[1] == '.') && (cp[2] == '\0'))))
//		continue;
//	    else
//
		return make_ascii_string_from_c_string (task, cp);
	}
    }
}
예제 #15
0
/* _lib7_Sock_socketpair : (int * int * int) -> (socket * socket)
 *
 * Create a pair of sockets.  The arguments are: domain (should be
 * AF_UNIX), type, and protocol.
 *
 * This function gets imported into the Mythryl world via:
 *     src/lib/std/src/socket/generic-socket.pkg

 */
lib7_val_t _lib7_Sock_socketpair (lib7_state_t *lib7_state, lib7_val_t arg)
{
    int	 domain   = REC_SELINT(arg, 0);
    int	 type     = REC_SELINT(arg, 1);
    int	 protocol = REC_SELINT(arg, 2);

    int	 status;
    int	 socket[2];

    status = socketpair (domain, type, protocol, socket);

    if (status < 0) {

        return RAISE_SYSERR(lib7_state, status);

    } else {

	lib7_val_t	res;
	REC_ALLOC2(lib7_state, res, INT_CtoLib7(socket[0]), INT_CtoLib7(socket[1]));
	return res;
    }

} /* end of _lib7_Sock_socketpair */
예제 #16
0
/* _lib7_Sock_ctlNODELAY : (socket * Bool option) -> Bool
 *
 * NOTE: this is a TCP level option, so we cannot use the utility function.
 *
 * This function gets imported into the Mythryl world via:
 *     src/lib/std/src/socket/internet-socket.pkg
 */
lib7_val_t _lib7_Sock_ctlNODELAY (lib7_state_t *lib7_state, lib7_val_t arg)
{
    int		socket = REC_SELINT(arg, 0);
    lib7_val_t	ctl = REC_SEL(arg, 1);
    bool_t	flag;
    int		status;

    if (ctl == OPTION_NONE) {
	int	optSz = sizeof(int);
	status = getsockopt (socket, IPPROTO_TCP, TCP_NODELAY, (sockoptval_t)&flag, &optSz);
	ASSERT((status < 0) || (optSz == sizeof(int)));
    }
    else {
	flag = (bool_t)INT_LIB7toC(OPTION_get(ctl));
	status = setsockopt (socket, IPPROTO_TCP, TCP_NODELAY, (sockoptval_t)&flag, sizeof(int));
    }

    if (status < 0)
        return RAISE_SYSERR(lib7_state, status);
    else
	return (flag ? LIB7_true : LIB7_false);

} /* end of _lib7_Sock_ctlNODELAY */
예제 #17
0
파일: localtime.c 프로젝트: xyproto/smlnj
/* _ml_Date_localtime : Int32.int -> (int * int * int * int * int * int * int * int * int)
 *
 * Takes a local time value (in seconds), and converts it to a 9-tuple with
 * the fields:  tm_sec, tm_min, tm_hour, tm_mday, tm_mon, tm_year, tm_wday,
 * tm_yday, and tm_isdst.
 */
ml_val_t _ml_Date_localtime (ml_state_t *msp, ml_val_t arg)
{
    time_t	t = (time_t)INT32_MLtoC(arg);
    struct tm	*tm;

    tm = localtime (&t);

    if (tm == NULL) RAISE_SYSERR(msp,0);

    ML_AllocWrite(msp, 0, MAKE_DESC(DTAG_record, 9));
    ML_AllocWrite(msp, 1, INT_CtoML(tm->tm_sec));
    ML_AllocWrite(msp, 2, INT_CtoML(tm->tm_min));
    ML_AllocWrite(msp, 3, INT_CtoML(tm->tm_hour));
    ML_AllocWrite(msp, 4, INT_CtoML(tm->tm_mday));
    ML_AllocWrite(msp, 5, INT_CtoML(tm->tm_mon));
    ML_AllocWrite(msp, 6, INT_CtoML(tm->tm_year));
    ML_AllocWrite(msp, 7, INT_CtoML(tm->tm_wday));
    ML_AllocWrite(msp, 8, INT_CtoML(tm->tm_yday));
    ML_AllocWrite(msp, 9, INT_CtoML(tm->tm_isdst));

    return ML_Alloc(msp, 9);

} /* end of _ml_Date_localtime */
예제 #18
0
파일: accept.c 프로젝트: jes5199/mythryl
/* _lib7_Sock_accept : Socket -> (Socket, Address)
 *
 * This function gets imported into the Mythryl world via:
 *     src/lib/std/src/socket/socket-guts.pkg
 */
lib7_val_t _lib7_Sock_accept (lib7_state_t *lib7_state, lib7_val_t arg)
{
    int		socket = INT_LIB7toC(arg);
    char	addrBuf[MAX_SOCK_ADDR_SZB];
    int		addrLen = MAX_SOCK_ADDR_SZB;
    int		newSock;

/*  do { */	/* Backed out 2010-02-26 CrT: See discussion at bottom of src/runtime/c-libs/lib7-socket/connect.c	*/

        newSock = accept (socket, (struct sockaddr *)addrBuf, &addrLen);

/*  } while (newSock < 0 && errno == EINTR);	*/		/* Restart if interrupted by a SIGALRM or SIGCHLD or whatever.	*/

    if (newSock == -1) {
        return RAISE_SYSERR(lib7_state, newSock);
    } else {
	lib7_val_t	data = LIB7_CData (lib7_state, addrBuf, addrLen);
	lib7_val_t	addr, res;

	SEQHDR_ALLOC(lib7_state, addr, DESC_word8vec, data, addrLen);
	REC_ALLOC2(lib7_state, res, INT_CtoLib7(newSock), addr);
	return res;
    }
}
예제 #19
0
파일: poll.c 프로젝트: jes5199/mythryl
/* LIB7_Poll:
 *
 * The version of the polling operation for systems that provide BSD select.
 */
static lib7_val_t LIB7_Poll (lib7_state_t *lib7_state, lib7_val_t poll_list, struct timeval *timeout)
{
    fd_set	rset, wset, eset;
    fd_set	*rfds, *wfds, *efds;
    int		maxFD, status, fd, flag;
    lib7_val_t	l, item;

/*printf("src/runtime/c-libs/posix-os/poll.c: Using 'select' implementation\n");*/
    rfds = wfds = efds = NULL;
    maxFD = 0;
    for (l = poll_list;  l != LIST_nil;  l = LIST_tl(l)) {
	item	= LIST_hd(l);
	fd	= REC_SELINT(item, 0);
	flag	= REC_SELINT(item, 1);
	if ((flag & READABLE_BIT) != 0) {
/*int fd_flags = fcntl(fd,F_GETFL,0);*/
	    if (rfds == NULL) {
		rfds = &rset;
		FD_ZERO(rfds);
	    }
/*printf("src/runtime/c-libs/posix-os/poll.c: Will check fd %d for readability. fd flags x=%x O_NONBLOCK x=%x\n",fd,fd_flags,O_NONBLOCK);*/
	    FD_SET (fd, rfds);
	}
	if ((flag & WRITABLE_BIT) != 0) {
	    if (wfds == NULL) {
		wfds = &wset;
		FD_ZERO(wfds);
	    }
/*printf("src/runtime/c-libs/posix-os/poll.c: Will check fd %d for writability.\n",fd);*/
	    FD_SET (fd, wfds);
	}
	if ((flag & OOBDABLE_BIT) != 0) {
	    if (efds == NULL) {
		efds = &eset;
		FD_ZERO(efds);
	    }
/*printf("src/runtime/c-libs/posix-os/poll.c: Will check fd %d for oobdability.\n",fd);*/
	    FD_SET (fd, efds);
	}
	if (fd > maxFD) maxFD = fd;
    }

/*printf("src/runtime/c-libs/posix-os/poll.c: maxFD d=%d timeout x=%x.\n",maxFD,timeout);*/

/*  do { */	/* Backed out 2010-02-26 CrT: See discussion at bottom of src/runtime/c-libs/lib7-socket/connect.c	*/

        status = select (maxFD+1, rfds, wfds, efds, timeout);

/*  } while (status < 0 && errno == EINTR);	*/	/* Restart if interrupted by a SIGALRM or SIGCHLD or whatever.	*/

/*printf("src/runtime/c-libs/posix-os/poll.c: result status d=%d.\n",status);*/

    if (status < 0)
        return RAISE_SYSERR(lib7_state, status);
    else if (status == 0)
	return LIST_nil;
    else {
	lib7_val_t	*resVec = NEW_VEC(lib7_val_t, status);
	int		i;
	int		resFlag;

	for (i = 0, l = poll_list;  l != LIST_nil;  l = LIST_tl(l)) {
	    item	= LIST_hd(l);
	    fd		= REC_SELINT(item, 0);
	    flag	= REC_SELINT(item, 1);
	    resFlag	= 0;
	    if (((flag & READABLE_BIT) != 0) && FD_ISSET(fd, rfds)) {
/*int fd_flags = fcntl(fd,F_GETFL,0);*/
/*printf("src/runtime/c-libs/posix-os/poll.c: fd d=%d is in fact readable. fd flags x=%x O_NONBLOCK x=%x\n",fd,fd_flags,O_NONBLOCK);*/
		resFlag |= READABLE_BIT;
            }
	    if (((flag & WRITABLE_BIT) != 0) && FD_ISSET(fd, wfds)) {
/*printf("src/runtime/c-libs/posix-os/poll.c: fd d=%d is in fact writable.\n",fd);*/
		resFlag |= WRITABLE_BIT;
            }
	    if (((flag & OOBDABLE_BIT) != 0) && FD_ISSET(fd, efds)) {
/*printf("src/runtime/c-libs/posix-os/poll.c: fd d=%d is in fact oobdable.\n",fd);*/
		resFlag |= OOBDABLE_BIT;
            }
	    if (resFlag != 0) {
		REC_ALLOC2 (lib7_state, item, INT_CtoLib7(fd), INT_CtoLib7(resFlag));
		resVec[i++] = item;
	    }
	}

	ASSERT(i == status);

	for (i = status-1, l = LIST_nil;  i >= 0;  i--) {
	    item = resVec[i];
	    LIST_cons (lib7_state, l, item, l);
	}

	FREE(resVec);

	return l;
    }

} /* end of LIB7_Poll */
예제 #20
0
파일: poll.c 프로젝트: jes5199/mythryl
/* LIB7_Poll:
 *
 * The version of the polling operation for systems that provide SVR4 polling.
 */
static lib7_val_t LIB7_Poll (lib7_state_t *lib7_state, lib7_val_t poll_list, struct timeval *timeout)
{
    int		    tout;
    struct pollfd*   fds;
    struct pollfd*   fdp;
    int		    nfds, i, flag;
    lib7_val_t	    l, item;

    if (timeout == NULL)
	tout = -1;
    else
        /* Convert to miliseconds: */
	tout = (timeout->tv_sec * 1000) + (timeout->tv_usec / 1000);

    /* Count the number of polling items:
     */
    for (l = poll_list, nfds = 0;  l != LIST_nil;  l = LIST_tl(l))
	nfds++;

    /* Allocate the fds vector: */
    fds = NEW_VEC(struct pollfd, nfds);
    CLEAR_MEM (fds, sizeof(struct pollfd)*nfds);

    /* Initialize the polling descriptors:
     */
    for (l = poll_list, fdp = fds;  l != LIST_nil;  l = LIST_tl(l), fdp++) {

	item = LIST_hd(l);

	fdp->fd	= REC_SELINT(item, 0);
	flag    = REC_SELINT(item, 1);

	if ((flag & READABLE_BIT) != 0)  fdp->events |= POLLIN;
	if ((flag & WRITABLE_BIT) != 0)  fdp->events |= POLLOUT;
	if ((flag & OOBDABLE_BIT) != 0)  fdp->events |= POLL_ERROR;
    }

    {   int status;


/*      do { */	/* Backed out 2010-02-26 CrT: See discussion at bottom of src/runtime/c-libs/lib7-socket/connect.c	*/

            status = poll (fds, nfds, tout);

/*      } while (status < 0 && errno == EINTR);	*/	/* Restart if interrupted by a SIGALRM or SIGCHLD or whatever.	*/

	if (status < 0) {
	    FREE(fds);
	    return RAISE_SYSERR(lib7_state, status);
	}
	else {
	    for (i = nfds-1, l = LIST_nil;  i >= 0;  i--) {

		fdp = &(fds[i]);

		if (fdp->revents != 0) {

		    flag = 0;

		    if ((fdp->revents & POLLIN    ) != 0)  flag |= READABLE_BIT;
		    if ((fdp->revents & POLLOUT   ) != 0)  flag |= WRITABLE_BIT;
		    if ((fdp->revents & POLL_ERROR) != 0)  flag |= OOBDABLE_BIT;

		    REC_ALLOC2(lib7_state, item, INT_CtoLib7(fdp->fd), INT_CtoLib7(flag));
		    LIST_cons(lib7_state, l, item, l);
		}
	    }
	    FREE(fds);
	    return l;
	}
    }
}