static void caching_topic_exec(void *data, struct stasis_subscription *sub, struct stasis_message *message) { RAII_VAR(struct stasis_caching_topic *, caching_topic_needs_unref, NULL, ao2_cleanup); struct stasis_caching_topic *caching_topic = data; const char *id = NULL; ast_assert(caching_topic != NULL); ast_assert(caching_topic->topic != NULL); ast_assert(caching_topic->cache != NULL); ast_assert(caching_topic->cache->id_fn != NULL); if (stasis_subscription_final_message(sub, message)) { caching_topic_needs_unref = caching_topic; } /* Handle cache clear event */ if (stasis_cache_clear_type() == stasis_message_type(message)) { RAII_VAR(struct stasis_message *, old_snapshot, NULL, ao2_cleanup); RAII_VAR(struct stasis_message *, update, NULL, ao2_cleanup); struct stasis_message *clear_msg = stasis_message_data(message); const char *clear_id = caching_topic->cache->id_fn(clear_msg); struct stasis_message_type *clear_type = stasis_message_type(clear_msg); ast_assert(clear_type != NULL); if (clear_id) { old_snapshot = cache_put(caching_topic->cache, clear_type, clear_id, NULL); if (old_snapshot) { update = update_create(old_snapshot, NULL); stasis_publish(caching_topic->topic, update); return; } ast_log(LOG_ERROR, "Attempting to remove an item from the %s cache that isn't there: %s %s\n", stasis_topic_name(caching_topic->topic), stasis_message_type_name(clear_type), clear_id); return; } } id = caching_topic->cache->id_fn(message); if (id == NULL) { /* Object isn't cached; discard */ } else { /* Update the cache */ RAII_VAR(struct stasis_message *, old_snapshot, NULL, ao2_cleanup); RAII_VAR(struct stasis_message *, update, NULL, ao2_cleanup); old_snapshot = cache_put(caching_topic->cache, stasis_message_type(message), id, message); update = update_create(old_snapshot, message); if (update == NULL) { return; } stasis_publish(caching_topic->topic, update); } }
void op_indpat(mval *v, mval *dst) { int rval; icode_str indir_src; mstr *obj, object; oprtype x, getdst; DCL_THREADGBL_ACCESS; SETUP_THREADGBL_ACCESS; MV_FORCE_STR(v); indir_src.str = v->str; indir_src.code = indir_pattern; if (NULL == (obj = cache_get(&indir_src))) { obj = &object; comp_init(&v->str, &getdst); source_column = 1; /* to coordinate with scanner redirection*/ rval = compile_pattern(&x, (TK_ATSIGN == TREF(window_token))); if (EXPR_FAIL == comp_fini(rval, obj, OC_IRETMVAL, &x, &getdst, v->str.len)) return; indir_src.str.addr = v->str.addr; cache_put(&indir_src, obj); /* Fall into code activation below */ } TREF(ind_result) = dst; /* Where to store return value */ comp_indr(obj); return; }
bool oid2name_from_file(const char *file) { FILE *fp; Oid oid; char name[NAMEDATALEN]; if ( (fp = fopen(file, "r"))==NULL ) { fprintf(stderr, "ERROR: %s not found.\n", file); return false; } printf("NOTICE: Using '%s' as an oid2name cache file.\n", file); while ( fscanf(fp, "%d %s", &oid, name)>=2 ) { // printf("oid=%d, name=%s\n", oid, name); cache_put(oid, name); } fclose(fp); return true; }
void op_indfun(mval *v, mint code, mval *dst) { bool rval; mstr *obj, object; oprtype x; unsigned char argcode; error_def(ERR_INDMAXNEST); argcode = (unsigned char)code; assert(UCHAR_MAX >= code); /* if not, the assignment to argcode is lossy */ assert(indir_opcode[argcode]); MV_FORCE_STR(v); if (!(obj = cache_get(argcode, &v->str))) { comp_init(&v->str); rval = (*indir_fcn[argcode])(&x, indir_opcode[argcode]); if (!comp_fini(rval, &object, OC_IRETMVAL, &x, v->str.len)) return; cache_put(argcode, &v->str, &object); *ind_result_sp++ = dst; if (ind_result_sp >= ind_result_top) rts_error(VARLSTCNT(1) ERR_INDMAXNEST); comp_indr(&object); return; } *ind_result_sp++ = dst; if (ind_result_sp >= ind_result_top) rts_error(VARLSTCNT(1) ERR_INDMAXNEST); comp_indr(obj); return; }
void * bg_db_get_thumbnail(bg_db_t * db, int64_t id, int max_width, int max_height, const char * mimetype) { browse_t b; int64_t thumb_id; if((thumb_id = cache_get(&db->th_cache, id, max_width, max_height, mimetype)) > 0) return bg_db_object_query(db, thumb_id); memset(&b, 0, sizeof(b)); b.max_width = max_width; b.max_height = max_height; b.mimetype = mimetype; bg_db_browse_thumbnails(db, id, browse_callback, &b); if(!b.ret) { bg_db_object_t * img = bg_db_object_query(db, id); b.ret = make_thumbnail(db, img, max_width, max_height, mimetype); bg_db_object_unref(img); } cache_put(&db->th_cache, id, max_width, max_height, mimetype, bg_db_object_get_id(b.ret)); return b.ret; }
void op_indpat(mval *v, mval *dst) { bool rval; mstr *obj, object; oprtype x; error_def(ERR_INDMAXNEST); MV_FORCE_STR(v); if (!(obj = cache_get(indir_pattern, &v->str))) { comp_init(&v->str); source_column = 1; /* to coordinate with scanner redirection*/ rval = compile_pattern(&x,window_token == TK_ATSIGN); if (comp_fini(rval, &object, OC_IRETMVAL, &x, v->str.len)) { cache_put(indir_pattern, &v->str, &object); *ind_result_sp++ = dst; if (ind_result_sp >= ind_result_top) rts_error(VARLSTCNT(1) ERR_INDMAXNEST); comp_indr(&object); } } else { *ind_result_sp++ = dst; if (ind_result_sp >= ind_result_top) rts_error(VARLSTCNT(1) ERR_INDMAXNEST); comp_indr(obj); } }
void op_indglvn(mval *v,mval *dst) { bool rval; mstr *obj, object; oprtype x; lv_val *a; icode_str indir_src; lv_val *lv; var_tabent targ_key; ht_ent_mname *tabent; error_def(ERR_INDMAXNEST); error_def(ERR_UNDEF); MV_FORCE_STR(v); indir_src.str = v->str; indir_src.code = indir_glvn; if (NULL == (obj = cache_get(&indir_src))) { if (valid_mname(&v->str)) { targ_key.var_name = v->str; COMPUTE_HASH_MNAME(&targ_key); tabent = lookup_hashtab_mname(&curr_symval->h_symtab, &targ_key); assert(NULL == tabent || NULL != tabent->value); if (!tabent || !MV_DEFINED(&((lv_val *)tabent->value)->v)) { if (undef_inhibit) { *dst = literal_null; return; } else rts_error(VARLSTCNT(4) ERR_UNDEF, 2, v->str.len, v->str.addr); } a = (lv_val *)tabent->value; *dst = a->v; return; } comp_init(&v->str); rval = glvn(&x); if (comp_fini(rval, &object, OC_IRETMVAL, &x, v->str.len)) { indir_src.str.addr = v->str.addr; cache_put(&indir_src, &object); *ind_result_sp++ = dst; if (ind_result_sp >= ind_result_top) rts_error(VARLSTCNT(1) ERR_INDMAXNEST); comp_indr(&object); } } else { *ind_result_sp++ = dst; if (ind_result_sp >= ind_result_top) rts_error(VARLSTCNT(1) ERR_INDMAXNEST); comp_indr(obj); } }
static void rsi_put(struct cache_head *item, struct cache_detail *cd) { struct rsi *rsii = container_of(item, struct rsi, h); if (cache_put(item, cd)) { rsi_free(rsii); kfree(rsii); } }
static void test_sunrpc_cache(void){ struct cache_head head; struct cache_detail detail; cache_get(&head); cache_put(&head, &detail); printk("finished cache test\n"); }
void op_indrzshow(mval *s1,mval *s2) { mstr object; bool rval; oprtype v; triple *src, *r, *outtype, *lvar; error_def(ERR_VAREXPECTED); error_def(ERR_INDMAXNEST); comp_init(&s2->str); src = maketriple(OC_IGETSRC); ins_triple(src); switch(window_token) { case TK_CIRCUMFLEX: if (rval = gvn()) { r = maketriple(OC_ZSHOW); outtype = newtriple(OC_PARAMETER); r->operand[1] = put_tref(outtype); r->operand[0] = put_tref(src); outtype->operand[0] = put_ilit(ZSHOW_GLOBAL); ins_triple(r); } break; case TK_IDENT: if (rval = lvn(&v, OC_PUTINDX, 0)) { r = maketriple(OC_ZSHOWLOC); outtype = newtriple(OC_PARAMETER); r->operand[1] = put_tref(outtype); r->operand[0] = put_tref(src); lvar = newtriple(OC_PARAMETER); outtype->operand[1] = put_tref(lvar); lvar->operand[0] = v; outtype->operand[0] = put_ilit(ZSHOW_LOCAL); ins_triple(r); } break; case TK_ATSIGN: if (rval = indirection(&v)) { r = newtriple(OC_INDRZSHOW); r->operand[0] = put_tref(src); r->operand[1] = v; } break; default: stx_error(ERR_VAREXPECTED); break; } if (comp_fini(rval, &object, OC_RET, 0, s2->str.len)) { cache_put(indir_zshow, &s2->str, &object); *ind_source_sp++ = s1; if (ind_source_sp >= ind_source_top) rts_error(VARLSTCNT(1) ERR_INDMAXNEST); comp_indr(&object); } return; }
void op_indlvadr(mval *target) { error_def(ERR_VAREXPECTED); bool rval; mstr object, *obj; oprtype v; triple *s; MV_FORCE_STR(target); if (!(obj = cache_get(indir_lvadr, &target->str))) { comp_init(&target->str); switch (window_token) { case TK_IDENT: rval = lvn(&v, OC_PUTINDX, 0); if (comp_fini(rval, &object, OC_IRETMVAD, &v, target->str.len)) { cache_put(indir_lvadr, &target->str, &object); comp_indr(&object); } break; case TK_ATSIGN: if (rval = indirection(&v)) { s = newtriple(OC_INDLVADR); s->operand[0] = v; v = put_tref(s); if (comp_fini(rval, &object, OC_IRETMVAD, &v, target->str.len)) { cache_put(indir_lvadr, &target->str, &object); comp_indr(&object); } } break; default: stx_error(ERR_VAREXPECTED); break; } } else { comp_indr(obj); } }
void op_indlvarg(mval *v, mval *dst) { bool rval; mstr *obj, object; oprtype x; triple *ref; icode_str indir_src; error_def(ERR_INDMAXNEST); error_def(ERR_VAREXPECTED); MV_FORCE_STR(v); if (v->str.len < 1) rts_error(VARLSTCNT(1) ERR_VAREXPECTED); if (valid_mname(&v->str)) { *dst = *v; dst->mvtype &= ~MV_ALIASCONT; /* Make sure alias container property does not pass */ return; } if (*v->str.addr == '@') { indir_src.str = v->str; indir_src.code = indir_lvarg; if (NULL == (obj = cache_get(&indir_src))) { object.addr = v->str.addr; object.len = v->str.len; comp_init(&object); if (rval = indirection(&x)) { ref = newtriple(OC_INDLVARG); ref->operand[0] = x; x = put_tref(ref); } if (comp_fini(rval, &object, OC_IRETMVAL, &x, object.len)) { indir_src.str.addr = v->str.addr; cache_put(&indir_src, &object); *ind_result_sp++ = dst; if (ind_result_sp >= ind_result_top) rts_error(VARLSTCNT(1) ERR_INDMAXNEST); comp_indr(&object); return; } } else { *ind_result_sp++ = dst; if (ind_result_sp >= ind_result_top) rts_error(VARLSTCNT(1) ERR_INDMAXNEST); comp_indr(obj); return; } } rts_error(VARLSTCNT(1) ERR_VAREXPECTED); }
static int idx_flush_page(IDX *idx) { if (idx -> page_dirty) { idx -> page_dirty = 0; return cache_put(idx -> cache, idx -> page_number, &idx -> page); } return 0; }
void ExistsFeatures::new_feature(item_group_ty group, item_predicate_ty predicate, unsigned value) { ExistsFeature f(group, predicate, value); f.newID(); _all.push_back(f); _all_ptrs.push_back(&_all.back()); cache_put(group, predicate, value, &_all.back()); // Insert f into Unique<ExistsFeature> to ensure that f is unique (i.e. it has not already been constructed). Unique<ExistsFeature>::insert(f); }
/** * camel_imap_message_cache_new: * @path: directory to use for storage * @summary: CamelFolderSummary for the folder we are caching * @ex: a CamelException * * Return value: a new CamelImapMessageCache object using @path for * storage. If cache files already exist in @path, then any that do not * correspond to messages in @summary will be deleted. **/ CamelImapMessageCache * camel_imap_message_cache_new (const char *path, CamelFolderSummary *summary, CamelException *ex) { CamelImapMessageCache *cache; GDir *dir; const char *dname; char *uid, *p; GPtrArray *deletes; CamelMessageInfo *info; GError *error = NULL; dir = g_dir_open (path, 0, &error); if (!dir) { camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, _("Could not open cache directory: %s"), error->message); g_error_free (error); return NULL; } cache = (CamelImapMessageCache *)camel_object_new (CAMEL_IMAP_MESSAGE_CACHE_TYPE); cache->path = g_strdup (path); cache->parts = g_hash_table_new (g_str_hash, g_str_equal); cache->cached = g_hash_table_new (NULL, NULL); deletes = g_ptr_array_new (); while ((dname = g_dir_read_name (dir))) { if (!isdigit (dname[0])) continue; p = strchr (dname, '.'); if (p) uid = g_strndup (dname, p - dname); else uid = g_strdup (dname); info = camel_folder_summary_uid (summary, uid); if (info) { camel_message_info_free(info); cache_put (cache, uid, dname, NULL); } else g_ptr_array_add (deletes, g_strdup_printf ("%s/%s", cache->path, dname)); g_free (uid); } g_dir_close (dir); while (deletes->len) { g_unlink (deletes->pdata[0]); g_free (deletes->pdata[0]); g_ptr_array_remove_index_fast (deletes, 0); } g_ptr_array_free (deletes, TRUE); return cache; }
static CamelStream * insert_finish (CamelImapMessageCache *cache, const char *uid, char *path, char *key, CamelStream *stream) { camel_stream_flush (stream); camel_stream_reset (stream); cache_put (cache, uid, key, stream); g_free (path); return stream; }
void op_commarg(mval *v, unsigned char argcode) { bool rval; mstr *obj, object; icode_str indir_src; error_def (ERR_INDEXTRACHARS); MV_FORCE_STR(v); assert(argcode >=3 && argcode < SIZEOF(indir_fcn) / SIZEOF(indir_fcn[0])); indir_src.str = v->str; indir_src.code = argcode; if (NULL == (obj = cache_get(&indir_src))) { if (((indir_do == argcode) || (indir_goto == argcode)) && (frame_pointer->type & SFT_COUNT) && v->str.len && (v->str.len < MAX_MIDENT_LEN) && !proc_act_type && do_indir_do(v, argcode)) { return; } comp_init(&v->str); for (;;) { if (!(rval = (*indir_fcn[argcode])())) break; if (TK_EOL == window_token) break; if (TK_COMMA == window_token) advancewindow(); else { /* Allow trailing spaces/comments that we will ignore */ while (TK_SPACE == window_token) advancewindow(); if (TK_EOL == window_token) break; rts_error(VARLSTCNT(1) ERR_INDEXTRACHARS); } } if (comp_fini(rval, &object, OC_RET, 0, v->str.len)) { indir_src.str.addr = v->str.addr; /* we reassign because v->str.addr might have been changed by stp_gcol() */ cache_put(&indir_src, &object); comp_indr(&object); if (indir_linetail == argcode) frame_pointer->type = SFT_COUNT; } } else { comp_indr(obj); if (indir_linetail == argcode) frame_pointer->type = SFT_COUNT; } }
errno_t cache_put_multiple( cache_t *c, long blk, int nblk, const void *data ) { //SHOW_FLOW( 3, "put mult for %p from %ld, num %d", c, blk, nblk ); while(nblk-- > 0) { errno_t rc = cache_put( c, blk, data ); if(rc) return rc; blk++; data += c->page_size; } return 0; }
char* sha256_file_hex(const char* filename) { size_t data_size; void* data = lslurpb(filename, &data_size); char* hash = cache_get(data, data_size); if (hash) return hash; printf("file_hex: Cache miss for file %s\n", filename); char* tempname = lstrdup("sha256_XXXXXX"); int fd = mkstemp(tempname); if (fd == -1) { perror("mkstemp"); carp("Giving up"); } char* cmd = lsprintf("sha256sum '%s' > '%s'", filename, tempname); int rv = system(cmd); if (rv != 0) { perror("system"); carp("Giving up"); } FILE* temp = fdopen(fd, "r"); hash = GC_malloc_atomic(68); int count = fread(hash, 64, 1, temp); if (count != 1) { perror("fread"); carp("Giving up"); } hash[64] = 0; fclose(temp); unlink(tempname); cache_put(data, data_size, hash); return hash; }
void op_indlvarg(mval *v, mval *dst) { icode_str indir_src; int rval; mstr *obj, object; oprtype x; triple *ref; DCL_THREADGBL_ACCESS; SETUP_THREADGBL_ACCESS; if (TREF(ind_result_sp) >= TREF(ind_result_top)) rts_error(VARLSTCNT(1) ERR_INDMAXNEST); /* mdbcondition_handler resets ind_result_sp */ MV_FORCE_STR(v); if (v->str.len < 1) rts_error(VARLSTCNT(1) ERR_VAREXPECTED); if (valid_mname(&v->str)) { *dst = *v; dst->mvtype &= ~MV_ALIASCONT; /* Make sure alias container property does not pass */ return; } if (*v->str.addr != '@') rts_error(VARLSTCNT(1) ERR_VAREXPECTED); indir_src.str = v->str; indir_src.code = indir_lvarg; if (NULL == (obj = cache_get(&indir_src))) { obj = &object; obj->addr = v->str.addr; obj->len = v->str.len; comp_init(obj); if (EXPR_FAIL != (rval = indirection(&x))) /* NOTE assignment */ { ref = newtriple(OC_INDLVARG); ref->operand[0] = x; x = put_tref(ref); } if (EXPR_FAIL == comp_fini(rval, obj, OC_IRETMVAL, &x, obj->len)) return; indir_src.str.addr = v->str.addr; cache_put(&indir_src, obj); /* Fall into code activation below */ } *(TREF(ind_result_sp))++ = dst; /* Where to store return value */ comp_indr(obj); return; }
static bool oid2name_get_name(uint32 oid, char *buf, size_t buflen, const char *query) { if (cache_get(oid)) { snprintf(buf, buflen, "%s", cache_get(oid)); return true; } if ( oid2name_query(buf, buflen, query) ) { cache_put(oid, buf); return true; } snprintf(buf, buflen, "%u", oid); return false; }
/* * Release a file handle. */ void fh_put(struct svc_fh *fhp) { struct dentry * dentry = fhp->fh_dentry; struct svc_export * exp = fhp->fh_export; if (dentry) { fh_unlock(fhp); fhp->fh_dentry = NULL; dput(dentry); #ifdef CONFIG_NFSD_V3 fhp->fh_pre_saved = 0; fhp->fh_post_saved = 0; #endif } if (exp) { cache_put(&exp->h, &svc_export_cache); fhp->fh_export = NULL; } return; }
/* * Resolve a mount point's glue ncp. This ncp connects creates the illusion * of continuity in the namecache tree by connecting the ncp related to the * vnode under the mount to the ncp related to the mount's root vnode. * * If no error occured a locked, ref'd ncp is stored in *ncpp. */ int nlookup_mp(struct mount *mp, struct nchandle *nch) { struct vnode *vp; int error; error = 0; cache_get(&mp->mnt_ncmountpt, nch); if (nch->ncp->nc_flag & NCF_UNRESOLVED) { while (vfs_busy(mp, 0)) ; error = VFS_ROOT(mp, &vp); vfs_unbusy(mp); if (error) { cache_put(nch); } else { cache_setvp(nch, vp); vput(vp); } } return(error); }
/** * camel_imap_message_cache_get: * @cache: the cache * @uid: the UID of the data to get * @part_spec: the part_spec of the data to get * @ex: exception * * Return value: a CamelStream containing the cached data (which the * caller must unref), or %NULL if that data is not cached. **/ CamelStream * camel_imap_message_cache_get (CamelImapMessageCache *cache, const char *uid, const char *part_spec, CamelException *ex) { CamelStream *stream; char *path, *key; if (uid[0] == 0) return NULL; #ifdef G_OS_WIN32 /* See comment in insert_setup() */ if (!*part_spec) part_spec = "~"; #endif path = g_strdup_printf ("%s/%s.%s", cache->path, uid, part_spec); key = strrchr (path, '/') + 1; stream = g_hash_table_lookup (cache->parts, key); if (stream) { camel_stream_reset (CAMEL_STREAM (stream)); camel_object_ref (CAMEL_OBJECT (stream)); g_free (path); return stream; } stream = camel_stream_fs_new_with_name (path, O_RDONLY, 0); if (stream) { cache_put (cache, uid, key, stream); } else { camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, _("Failed to cache %s: %s"), part_spec, g_strerror (errno)); } g_free (path); return stream; }
void op_inddevparms(mval *devpsrc, int4 ok_iop_parms, mval *devpiopl) { int rval; icode_str indir_src; mstr *obj, object; oprtype devpopr, plist, getdst; triple *indref; DCL_THREADGBL_ACCESS; SETUP_THREADGBL_ACCESS; MV_FORCE_STR(devpsrc); indir_src.str = devpsrc->str; indir_src.code = indir_devparms; if (NULL == (obj = cache_get(&indir_src))) /* NOTE assignment */ { /* No cached version, compile it now */ obj = &object; comp_init(&devpsrc->str, &getdst); if (TK_ATSIGN == TREF(window_token)) { /* For the indirection-obsessive */ if (EXPR_FAIL != (rval = indirection(&devpopr))) /* NOTE assignment */ { indref = newtriple(OC_INDDEVPARMS); indref->operand[0] = devpopr; indref->operand[1] = put_ilit(ok_iop_parms); plist = put_tref(indref); } } else /* We have the parm string to process now */ rval = deviceparameters(&plist, ok_iop_parms); if (EXPR_FAIL == comp_fini(rval, obj, OC_IRETMVAL, &plist, &getdst, devpsrc->str.len)) return; indir_src.str.addr = devpsrc->str.addr; cache_put(&indir_src, obj); /* Fall into code activation below */ } TREF(ind_result) = devpiopl; /* Where to store return value */ comp_indr(obj); return; }
void *run_thread(void *tid) { int i, id = (int)(long) tid; struct timespec start, end; int iters = shared.num_iters; pthread_barrier_wait(&shared.barrier); tracepoint(tl, start_test_thread, id); clock_gettime(CLOCK_MONOTONIC, &start); for (i = 0; i < iters; i++) { int r = rand() % DATA_SIZE_FULL; if ((rand() % 100) < 80) { cache_get(shared.cache, GET_KEY(r)); } else { cache_put(shared.cache, GET_KEY(r), GET_VAL(r)); } } clock_gettime(CLOCK_MONOTONIC, &end); tracepoint(tl, end_test_thread, id, ELAPSED_TIME(start, end)); //~ printf("%d\n", id); pthread_exit(NULL); }
void auth_domain_drop(struct cache_head *item, struct cache_detail *cd) { struct auth_domain *dom = container_of(item, struct auth_domain, h); if (cache_put(item,cd)) authtab[dom->flavour]->domain_release(dom); }
void op_indtext(mval *lab, mint offset, mval *rtn, mval *dst) { bool rval; mstr *obj, object; mval mv_off; oprtype opt; triple *ref; icode_str indir_src; error_def(ERR_INDMAXNEST); error_def(ERR_STACKOFLOW); error_def(ERR_STACKCRIT); MV_FORCE_STR(lab); indir_src.str.len = lab->str.len; indir_src.str.len += SIZEOF("+^") - 1; indir_src.str.len += MAX_NUM_SIZE; indir_src.str.len += rtn->str.len; ENSURE_STP_FREE_SPACE(indir_src.str.len); DBG_MARK_STRINGPOOL_UNEXPANDABLE; /* Now that we have ensured enough space in the stringpool, we dont expect any more * garbage collections or expansions until we are done with the below initialization. */ /* Push an mval pointing to the complete entry ref on to the stack so the string is valid even * if garbage collection occurs before cache_put() */ PUSH_MV_STENT(MVST_MVAL); mv_chain->mv_st_cont.mvs_mval.mvtype = 0; /* so stp_gcol (if invoked below) does not get confused by this otherwise * incompletely initialized mval in the M-stack */ mv_chain->mv_st_cont.mvs_mval.str.addr = (char *)stringpool.free; memcpy(stringpool.free, lab->str.addr, lab->str.len); stringpool.free += lab->str.len; *stringpool.free++ = '+'; MV_FORCE_MVAL(&mv_off, offset); MV_FORCE_STRD(&mv_off); /* goes at stringpool.free. we already made enough space in the stp_gcol() call */ *stringpool.free++ = '^'; memcpy(stringpool.free, rtn->str.addr, rtn->str.len); stringpool.free += rtn->str.len; mv_chain->mv_st_cont.mvs_mval.str.len = INTCAST(stringpool.free - (unsigned char*)mv_chain->mv_st_cont.mvs_mval.str.addr); mv_chain->mv_st_cont.mvs_mval.mvtype = MV_STR; /* initialize mvtype now that mval has been otherwise completely set up */ DBG_MARK_STRINGPOOL_EXPANDABLE; /* Now that we are done with stringpool.free initializations, mark as free for expansion */ indir_src.str = mv_chain->mv_st_cont.mvs_mval.str; indir_src.code = indir_text; if (NULL == (obj = cache_get(&indir_src))) { comp_init(&indir_src.str); rval = f_text(&opt, OC_FNTEXT); if (!comp_fini(rval, &object, OC_IRETMVAL, &opt, indir_src.str.len)) { assert(mv_chain->mv_st_type == MVST_MVAL); POP_MV_STENT(); return; } indir_src.str.addr = mv_chain->mv_st_cont.mvs_mval.str.addr; cache_put(&indir_src, &object); *ind_result_sp++ = dst; if (ind_result_sp >= ind_result_top) rts_error(VARLSTCNT(1) ERR_INDMAXNEST); assert(mv_chain->mv_st_type == MVST_MVAL); POP_MV_STENT(); /* unwind the mval entry before the new frame gets added by comp_indir below */ comp_indr(&object); return; } *ind_result_sp++ = dst; if (ind_result_sp >= ind_result_top) rts_error(VARLSTCNT(1) ERR_INDMAXNEST); assert(mv_chain->mv_st_type == MVST_MVAL); POP_MV_STENT(); /* unwind the mval entry before the new frame gets added by comp_indir below */ comp_indr(obj); return; }
/* * Make duplicate object index. * * If referred tag is only one, direct link which points the tag is generated. * Else if two or more tag exists, indirect link which points the tag list * is generated. */ int makedupindex(void) { STRBUF *sb = strbuf_open(0); STRBUF *tmp = strbuf_open(0); STRBUF *command = strbuf_open(0); int definition_count = 0; char srcdir[MAXPATHLEN]; int db; FILEOP *fileop = NULL; FILE *op = NULL; FILE *ip = NULL; snprintf(srcdir, sizeof(srcdir), "../%s", SRCS); for (db = GTAGS; db < GTAGLIM; db++) { const char *kind = kinds[db]; const char *option = options[db]; int writing = 0; int count = 0; int entry_count = 0; const char *ctags_xid, *ctags_x; char tag[IDENTLEN], prev[IDENTLEN], first_line[MAXBUFLEN]; if (gtags_exist[db] == 0) continue; prev[0] = 0; first_line[0] = 0; /* * construct command line. */ strbuf_reset(command); strbuf_sprintf(command, "%s -x%s --result=ctags-xid --encode-path=\" \t\" --nofilter=path", quote_shell(global_path), option); /* * Optimization when the --dynamic option is specified. */ if (dynamic) { strbuf_puts(command, " --nosource"); if (db != GSYMS) strbuf_puts(command, " --nofilter=sort"); } strbuf_puts(command, " \".*\""); if ((ip = popen(strbuf_value(command), "r")) == NULL) die("cannot execute command '%s'.", strbuf_value(command)); while ((ctags_xid = strbuf_fgets(sb, ip, STRBUF_NOCRLF)) != NULL) { char fid[MAXFIDLEN]; ctags_x = parse_xid(ctags_xid, fid, NULL); /* tag name */ (void)strcpy_withterm(tag, ctags_x, sizeof(tag), ' '); if (strcmp(prev, tag)) { count++; if (vflag) fprintf(stderr, " [%d] adding %s %s\n", count, kind, tag); if (writing) { if (!dynamic) { fputs_nl(gen_list_end(), op); fputs_nl(body_end, op); fputs_nl(gen_page_end(), op); close_file(fileop); html_count++; } writing = 0; /* * cache record: " <fid>\0<entry number>\0" */ strbuf_reset(tmp); strbuf_putc(tmp, ' '); strbuf_putn(tmp, count - 1); strbuf_putc(tmp, '\0'); strbuf_putn(tmp, entry_count); cache_put(db, prev, strbuf_value(tmp), strbuf_getlen(tmp) + 1); } /* single entry */ if (first_line[0]) { char fid[MAXFIDLEN]; const char *ctags_x = parse_xid(first_line, fid, NULL); const char *lno = nextelement(ctags_x); strbuf_reset(tmp); strbuf_puts_withterm(tmp, lno, ' '); strbuf_putc(tmp, '\0'); strbuf_puts(tmp, fid); cache_put(db, prev, strbuf_value(tmp), strbuf_getlen(tmp) + 1); } /* * Chop the tail of the line. It is not important. * strlimcpy(first_line, ctags_x, sizeof(first_line)); */ strncpy(first_line, ctags_xid, sizeof(first_line)); first_line[sizeof(first_line) - 1] = '\0'; strlimcpy(prev, tag, sizeof(prev)); entry_count = 0; } else { /* duplicate entry */ if (first_line[0]) { char fid[MAXFIDLEN]; const char *ctags_x = parse_xid(first_line, fid, NULL); if (!dynamic) { char path[MAXPATHLEN]; snprintf(path, sizeof(path), "%s/%s/%d.%s", distpath, dirs[db], count, HTML); fileop = open_output_file(path, cflag); op = get_descripter(fileop); fputs_nl(gen_page_begin(tag, SUBDIR), op); fputs_nl(body_begin, op); fputs_nl(gen_list_begin(), op); fputs_nl(gen_list_body(srcdir, ctags_x, fid), op); } writing = 1; entry_count++; first_line[0] = 0; } if (!dynamic) { fputs_nl(gen_list_body(srcdir, ctags_x, fid), op); } entry_count++; } } if (db == GTAGS) definition_count = count; if (pclose(ip) != 0) die("'%s' failed.", strbuf_value(command)); if (writing) { if (!dynamic) { fputs_nl(gen_list_end(), op); fputs_nl(body_end, op); fputs_nl(gen_page_end(), op); close_file(fileop); html_count++; } /* * cache record: " <fid>\0<entry number>\0" */ strbuf_reset(tmp); strbuf_putc(tmp, ' '); strbuf_putn(tmp, count); strbuf_putc(tmp, '\0'); strbuf_putn(tmp, entry_count); cache_put(db, prev, strbuf_value(tmp), strbuf_getlen(tmp) + 1); } if (first_line[0]) { char fid[MAXFIDLEN]; const char *ctags_x = parse_xid(first_line, fid, NULL); const char *lno = nextelement(ctags_x); strbuf_reset(tmp); strbuf_puts_withterm(tmp, lno, ' '); strbuf_putc(tmp, '\0'); strbuf_puts(tmp, fid); cache_put(db, prev, strbuf_value(tmp), strbuf_getlen(tmp) + 1); } } strbuf_close(sb); strbuf_close(tmp); strbuf_close(command); return definition_count; }
/* * Common code for vnode open operations. Check permissions, and call * the VOP_NOPEN or VOP_NCREATE routine. * * The caller is responsible for setting up nd with nlookup_init() and * for cleaning it up with nlookup_done(), whether we return an error * or not. * * On success nd->nl_open_vp will hold a referenced and, if requested, * locked vnode. A locked vnode is requested via NLC_LOCKVP. If fp * is non-NULL the vnode will be installed in the file pointer. * * NOTE: The vnode is referenced just once on return whether or not it * is also installed in the file pointer. */ int vn_open(struct nlookupdata *nd, struct file *fp, int fmode, int cmode) { struct vnode *vp; struct ucred *cred = nd->nl_cred; struct vattr vat; struct vattr *vap = &vat; int error; u_int flags; uint64_t osize; struct mount *mp; /* * Certain combinations are illegal */ if ((fmode & (FWRITE | O_TRUNC)) == O_TRUNC) return(EACCES); /* * Lookup the path and create or obtain the vnode. After a * successful lookup a locked nd->nl_nch will be returned. * * The result of this section should be a locked vnode. * * XXX with only a little work we should be able to avoid locking * the vnode if FWRITE, O_CREAT, and O_TRUNC are *not* set. */ nd->nl_flags |= NLC_OPEN; if (fmode & O_APPEND) nd->nl_flags |= NLC_APPEND; if (fmode & O_TRUNC) nd->nl_flags |= NLC_TRUNCATE; if (fmode & FREAD) nd->nl_flags |= NLC_READ; if (fmode & FWRITE) nd->nl_flags |= NLC_WRITE; if ((fmode & O_EXCL) == 0 && (fmode & O_NOFOLLOW) == 0) nd->nl_flags |= NLC_FOLLOW; if (fmode & O_CREAT) { /* * CONDITIONAL CREATE FILE CASE * * Setting NLC_CREATE causes a negative hit to store * the negative hit ncp and not return an error. Then * nc_error or nc_vp may be checked to see if the ncp * represents a negative hit. NLC_CREATE also requires * write permission on the governing directory or EPERM * is returned. */ nd->nl_flags |= NLC_CREATE; nd->nl_flags |= NLC_REFDVP; bwillinode(1); error = nlookup(nd); } else { /* * NORMAL OPEN FILE CASE */ error = nlookup(nd); } if (error) return (error); /* * split case to allow us to re-resolve and retry the ncp in case * we get ESTALE. */ again: if (fmode & O_CREAT) { if (nd->nl_nch.ncp->nc_vp == NULL) { if ((error = ncp_writechk(&nd->nl_nch)) != 0) return (error); VATTR_NULL(vap); vap->va_type = VREG; vap->va_mode = cmode; if (fmode & O_EXCL) vap->va_vaflags |= VA_EXCLUSIVE; error = VOP_NCREATE(&nd->nl_nch, nd->nl_dvp, &vp, nd->nl_cred, vap); if (error) return (error); fmode &= ~O_TRUNC; /* locked vnode is returned */ } else { if (fmode & O_EXCL) { error = EEXIST; } else { error = cache_vget(&nd->nl_nch, cred, LK_EXCLUSIVE, &vp); } if (error) return (error); fmode &= ~O_CREAT; } } else { error = cache_vget(&nd->nl_nch, cred, LK_EXCLUSIVE, &vp); if (error) return (error); } /* * We have a locked vnode and ncp now. Note that the ncp will * be cleaned up by the caller if nd->nl_nch is left intact. */ if (vp->v_type == VLNK) { error = EMLINK; goto bad; } if (vp->v_type == VSOCK) { error = EOPNOTSUPP; goto bad; } if ((fmode & O_CREAT) == 0) { if (fmode & (FWRITE | O_TRUNC)) { if (vp->v_type == VDIR) { error = EISDIR; goto bad; } error = vn_writechk(vp, &nd->nl_nch); if (error) { /* * Special stale handling, re-resolve the * vnode. */ if (error == ESTALE) { vput(vp); vp = NULL; cache_setunresolved(&nd->nl_nch); error = cache_resolve(&nd->nl_nch, cred); if (error == 0) goto again; } goto bad; } } } if (fmode & O_TRUNC) { vn_unlock(vp); /* XXX */ vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); /* XXX */ osize = vp->v_filesize; VATTR_NULL(vap); vap->va_size = 0; error = VOP_SETATTR(vp, vap, cred); if (error) goto bad; error = VOP_GETATTR(vp, vap); if (error) goto bad; mp = vq_vptomp(vp); VFS_ACCOUNT(mp, vap->va_uid, vap->va_gid, -osize); } /* * Set or clear VNSWAPCACHE on the vp based on nd->nl_nch.ncp->nc_flag. * These particular bits a tracked all the way from the root. * * NOTE: Might not work properly on NFS servers due to the * disconnected namecache. */ flags = nd->nl_nch.ncp->nc_flag; if ((flags & (NCF_UF_CACHE | NCF_UF_PCACHE)) && (flags & (NCF_SF_NOCACHE | NCF_SF_PNOCACHE)) == 0) { vsetflags(vp, VSWAPCACHE); } else { vclrflags(vp, VSWAPCACHE); } /* * Setup the fp so VOP_OPEN can override it. No descriptor has been * associated with the fp yet so we own it clean. * * f_nchandle inherits nl_nch. This used to be necessary only for * directories but now we do it unconditionally so f*() ops * such as fchmod() can access the actual namespace that was * used to open the file. */ if (fp) { if (nd->nl_flags & NLC_APPENDONLY) fmode |= FAPPENDONLY; fp->f_nchandle = nd->nl_nch; cache_zero(&nd->nl_nch); cache_unlock(&fp->f_nchandle); } /* * Get rid of nl_nch. vn_open does not return it (it returns the * vnode or the file pointer). Note: we can't leave nl_nch locked * through the VOP_OPEN anyway since the VOP_OPEN may block, e.g. * on /dev/ttyd0 */ if (nd->nl_nch.ncp) cache_put(&nd->nl_nch); error = VOP_OPEN(vp, fmode, cred, fp); if (error) { /* * setting f_ops to &badfileops will prevent the descriptor * code from trying to close and release the vnode, since * the open failed we do not want to call close. */ if (fp) { fp->f_data = NULL; fp->f_ops = &badfileops; } goto bad; } #if 0 /* * Assert that VREG files have been setup for vmio. */ KASSERT(vp->v_type != VREG || vp->v_object != NULL, ("vn_open: regular file was not VMIO enabled!")); #endif /* * Return the vnode. XXX needs some cleaning up. The vnode is * only returned in the fp == NULL case. */ if (fp == NULL) { nd->nl_open_vp = vp; nd->nl_vp_fmode = fmode; if ((nd->nl_flags & NLC_LOCKVP) == 0) vn_unlock(vp); } else { vput(vp); } return (0); bad: if (vp) vput(vp); return (error); }