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; }
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; }
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; }
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); }
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); }
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); }
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; }
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; }
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; }
Val _lib7_P_FileSys_unlink (Task* task, Val arg) { //====================== // // Mythryl type: String -> Void // // Remove directory entry // // This fn gets bound as unlink 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; char* heap_path = HEAP_STRING_AS_C_STRING( 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_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. RELEASE_MYTHRYL_HEAP( task->hostthread, __func__, NULL ); // status = unlink( c_path ); // 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; }
Val _lib7_P_FileSys_mkfifo (Task* task, Val arg) { //====================== // // Mythryl type: (String, Unt) -> Void // name mode // // Make a FIFO special file. // // This fn gets bound as make_pipe' in: // // src/lib/std/src/posix-1003.1b/posix-file.pkg // // This fn gets bound as make_fifo' in: // // src/lib/std/src/posix-1003.1b/posix-file-system-64.pkg ENTER_MYTHRYL_CALLABLE_C_FN("_lib7_P_FileSys_mkfifo"); int status; Val path = GET_TUPLE_SLOT_AS_VAL( arg, 0); mode_t mode = TUPLE_GETWORD( arg, 1); // char* heap_path = HEAP_STRING_AS_C_STRING( path ); // 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. RELEASE_MYTHRYL_HEAP( task->pthread, "_lib7_P_FileSys_mkfifo", NULL ); // status = mkfifo (c_path, mode); // RECOVER_MYTHRYL_HEAP( task->pthread, "_lib7_P_FileSys_mkfifo" ); unbuffer_mythryl_heap_value( &path_buf ); } RETURN_VOID_EXCEPT_RAISE_SYSERR_ON_NEGATIVE_STATUS__MAY_HEAPCLEAN(task, status, NULL); }
Val _lib7_Sock_listen (Task* task, Val arg) { //================= // // Mythryl type: (Socket, Int) -> Void // // This fn gets bound as listen' in: // // src/lib/std/src/socket/socket-guts.pkg ENTER_MYTHRYL_CALLABLE_C_FN("_lib7_Sock_listen"); int socket = GET_TUPLE_SLOT_AS_INT( arg, 0 ); int backlog = GET_TUPLE_SLOT_AS_INT( arg, 1 ); // Last use of 'arg'. RELEASE_MYTHRYL_HEAP( task->pthread, "_lib7_Sock_listen", NULL ); // int status = listen( socket, backlog ); // RECOVER_MYTHRYL_HEAP( task->pthread, "_lib7_Sock_listen" ); RETURN_VOID_EXCEPT_RAISE_SYSERR_ON_NEGATIVE_STATUS__MAY_HEAPCLEAN( task, status, NULL ); }
Val _lib7_P_TTY_tcdrain (Task* task, Val arg) { //=================== // // Mythryl type: Int -> Void // // Wait for all output to be transmitted. // // This fn gets bound as tcdrain in: // // src/lib/std/src/posix-1003.1b/posix-tty.pkg ENTER_MYTHRYL_CALLABLE_C_FN("_lib7_P_TTY_tcdrain"); int fd = TAGGED_INT_TO_C_INT( arg ); RELEASE_MYTHRYL_HEAP( task->pthread, "_lib7_P_TTY_tcdrain", NULL ); // int status = tcdrain( fd ); // RECOVER_MYTHRYL_HEAP( task->pthread, "_lib7_P_TTY_tcdrain" ); RETURN_VOID_EXCEPT_RAISE_SYSERR_ON_NEGATIVE_STATUS__MAY_HEAPCLEAN(task, status, NULL); }
Val _lib7_P_FileSys_chdir (Task* task, Val arg) { //===================== // // Mythryl type: String -> Void // // Change working directory. // // This fn gets bound as change_directory 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_chdir"); int status; char* heap_dir = HEAP_STRING_AS_C_STRING( 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_path into C storage: // Mythryl_Heap_Value_Buffer dir_buf; // { char* c_dir = buffer_mythryl_heap_value( &dir_buf, (void*) heap_dir, strlen( heap_dir )+1 ); // '+1' for terminal NUL on string. // RELEASE_MYTHRYL_HEAP( task->pthread, "_lib7_P_FileSys_chdir", NULL ); // status = chdir( c_dir ); // RECOVER_MYTHRYL_HEAP( task->pthread, "_lib7_P_FileSys_chdir" ); // unbuffer_mythryl_heap_value( &dir_buf ); } RETURN_VOID_EXCEPT_RAISE_SYSERR_ON_NEGATIVE_STATUS__MAY_HEAPCLEAN(task, status, NULL); }
Val _lib7_P_TTY_tcsetpgrp (Task* task, Val arg) { //===================== // // _lib7_P_TTY_tcsetpgrp : (Int, Int) -> Void // // Set foreground process group id of tty. // // This fn gets bound as tcsetpgrp in: // // src/lib/std/src/posix-1003.1b/posix-tty.pkg ENTER_MYTHRYL_CALLABLE_C_FN("_lib7_P_TTY_tcsetpgrp"); int fd = GET_TUPLE_SLOT_AS_INT(arg, 0); int pgrp = GET_TUPLE_SLOT_AS_INT(arg, 1); RELEASE_MYTHRYL_HEAP( task->pthread, "_lib7_P_TTY_tcsetpgrp", NULL ); // int status = tcsetpgrp( fd, pgrp ); // RECOVER_MYTHRYL_HEAP( task->pthread, "_lib7_P_TTY_tcsetpgrp" ); RETURN_VOID_EXCEPT_RAISE_SYSERR_ON_NEGATIVE_STATUS__MAY_HEAPCLEAN(task, status, NULL); }
Val _lib7_P_TTY_tcsendbreak (Task* task, Val arg) { //======================= // // Mythryl type: (Int, Int) -> Void // // Send break condition on tty line. // // This fn gets bound as tcsendbreak in: // // src/lib/std/src/posix-1003.1b/posix-tty.pkg ENTER_MYTHRYL_CALLABLE_C_FN("_lib7_P_TTY_tcsendbreak"); int fd = GET_TUPLE_SLOT_AS_INT( arg, 0 ); int duration = GET_TUPLE_SLOT_AS_INT( arg, 1 ); RELEASE_MYTHRYL_HEAP( task->pthread, "_lib7_P_TTY_tcsendbreak", NULL ); // int status = tcsendbreak( fd, duration ); // RECOVER_MYTHRYL_HEAP( task->pthread, "_lib7_P_TTY_tcsendbreak" ); RETURN_VOID_EXCEPT_RAISE_SYSERR_ON_NEGATIVE_STATUS__MAY_HEAPCLEAN(task, status, NULL); }
Val _lib7_P_ProcEnv_setgid (Task* task, Val arg) { //====================== // // Mythryl type: Unt -> Void // // Set group id. // // This fn gets bound as set_group_id in: // // src/lib/std/src/psx/posix-id.pkg ENTER_MYTHRYL_CALLABLE_C_FN(__func__); RELEASE_MYTHRYL_HEAP( task->hostthread, __func__, &arg ); // int status = setgid( WORD_LIB7toC( arg )); // 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; }
Val _lib7_P_FileSys_utime (Task* task, Val arg) { //===================== // // Mythryl type: (String, one_word_int::Int, one_word_int::Int) -> Void // name actime modtime // // Sets file access and modification times. // If actime = -1, then set both to current time. // // This fn gets bound as utime' 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); time_t actime = TUPLE_GET_INT1( arg, 1); time_t modtime = TUPLE_GET_INT1( 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*) heap_path, strlen( heap_path ) +1 ); // '+1' for terminal NUL on string. if (actime == -1) { RELEASE_MYTHRYL_HEAP( task->hostthread, __func__, NULL ); // status = utime( c_path, NULL ); // RECOVER_MYTHRYL_HEAP( task->hostthread, __func__ ); } else { struct utimbuf tb; tb.actime = actime; tb.modtime = modtime; RELEASE_MYTHRYL_HEAP( task->hostthread, __func__, NULL ); // status = utime( c_path, &tb ); // 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; }
static Val set__time_profiling_is_running__to (Task* task, Val arg) { // ================================== // // Mythryl type: Bool -> Void // // This dis/ables sending of SIGVTALRM signals to the process, // vs set_time_profiling_rw_vector() above which // dis/ables handling of SIGVTALRM signals by the process. // // This fn gets bound to set__time_profiling_is_running__to in: // // src/lib/std/src/nj/runtime-profiling-control.pkg ENTER_MYTHRYL_CALLABLE_C_FN("set__time_profiling_is_running__to"); #ifndef HAS_SETITIMER // return RAISE_ERROR__MAY_HEAPCLEAN(task, "time profiling not supported", NULL); // #else // "The system provides each process with three interval timers, // each decrementing in a distinct time domain. When any timer // expires, a signal is sent to the process, and the timer // (potentially) restarts. // // ITIMER_REAL Decrements in real time, and delivers SIGALRM upon expiration. // ITIMER_VIRTUAL Decrements only when the process is executing, and delivers SIGVTALRM upon expiration. // ITIMER_PROF Decrements both when the process executes and when the system is executing on behalf of the process. // Coupled with ITIMER_VIRTUAL, this timer is usually used to profile the time spent by the application // in user and kernel space. SIGPROF is delivered upon expiration. // // -- http://linux.about.com/library/cmd/blcmdl2_setitimer.htm // struct itimerval new_itv; if (arg == HEAP_FALSE) { // new_itv.it_interval.tv_sec = new_itv.it_value.tv_sec = new_itv.it_interval.tv_usec = new_itv.it_value.tv_usec = 0; } else if (time_profiling_rw_vector__global == HEAP_VOID) { // return RAISE_ERROR__MAY_HEAPCLEAN(task, "no time_profiling_rw_vector set", NULL); } else { // new_itv.it_interval.tv_sec = new_itv.it_value.tv_sec = 0; new_itv.it_interval.tv_usec = new_itv.it_value.tv_usec = MICROSECONDS_PER_SIGVTALRM; // From src/c/h/profiler-call-counts.h } int status = setitimer (ITIMER_VIRTUAL, &new_itv, NULL); RETURN_VOID_EXCEPT_RAISE_SYSERR_ON_NEGATIVE_STATUS__MAY_HEAPCLEAN(task, status, NULL); #endif }