Exemplo n.º 1
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 */
Exemplo n.º 2
0
Arquivo: link.c Projeto: xyproto/smlnj
/* _ml_P_FileSys_link : string * string -> unit
 *                      existing newname
 *
 * Creates a hard link from newname to existing file.
 */
ml_val_t _ml_P_FileSys_link (ml_state_t *msp, ml_val_t arg)
{
    int		sts;
    ml_val_t	existing = REC_SEL(arg, 0);
    ml_val_t	newname = REC_SEL(arg, 1);

    sts = link(STR_MLtoC(existing), STR_MLtoC(newname));

    CHK_RETURN_UNIT (msp, sts)

} /* end of _ml_P_FileSys_link */
Exemplo n.º 3
0
/* _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;
}
Exemplo n.º 4
0
/* _ml_NetDB_getservbyport
 *     : (int * string option) -> (string * string list * int * string) option
 */
ml_val_t _ml_NetDB_getservbyport (ml_state_t *msp, ml_val_t arg)
{
    ml_val_t	mlProto = REC_SEL(arg, 1);
    char	*proto;

    if (mlProto == OPTION_NONE)
	proto = NIL(char *);
    else
Exemplo n.º 5
0
lib7_val_t   _lib7_runtime_recordmeld   (   lib7_state_t*   lib7_state,
                                                lib7_val_t      arg
                                            )
{
    /* _lib7_runtime_recordmeld : (chunk * chunk) -> chunk */

    lib7_val_t    r1 = REC_SEL(arg,0);
    lib7_val_t    r2 = REC_SEL(arg,1);

    if (r1 == LIB7_void)	return r2;
    else if (r2 == LIB7_void)	return r1;
    else {
	lib7_val_t	result = RecordMeld (lib7_state, r1, r2);

	if (result == LIB7_void)   return RAISE_ERROR( lib7_state, "recordmeld: not a record");
	else                       return result;
    }
}
Exemplo n.º 6
0
/* _lib7_OS_poll : (List (Int, Unt), Null_Or(int32.Int, Int)) -> List (Int, Unt) 
 */
lib7_val_t _lib7_OS_poll (lib7_state_t *lib7_state, lib7_val_t arg)
{
    lib7_val_t	    poll_list = REC_SEL(arg, 0);
    lib7_val_t	    timeout  = REC_SEL(arg, 1);
    struct timeval  tv, *tvp;

    if (timeout == OPTION_NONE)
	tvp = NULL;
    else {
	timeout		= OPTION_get(timeout);
	tv.tv_sec	= REC_SELINT32(timeout, 0);
	tv.tv_usec	= REC_SELINT(timeout, 1);
	tvp = &tv;
    }

    return LIB7_Poll (lib7_state, poll_list, tvp);

} /* end of _lib7_OS_poll */
Exemplo n.º 7
0
/* _ml_P_FileSys_utime : (string * Int32.int * Int32.int) -> unit
 *                        name     actime modtime
 *
 * Sets file access and modification times. If
 * actime = -1, then set both to current time.
 */
ml_val_t _ml_P_FileSys_utime (ml_state_t *msp, ml_val_t arg)
{
    ml_val_t	    path = REC_SEL(arg, 0);
    time_t          actime = REC_SELINT32(arg, 1);
    time_t          modtime = REC_SELINT32(arg, 2);
    int		    sts;

    if (actime == -1) {
      sts = utime (STR_MLtoC(path), NIL(struct utimbuf *));
    }
Exemplo n.º 8
0
/* _lib7_P_FileSys_ftruncate_64 : (int * word32 * word32) -> Void
 *                               fd   lengthhi  lengthlo
 *
 * Make a directory
 */
lib7_val_t _lib7_P_FileSys_ftruncate_64 (lib7_state_t *lib7_state, lib7_val_t arg)
{
    int		    fd = REC_SELINT(arg, 0);
    off_t	    len =
      (sizeof(off_t) > 4)
      ? (((off_t)WORD_LIB7toC(REC_SEL(arg, 1))) << 32) |
        ((off_t)(WORD_LIB7toC(REC_SEL(arg, 2))))
      : ((off_t)(WORD_LIB7toC(REC_SEL(arg, 2))));
    int		    status;

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

        status = ftruncate (fd, len);

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

    CHECK_RETURN_UNIT(lib7_state, status)

} /* end of _lib7_P_FileSys_ftruncate_64 */
Exemplo n.º 9
0
/* _ml_P_Dynload_dlsym : Word32.word * string -> Word32.word
 *
 * Extract symbol from dynamically loaded library.
 */
ml_val_t _ml_U_Dynload_dlsym (ml_state_t *msp, ml_val_t arg)
{
  ml_val_t ml_handle = REC_SEL (arg, 0);
  char *symname = STR_MLtoC (REC_SEL (arg, 1));
  void *handle = (void *) (WORD_MLtoC (ml_handle));
  void *addr;
  ml_val_t res;

#ifdef OPSYS_WIN32
  addr = GetProcAddress (handle, symname);
  if (addr == NULL && symname != NULL)
    dlerror_set ("Symbol `%s' not found", symname);
#else
  addr = dlsym (handle, symname);
#endif
  
  WORD_ALLOC (msp, res, (Word_t) addr);
  return res;
}
Exemplo n.º 10
0
/* _lib7_P_FileSys_mkdir : (String * word) -> Void
 *                        name     mode
 *
 * Make a directory
 */
lib7_val_t _lib7_P_FileSys_mkdir (lib7_state_t *lib7_state, lib7_val_t arg)
{
    lib7_val_t	    path = REC_SEL(arg, 0);
    mode_t	    mode = REC_SELWORD(arg, 1);
    int		    status;

    status = mkdir (STR_LIB7toC(path), mode);

    CHECK_RETURN_UNIT(lib7_state, status)

} /* end of _lib7_P_FileSys_mkdir */
Exemplo n.º 11
0
/* _ml_P_FileSys_access : (string * word) -> bool
 *                         name     access_mode
 *
 * Determine accessibility of a file.
 */
ml_val_t _ml_P_FileSys_access (ml_state_t *msp, ml_val_t arg)
{
    ml_val_t	    path = REC_SEL(arg, 0);
    mode_t	    mode = REC_SELWORD(arg, 1);
    int		    sts;

    sts = access (STR_MLtoC(path), mode);

    if (sts == 0)
        return ML_true;
    else
        return ML_false;

} /* end of _ml_P_FileSys_access */
Exemplo n.º 12
0
/* _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 */
Exemplo n.º 13
0
lib7_val_t   _lib7_runtime_mkexec   (   lib7_state_t*   lib7_state,
                                          lib7_val_t      arg
                                      )
{
    /* _lib7_runtime_mkexec : rw_unt8_vector.Rw_Vector * int -> (chunk -> chunk)
     *
     * Turn a previously allocated code chunk into a closure.
     * This requires that we flush the I-cache.
     */

    lib7_val_t   seq        = REC_SEL(   arg, 0);
    int           entrypoint = REC_SELINT(arg, 1);

    char*	  code       = GET_SEQ_DATAPTR( char, seq );
    Word_t	  nbytes     = GET_SEQ_LEN(           seq );

    FlushICache (code, nbytes);

    {   lib7_val_t	        result;
        REC_ALLOC1(lib7_state, result, PTR_CtoLib7(code + entrypoint));
        return                  result;
    }
}
Exemplo n.º 14
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 */
Exemplo n.º 15
0
/* _lib7_Sock_connect: (Socket, Address) -> Void
 *
 * This function gets imported into the Mythryl world via:
 *     src/lib/std/src/socket/socket-guts.pkg
 */
lib7_val_t _lib7_Sock_connect (lib7_state_t *lib7_state, lib7_val_t arg)
{
    int		socket = REC_SELINT(arg, 0);
    lib7_val_t	addr   = REC_SEL(   arg, 1);
    int		status;

    socklen_t addrlen  = GET_SEQ_LEN(addr);

    {   unsigned char* a = GET_SEQ_DATAPTR(unsigned char, addr);
        char buf[ 1024 ];
	int i;
	buf[0] = '\0';
	for (i = 0; i < addrlen; ++i) {
	    sprintf (buf+strlen(buf), "%02x.", a[i]);
	}
        print_if( "connect.c/top: socket d=%d addrlen d=%d addr s='%s'\n", socket, addrlen, buf );
    }
    errno = 0;

    status
        =
        connect (
	    socket,
	    GET_SEQ_DATAPTR(struct sockaddr, addr),
	    addrlen
        );

    /* NB: Unix Network Programming p135 S5.9 says that
     *     for connect() we cannot just retry on EINTR.
     *     On p452 it says we must instead do a select(),
     *     which will wait until the three-way TCP
     *     handshake either succeeds or fails:
     */
    /* Backed out 2010-02-26 CrT: See discussion at bottom of src/runtime/c-libs/lib7-socket/connect.c	*/
#ifdef SOME_OTHER_TIME
    if (status < 0 && errno == EINTR) {

        int eintr_count = 1;

        int maxfd = socket+1;

	fd_set read_set;
	fd_set write_set;

	do {
	    print_if( "connect.c/mid: Caught EINTR #%d, doing a select() on fd %d\n", eintr_count, socket);

	    FD_ZERO( &read_set);
	    FD_ZERO(&write_set);

	    FD_SET( socket,  &read_set );
	    FD_SET( socket, &write_set );

	    errno = 0;

	    status = select(maxfd, &read_set, &write_set, NULL, NULL); 

            ++eintr_count;

	} while (status < 0 && errno == EINTR);

	/* According to p452, if the connection completes properly
         * the socket will be writable, but if it fails it will be
         * both readable and writable.  On return 'status' is the
         * count of bits set in the fd_sets;  if it is 2, the fd
         * is both readable and writable, implying connect failure.
         * To be on the safe side, in this case I ensure that status
         * is negative and errno set to something valid for a failed
         * connect().  I don't know if this situation is even possible:
         */
	if (status == 2) {
	    status = -1;
	    errno  = ENETUNREACH;	/* Possibly ETIMEDOUT would be better?	*/
	}
    }
#endif

    print_if( "connect.c/bot: status d=%d errno d=%d\n", status, errno);

    CHECK_RETURN_UNIT(lib7_state, status);		/* CHECK_RETURN_UNIT	is from   src/runtime/c-libs/lib7-c.h	*/
}
Exemplo n.º 16
0
PVT Word_t getWord32(ml_val_t v)
{
    return (Word_t) REC_SEL(v,0);
}