static int unmount_root(void) { int r; if (!root->mounted) return -EINVAL; mounts_remove(root); if (root->session) fuse_session_destroy(root->session); // also destroys root->channel if (root->channel_fd >= 0) (void) close(root->channel_fd); // only use fuse_unmount if there are no nested mounts if (nmounts == 0) fuse_unmount(root->mountpoint); fuse_opt_free_args(&root->args); free(root->mountpoint); free(root->fstitch_path); hash_map_destroy(root->parents); memset(root, 0, sizeof(*root)); free(root); root = NULL; if ((r = helper_shutdown()) < 0) fprintf(stderr, "%s(): helper_shutdown() failed (%d), continuing anyway\n", __FUNCTION__, r); destroy_locals(); return 0; }
struct compile_error expr_parse(struct input ci, struct expr_environ *env, struct parse_options opts, struct objcode **ocode) { struct compile_error ret; struct chain locals = new_chain(); struct proto_obj outp; char *end_ptr; int error = -E_OK, prev_stat=NADA, input_counter = 0; ret = init_ce(); *ocode = NULL; end_ptr = ""; /*force an input read ("" != NULL) */ //error = load_expr(&outp, expr); error = po_init(&outp, opts.n_args, opts.n_rets); while (error == -E_OK && end_ptr != NULL) { char *startptr = end_ptr; data_t tmp_data; int tmp_int; char *ident = NULL; if (eatspace(startptr, &end_ptr)) { /* do nothing */ } else if (*startptr == TERM) { startptr = end_ptr = get_input(ci); } else if (prev_stat == NADA && atodata_load(startptr, &end_ptr, &tmp_data)){ error = inject_data(&outp, tmp_data); prev_stat = NADA; } else if (prev_stat == ARG || prev_stat == NCLEAR) { if (atoint_load(startptr, &end_ptr, &tmp_int)) { if (prev_stat == ARG) error = inject_arg(&outp, tmp_int); else error = inject_nclear(&outp, tmp_int); } else { error = -EXPR_EXPECTING_INT; } prev_stat = NADA; } else if (loadtok(&ident, startptr, &end_ptr)) { int l_index; struct expr_var *tmp_var; if (prev_stat == NADA) { int kwn = strtoKW(ident); switch (kwn) { case KW_VARSET: prev_stat = VARSET; break; case KW_ARG: prev_stat = ARG; break; case KW_FULLCLEAR: error = inject_clear(&outp); prev_stat = NADA; break; case KW_NCLEAR: prev_stat = NCLEAR; break; default: /* not a kw */ { struct expr_func *tmp_fn; struct expr_const *tmp_const; int l_index; if ((l_index = strtoLocal(&locals, ident )) != _NO_SUCH_LOCAL) { error = inject_localvar_get(&outp, l_index); } else if ((tmp_var = strtoVar(&env->vars, ident)) != NULL) { error = inject_globalvar_get(&outp, tmp_var); } else if ((tmp_fn = strtoFun(env, ident)) != NULL) { error = inject_fn(&outp, tmp_fn); } else if ((tmp_const = strtoConst(env, ident)) != NULL) { error = inject_const(&outp, tmp_const); } else { error = -EXPR_NOSYM; } } } } else { if (strtoKW(ident) != NOT_A_KW) { if (prev_stat == VARSET) error = -EXPR_EXPECTING_VAR; else error = -EXPR_EXPECTING_VALUE; } else if (prev_stat == VARSET) { if ((l_index = strtoLocal(&locals, ident )) != _NO_SUCH_LOCAL) { error = inject_localvar_set(&outp, l_index); } else if ((tmp_var = strtoVar(&env->vars, ident)) != NULL) { error = inject_globalvar_set(&outp, tmp_var); } else { l_index =inject_localvar_setdeclare( &outp); if (l_index < 0) { error = l_index; } else { error = ins_local(&locals, ident, l_index); } } } else { error = -EXPR_NOSYM; } prev_stat = NADA; } } else { error = -EXPR_NOSYM; } input_counter += end_ptr - startptr; if (error != -E_OK) { ret.pos = input_counter; ret.lineno = get_lineno(ci); ret.type = error; if (ident != NULL) { ret.fname = ident; ident = NULL; /* prevent free() */ } else { ret.fname = strndup(startptr, end_ptr - startptr); } } free(ident); } { char *bad_string; switch (ret.type) { case -EXPR_ARG_OORANGE: ret.n = query_bad_argument(&outp); break; case -EXPR_FEWARGS: ret.n = query_bf_in(&outp); ret.m = query_bf_real(&outp); break; default: /* <-- includes EXPECTING_STH */ break; case -E_OK: { int nr = query_excess_rets(&outp); if (!opts.auto_clear && nr > 0) ret.type = -EXPR_MANYVALUES; if (ret.type != -E_OK) ret.n = query_n_rets(&outp); else if ((*ocode = po_compile(&outp))==NULL) ret.type = query_status(&outp); } break; } if (ret.fname == NULL && (bad_string = query_bad_fname(&outp)) != NULL) { ret.fname = strdup(bad_string); } } destroy_locals(&locals); if (*ocode == NULL) { po_abort(&outp); } return ret; }