Ejemplo n.º 1
0
Val   _lib7_Sock_getpeername   (Task* task,  Val arg)   {
    //======================
    //
    // Mythryl type:   Socket -> (Address_Family, Address)
    //
    // This function gets bound as   get_peer_name'   in:
    //
    //     src/lib/std/src/socket/socket-guts.pkg

												ENTER_MYTHRYL_CALLABLE_C_FN(__func__);

    char addr[ MAX_SOCK_ADDR_BYTESIZE ];

    socklen_t  address_len =  MAX_SOCK_ADDR_BYTESIZE;

    int sockfd = TAGGED_INT_TO_C_INT( arg );							// Last use of 'arg'.

    RELEASE_MYTHRYL_HEAP( task->hostthread, __func__, NULL );
	//
	int status = getpeername (sockfd, (struct sockaddr *)addr, &address_len);
	//
    RECOVER_MYTHRYL_HEAP( task->hostthread, __func__ );

    if (status < 0)   return RAISE_SYSERR__MAY_HEAPCLEAN(task, status, NULL);

    Val cdata =  make_biwordslots_vector_sized_in_bytes__may_heapclean( task, addr, address_len, NULL );

    Val result =  make_vector_header(task,  UNT8_RO_VECTOR_TAGWORD, cdata, address_len);

									    EXIT_MYTHRYL_CALLABLE_C_FN(__func__);
    return result;
}
Ejemplo n.º 2
0
Val   _lib7_Sock_inetany   (Task* task,  Val arg)   {
    //==================
    //
    // Mythryl type:   Int -> Internet_Address
    //
    // Make an INET_ANY INET socket address, with the given port ID.
    //
    // This fn gets bound as   inet_any   in:
    //
    //     src/lib/std/src/socket/internet-socket.pkg
    //

																ENTER_MYTHRYL_CALLABLE_C_FN("_lib7_Sock_inetany");

    struct sockaddr_in	addr;
    memset(            &addr, 0, sizeof(struct sockaddr_in) );

    addr.sin_family      =  AF_INET;
    addr.sin_addr.s_addr =  htonl( INADDR_ANY );
    addr.sin_port        =  htons( TAGGED_INT_TO_C_INT( arg ) );								// Last use of 'arg'.

    Val data =  make_biwordslots_vector_sized_in_bytes__may_heapclean(	task, &addr, sizeof(struct sockaddr_in), NULL );

    return make_vector_header(task,  UNT8_RO_VECTOR_TAGWORD, data, sizeof(struct sockaddr_in) );
}
Ejemplo n.º 3
0
Val   _lib7_Sock_accept   (Task* task,  Val arg)   {
    //=================
    //
    // Mythryl type:   Socket -> (Socket, Address)
    //
    // This fn gets bound as   accept'   in:
    //
    //     src/lib/std/src/socket/socket-guts.pkg

									    ENTER_MYTHRYL_CALLABLE_C_FN("_lib7_Sock_accept");

    int		socket = TAGGED_INT_TO_C_INT( arg );				// Last use of 'arg'.
    char	address_buf[  MAX_SOCK_ADDR_BYTESIZE ];
    socklen_t	address_len = MAX_SOCK_ADDR_BYTESIZE;
    int		new_socket;

    RELEASE_MYTHRYL_HEAP( task->pthread, "_lib7_Sock_accept", NULL );
	//
    /*  do { */	/* Backed out 2010-02-26 CrT: See discussion at bottom of src/c/lib/socket/connect.c	*/

	    new_socket = accept (socket, (struct sockaddr*) address_buf, &address_len);

    /*  } while (new_socket < 0 && errno == EINTR);	*/		/* Restart if interrupted by a SIGALRM or SIGCHLD or whatever.	*/
	//
    RECOVER_MYTHRYL_HEAP( task->pthread, "_lib7_Sock_accept" );

    if (new_socket == -1) {
        //
	return  RAISE_SYSERR__MAY_HEAPCLEAN( task, new_socket, NULL);
        //
    } else {
        //
	Val data    =  make_biwordslots_vector_sized_in_bytes__may_heapclean(	task, address_buf,                  address_len, NULL );
	Val address =  make_vector_header(					task, UNT8_RO_VECTOR_TAGWORD, data, address_len);

	return  make_two_slot_record(task,  TAGGED_INT_FROM_C_INT( new_socket ), address);
    }
}
Ejemplo n.º 4
0
Val   _lib7_Sock_frominetaddr   (Task* task,  Val arg)   {
    //=======================
    //
    // Mythryl type:   Internet_Address -> (Internet_Address, Int)
    //
    // Given a INET-domain socket address, return the INET address and port number.
    //
    // This fn gets bound as   from_inet_addr   in:
    //
    //     src/lib/std/src/socket/internet-socket.pkg

										ENTER_MYTHRYL_CALLABLE_C_FN("_lib7_Sock_frominetaddr");

    struct sockaddr_in*	addr
        =
        GET_VECTOR_DATACHUNK_AS( struct sockaddr_in*, arg );			// Last use of 'arg'.

    ASSERT( addr->sin_family == AF_INET );

    Val data   =  make_biwordslots_vector_sized_in_bytes__may_heapclean( task, &(addr->sin_addr), sizeof(struct in_addr), NULL );
    Val inAddr =  make_vector_header( task,  UNT8_RO_VECTOR_TAGWORD, data,  sizeof(struct in_addr) );

    return  make_two_slot_record(task, inAddr, TAGGED_INT_FROM_C_INT(ntohs(addr->sin_port)) );
}
Ejemplo n.º 5
0
Val   _lib7_Sock_recvbuffrom   (Task* task,  Val arg)   {
    //======================
    //
    // Mythryl type:   (Socket, rw_vector_of_one_byte_unts::Rw_Vector, Int, Int, Bool, Bool) -> (Int, Addr)
    //
    // The arguments are:
    //     socket,
    //     data buffer,
    //     start position,
    //     number of bytes,
    //     OOB flag
    //     peek flag.
    //
    // The result is:
    //     number of bytes read
    //     source address.
    //
    // This fn gets bound as   recv_from_a   in:
    //
    //     src/lib/std/src/socket/socket-guts.pkg

										ENTER_MYTHRYL_CALLABLE_C_FN(__func__);

    char       address_buf[  MAX_SOCK_ADDR_BYTESIZE ];
    socklen_t  address_len = MAX_SOCK_ADDR_BYTESIZE;

    int	  socket  = GET_TUPLE_SLOT_AS_INT( arg, 0);
//  Val   buf     = GET_TUPLE_SLOT_AS_VAL( arg, 1);				// Mythryl buffer to read bytes into.	// We'll fetch this after the call, since it may move around during the call.
    int   offset  = GET_TUPLE_SLOT_AS_INT( arg, 2);				// Offset within buf to read bytes into.
    int	  nbytes  = GET_TUPLE_SLOT_AS_INT( arg, 3);				// Number of bytes to read.

    int	  flag = 0;

    int	   n;

    if (GET_TUPLE_SLOT_AS_VAL(arg, 4) == HEAP_TRUE) flag |= MSG_OOB;
    if (GET_TUPLE_SLOT_AS_VAL(arg, 5) == HEAP_TRUE) flag |= MSG_PEEK;

    // We cannot reference anything on the Mythryl heap
    // between RELEASE_MYTHRYL_HEAP and RECOVER_MYTHRYL_HEAP
    // because garbage collection might be moving
    // it around, so allocate a C-side read buffer:
    //
    Mythryl_Heap_Value_Buffer  readbuf_buf;
    //
    {   char* c_readbuf =  buffer_mythryl_heap_nonvalue( &readbuf_buf, nbytes );

	RELEASE_MYTHRYL_HEAP( task->hostthread, __func__, &arg );		// 'arg' is still live here!
	    //
	    do {
		//
		n = recvfrom( socket,
			      c_readbuf,
			      nbytes,
			      flag,
			      (struct sockaddr *)address_buf,
			      &address_len
			    );
	    } while (n < 0 && errno == EINTR);					// Restart if interrupted by a SIGALRM or SIGCHLD or whatever.
	    //
	RECOVER_MYTHRYL_HEAP( task->hostthread, __func__ );

	if (n < 0) {
	    unbuffer_mythryl_heap_value( &readbuf_buf );
	    return RAISE_SYSERR__MAY_HEAPCLEAN(task, status, NULL);
	}

	Val   buf      =  GET_TUPLE_SLOT_AS_VAL( arg, 1);			// Mythryl buffer to read bytes into.
	char* bufstart =  HEAP_STRING_AS_C_STRING(buf) + offset;

	memcpy( bufstart, c_readbuf, n);

	unbuffer_mythryl_heap_value( &readbuf_buf );
    }

    Val	data    =  make_biwordslots_vector_sized_in_bytes__may_heapclean(   task, address_buf,                   address_len, NULL );
    Val address =  make_vector_header(					    task,  UNT8_RO_VECTOR_TAGWORD, data, address_len);

    Val result  =  make_two_slot_record(task,  TAGGED_INT_FROM_C_INT(n), address);

										EXIT_MYTHRYL_CALLABLE_C_FN(__func__);
    return result;
}