void f_async_db_exec(){ array_t *info; db_t *db; info = allocate_empty_array(1); info->item[0].type = T_STRING; info->item[0].subtype = STRING_MALLOC; info->item[0].u.string = string_copy((sp-1)->u.string, "f_db_exec"); valid_database("exec", info); db = find_db_conn((sp-1)->u.number); if (!db) { error("Attempt to exec on an invalid database handle\n"); } if (db->type->cleanup) { db->type->cleanup(&(db->c)); } function_to_call_t *cb = get_cb(); process_efun_callback(2, cb, F_ASYNC_READ); cb->f.fp->hdr.ref++; add_db_exec(db, (sp-1)->u.string, cb); pop_2_elems(); }
void f_async_getdir(){ function_to_call_t *cb = get_cb(); process_efun_callback(1, cb, F_ASYNC_READ); cb->f.fp->hdr.ref++; add_getdir(check_valid_path((sp-1)->u.string, current_object, "get_dir", 0), cb); pop_2_elems(); }
void f_async_write(){ function_to_call_t *cb = get_cb(); process_efun_callback(3, cb, F_ASYNC_WRITE); cb->f.fp->hdr.ref++; add_write(check_valid_path((sp-3)->u.string, current_object, "write_file", 1), (sp-2)->u.string, strlen((sp-2)->u.string), (sp-1)->u.number, cb); pop_n_elems(4); }
void f_async_db_exec(){ array_t *info; db_t *db; info = allocate_empty_array(1); info->item[0].type = T_STRING; info->item[0].subtype = STRING_MALLOC; info->item[0].u.string = string_copy((sp-1)->u.string, "f_db_exec"); int num_arg = st_num_arg; valid_database("exec", info); db = find_db_conn((sp-2)->u.number); if (!db) { error("Attempt to exec on an invalid database handle\n"); } if(!db_mut){ db_mut = (pthread_mutex_t *) malloc(sizeof(pthread_mutex_t)); pthread_mutex_init(db_mut, NULL); } st_num_arg = num_arg; function_to_call_t *cb = get_cb(); process_efun_callback(2, cb, F_ASYNC_DB_EXEC); cb->f.fp->hdr.ref++; add_db_exec((sp-2)->u.number, cb); pop_3_elems(); }
void f_thread() { int sv[2]; fd = find_new_socket(); if (fd < 0) return fd; if (socketpair(PF_UNIX, SOCK_STREAM, 0, sv) == -1) return EESOCKET; ret = fork(); if (ret == -1) { error("fork() in debug() failed: %s\n", strerror(errno)); } if(ret){ close(sv[1]); lpc_socks[fd].fd = sv[0]; lpc_socks[fd].flags = S_EXTERNAL; set_read_callback(fd, sp-3); set_write_callback(fd, sp-2); set_close_callback(fd, sp-1); lpc_socks[fd].owner_ob = current_object; lpc_socks[fd].mode = MUD; lpc_socks[fd].state = STATE_DATA_XFER; memset((char *) &lpc_socks[fd].l_addr, 0, sizeof(lpc_socks[fd].l_addr)); memset((char *) &lpc_socks[fd].r_addr, 0, sizeof(lpc_socks[fd].r_addr)); lpc_socks[fd].owner_ob = current_object; lpc_socks[fd].release_ob = NULL; lpc_socks[fd].r_buf = NULL; lpc_socks[fd].r_off = 0; lpc_socks[fd].r_len = 0; lpc_socks[fd].w_buf = NULL; lpc_socks[fd].w_off = 0; lpc_socks[fd].w_len = 0; current_object->flags |= O_EFUN_SOCKET; return fd; } close(sv[0]); function_to_call_t cb; memset(&cb, 0, sizeof(function_to_call_t)); process_efun_callback(0, &cb, F_THREAD); for(i=0; i<5; i++) if(external_port[i].port) close(external_port[i].fd); //close external ports for(i=0;i<sizeof(lpc_socks)/sizeof(lpc_socks[0]);i++) close(lpc_sock[i].fd); svalue_t *res = call_efun_callback(&cb, 1); switch (res->type) { case T_OBJECT: break; default: save_svalue_depth = 0; int len = svalue_save_size(message); if (save_svalue_depth > MAX_SAVE_SVALUE_DEPTH) { OS_socket_write(sv[1], "\x00\x00\x00\x11\"result too big\"", 21); break; } char *buf = (char *) DMALLOC(len + 5, TAG_TEMPORARY, "socket_write: default"); if (buf == NULL) break; *(INT_32 *) buf = htonl((long) len); len += 4; buf[4] = '\0'; p = buf + 4; save_svalue(message, &p); int ret,written = 0; while(written < len){ ret = OS_socket_write(sv[1], buf+written, len-written); if(ret < 0) break; written += ret; } break; } fflush(0); exit(0); }
//string pcre_replace_callback(string, string, function) void f_pcre_replace_callback(void) { int num_arg = st_num_arg, i; char *ret; pcre_t *run; svalue_t *arg; array_t *arr, *r; function_to_call_t ftc; arg = sp - num_arg + 1; run = CALLOCATE(1, pcre_t, TAG_TEMPORARY, "f_pcre_replace: run"); run->ovector = NULL; run->ovecsize = 0; run->subject = arg->u.string; assign_svalue_no_free(&run->pattern, (arg + 1)); run->s_length = SVALUE_STRLEN(arg); if(pcre_magic(run) < 0) { pcre_free_memory(run); error("PCRE compilation failed at offset %d: %s\n", run->erroffset, run->error); } if (run->rc < 0) /* No match. could do handling of matching errors if wanted */ { pop_n_elems(num_arg-1); pcre_free_memory(run); return; } if (run->rc > (run->ovecsize/3-1)) { pcre_free_memory(run); error("Too many substrings.\n"); } arr = pcre_get_substrings(run); if(arg[2].type == T_FUNCTION || arg[2].type == T_STRING) process_efun_callback(2, &ftc, F_PCRE_REPLACE_CALLBACK); else {// 0 pcre_free_memory(run); error("Illegal third argument (0) to pcre_replace_callback"); } r = allocate_array(run->rc - 1); //can't use the empty variant in case we error below push_refed_array(r); push_refed_array(arr); error_context_t econ; if (!save_context(&econ)){ pcre_free_memory(run); error("context stack full!\n"); } if (SETJMP(econ.context)) { restore_context(&econ); /* condition was restored to where it was when we came in */ pcre_free_memory(run); pop_context(&econ); error("error in callback!\n"); } for (i = 0; i < run->rc - 1; i++) { svalue_t *v; push_svalue(arr->item + i); push_number(i); v = call_efun_callback(&ftc, 2); /* Mimic behaviour of map(string, function) when function pointer returns null, ie return the input. */ if (v && v->type == T_STRING && v->u.string != NULL) assign_svalue_no_free(&r->item[i], v); else assign_svalue_no_free(&r->item[i], &arr->item[i]); } pop_context(&econ); ret = pcre_get_replace(run, r); pop_n_elems(num_arg+2); //refed arrays push_malloced_string(ret); pcre_free_memory(run); return; }