static int64_t posix_write(SgObject self, uint8_t *buf, int64_t size) { int64_t result; do { result = write(SG_FD(self)->fd, buf, size); } while (result < 0 && errno == EINTR); setLastError(self); if (result < 0) { SgObject err = get_last_error_message(self); Sg_IOWriteError(SG_INTERN("file writer"), err, SG_FALSE, self); } return result; }
static int posix_ready(SgObject self) { #ifdef HAVE_SELECT struct timeval tm = {0 , 0}; fd_set fds; int state; FD_ZERO(&fds); /* what would be the best behaviour if the given FD is larger than FD_SETSIZE? I don't like predicates raise an error, so for now I only return #f. */ /* if FD id less than 0, then it must be invalid and signaled error by now but just in case. (NB: I've seen bunch of stack overflow dump on 64 bit Linux, checking negative FD may prevent it) */ if (SG_FD(self)->fd < 0 || SG_FD(self)->fd >= FD_SETSIZE) return FALSE; FD_SET(SG_FD(self)->fd, &fds); state = select(SG_FD(self)->fd + 1, &fds, NULL, NULL, &tm); if (state < 0) { /* in this case it's basically bad file descriptor means either it's closed or exceed the FD_SETSIZE. However, I don't think predicate should raise an error so just return FALSE. */ #if 0 SgObject err; if (errno == EINTR) return FALSE; setLastError(self); err = Sg_Sprintf(UC("%A [FD %d]"), get_last_error_message(self), SG_FD(self)->fd); Sg_IOError(-1, SG_INTERN("file ready"), err, self, self); #endif return FALSE; } return (state != 0); #else /* default true */ return TRUE; #endif }
SgObject Sg_FileErrorMessage(SgObject file) { return get_last_error_message(file); }
ERROR_CODE error_module_diag(unsigned char **message_pointer) { /* sets the message pointer with the current last error message then returns normally */ *message_pointer = get_last_error_message(); RAISE_NO_ERROR; }
int main(int argc, char *argv[]) { struct rooted_tree *tree; struct parameters params; int align_leaves; int with_scale_bar; enum display_status status; void (*node_destroyer)(struct rnode *) = NULL; params = get_params(argc, argv); if (params.svg) { set_svg_parameters(params); if(! svg_init()) { fprintf (stderr, "%s\n", get_last_error_message()); exit(EXIT_FAILURE); } node_destroyer = destroy_svg_node_data; } while (NULL != (tree = parse_tree())) { align_leaves = is_cladogram(tree); /* show scale bar IFF tree is NOT a cladogram. Since * is_cladogram() takes some time to run, we just look * up 'align_leaves' which has the same value. */ with_scale_bar = !align_leaves; /* User can also suppress scale bar */ if (params.no_scale_bar) with_scale_bar = FALSE; if (params.svg) { svg_header(leaf_count(tree), with_scale_bar); svg_run_params_comment(argc, argv); status = display_svg_tree(tree, align_leaves, with_scale_bar, params.branch_length_unit); switch(status) { case DISPLAY_OK: break; assert(0); case DISPLAY_MEM_ERROR: perror(NULL); exit(EXIT_FAILURE); /* The following two should never happen */ case DISPLAY_UNKNOWN_STYLE: default: assert(0); } svg_footer(); } else { prettify_labels(tree); status = display_tree(tree, params.width, align_leaves, params.inner_label_pos, with_scale_bar, params.branch_length_unit, params.scale_zero_at_root); switch(status) { case DISPLAY_OK: break; assert(0); case DISPLAY_MEM_ERROR: perror(NULL); exit(EXIT_FAILURE); /* The following two should never happen */ case DISPLAY_UNKNOWN_STYLE: default: assert(0); } } destroy_tree_cb(tree, node_destroyer); } return 0; }