void kino_Host_callback(void *vobj, char *method, chy_u32_t num_args, ...) { kino_Obj *obj = (kino_Obj*)vobj; dSP; va_list args; int count; chy_u32_t i; SV *invoker; kino_VTable *vtable; if (KINO_OBJ_IS_A(obj, KINO_VTABLE)) { vtable = (kino_VTable*)obj; invoker = XSBind_cb_to_sv(vtable->name); } else { vtable = obj->vtable; invoker = (SV*)Kino_Obj_To_Host(obj); } ENTER; SAVETMPS; PUSHMARK(SP); XPUSHs( sv_2mortal(invoker) ); va_start(args, num_args); for (i = 0; i < num_args; i++) { PUSH_ARG(args, num_args); } va_end(args); PUTBACK; count = call_method(method, G_VOID|G_DISCARD); if (count != 0) { KINO_THROW("callback '%s' in '%o' returned too many values: %i32", method, Kino_VTable_Get_Name(vtable), (chy_i32_t)count); } PUTBACK; FREETMPS; LEAVE; }
static SV* do_callback_sv(kino_Obj *obj, char *method, chy_u32_t num_args, va_list args) { dSP; int num_returned; SV *return_val; SV *invoker; chy_u32_t i; if (KINO_OBJ_IS_A(obj, KINO_VTABLE)) { kino_VTable *vtable = (kino_VTable*)obj; invoker = XSBind_cb_to_sv(vtable->name); } else { invoker = (SV*)Kino_Obj_To_Host(obj); } ENTER; SAVETMPS; PUSHMARK(SP); XPUSHs( sv_2mortal(invoker) ); for (i = 0; i < num_args; i++) { PUSH_ARG(args, num_args); } PUTBACK; num_returned = call_method(method, G_SCALAR); SPAGAIN; if (num_returned != 1) { KINO_THROW("Bad number of return vals from %s: %i32", method, (chy_i32_t)num_returned); } return_val = POPs; PUTBACK; return return_val; }
/* We're lazy and just pass the arguments to fuse to interpret, but along * the way we sniff them to adjust logging, &ct appropriately. */ static void parse_commandline(int argc, char **argv, int *fuse_argc_out, char ***fuse_argv_out) { argv0 = strdup(basename(argv[0])); struct option long_opts[] = { {"version", 0, 0, 'V'}, {"help", 0, 0, 'h'}, {0, 0, 0, 0}, }; int fuse_argc = 0; char **fuse_argv = malloc(sizeof(char*) * FUSE_ARG_MAX); #define PUSH_ARG(_s) \ push_arg(&fuse_argc, fuse_argv, _s) PUSH_ARG(argv[0]); int opt; while ((opt = getopt_long(argc, argv, "dD:fhH:so:pu:V", long_opts, NULL)) != -1) { switch (opt) { case 'd': debug = true; log_level = LOG_LEVEL_DEBUG; daemonized = false; PUSH_ARG("-d"); break; case 'f': daemonized = false; PUSH_ARG("-f"); break; case 'H': host = optarg; break; case 'u': user = optarg; break; case 'p': passwd = getpass("Password: "******"please provide a database password"); break; case 'D': db = optarg; break; case 'S': unix_socket = optarg; break; case 'h': usage(); exit(0); break; case 's': PUSH_ARG("-s"); break; case 'V': PUSH_ARG("-V"); break; case 'o': PUSH_ARG("-o"); PUSH_ARG(optarg); break; case '?': exit(1); default: assert(0); } } static char *static_opts[] = { "-o", "big_writes", "-o", "default_permissions", }; int nstatic_opts = sizeof(static_opts) / sizeof(char*); for (int i = 0; i < nstatic_opts; ++i) PUSH_ARG(static_opts[i]); for (int i = optind; i < argc; ++i) PUSH_ARG(argv[i]); #undef PUSH_ARG *fuse_argc_out = fuse_argc; *fuse_argv_out = fuse_argv; }