5 s64 current_millis(void)
9 return (s64)t.tv_sec * 1000 + t.tv_usec / 1000;
12 void sleep_millis(CELL msec)
19 /* NULL_DLL is "libfactor.dylib" for OS X and NULL for generic unix */
20 null_dll = dlopen(NULL_DLL,RTLD_LAZY);
23 void ffi_dlopen(F_DLL *dll, bool error)
25 void *dllptr = dlopen(alien_offset(dll->path), RTLD_LAZY);
31 general_error(ERROR_FFI,F,
32 tag_object(from_char_string(dlerror())),
44 void *ffi_dlsym(F_DLL *dll, F_SYMBOL *symbol)
46 void *handle = (dll == NULL ? null_dll : dll->dll);
47 return dlsym(handle,symbol);
50 void ffi_dlclose(F_DLL *dll)
54 general_error(ERROR_FFI,tag_object(
55 from_char_string(dlerror())),F,NULL);
60 DEFINE_PRIMITIVE(stat)
64 if(stat(unbox_char_string(),&sb) < 0)
73 box_boolean(S_ISDIR(sb.st_mode));
74 box_signed_4(sb.st_mode & ~S_IFMT);
75 box_unsigned_8(sb.st_size);
76 box_unsigned_8(sb.st_mtime);
80 /* Allocates memory */
81 CELL parse_dir_entry(struct dirent *file)
83 CELL name = tag_object(from_char_string(file->d_name));
84 if(UNKNOWN_TYPE_P(file))
88 CELL dirp = tag_boolean(DIRECTORY_P(file));
89 return allot_array_2(name,dirp);
93 DEFINE_PRIMITIVE(read_dir)
95 DIR* dir = opendir(unbox_char_string());
96 GROWABLE_ARRAY(result);
102 while((file = readdir(dir)) != NULL)
104 REGISTER_UNTAGGED(result);
105 CELL pair = parse_dir_entry(file);
106 UNREGISTER_UNTAGGED(result);
107 GROWABLE_ADD(result,pair);
113 GROWABLE_TRIM(result);
115 dpush(tag_object(result));
118 DEFINE_PRIMITIVE(cwd)
121 if(getcwd(wd,MAXPATHLEN) == NULL)
128 chdir(unbox_char_string());
131 F_SEGMENT *alloc_segment(CELL size)
133 int pagesize = getpagesize();
135 char *array = mmap(NULL,pagesize + size + pagesize,
136 PROT_READ | PROT_WRITE | PROT_EXEC,
137 MAP_ANON | MAP_PRIVATE,-1,0);
139 if(array == (char*)-1)
140 fatal_error("Out of memory in alloc_segment",0);
142 if(mprotect(array,pagesize,PROT_NONE) == -1)
143 fatal_error("Cannot protect low guard page",(CELL)array);
145 if(mprotect(array + pagesize + size,pagesize,PROT_NONE) == -1)
146 fatal_error("Cannot protect high guard page",(CELL)array);
148 F_SEGMENT *retval = safe_malloc(sizeof(F_SEGMENT));
150 retval->start = (CELL)(array + pagesize);
152 retval->end = retval->start + size;
157 void dealloc_segment(F_SEGMENT *block)
159 int pagesize = getpagesize();
161 int retval = munmap((void*)(block->start - pagesize),
162 pagesize + block->size + pagesize);
165 fatal_error("dealloc_segment failed",0);
170 INLINE F_STACK_FRAME *uap_stack_pointer(void *uap)
172 /* There is a race condition here, but in practice a signal
173 delivered during stack frame setup/teardown or while transitioning
174 from Factor to C is a sign of things seriously gone wrong, not just
175 a divide by zero or stack underflow in the listener */
176 if(in_code_heap_p(UAP_PROGRAM_COUNTER(uap)))
177 return ucontext_stack_pointer(uap);
182 void memory_signal_handler_impl(void)
184 memory_protection_error(signal_fault_addr,signal_callstack_top);
187 void memory_signal_handler(int signal, siginfo_t *siginfo, void *uap)
189 signal_fault_addr = (CELL)siginfo->si_addr;
190 signal_callstack_top = uap_stack_pointer(uap);
191 UAP_PROGRAM_COUNTER(uap) = (CELL)memory_signal_handler_impl;
194 void misc_signal_handler_impl(void)
196 signal_error(signal_number,signal_callstack_top);
199 void misc_signal_handler(int signal, siginfo_t *siginfo, void *uap)
201 signal_number = signal;
202 signal_callstack_top = uap_stack_pointer(uap);
203 UAP_PROGRAM_COUNTER(uap) = (CELL)misc_signal_handler_impl;
206 static void sigaction_safe(int signum, const struct sigaction *act, struct sigaction *oldact)
211 ret = sigaction(signum, act, oldact);
213 while(ret == -1 && errno == EINTR);
216 void unix_init_signals(void)
218 struct sigaction memory_sigaction;
219 struct sigaction misc_sigaction;
220 struct sigaction ignore_sigaction;
222 memset(&memory_sigaction,0,sizeof(struct sigaction));
223 sigemptyset(&memory_sigaction.sa_mask);
224 memory_sigaction.sa_sigaction = memory_signal_handler;
225 memory_sigaction.sa_flags = SA_SIGINFO;
227 sigaction_safe(SIGBUS,&memory_sigaction,NULL);
228 sigaction_safe(SIGSEGV,&memory_sigaction,NULL);
230 memset(&misc_sigaction,0,sizeof(struct sigaction));
231 sigemptyset(&misc_sigaction.sa_mask);
232 misc_sigaction.sa_sigaction = misc_signal_handler;
233 misc_sigaction.sa_flags = SA_SIGINFO;
235 sigaction_safe(SIGABRT,&misc_sigaction,NULL);
236 sigaction_safe(SIGFPE,&misc_sigaction,NULL);
237 sigaction_safe(SIGQUIT,&misc_sigaction,NULL);
238 sigaction_safe(SIGILL,&misc_sigaction,NULL);
240 memset(&ignore_sigaction,0,sizeof(struct sigaction));
241 sigemptyset(&ignore_sigaction.sa_mask);
242 ignore_sigaction.sa_handler = SIG_IGN;
243 sigaction_safe(SIGPIPE,&ignore_sigaction,NULL);
246 void reset_stdio(void)