Example #1
0
Val   _lib7_P_IO_read   (Task* task,  Val arg)   {
    //===============
    //
    // Mythryl type:   (Int, Int) -> vector_of_one_byte_unts::Vector
    //                  fd   nbytes
    //
    // Read the specified number of bytes from the specified file,
    // returning them in a vector.
    //
    // This fn gets bound as   read'   in:
    //
    //     src/lib/std/src/psx/posix-io.pkg
    //     src/lib/std/src/psx/posix-io-64.pkg

										ENTER_MYTHRYL_CALLABLE_C_FN(__func__);

    Val vec;
    int n;

    int fd     =  GET_TUPLE_SLOT_AS_INT( arg, 0 );
    int nbytes =  GET_TUPLE_SLOT_AS_INT( arg, 1 );

    if (nbytes == 0)   return ZERO_LENGTH_STRING__GLOBAL;

    // 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 C space in which to do the read:
    //
    Mythryl_Heap_Value_Buffer  vec_buf;
    //
    {	char* c_vec =   buffer_mythryl_heap_nonvalue( &vec_buf, nbytes );	// buffer_mythryl_heap_nonvalue		is from   src/c/main/runtime-state.c


	do {
	    RELEASE_MYTHRYL_HEAP( task->hostthread, __func__, NULL );
		//
		n = read (fd, c_vec, nbytes);
		//
	    RECOVER_MYTHRYL_HEAP( task->hostthread, __func__ );
	    //
	} while (n < 0 && errno == EINTR);					// Restart if interrupted by a SIGALRM or SIGCHLD or whatever.

	if (n <  0)    	{ unbuffer_mythryl_heap_value( &vec_buf );	return RAISE_SYSERR__MAY_HEAPCLEAN(task, n, NULL);		}
	if (n == 0)	{ unbuffer_mythryl_heap_value( &vec_buf );	return ZERO_LENGTH_STRING__GLOBAL;				}

	// Allocate the vector.
	// Note that this might trigger a heapcleaning, moving things around:
	//
	vec = allocate_nonempty_wordslots_vector__may_heapclean( task, BYTES_TO_WORDS(n), NULL );

	memcpy( PTR_CAST(char*, vec), c_vec, n );

	unbuffer_mythryl_heap_value( &vec_buf );
    }

    Val result = make_vector_header(task,  STRING_TAGWORD, vec, n);
										EXIT_MYTHRYL_CALLABLE_C_FN(__func__);
    return result;
}
Example #2
0
Val   _lib7_P_FileSys_fchown   (Task* task,  Val arg)   {
    //======================
    //
    // Mythryl type: (Int, Unt, Unt) -> Void
    //                fd   uid  gid
    //
    // Change owner and group of file given a file descriptor for it.
    //
    // This fn gets bound as   fchown'   in:
    //
    //     src/lib/std/src/psx/posix-file.pkg
    //     src/lib/std/src/psx/posix-file-system-64.pkg

									    ENTER_MYTHRYL_CALLABLE_C_FN(__func__);

    int	    fd =  GET_TUPLE_SLOT_AS_INT( arg, 0);
    uid_t  uid =  TUPLE_GETWORD(         arg, 1);
    gid_t  gid =  TUPLE_GETWORD(         arg, 2);

    RELEASE_MYTHRYL_HEAP( task->hostthread, __func__, NULL );
	//
        int status = fchown (fd, uid, gid);
	//
    RECOVER_MYTHRYL_HEAP( task->hostthread, __func__ );

    Val result = RETURN_VOID_EXCEPT_RAISE_SYSERR_ON_NEGATIVE_STATUS__MAY_HEAPCLEAN(task, status, NULL);

									    EXIT_MYTHRYL_CALLABLE_C_FN(__func__);
    return result;
}
Example #3
0
Val   _lib7_P_TTY_tcgetattr   (Task* task,  Val arg)   {
    //=====================
    //
    // Mythryl type:   Int -> (Unt, Unt, Unt, Unt, String, Unt, Unt)
    //
    // Get parameters associated with tty.
    //
    // NOTE: the calls to cfget[io] speed by making the code more OS-dependent
    // and using the package of struct termios.
    //
    // This fn gets bound as   tcgetattr   in:
    //
    //     src/lib/std/src/psx/posix-tty.pkg

									    ENTER_MYTHRYL_CALLABLE_C_FN(__func__);

    int fd = TAGGED_INT_TO_C_INT( arg );

    struct termios  data;

    RELEASE_MYTHRYL_HEAP( task->hostthread, __func__, NULL);
	//
	int status =  tcgetattr( fd, &data );
	//
    RECOVER_MYTHRYL_HEAP( task->hostthread, __func__ );

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

    Val iflag  =  make_one_word_unt(task, data.c_iflag  );			Roots roots1 = { &iflag,   NULL   };
    Val oflag  =  make_one_word_unt(task, data.c_oflag  );			Roots roots2 = { &oflag,  &roots1 };
    Val cflag  =  make_one_word_unt(task, data.c_cflag  );			Roots roots3 = { &cflag,  &roots2 };
    Val lflag  =  make_one_word_unt(task, data.c_lflag  );			Roots roots4 = { &lflag,  &roots3 };

    Val ispeed =  make_one_word_unt(task, cfgetispeed (&data) );		Roots roots5 = { &ispeed, &roots4 };
    Val ospeed =  make_one_word_unt(task, cfgetospeed (&data) );		Roots roots6 = { &ospeed, &roots5 };
    
    Val cc = allocate_nonempty_ascii_string__may_heapclean (task, NCCS, &roots6 );

    memcpy(
	GET_VECTOR_DATACHUNK_AS( void*, cc ),
        data.c_cc,
	NCCS
    );

    // Construct the result vector:
    //
    set_slot_in_nascent_heapchunk   (task, 0, MAKE_TAGWORD(PAIRS_AND_RECORDS_BTAG, 7));
    set_slot_in_nascent_heapchunk   (task, 1, iflag);
    set_slot_in_nascent_heapchunk   (task, 2, oflag);
    set_slot_in_nascent_heapchunk   (task, 3, cflag);
    set_slot_in_nascent_heapchunk   (task, 4, lflag);
    set_slot_in_nascent_heapchunk   (task, 5, cc);
    set_slot_in_nascent_heapchunk   (task, 6, ispeed);
    set_slot_in_nascent_heapchunk   (task, 7, ospeed);

    Val result = commit_nascent_heapchunk (task, 7);

									    EXIT_MYTHRYL_CALLABLE_C_FN(__func__);
    return result;
}
Example #4
0
Val   _lib7_P_IO_lseek   (Task* task,  Val arg)   {
    //================
    //
    // Mythryl type:  (Int, Int, Int) -> Int
    //
    // Move read/write file pointer.
    //
    // This fn gets bound as   lseek'   in:
    //
    //     src/lib/std/src/psx/posix-io.pkg

									    ENTER_MYTHRYL_CALLABLE_C_FN(__func__);

    int       fd =  GET_TUPLE_SLOT_AS_INT( arg, 0 );
    off_t offset =  GET_TUPLE_SLOT_AS_INT( arg, 1 );
    int   whence =  GET_TUPLE_SLOT_AS_INT( arg, 2 );

    RELEASE_MYTHRYL_HEAP( task->hostthread, __func__, NULL );
	//
	off_t pos = lseek(fd, offset, whence);
	//
    RECOVER_MYTHRYL_HEAP( task->hostthread, __func__ );

    Val result = RETURN_STATUS_EXCEPT_RAISE_SYSERR_ON_NEGATIVE_STATUS__MAY_HEAPCLEAN(task, pos, NULL);

									    EXIT_MYTHRYL_CALLABLE_C_FN(__func__);
    return result;
}
Example #5
0
Val   _lib7_P_ProcEnv_setpgid   (Task* task,  Val arg)   {
    //=======================
    //
    // Mythryl type:  (Int, Int) -> Void
    //
    // Set user id
    //
    // This fn gets bound as   set_process_group_id   in:
    //
    //     src/lib/std/src/psx/posix-id.pkg

									    ENTER_MYTHRYL_CALLABLE_C_FN(__func__);

    int pid  =  GET_TUPLE_SLOT_AS_INT( arg, 0 );
    int pgid =  GET_TUPLE_SLOT_AS_INT( arg, 1 );

    RELEASE_MYTHRYL_HEAP( task->hostthread, __func__, NULL );
	//
	int status =  setpgid( pid, pgid );
	//
    RECOVER_MYTHRYL_HEAP( task->hostthread, __func__ );

    Val result =  RETURN_VOID_EXCEPT_RAISE_SYSERR_ON_NEGATIVE_STATUS__MAY_HEAPCLEAN(task, status, NULL);

									    EXIT_MYTHRYL_CALLABLE_C_FN(__func__);
    return result;
}
Example #6
0
Val   _lib7_P_ProcEnv_times   (Task* task,  Val arg)   {
    //=====================
    //
    // Mythryl type:   Void -> (Int, Int, Int, Int, Int)
    //
    // Return process and child process times, in clock ticks.
    //
    // This fn gets bound as   times'   in:
    //
    //     src/lib/std/src/posix-1003.1b/posix-id.pkg

									    ENTER_MYTHRYL_CALLABLE_C_FN("_lib7_P_ProcEnv_times");

    Val  e;
    Val  u, s;
    Val  cu, cs;

    struct tms   ts;

    RELEASE_MYTHRYL_HEAP( task->pthread, "_lib7_P_ProcEnv_times", NULL );
	//
	clock_t t = times( &ts );
	//
    RECOVER_MYTHRYL_HEAP( task->pthread, "_lib7_P_ProcEnv_times" );

    if (t == -1)   return RAISE_SYSERR__MAY_HEAPCLEAN(task, -1, NULL);

    e  =  make_one_word_int(task,  t            );
    u  =  make_one_word_int(task,  ts.tms_utime );
    s  =  make_one_word_int(task,  ts.tms_stime );
    cu =  make_one_word_int(task,  ts.tms_cutime);
    cs =  make_one_word_int(task,  ts.tms_cstime);

    return  make_five_slot_record(task,  e, u, s, cu, cs  );
}
Example #7
0
Val   _lib7_P_FileSys_ftruncate   (Task* task,  Val arg)   {
    //=========================
    //
    // Mythryl type: (Int, Int) -> Void
    //                fd   length
    //
    // This fn gets bound as   ftruncate'   in:
    //
    //     src/lib/std/src/psx/posix-file.pkg
											ENTER_MYTHRYL_CALLABLE_C_FN(__func__);
    int	    fd = GET_TUPLE_SLOT_AS_INT(arg, 0);
    off_t  len = GET_TUPLE_SLOT_AS_INT(arg, 1);

    int	    status;

    do {
        RELEASE_MYTHRYL_HEAP( task->hostthread, __func__, NULL );
	    //
	    status = ftruncate (fd, len);						// This call can return EINTR, so it is officially "slow".
	    //
	RECOVER_MYTHRYL_HEAP( task->hostthread, __func__ );
	//
    } while (status < 0 && errno == EINTR);						// Restart if interrupted by a SIGALRM or SIGCHLD or whatever.

    Val result = RETURN_VOID_EXCEPT_RAISE_SYSERR_ON_NEGATIVE_STATUS__MAY_HEAPCLEAN(task, status, NULL);

											EXIT_MYTHRYL_CALLABLE_C_FN(__func__);
    return result;
}
Example #8
0
Val   _lib7_P_FileSys_umask   (Task* task,  Val arg)   {
    //=====================
    //
    // Mythryl type : Unt -> Unt
    //
    // Set and get file creation mask
    // Assumes umask never fails.
    //
    // This fn gets bound as   umask'   in:
    //
    //     src/lib/std/src/psx/posix-file.pkg
    //     src/lib/std/src/psx/posix-file-system-64.pkg

									    ENTER_MYTHRYL_CALLABLE_C_FN(__func__);

    RELEASE_MYTHRYL_HEAP( task->hostthread, __func__, NULL );
	//
	mode_t omask = umask(WORD_LIB7toC(arg));
	//
    RECOVER_MYTHRYL_HEAP( task->hostthread, __func__ );

    Val result = make_one_word_unt(task, (Vunt) omask  );
									    EXIT_MYTHRYL_CALLABLE_C_FN(__func__);
    return result;
}
Example #9
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;
}
Example #10
0
Val   _lib7_P_IO_pipe   (Task* task,  Val arg)   {
    //===============
    //
    // Mythryl type:   Void -> (Int, Int)
    //
    // Create a pipe and return its input and output descriptors.
    //
    // This fn gets bound as   pipe'   in:
    //
    //     src/lib/std/src/psx/posix-io.pkg
    //     src/lib/std/src/psx/posix-io-64.pkg

									    ENTER_MYTHRYL_CALLABLE_C_FN(__func__);

    int         status;
    int         fds[2];

    RELEASE_MYTHRYL_HEAP( task->hostthread, __func__, NULL );
	//
	status =  pipe(fds);
	//
    RECOVER_MYTHRYL_HEAP( task->hostthread, __func__ );
// printf("Created pipe %d -> %d   -- pipe.c thread id %lx\n", fds[0], fds[1], pth__get_hostthread_id);	fflush(stdout);

    Val result;

    if (status == -1)  result = RAISE_SYSERR__MAY_HEAPCLEAN(task, -1, NULL);
    else  	       result = make_two_slot_record( task,  TAGGED_INT_FROM_C_INT(fds[0]), TAGGED_INT_FROM_C_INT(fds[1]) );

									    EXIT_MYTHRYL_CALLABLE_C_FN(__func__);
    return result;
}
Example #11
0
Val   _lib7_netdb_get_protocol_by_number   (Task* task,  Val arg)   {
    //==================================
    //
    // Mythryl type:  Int -> Null_Or(  (String, List(String), Int)   )
    //
    // This fn gets bound as   get_prot_by_number'   in:
    //
    //     src/lib/std/src/socket/net-protocol-db.pkg

															ENTER_MYTHRYL_CALLABLE_C_FN(__func__);

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

    RELEASE_MYTHRYL_HEAP( task->hostthread, __func__, NULL );
	//
	struct protoent*  pentry =   getprotobynumber( number );
	//
    RECOVER_MYTHRYL_HEAP( task->hostthread, __func__ );


    if (pentry == NULL)   return OPTION_NULL;


    Val name    =  make_ascii_string_from_c_string__may_heapclean	     (task, pentry->p_name,	NULL   );				Roots roots1 = { &name, NULL };

    Val aliases =  make_ascii_strings_from_vector_of_c_strings__may_heapclean(task, pentry->p_aliases, &roots1 );

    Val result	=  make_three_slot_record( task,   name,  aliases,  TAGGED_INT_FROM_C_INT(pentry->p_proto)  );

    result =  OPTION_THE( task, result );

									    EXIT_MYTHRYL_CALLABLE_C_FN(__func__);
    return result;
}
Example #12
0
File: bind.c Project: omork/mythryl
Val   _lib7_Sock_bind   (Task* task,  Val arg)   {
    //===============
    //
    // Mythryl type: (Socket, Addr) -> Void
    //
    // This function gets bound as   bind'   in:
    //
    //     src/lib/std/src/socket/socket-guts.pkg

												ENTER_MYTHRYL_CALLABLE_C_FN("_lib7_Sock_bind");

    int	socket =  GET_TUPLE_SLOT_AS_INT( arg, 0 );
    Val	addr   =  GET_TUPLE_SLOT_AS_VAL( arg, 1 );						// Last use of 'arg'.

    struct sockaddr* heap_sockaddr = GET_VECTOR_DATACHUNK_AS( struct sockaddr*, addr );
    int              addr_len      = GET_VECTOR_LENGTH( addr );					// Last use of 'addr'.

    struct sockaddr c_sockaddr = *heap_sockaddr;						// May not reference Mythryl heap between RELEASE_MYTHRYL_HEAP and RECOVER_MYTHRYL_HEAP, so make copy on C stack.

    RELEASE_MYTHRYL_HEAP( task->pthread, "_lib7_Sock_bind", NULL );
	//
	int status = bind (socket, &c_sockaddr, addr_len);
	//
    RECOVER_MYTHRYL_HEAP( task->pthread, "_lib7_Sock_bind" );

    RETURN_VOID_EXCEPT_RAISE_SYSERR_ON_NEGATIVE_STATUS__MAY_HEAPCLEAN(task, status, NULL);
}
Example #13
0
Val   _lib7_P_IO_fcntl_sfd   (Task* task,  Val arg)   {
    //====================
    //
    // Mythryl type:  (Int, Unt) -> Void
    //
    // Set the close-on-exec flag associated with the file descriptor.
    //
    // This fn gets bound as   fcntl_sfd   in:
    //
    //     src/lib/std/src/posix-1003.1b/posix-io.pkg
    //     src/lib/std/src/posix-1003.1b/posix-io-64.pkg

									    ENTER_MYTHRYL_CALLABLE_C_FN("_lib7_P_IO_fcntl_sfd");

    int             status;

    int             fd0  = GET_TUPLE_SLOT_AS_INT( arg, 0 );
    Vunt   flag = TUPLE_GETWORD(         arg, 1 );


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

	RELEASE_MYTHRYL_HEAP( task->pthread, "_lib7_P_IO_fcntl_sfd", NULL );
	    //
	    status = fcntl(fd0, F_SETFD, flag);
	    //
	RECOVER_MYTHRYL_HEAP( task->pthread, "_lib7_P_IO_fcntl_sfd" );

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

    RETURN_VOID_EXCEPT_RAISE_SYSERR_ON_NEGATIVE_STATUS__MAY_HEAPCLEAN(task, status, NULL);
}
Example #14
0
Val   _lib7_P_FileSys_fchmod   (Task* task,  Val arg) {
    //======================
    //
    // Mythryl type: (Fd, Unt) -> Void
    //                fd  mode
    //
    // Change mode of file.
    //
    // This fn gets bound as   fchmod'   in:
    //
    //     src/lib/std/src/psx/posix-file.pkg
    //     src/lib/std/src/psx/posix-file-system-64.pkg

									    ENTER_MYTHRYL_CALLABLE_C_FN(__func__);

    int	   fd   =  GET_TUPLE_SLOT_AS_INT( arg, 0);
    mode_t mode =  TUPLE_GETWORD(         arg, 1);

    RELEASE_MYTHRYL_HEAP( task->hostthread, __func__, NULL );
	//
        int status = fchmod (fd, mode);
	//
    RECOVER_MYTHRYL_HEAP( task->hostthread, __func__ );

    Val result = RETURN_VOID_EXCEPT_RAISE_SYSERR_ON_NEGATIVE_STATUS__MAY_HEAPCLEAN(task, status, NULL);

									    EXIT_MYTHRYL_CALLABLE_C_FN(__func__);
    return result;
}
Example #15
0
Val   _lib7_P_IO_fsync   (Task* task,  Val arg)   {
    //================
    //
    // Mythryl type:   Sy_Int -> Void
    //
    // Synchronize  a  file's in-core state with storage
    //
    // This fn gets bound as   fsync'   in:
    //
    //     src/lib/std/src/posix-1003.1b/posix-io.pkg
    //     src/lib/std/src/posix-1003.1b/posix-io-64.pkg

									    ENTER_MYTHRYL_CALLABLE_C_FN("_lib7_P_IO_fsync");

    int status;
    int fd = TAGGED_INT_TO_C_INT(arg);

    RELEASE_MYTHRYL_HEAP( task->pthread, "_lib7_P_IO_fsync", NULL );
	//
	status = fsync(fd);
	//
    RECOVER_MYTHRYL_HEAP( task->pthread, "_lib7_P_IO_fsync" );

    RETURN_VOID_EXCEPT_RAISE_SYSERR_ON_NEGATIVE_STATUS__MAY_HEAPCLEAN(task, status, NULL);
}
Example #16
0
Val   _lib7_Sock_getATMARK   (Task* task,  Val arg)   {
    //====================
    //
    // Mythryl type:   Socket_Fd -> Int
    //
    // This fn gets bound as   get_atmark'   in:
    //
    //     src/lib/std/src/socket/socket-guts.pkg
    //

											ENTER_MYTHRYL_CALLABLE_C_FN(__func__);

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

    RELEASE_MYTHRYL_HEAP( task->hostthread, __func__, NULL );
	//
	int	                                         n;
	int status = ioctl (device, SIOCATMARK, (char*) &n );
	//
    RECOVER_MYTHRYL_HEAP( task->hostthread, __func__ );

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

									    EXIT_MYTHRYL_CALLABLE_C_FN(__func__);
    return    n ? HEAP_TRUE : HEAP_FALSE;
}
Example #17
0
Val   _lib7_Time_timeofday   (Task* task,  Val arg)   {
    //====================
    //
    // Mythryl type:   Void -> (one_word_int::Int, Int)
    //
    // Return the time of day.
    // NOTE: gettimeofday() is not POSIX (time() returns seconds, and is POSIX and ISO C).
    //
    // This fn gets bound as   get_time_of_day   in:
    //
    //     src/lib/std/src/time-guts.pkg

									    ENTER_MYTHRYL_CALLABLE_C_FN(__func__);

    int	c_microseconds;
    Val	lib7_seconds;

    RELEASE_MYTHRYL_HEAP( task->hostthread, __func__, NULL );
	//
	int c_seconds = _lib7_time_gettimeofday( &c_microseconds );
	//
    RECOVER_MYTHRYL_HEAP( task->hostthread, __func__ );

    lib7_seconds =  make_one_word_int(task,  c_seconds  );

    Val result =  make_two_slot_record(task,  lib7_seconds, TAGGED_INT_FROM_C_INT( c_microseconds ) );

									    EXIT_MYTHRYL_CALLABLE_C_FN(__func__);
    return result;
}
Example #18
0
Val   _lib7_P_IO_readbuf   (Task* task,  Val arg)   {
    //==================
    //
    // Mythryl type: (Int, rw_vector_of_one_byte_unts::Rw_Vector, Int,   Int) -> Int
    //                fd   data                       nbytes start
    //
    // Read nbytes of data from the specified file
    // into the given array starting at start.
    // Return the number of bytes read.
    // Assume bounds have been checked.
    //
    // This fn gets bound as   readbuf'   in:
    //
    //     src/lib/std/src/posix-1003.1b/posix-io.pkg
    //     src/lib/std/src/posix-1003.1b/posix-io-64.pkg

									    ENTER_MYTHRYL_CALLABLE_C_FN("_lib7_P_IO_readbuf");

    int	  fd     =  GET_TUPLE_SLOT_AS_INT( arg, 0 );
//  Val	  buf    =  GET_TUPLE_SLOT_AS_VAL( arg, 1 );	// We'll do this after the read().
    int	  nbytes =  GET_TUPLE_SLOT_AS_INT( arg, 2 );
//  int   offset =  GET_TUPLE_SLOT_AS_INT( arg, 3 );	// We'll do this after the read().

    int  n;

    Mythryl_Heap_Value_Buffer  vec_buf;

    {	char* c_vec								// Get a pointer to 'nbytes' of free ram outside the Mythryl heap
	    = 									// (i.e., ram guaranteed not to move around during a heapcleaning).
	    buffer_mythryl_heap_nonvalue( &vec_buf, nbytes );

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

	RELEASE_MYTHRYL_HEAP( task->pthread, "_lib7_P_IO_readbuf", &arg );	// 'arg' is still live here! 
	    //
	    n = read( fd, c_vec, nbytes );
	    //
	RECOVER_MYTHRYL_HEAP( task->pthread, "_lib7_P_IO_readbuf" );

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

	// The heapcleaner may have moved everything around
	// during our read() call, so we wait until now to
	// track down the location of our buf vector:
	//
	Val   buf    =                                GET_TUPLE_SLOT_AS_VAL( arg, 1 );
	char* start  = HEAP_STRING_AS_C_STRING(buf) + GET_TUPLE_SLOT_AS_INT( arg, 3 );

	// Copy the bytes read into given
	// string 'buf' on Mythryl heap:
	//
	memcpy( start, c_vec, n );						// Caller is responsible for guaranteeing that this will not overrun the vector and clobber the Mythryl heap.

	unbuffer_mythryl_heap_value( &vec_buf );
    }

    RETURN_STATUS_EXCEPT_RAISE_SYSERR_ON_NEGATIVE_STATUS__MAY_HEAPCLEAN(task, n, NULL);
}
Val   get_or_set_socket_nodelay_option   (Task* task,  Val arg)   {
    //================================
    //
    // Mythryl type:   (Int,  Null_Or(Bool)) -> Bool
    //
    // NOTE: this is a TCP level option, so we cannot use the utility function.
    //
    // This fn gets bound as   ctl_delay   in:
    //
    //     src/lib/std/src/socket/internet-socket.pkg

													ENTER_MYTHRYL_CALLABLE_C_FN("get_or_set_socket_nodelay_option");

    int	socket =  GET_TUPLE_SLOT_AS_INT( arg, 0 );
    Val	ctl    =  GET_TUPLE_SLOT_AS_VAL( arg, 1 );							// Last use of 'arg'.
    //
    Bool flag;
    int status;

    if (ctl == OPTION_NULL) {
        //
	socklen_t opt_size = sizeof(int);

	RELEASE_MYTHRYL_HEAP( task->pthread, "get_or_set_socket_nodelay_option", NULL );
	    //
	    status = getsockopt (socket, IPPROTO_TCP, TCP_NODELAY, (sockoptval_t)&flag, &opt_size);
	    //
	RECOVER_MYTHRYL_HEAP( task->pthread, "get_or_set_socket_nodelay_option" );

	ASSERT((status < 0) || (opt_size == sizeof(int)));

    } else {

	flag = (Bool) TAGGED_INT_TO_C_INT(OPTION_GET(ctl));

	RELEASE_MYTHRYL_HEAP( task->pthread, "get_or_set_socket_nodelay_option", NULL );
	    //
	    status = setsockopt (socket, IPPROTO_TCP, TCP_NODELAY, (sockoptval_t)&flag, sizeof(int));
	    //
	RECOVER_MYTHRYL_HEAP( task->pthread, "get_or_set_socket_nodelay_option" );
    }

    if (status < 0)     return RAISE_SYSERR__MAY_HEAPCLEAN(task, status, NULL);
    else		return (flag ? HEAP_TRUE : HEAP_FALSE);
}
Example #20
0
Val   _lib7_Date_strftime   (Task* task,  Val arg) {
    //===================
    //
    // Mythryl type:    (String, (Int, Int, Int, Int, Int, Int, Int, Int, Int))  ->  String
    //
    // This takes a format field and nine integer fields (sec, min, hour, mday, mon,
    // year, wday, yday, and isdst), and converts it into a string representation
    // according to the format string.
    //
    // This fn gets bound to   strf_time   in:
    //
    //     src/lib/std/src/date.pkg

									    ENTER_MYTHRYL_CALLABLE_C_FN("_lib7_Date_strftime");

    Val	fmt = GET_TUPLE_SLOT_AS_VAL(arg, 0);
    Val	date;
    struct tm	tm;
    char	buf[512];
    size_t	size;

    date	= GET_TUPLE_SLOT_AS_VAL(arg, 1);
    tm.tm_sec	= GET_TUPLE_SLOT_AS_INT(date, 0);
    tm.tm_min	= GET_TUPLE_SLOT_AS_INT(date, 1);
    tm.tm_hour	= GET_TUPLE_SLOT_AS_INT(date, 2);
    tm.tm_mday	= GET_TUPLE_SLOT_AS_INT(date, 3);
    tm.tm_mon	= GET_TUPLE_SLOT_AS_INT(date, 4);
    tm.tm_year	= GET_TUPLE_SLOT_AS_INT(date, 5);
    tm.tm_wday	= GET_TUPLE_SLOT_AS_INT(date, 6);
    tm.tm_yday	= GET_TUPLE_SLOT_AS_INT(date, 7);
    tm.tm_isdst	= GET_TUPLE_SLOT_AS_INT(date, 8);

    Mythryl_Heap_Value_Buffer fmt_buf;
    //
    {   void* c_fmt
	    =
	    buffer_mythryl_heap_value(
		//
		&fmt_buf,
		(void*) HEAP_STRING_AS_C_STRING(fmt),
		 strlen(HEAP_STRING_AS_C_STRING(fmt) ) +1		// '+1' for terminal NUL on string.
	     );
	RELEASE_MYTHRYL_HEAP( task->pthread, "_lib7_Date_strftime", NULL );
	    //
	    size = strftime (buf, sizeof(buf), c_fmt, &tm);							// This call might not be slow enough to need CEASE/BEGIN guards. (Cannot return EINTR.)
	    //
	RECOVER_MYTHRYL_HEAP( task->pthread, "_lib7_Date_strftime" );
	//
	unbuffer_mythryl_heap_value( &fmt_buf );    
    }

    if (size <= 0)   return RAISE_ERROR__MAY_HEAPCLEAN(task, "strftime failed", NULL);

    Val                               result = allocate_nonempty_ascii_string__may_heapclean(task, size, NULL);	// Tried 'size+1' for terminal NUL byte here:  It injected NULs into text logfiles. Ungood. -- 2011-11-19 CrT
    strncpy (HEAP_STRING_AS_C_STRING( result ), buf, size);
    return                            result;
}
Example #21
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/psx/posix-file.pkg
    //     src/lib/std/src/psx/posix-file-system-64.pkg

									    ENTER_MYTHRYL_CALLABLE_C_FN(__func__);

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

	RELEASE_MYTHRYL_HEAP( task->hostthread, __func__, NULL );
	    //
	    dirent = readdir(PTR_CAST(DIR*, arg));					// Note that 'arg' points into the C heap not the Mythryl heap -- check src/c/lib/posix-file-system/opendir.c 
	    //
	RECOVER_MYTHRYL_HEAP( task->hostthread, __func__ );

	Val result;

	if (dirent == NULL) {
	    if (errno != 0)  result = RAISE_SYSERR__MAY_HEAPCLEAN(task, -1, NULL);	// Error occurred.
	    else	     result = ZERO_LENGTH_STRING__GLOBAL;			// End of stream.

									    EXIT_MYTHRYL_CALLABLE_C_FN(__func__);
	    return result;
	} 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
//
	    result = make_ascii_string_from_c_string__may_heapclean (task, cp, NULL);

									    EXIT_MYTHRYL_CALLABLE_C_FN(__func__);
	    return result;	
	}
    }
}
Example #22
0
Val   _lib7_P_IO_writebuf   (Task* task,  Val arg)   {
    //===================
    //
    // Mythryl type:   (Int, rw_vector_of_one_byte_unts::Rw_Vector, Int,   Int) -> Int
    //                  fd    data                                  nbytes start  
    //
    // Write nbytes of data from the given rw_vector to the specified file, 
    // starting at the given offset. Assume bounds have been checked.
    //
    // This fn gets bound as   writevec', writearr'   in:
    //
    //     src/lib/std/src/psx/posix-io.pkg
    //     src/lib/std/src/psx/posix-io-64.pkg

										ENTER_MYTHRYL_CALLABLE_C_FN(__func__);

    int		fd         = GET_TUPLE_SLOT_AS_INT(                               arg, 0);
    Val		buf        = GET_TUPLE_SLOT_AS_VAL(                               arg, 1);
    size_t	nbytes     = GET_TUPLE_SLOT_AS_INT(                               arg, 2);
    char*	heap_data  = HEAP_STRING_AS_C_STRING(buf) + GET_TUPLE_SLOT_AS_INT(arg, 3);


    ssize_t    	n;

    // 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 copy heap_data into C storage: 
    //
    Mythryl_Heap_Value_Buffer  data_buf;
    //
    {	char* c_data
	    = 
	    buffer_mythryl_heap_value( &data_buf, (void*) heap_data, nbytes );

	do {
	    RELEASE_MYTHRYL_HEAP( task->hostthread, __func__, NULL );
		//
		n = write (fd, c_data, nbytes);
		//
	    RECOVER_MYTHRYL_HEAP( task->hostthread, __func__ );
	    //
      } while (n < 0 && errno == EINTR);					// Restart if interrupted by a SIGALRM or SIGCHLD or whatever.

	unbuffer_mythryl_heap_value( &data_buf );
    }

    Val result = RETURN_STATUS_EXCEPT_RAISE_SYSERR_ON_NEGATIVE_STATUS__MAY_HEAPCLEAN(task, n, NULL);				// from   src/c/lib/raise-error.h

										EXIT_MYTHRYL_CALLABLE_C_FN(__func__);
    return result;
}
Example #23
0
Val   _lib7_U_Dynload_dlopen   (Task* task, Val arg)   {	//  (String, Bool, Bool) -> one_word_unt::Unt
    //======================
    //
    // Open a dynamically loaded library.
    //

									    ENTER_MYTHRYL_CALLABLE_C_FN("_lib7_U_Dynload_dlopen");

    Val ml_libname = GET_TUPLE_SLOT_AS_VAL (arg, 0);
    int lazy       = GET_TUPLE_SLOT_AS_VAL (arg, 1) == HEAP_TRUE;
    int global     = GET_TUPLE_SLOT_AS_VAL (arg, 2) == HEAP_TRUE;

    char *libname = NULL;
    void *handle;


    Mythryl_Heap_Value_Buffer  libname_buf;

    if (ml_libname != OPTION_NULL) {
	//
        libname = HEAP_STRING_AS_C_STRING (OPTION_GET (ml_libname));
	//
	// Copy libname out of Mythryl heap to
        // make it safe to reference between
	// RELEASE_MYTHRYL_HEAP and
	// RECOVER_MYTHRYL_HEAP:
	//
	libname =  (char*)  buffer_mythryl_heap_value( &libname_buf, (void*)libname, strlen(libname)+1 );		// '+1' for terminal NUL on string.
    }

    #ifdef OPSYS_WIN32

	handle = (void *) LoadLibrary (libname);

	if (handle == NULL && libname != NULL)	  dlerror_set ("Library `%s' not found", libname);

    #else
	int flag = (lazy ? RTLD_LAZY : RTLD_NOW);

	if (global) flag |= RTLD_GLOBAL;

	RELEASE_MYTHRYL_HEAP( task->pthread, "_lib7_U_Dynload_dlopen", NULL );
	    //
	    handle = dlopen (libname, flag);
	    //
	RECOVER_MYTHRYL_HEAP( task->pthread, "_lib7_U_Dynload_dlopen" );
    #endif

    if (libname)  unbuffer_mythryl_heap_value( &libname_buf );

    return  make_one_word_unt(task,  (Vunt) handle  );
}
Example #24
0
Val   _lib7_P_FileSys_symlink   (Task* task,  Val arg)   {
    //=======================
    //
    // Mythryl type:  (String, String) -> Void
    //                existing newname
    //
    // Creates a symbolic link from newname to existing file.
    //
    // This fn gets bound as   symlink'   in:
    //
    //     src/lib/std/src/psx/posix-file.pkg
    //     src/lib/std/src/psx/posix-file-system-64.pkg

									    ENTER_MYTHRYL_CALLABLE_C_FN(__func__);

    int status;

    Val	existing =  GET_TUPLE_SLOT_AS_VAL( arg, 0 );
    Val	new_name =  GET_TUPLE_SLOT_AS_VAL( arg, 1 );

    char* heap_existing =  HEAP_STRING_AS_C_STRING( existing );
    char* heap_new_name =  HEAP_STRING_AS_C_STRING( new_name );

    // 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 copy heap_existing and
    // heap_new_name into C storage: 
    //
    Mythryl_Heap_Value_Buffer  existing_buf;
    Mythryl_Heap_Value_Buffer  new_name_buf;
    //
    {	char* c_existing	=  buffer_mythryl_heap_value( &existing_buf, (void*) heap_existing, strlen( heap_existing ) +1 );		// '+1' for terminal NUL on string.
     	char* c_new_name	=  buffer_mythryl_heap_value( &new_name_buf, (void*) heap_new_name, strlen( heap_new_name ) +1 );		// '+1' for terminal NUL on string.

	RELEASE_MYTHRYL_HEAP( task->hostthread, __func__, NULL );
	    //
	    status = symlink( c_existing, c_new_name );
	    //
	RECOVER_MYTHRYL_HEAP( task->hostthread, __func__ );

	unbuffer_mythryl_heap_value( &existing_buf );
	unbuffer_mythryl_heap_value( &new_name_buf );
    }

    Val result = RETURN_VOID_EXCEPT_RAISE_SYSERR_ON_NEGATIVE_STATUS__MAY_HEAPCLEAN(task, status, NULL);

									    EXIT_MYTHRYL_CALLABLE_C_FN(__func__);
    return result;
}
Example #25
0
Val   _lib7_P_FileSys_openf   (Task* task,  Val arg)   {
    //=====================
    //
    // Mythryl type:  (String, Unt,  Unt) -> int
    //                 name    flags mode
    //
    // Open a file and return the file descriptor.
    //
    // This fn gets bound as   openf'   in:
    //
    //     src/lib/std/src/posix-1003.1b/posix-file.pkg
    //     src/lib/std/src/posix-1003.1b/posix-file-system-64.pkg

									    ENTER_MYTHRYL_CALLABLE_C_FN("_lib7_P_FileSys_openf");

    Val path  = GET_TUPLE_SLOT_AS_VAL( arg, 0);
    int flags = TUPLE_GETWORD(         arg, 1);
    int mode  = TUPLE_GETWORD(         arg, 2);

    int	 fd;

    char* heap_path = HEAP_STRING_AS_C_STRING( path );

    // 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 copy heap_path into C storage: 
    //
    Mythryl_Heap_Value_Buffer  path_buf;
    //
    {	char* c_path
	    = 
	    buffer_mythryl_heap_value( &path_buf, (void*) heap_path, strlen( heap_path ) +1 );		// '+1' for terminal NUL on string.

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

	    RELEASE_MYTHRYL_HEAP( task->pthread, "_lib7_P_FileSys_openf", NULL );
		//
		fd    = open( c_path, flags, mode );
		//
	    RECOVER_MYTHRYL_HEAP( task->pthread, "_lib7_P_FileSys_openf" );

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

	unbuffer_mythryl_heap_value( &path_buf );
    }

    RETURN_STATUS_EXCEPT_RAISE_SYSERR_ON_NEGATIVE_STATUS__MAY_HEAPCLEAN( task, fd, NULL );
}
Example #26
0
Val   _lib7_netdb_get_protocol_by_name   (Task* task,  Val arg)   {
    //================================
    //
    // Mythryl type:   String -> Null_Or(   (String, List(String), Int)   )
    //
    // This fn gets bound as   get_prot_by_name'   in:
    // 
    //     src/lib/std/src/socket/net-protocol-db.pkg

															ENTER_MYTHRYL_CALLABLE_C_FN(__func__);

    struct protoent*  pentry;

    char* heap_name = HEAP_STRING_AS_C_STRING( arg );									// Last use of 'arg'.

    // 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 copy heap_name into C storage: 
    //
    Mythryl_Heap_Value_Buffer  name_buf;
    //
    {	char* c_name =  buffer_mythryl_heap_value( &name_buf, (void*) heap_name, strlen( heap_name ) +1 );		// '+1' for terminal NUL on string.

	RELEASE_MYTHRYL_HEAP( task->hostthread, __func__, NULL );
	    //
	    pentry =	getprotobyname( c_name );
	    //
	RECOVER_MYTHRYL_HEAP( task->hostthread, __func__ );

	unbuffer_mythryl_heap_value( &name_buf );
    }

    if (pentry == NULL)   return OPTION_NULL;


    Val name    =  make_ascii_string_from_c_string__may_heapclean		(task, pentry->p_name,	   NULL   );					Roots roots1 = { &name, NULL };

    Val aliases =  make_ascii_strings_from_vector_of_c_strings__may_heapclean	(task, pentry->p_aliases, &roots1 );

    Val result
	=
        make_three_slot_record( task,   name,  aliases,  TAGGED_INT_FROM_C_INT(pentry->p_proto) );

    result =  OPTION_THE( task, result );

									    EXIT_MYTHRYL_CALLABLE_C_FN(__func__);
    return result;
}
Example #27
0
Val   _lib7_P_FileSys_chown   (Task* task,  Val arg)   {
    //=====================
    //
    // Mythryl type: (String, Unt, Unt) -> Void
    //                name    uid  gid
    //
    // Change owner and group of file given its name.
    //
    // This fn gets bound as   chown'   in:
    //
    //     src/lib/std/src/psx/posix-file.pkg
    //     src/lib/std/src/psx/posix-file-system-64.pkg

									    ENTER_MYTHRYL_CALLABLE_C_FN(__func__);

    int   status;

    Val	  path = GET_TUPLE_SLOT_AS_VAL(   arg, 0);
    uid_t uid  = TUPLE_GETWORD(           arg, 1);
    gid_t gid  = TUPLE_GETWORD(           arg, 2);

    char* heap_path=  HEAP_STRING_AS_C_STRING(path);


    // 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 copy heap_path into C storage: 
    //
    Mythryl_Heap_Value_Buffer  path_buf;
    //
    {	char* c_path
	    = 
	    buffer_mythryl_heap_value( &path_buf, (void*) path, strlen( heap_path ) +1 );		// '+1' for terminal NUL on string.

	RELEASE_MYTHRYL_HEAP( task->hostthread, __func__, NULL );
	    //
	    status = chown (c_path, uid, gid);
	    //
	RECOVER_MYTHRYL_HEAP( task->hostthread, __func__ );
	//
	unbuffer_mythryl_heap_value( &path_buf );
    }

    Val result = RETURN_VOID_EXCEPT_RAISE_SYSERR_ON_NEGATIVE_STATUS__MAY_HEAPCLEAN(task, status, NULL);

									    EXIT_MYTHRYL_CALLABLE_C_FN(__func__);
    return result;
}
Example #28
0
Val   _lib7_P_SysDB_getpwnam   (Task* task,  Val arg)   {
    //======================
    //
    // _lib7_P_SysDB_getpwnam : String -> (String, word, word, String, String)
    //
    // Get password file entry by name.
    //
    // This fn gets bound as   getpwnam'   in:
    //
    //     src/lib/std/src/posix-1003.1b/posix-etc.pkg

									    ENTER_MYTHRYL_CALLABLE_C_FN("_lib7_P_SysDB_getpwnam");


    struct passwd*  info;

    // 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 copy heap_path into C storage: 
    //
    Mythryl_Heap_Value_Buffer  name_buf;
    //
    {	char* heap_name = HEAP_STRING_AS_C_STRING( arg );

	char* c_name
	    = 
	    buffer_mythryl_heap_value( &name_buf, (void*) heap_name, strlen( heap_name ) +1 );		// '+1' for terminal NUL on string.

	RELEASE_MYTHRYL_HEAP( task->pthread, "_lib7_P_SysDB_getpwnam", NULL );
	    //
	    info =  getpwnam( c_name );
	    //
	RECOVER_MYTHRYL_HEAP( task->pthread, "_lib7_P_SysDB_getpwnam" );

	unbuffer_mythryl_heap_value( &name_buf );
    }

    if (info == NULL)   return RAISE_SYSERR__MAY_HEAPCLEAN(task, -1, NULL);
  
    Val pw_name  =  make_ascii_string_from_c_string__may_heapclean(	task,                  info->pw_name, NULL	);		Roots roots1 = { &pw_name, NULL };
    Val pw_uid   =  make_one_word_unt(					task, (Vunt) (info->pw_uid)		);		Roots roots2 = { &pw_uid,  &roots1 };
    Val pw_gid   =  make_one_word_unt(					task, (Vunt) (info->pw_gid)		);		Roots roots3 = { &pw_gid,  &roots2 };
    Val pw_dir   =  make_ascii_string_from_c_string__may_heapclean(	task,                  info->pw_dir,   &roots3	);		Roots roots4 = { &pw_dir,  &roots3 };
    Val pw_shell =  make_ascii_string_from_c_string__may_heapclean(	task,                  info->pw_shell, &roots4	);

    return  make_five_slot_record(task,  pw_name, pw_uid, pw_gid, pw_dir, pw_shell  );
}
Example #29
0
Val   _lib7_P_IO_fcntl_l   (Task* task,  Val arg)   {
    //==================
    //
    // Mythryl type:   (Int, Int, Flock_Rep) -> Flock_Rep
    //    Flock_Rep = (Int, Int, Offset, Offset, Int)
    //
    // Handle record locking.
    //
    // This fn gets bound as   fcntl_l   in:
    //
    //     src/lib/std/src/psx/posix-io.pkg
										ENTER_MYTHRYL_CALLABLE_C_FN(__func__);
    int fd        =  GET_TUPLE_SLOT_AS_INT( arg, 0 );
    int cmd       =  GET_TUPLE_SLOT_AS_INT( arg, 1 );
    Val flock_rep =  GET_TUPLE_SLOT_AS_VAL( arg, 2 );

    struct flock     flock;
    int              status;
    
    flock.l_type   =  GET_TUPLE_SLOT_AS_INT( flock_rep, 0 );
    flock.l_whence =  GET_TUPLE_SLOT_AS_INT( flock_rep, 1 );
    flock.l_start  =  GET_TUPLE_SLOT_AS_INT( flock_rep, 2 );
    flock.l_len    =  GET_TUPLE_SLOT_AS_INT( flock_rep, 3 );
   
    do {
	//
	RELEASE_MYTHRYL_HEAP( task->hostthread, __func__, NULL );
	    //
	    status = fcntl(fd, cmd, &flock);
	    //
	RECOVER_MYTHRYL_HEAP( task->hostthread, __func__ );
	//
    } while (status < 0 && errno == EINTR);					// Restart if interrupted by a SIGALRM or SIGCHLD or whatever.

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

    Val result = make_five_slot_record( task,
		//
		TAGGED_INT_FROM_C_INT( flock.l_type ),
		TAGGED_INT_FROM_C_INT( flock.l_whence ), 
		TAGGED_INT_FROM_C_INT( flock.l_start ),
		TAGGED_INT_FROM_C_INT( flock.l_len ),
		TAGGED_INT_FROM_C_INT( flock.l_pid )
	    );
										EXIT_MYTHRYL_CALLABLE_C_FN(__func__);
    return result;
}
Example #30
0
Val   _lib7_P_ProcEnv_getenv   (Task* task,  Val arg)   {
    //======================
    //
    // Mythryl type:  String -> Null_Or(String)
    //
    // Return value for environment name
    //
    // This fn gets bound as   getenv   in:
    //
    //     src/lib/std/src/posix-1003.1b/posix-id.pkg

									    ENTER_MYTHRYL_CALLABLE_C_FN("_lib7_P_ProcEnv_getenv");

    char* status;

    // 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 copy heap_path into C storage: 
    //
    Mythryl_Heap_Value_Buffer  key_buf;
    {
	char* heap_key = HEAP_STRING_AS_C_STRING( arg );

	char* c_key
	    = 
	    buffer_mythryl_heap_value( &key_buf, (void*) heap_key, strlen( heap_key ) +1 );		// '+1' for terminal NUL on string.

	RELEASE_MYTHRYL_HEAP( task->pthread, "_lib7_P_ProcEnv_getenv", NULL );
	    //
	    status = getenv( c_key );
	    //
	RECOVER_MYTHRYL_HEAP( task->pthread, "_lib7_P_ProcEnv_getenv" );

	unbuffer_mythryl_heap_value( &key_buf );
    }

    if (status == NULL)   return OPTION_NULL;

    Val s = make_ascii_string_from_c_string__may_heapclean( task, status, NULL);			// make_ascii_string_from_c_string__may_heapclean	def in    src/c/heapcleaner/make-strings-and-vectors-etc.c

    return  OPTION_THE( task, s );
}