| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | #include "master.hpp"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-04 02:46:13 -04:00
										 |  |  | namespace factor | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | /* Simple wrappers for ANSI C I/O functions, used for bootstrapping.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Note the ugly loop logic in almost every function; we have to handle EINTR | 
					
						
							|  |  |  | and restart the operation if the system call was interrupted. Naive | 
					
						
							|  |  |  | applications don't do this, but then they quickly fail if one enables | 
					
						
							|  |  |  | itimer()s or other signals. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The Factor library provides platform-specific code for Unix and Windows | 
					
						
							|  |  |  | with many more capabilities so these words are not usually used in | 
					
						
							|  |  |  | normal operation. */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-23 14:05:46 -04:00
										 |  |  | void factor_vm::init_c_io() | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-10-23 01:33:53 -04:00
										 |  |  | 	special_objects[OBJ_STDIN] = allot_alien(false_object,(cell)stdin); | 
					
						
							|  |  |  | 	special_objects[OBJ_STDOUT] = allot_alien(false_object,(cell)stdout); | 
					
						
							|  |  |  | 	special_objects[OBJ_STDERR] = allot_alien(false_object,(cell)stderr); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-23 14:05:46 -04:00
										 |  |  | void factor_vm::io_error() | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | { | 
					
						
							|  |  |  | 	if(errno == EINTR) | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-03-27 07:33:28 -04:00
										 |  |  | 	general_error(ERROR_IO,tag_fixnum(errno),false_object); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-05 00:52:55 -05:00
										 |  |  | FILE *factor_vm::safe_fopen(char *filename, char *mode) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	FILE *file; | 
					
						
							| 
									
										
										
										
											2010-02-24 03:47:45 -05:00
										 |  |  | 	for(;;) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2010-02-05 00:52:55 -05:00
										 |  |  | 		file = fopen(filename,mode); | 
					
						
							|  |  |  | 		if(file == NULL) | 
					
						
							|  |  |  | 			io_error(); | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2010-02-24 03:47:45 -05:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2010-02-05 00:52:55 -05:00
										 |  |  | 	return file; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int factor_vm::safe_fgetc(FILE *stream) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	int c; | 
					
						
							| 
									
										
										
										
											2010-02-24 03:47:45 -05:00
										 |  |  | 	for(;;) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2011-10-27 00:40:14 -04:00
										 |  |  | 		c = getc(stream); | 
					
						
							| 
									
										
										
										
											2010-02-05 00:52:55 -05:00
										 |  |  | 		if(c == EOF) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			if(feof(stream)) | 
					
						
							|  |  |  | 				return EOF; | 
					
						
							|  |  |  | 			else | 
					
						
							|  |  |  | 				io_error(); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2010-02-24 03:47:45 -05:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2010-02-05 00:52:55 -05:00
										 |  |  | 	return c; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | size_t factor_vm::safe_fread(void *ptr, size_t size, size_t nitems, FILE *stream) | 
					
						
							| 
									
										
										
										
											2010-01-19 15:01:11 -05:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-01-23 10:07:35 -05:00
										 |  |  | 	size_t items_read = 0; | 
					
						
							| 
									
										
										
										
											2010-02-24 03:47:45 -05:00
										 |  |  | 	size_t ret = 0; | 
					
						
							| 
									
										
										
										
											2010-01-19 15:01:11 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-24 03:47:45 -05:00
										 |  |  | 	do | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		ret = fread((void*)((int*)ptr+items_read*size),size,nitems-items_read,stream); | 
					
						
							|  |  |  | 		if(ret == 0) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			if(feof(stream)) | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			else | 
					
						
							|  |  |  | 				io_error(); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		items_read += ret; | 
					
						
							|  |  |  | 	} while(items_read != nitems); | 
					
						
							| 
									
										
										
										
											2010-01-19 15:01:11 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-23 10:07:35 -05:00
										 |  |  | 	return items_read; | 
					
						
							| 
									
										
										
										
											2010-01-19 15:01:11 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-05 00:52:55 -05:00
										 |  |  | void factor_vm::safe_fputc(int c, FILE *stream) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2010-02-24 03:47:45 -05:00
										 |  |  | 	for(;;) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2011-10-27 00:40:14 -04:00
										 |  |  | 		if(putc(c,stream) == EOF) | 
					
						
							| 
									
										
										
										
											2010-02-05 00:52:55 -05:00
										 |  |  | 			io_error(); | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2010-02-24 03:47:45 -05:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2010-02-05 00:52:55 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | size_t factor_vm::safe_fwrite(void *ptr, size_t size, size_t nitems, FILE *stream) | 
					
						
							| 
									
										
										
										
											2010-01-19 15:01:11 -05:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-01-23 10:07:35 -05:00
										 |  |  | 	size_t items_written = 0; | 
					
						
							| 
									
										
										
										
											2010-02-24 03:47:45 -05:00
										 |  |  | 	size_t ret = 0; | 
					
						
							| 
									
										
										
										
											2010-01-19 15:01:11 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-23 10:07:35 -05:00
										 |  |  | 	do { | 
					
						
							| 
									
										
										
										
											2010-02-24 03:47:45 -05:00
										 |  |  | 		ret = fwrite((void*)((int*)ptr+items_written*size),size,nitems-items_written,stream); | 
					
						
							|  |  |  | 		if(ret == 0) | 
					
						
							|  |  |  | 			io_error(); | 
					
						
							|  |  |  | 		items_written += ret; | 
					
						
							|  |  |  | 	} while(items_written != nitems); | 
					
						
							| 
									
										
										
										
											2010-01-19 15:01:11 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-23 10:07:35 -05:00
										 |  |  | 	return items_written; | 
					
						
							| 
									
										
										
										
											2010-01-19 15:01:11 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-05 00:52:55 -05:00
										 |  |  | int factor_vm::safe_ftell(FILE *stream) | 
					
						
							| 
									
										
										
										
											2010-01-19 15:01:11 -05:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-02-05 00:52:55 -05:00
										 |  |  | 	off_t offset; | 
					
						
							| 
									
										
										
										
											2010-02-24 03:47:45 -05:00
										 |  |  | 	for(;;) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2010-02-05 00:52:55 -05:00
										 |  |  | 		if((offset = FTELL(stream)) == -1) | 
					
						
							|  |  |  | 			io_error(); | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2010-02-24 03:47:45 -05:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2010-02-05 00:52:55 -05:00
										 |  |  | 	return offset; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void factor_vm::safe_fseek(FILE *stream, off_t offset, int whence) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	switch(whence) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 	case 0: whence = SEEK_SET; break; | 
					
						
							|  |  |  | 	case 1: whence = SEEK_CUR; break; | 
					
						
							|  |  |  | 	case 2: whence = SEEK_END; break; | 
					
						
							|  |  |  | 	default: | 
					
						
							|  |  |  | 		critical_error("Bad value for whence",whence); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2010-01-19 15:01:11 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-24 03:47:45 -05:00
										 |  |  | 	for(;;) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2010-02-05 00:52:55 -05:00
										 |  |  | 		if(FSEEK(stream,offset,whence) == -1) | 
					
						
							|  |  |  | 			io_error(); | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2010-02-24 03:47:45 -05:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2010-02-05 00:52:55 -05:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2010-01-19 15:01:11 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-05 00:52:55 -05:00
										 |  |  | void factor_vm::safe_fflush(FILE *stream) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2010-02-24 03:47:45 -05:00
										 |  |  | 	for(;;) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2010-02-05 00:52:55 -05:00
										 |  |  | 		if(fflush(stream) == EOF) | 
					
						
							|  |  |  | 			io_error(); | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2010-02-24 03:47:45 -05:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2010-02-05 00:52:55 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void factor_vm::safe_fclose(FILE *stream) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2010-02-24 03:47:45 -05:00
										 |  |  | 	for(;;) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2010-02-05 00:52:55 -05:00
										 |  |  | 		if(fclose(stream) == EOF) | 
					
						
							|  |  |  | 			io_error(); | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2010-02-24 03:47:45 -05:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2010-01-19 15:01:11 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-27 14:42:18 -04:00
										 |  |  | void factor_vm::primitive_fopen() | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-12-18 16:59:56 -05:00
										 |  |  | 	data_root<byte_array> mode(ctx->pop(),this); | 
					
						
							|  |  |  | 	data_root<byte_array> path(ctx->pop(),this); | 
					
						
							| 
									
										
										
										
											2009-08-17 16:37:15 -04:00
										 |  |  | 	mode.untag_check(this); | 
					
						
							|  |  |  | 	path.untag_check(this); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-19 15:01:11 -05:00
										 |  |  | 	FILE *file; | 
					
						
							| 
									
										
										
										
											2010-02-05 00:52:55 -05:00
										 |  |  | 	file = safe_fopen((char *)(path.untagged() + 1), | 
					
						
							| 
									
										
										
										
											2010-02-06 01:45:06 -05:00
										 |  |  | 		(char *)(mode.untagged() + 1)); | 
					
						
							| 
									
										
										
										
											2010-01-19 15:01:11 -05:00
										 |  |  | 	ctx->push(allot_alien(file)); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-18 16:59:56 -05:00
										 |  |  | FILE *factor_vm::pop_file_handle() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return (FILE *)alien_offset(ctx->pop()); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-27 14:42:18 -04:00
										 |  |  | void factor_vm::primitive_fgetc() | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-12-18 16:59:56 -05:00
										 |  |  | 	FILE *file = pop_file_handle(); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-05 00:52:55 -05:00
										 |  |  | 	int c = safe_fgetc(file); | 
					
						
							|  |  |  | 	if(c == EOF && feof(file)) | 
					
						
							| 
									
										
										
										
											2010-08-22 23:56:29 -04:00
										 |  |  | 	{ | 
					
						
							|  |  |  | 		clearerr(file); | 
					
						
							| 
									
										
										
										
											2010-02-05 00:52:55 -05:00
										 |  |  | 		ctx->push(false_object); | 
					
						
							| 
									
										
										
										
											2010-08-22 23:56:29 -04:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2010-02-05 00:52:55 -05:00
										 |  |  | 	else | 
					
						
							|  |  |  | 		ctx->push(tag_fixnum(c)); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-27 14:42:18 -04:00
										 |  |  | void factor_vm::primitive_fread() | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-12-18 16:59:56 -05:00
										 |  |  | 	FILE *file = pop_file_handle(); | 
					
						
							| 
									
										
										
										
											2011-10-11 02:00:03 -04:00
										 |  |  | 	void *buf = (void*)alien_offset(ctx->pop()); | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | 	fixnum size = unbox_array_size(); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if(size == 0) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2011-10-11 02:00:03 -04:00
										 |  |  | 		ctx->push(from_unsigned_cell(0)); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-11 02:00:03 -04:00
										 |  |  | 	size_t c = safe_fread(buf,1,size,file); | 
					
						
							|  |  |  | 	if(c == 0 || feof(file)) | 
					
						
							| 
									
										
										
										
											2010-08-22 23:56:29 -04:00
										 |  |  | 		clearerr(file); | 
					
						
							| 
									
										
										
										
											2011-10-11 02:00:03 -04:00
										 |  |  | 	ctx->push(from_unsigned_cell(c)); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-27 14:42:18 -04:00
										 |  |  | void factor_vm::primitive_fputc() | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-12-18 16:59:56 -05:00
										 |  |  | 	FILE *file = pop_file_handle(); | 
					
						
							|  |  |  | 	fixnum ch = to_fixnum(ctx->pop()); | 
					
						
							| 
									
										
										
										
											2010-05-06 01:32:45 -04:00
										 |  |  | 	safe_fputc((int)ch, file); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-27 14:42:18 -04:00
										 |  |  | void factor_vm::primitive_fwrite() | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-12-18 16:59:56 -05:00
										 |  |  | 	FILE *file = pop_file_handle(); | 
					
						
							| 
									
										
										
										
											2010-02-24 02:18:41 -05:00
										 |  |  | 	cell length = to_cell(ctx->pop()); | 
					
						
							|  |  |  | 	char *text = alien_offset(ctx->pop()); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if(length == 0) | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-24 02:18:41 -05:00
										 |  |  | 	size_t written = safe_fwrite(text,1,length,file); | 
					
						
							| 
									
										
										
										
											2010-01-19 15:01:11 -05:00
										 |  |  | 	if(written != length) | 
					
						
							|  |  |  | 		io_error(); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-03 19:20:35 -04:00
										 |  |  | void factor_vm::primitive_ftell() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2009-12-18 16:59:56 -05:00
										 |  |  | 	FILE *file = pop_file_handle(); | 
					
						
							| 
									
										
										
										
											2010-02-05 00:52:55 -05:00
										 |  |  | 	ctx->push(from_signed_8(safe_ftell(file))); | 
					
						
							| 
									
										
										
										
											2009-10-03 19:20:35 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-27 14:42:18 -04:00
										 |  |  | void factor_vm::primitive_fseek() | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-12-18 16:59:56 -05:00
										 |  |  | 	FILE *file = pop_file_handle(); | 
					
						
							| 
									
										
										
										
											2010-05-06 01:32:45 -04:00
										 |  |  | 	int whence = (int)to_fixnum(ctx->pop()); | 
					
						
							|  |  |  | 	off_t offset = (off_t)to_signed_8(ctx->pop()); | 
					
						
							| 
									
										
										
										
											2010-02-05 00:52:55 -05:00
										 |  |  | 	safe_fseek(file,offset,whence); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-27 14:42:18 -04:00
										 |  |  | void factor_vm::primitive_fflush() | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-12-18 16:59:56 -05:00
										 |  |  | 	FILE *file = pop_file_handle(); | 
					
						
							| 
									
										
										
										
											2010-02-05 00:52:55 -05:00
										 |  |  | 	safe_fflush(file); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-27 14:42:18 -04:00
										 |  |  | void factor_vm::primitive_fclose() | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-12-18 16:59:56 -05:00
										 |  |  | 	FILE *file = pop_file_handle(); | 
					
						
							| 
									
										
										
										
											2010-02-05 00:52:55 -05:00
										 |  |  | 	safe_fclose(file); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* This function is used by FFI I/O. Accessing the errno global directly is
 | 
					
						
							|  |  |  | not portable, since on some libc's errno is not a global but a funky macro that | 
					
						
							|  |  |  | reads thread-local storage. */ | 
					
						
							| 
									
										
										
										
											2009-08-17 16:37:07 -04:00
										 |  |  | VM_C_API int err_no() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2009-08-21 15:44:06 -04:00
										 |  |  | 	return errno; | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2009-05-04 02:46:13 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-03 18:20:24 -05:00
										 |  |  | VM_C_API void set_err_no(int err) | 
					
						
							| 
									
										
										
										
											2009-08-17 16:37:07 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-02-03 18:20:24 -05:00
										 |  |  | 	errno = err; | 
					
						
							| 
									
										
										
										
											2009-08-17 16:37:07 -04:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2009-05-04 02:46:13 -04:00
										 |  |  | } |