/* * readdir.c - illumos/Solaris compatible version for dune * * This file replaces otherlibs/stdune/dune_filesystem_stubs/readdir.c * in dune to fix compilation on illumos/Solaris where struct dirent * does not have d_type field. * * Apply by copying this file to: * dune-X.Y.Z/otherlibs/stdune/dune_filesystem_stubs/readdir.c * * For opam's bundled dune-local: * opam-X.Y.Z/src_ext/dune-local/otherlibs/stdune/dune_filesystem_stubs/readdir.c */ #include #include #include #include #include #ifndef _WIN32 #include #include #include #include /* illumos/Solaris compatibility - d_type not in struct dirent */ #ifndef DT_UNKNOWN #define DT_UNKNOWN 0 #define DT_FIFO 1 #define DT_CHR 2 #define DT_DIR 4 #define DT_BLK 6 #define DT_REG 8 #define DT_LNK 10 #define DT_SOCK 12 #define DT_WHT 14 #define ILLUMOS_NO_DTYPE 1 #endif typedef struct dirent directory_entry; value val_file_type(int typ) { switch(typ) { #ifndef __HAIKU__ case DT_REG: return Val_int(0); case DT_DIR: return Val_int(1); case DT_CHR: return Val_int(2); case DT_BLK: return Val_int(3); case DT_LNK: return Val_int(4); case DT_FIFO: return Val_int(5); case DT_SOCK: return Val_int(6); case DT_UNKNOWN: return Val_int(7); #endif default: return Val_int(7); } } CAMLprim value caml__dune_filesystem_stubs__readdir(value vd) { CAMLparam1(vd); CAMLlocal2(v_filename, v_tuple); DIR * d; directory_entry * e; d = DIR_Val(vd); if (d == (DIR *) NULL) unix_error(EBADF, "readdir", Nothing); caml_enter_blocking_section(); errno = 0; e = readdir((DIR *) d); caml_leave_blocking_section(); if (e == (directory_entry *) NULL) { if(errno == 0) { CAMLreturn(Val_int(0)); } else { uerror("readdir", Nothing); } } v_filename = caml_copy_string(e->d_name); v_tuple = caml_alloc_small(2, 0); Field(v_tuple, 0) = v_filename; #if defined(__HAIKU__) || defined(ILLUMOS_NO_DTYPE) /* illumos/Solaris don't have d_type, always return unknown */ Field(v_tuple, 1) = Val_int(7); #else Field(v_tuple, 1) = val_file_type(e->d_type); #endif CAMLreturn(v_tuple); } #else CAMLprim value caml__dune_filesystem_stubs__readdir(value vd) { unix_error(ENOSYS, "readdir", Nothing); } #endif #include #ifdef _WIN32 #include void dune_wait4(value v_pid, value flags) { caml_failwith("wait4: not supported"); } #else #include #include #include #include #include #include #include #include #include #include #define TAG_WEXITED 0 #define TAG_WSIGNALED 1 #define TAG_WSTOPPED 2 CAMLextern int caml_rev_convert_signal_number(int); static value alloc_process_status(int status) { value st; if (WIFEXITED(status)) { st = caml_alloc_small(1, TAG_WEXITED); Field(st, 0) = Val_int(WEXITSTATUS(status)); } else if (WIFSTOPPED(status)) { st = caml_alloc_small(1, TAG_WSTOPPED); Field(st, 0) = Val_int(caml_rev_convert_signal_number(WSTOPSIG(status))); } else { st = caml_alloc_small(1, TAG_WSIGNALED); Field(st, 0) = Val_int(caml_rev_convert_signal_number(WTERMSIG(status))); } return st; } static int wait_flag_table[] = {WNOHANG, WUNTRACED}; value dune_wait4(value v_pid, value flags) { CAMLparam2(v_pid, flags); CAMLlocal2(times, res); int pid, status, cv_flags = caml_convert_flag_list(flags, wait_flag_table); struct rusage ru; struct timeval tp; memset(&ru, 0, sizeof(ru)); caml_enter_blocking_section(); pid = waitpid(Int_val(v_pid), &status, cv_flags); if (pid > 0) getrusage(RUSAGE_CHILDREN, &ru); gettimeofday(&tp, NULL); caml_leave_blocking_section(); if (pid == -1) uerror("wait4", Nothing); times = caml_alloc_small(2 * Double_wosize, Double_array_tag); Store_double_field(times, 0, ru.ru_utime.tv_sec + ru.ru_utime.tv_usec / 1e6); Store_double_field(times, 1, ru.ru_stime.tv_sec + ru.ru_stime.tv_usec / 1e6); res = caml_alloc_tuple(4); Store_field(res, 0, Val_int(pid)); Store_field(res, 1, alloc_process_status(status)); Store_field(res, 2, caml_copy_double(((double)tp.tv_sec + (double)tp.tv_usec / 1e6))); Store_field(res, 3, times); CAMLreturn(res); } #endif /* * winsize.c - illumos/Solaris compatible version for notty (used by dune) * * This file replaces vendor/notty/src-unix/native/winsize.c * in dune to fix compilation on illumos/Solaris where TIOCGWINSZ * is defined in sys/termios.h rather than sys/ioctl.h. * * Apply by copying this file to: * dune-X.Y.Z/vendor/notty/src-unix/native/winsize.c * * For opam's bundled dune-local: * opam-X.Y.Z/src_ext/dune-local/vendor/notty/src-unix/native/winsize.c */ #include #include #include #ifdef __sun /* illumos/Solaris: struct winsize and TIOCGWINSZ in termios */ #include #include #else #include #endif #include #include CAMLprim value caml_notty_winsize (value fd) { #ifdef TIOCGWINSZ struct winsize w; if (ioctl(Int_val(fd), TIOCGWINSZ, &w) == -1) caml_failwith("ioctl"); value res = caml_alloc_small(2, 0); Field(res, 0) = Val_int(w.ws_col); Field(res, 1) = Val_int(w.ws_row); return res; #else /* Fallback: return default 80x24 */ value res = caml_alloc_small(2, 0); Field(res, 0) = Val_int(80); Field(res, 1) = Val_int(24); return res; #endif } /* Return SIGWINCH signal number */ CAMLprim value caml_notty_winch_number (value unit) { #ifdef SIGWINCH return Val_int(SIGWINCH); #else return Val_int(0); #endif }