static void free_histotier(void *vht) { int i; histotier *ht = vht; if(vht == NULL) return; for(i=0;i<10;i++) if(ht->secs[i]) hist_free(ht->secs[i]); for(i=0;i<6;i++) if(ht->tensecs[i]) hist_free(ht->tensecs[i]); if(ht->last_aggr) hist_free(ht->last_aggr); }
/** * im_hist_indexed: * @index: input image * @value: input image * @out: output image * * Make a histogram of @value, but use image @index to pick the bins. In other * words, element zero in @out contains the sum of all the pixels in @value * whose corresponding pixel in @index is zero. * * @index must have just one band and be u8 or u16. @value must be * non-complex. @out always has the same size and format as @value. * * This operation is useful in conjunction with im_label_regions(). You can * use it to find the centre of gravity of blobs in an image, for example. * * See also: im_histgr(), im_label_regions(). * * Returns: 0 on success, -1 on error */ int im_hist_indexed( IMAGE *index, IMAGE *value, IMAGE *out ) { int size; /* Length of hist */ Histogram *mhist; VipsGenerateFn scanfn; /* Check images. PIO from in, WIO to out. */ if( im_pincheck( index ) || im_pincheck( value ) || im_outcheck( out ) || im_check_uncoded( "im_hist_indexed", index ) || im_check_uncoded( "im_hist_indexed", value ) || im_check_noncomplex( "im_hist_indexed", value ) || im_check_size_same( "im_hist_indexed", index, value ) || im_check_u8or16( "im_hist_indexed", index ) || im_check_mono( "im_hist_indexed", index ) ) return( -1 ); /* Find the range of pixel values we must handle. */ if( index->BandFmt == IM_BANDFMT_UCHAR ) { size = 256; scanfn = hist_scan_uchar; } else { size = 65536; scanfn = hist_scan_ushort; } /* Build main hist we accumulate data in. */ if( !(mhist = hist_build( index, value, out, value->Bands, size )) ) return( -1 ); /* Accumulate data. */ if( vips_sink( index, hist_start, scanfn, hist_stop, mhist, NULL ) || hist_write( out, mhist ) ) { hist_free( mhist ); return( -1 ); } hist_free( mhist ); return( 0 ); }
/* Build a Histogram. */ static Histogram * hist_build( IMAGE *index, IMAGE *value, IMAGE *out, int bands, int size ) { Histogram *hist; if( !(hist = IM_NEW( NULL, Histogram )) ) return( NULL ); hist->index = index; hist->value = value; hist->out = out; hist->vreg = NULL; hist->bands = bands; hist->size = size; hist->mx = 0; hist->bins = NULL; if( !(hist->bins = IM_ARRAY( NULL, bands * size, double )) || !(hist->vreg = im_region_create( value )) ) { hist_free( hist ); return( NULL ); } memset( hist->bins, 0, bands * size * sizeof( double ) ); return( hist ); }
static void sweep_roll_n_log(struct histogram_config *conf, noit_check_t *check, histotier *ht, const char *name) { histogram_t *tgt; u_int64_t aligned_seconds = ht->last_minute * 60; int cidx = 0, sidx = 0; /* find the first histogram to use as an aggregation target */ for(cidx=0; cidx<6; cidx++) { if(NULL != (tgt = ht->tensecs[cidx])) { ht->tensecs[cidx] = NULL; break; } } if(tgt == NULL) { for(sidx=0; sidx<10; sidx++) { if(NULL != (tgt = ht->secs[sidx])) { ht->secs[sidx] = NULL; break; } } } if(tgt != NULL) { /* aggregate all remaining tensecs */ /* we can do all of them b/c we've removed the tgt */ if(cidx < 5) hist_accumulate(tgt, ht->tensecs, 6); if(sidx < 9) hist_accumulate(tgt, ht->secs, 10); for(cidx=0;cidx<6;cidx++) { hist_free(ht->tensecs[cidx]); ht->tensecs[cidx] = NULL; } for(sidx=0;sidx<10;sidx++) { hist_free(ht->secs[sidx]); ht->secs[sidx] = NULL; } } /* push this out to the log streams */ log_histo(conf, check, aligned_seconds, name, tgt, mtev_false); debug_print_hist(tgt); /* drop the tgt, it's ours */ if(ht->last_aggr) hist_free(ht->last_aggr); ht->last_aggr = tgt; }
/* Join a sub-hist onto the main hist, then free it. */ static int hist_stop( void *seq, void *a, void *b ) { Histogram *shist = (Histogram *) seq; Histogram *mhist = (Histogram *) a; int i; g_assert( shist->bands == mhist->bands && shist->size == mhist->size ); /* Add on sub-data. */ mhist->mx = IM_MAX( mhist->mx, shist->mx ); for( i = 0; i < mhist->bands * mhist->size; i++ ) mhist->bins[i] += shist->bins[i]; hist_free( shist ); return( 0 ); }
static void sweep_roll_tensec(histotier *ht) { histogram_t *tgt; int tgt_bucket = ht->last_second / 10; int sidx; /* We can't very well rollup the same bucket twice */ assert(tgt_bucket >= 0 && tgt_bucket < 6 && ht->tensecs[tgt_bucket] == NULL); for(sidx=0;sidx<10;sidx++) { if(NULL != (tgt = ht->secs[sidx])) { ht->secs[sidx] = NULL; break; } } if(tgt == NULL) return; /* nothing to do */ ht->tensecs[tgt_bucket] = tgt; hist_accumulate(tgt, ht->secs, 10); for(sidx=0;sidx<10;sidx++) { hist_free(ht->secs[sidx]); ht->secs[sidx] = NULL; } }
// // Open the history file. If HISTNAME is not given and userid==0 then no history file. If login_sh // and HISTFILE is longer than HIST_MAX bytes then it is cleaned up. // // hist_open() returns 1, if history file is opened. // int sh_histinit(void *sh_context) { Shell_t *shp = sh_context; int fd; History_t *hp; char *histname; char *fname = NULL; int histmask, maxlines, hist_start = 0; char *cp; off_t hsize = 0; shgd->hist_ptr = hist_ptr; if (shgd->hist_ptr) return 1; if (!(histname = nv_getval(HISTFILE))) { int offset = stktell(shp->stk); cp = nv_getval(HOME); if (cp) sfputr(shp->stk, cp, -1); sfputr(shp->stk, hist_fname, 0); stkseek(shp->stk, offset); histname = stkptr(shp->stk, offset); } #if 0 // TODO: Figure out if this should be enabled. Originally excluded via `#ifdef future`. if (hp = wasopen) { // Reuse history file if same name. wasopen = 0; shgd->hist_ptr = hist_ptr = hp; if (strcmp(histname, hp->histname) == 0) { return 1; } else { hist_free(); } } #endif // future retry: cp = path_relative(shp, histname); if (!histinit) histmode = S_IRUSR | S_IWUSR; if ((fd = open(cp, O_BINARY | O_APPEND | O_RDWR | O_CREAT | O_CLOEXEC, histmode)) >= 0) { hsize = lseek(fd, (off_t)0, SEEK_END); } if ((unsigned)fd < 10) { int n; if ((n = sh_fcntl(fd, F_DUPFD_CLOEXEC, 10)) >= 0) { sh_close(fd); fd = n; } } // Make sure that file has history file format. if (hsize && hist_check(fd)) { sh_close(fd); hsize = 0; if (unlink(cp) >= 0) goto retry; fd = -1; } // Don't allow root a history_file in /tmp. if (fd < 0 && shgd->userid) { fname = ast_temp_file(NULL, NULL, &fd, O_APPEND | O_CLOEXEC); if (!fname) return 0; } if (fd < 0) return 0; // Set the file to close-on-exec. (void)fcntl(fd, F_SETFD, FD_CLOEXEC); cp = nv_getval(HISTSIZE); if (cp) { maxlines = (unsigned)strtol(cp, NULL, 10); } else { maxlines = HIST_DFLT; } for (histmask = 16; histmask <= maxlines; histmask <<= 1) { ; // empty loop } histmask -= 1; hp = calloc(1, sizeof(History_t) + histmask * sizeof(off_t)); if (!hp) { sh_close(fd); return 0; } shgd->hist_ptr = hist_ptr = hp; hp->histshell = shp; hp->histsize = maxlines; hp->histmask = histmask; hp->histfp = sfnew(NULL, NULL, HIST_BSIZE, fd, SF_READ | SF_WRITE | SF_APPENDWR | SF_SHARE); hp->histind = 1; hp->histcmds[1] = 2; hp->histcnt = 2; hp->histname = strdup(histname); hp->histdisc = hist_disc; if (hsize == 0) { // Put special characters at front of file. sfwrite(hp->histfp, (char *)hist_stamp, 2); sfsync(hp->histfp); } else { // Initialize history list. int first, last; off_t mark, size = (HIST_MAX / 4) + maxlines * HIST_LINE; hp->histind = first = hist_nearend(hp, hp->histfp, hsize - size); histinit = 1; hist_eof(hp); // this sets histind to last command if ((hist_start = (last = (int)hp->histind) - maxlines) <= 0) hist_start = 1; mark = hp->histmarker; while (first > hist_start) { size += size; first = hist_nearend(hp, hp->histfp, hsize - size); hp->histind = first; } histinit = hist_start; hist_eof(hp); if (!histinit) { sfseek(hp->histfp, hp->histcnt = hsize, SEEK_SET); hp->histind = last; hp->histmarker = mark; } histinit = 0; } if (fname) { unlink(fname); free(fname); } if (hist_clean(fd) && hist_start > 1 && hsize > HIST_MAX) { #ifdef DEBUG sfprintf(sfstderr, "%d: hist_trim hsize=%d\n", getpid(), hsize); sfsync(sfstderr); #endif // DEBUG hp = hist_trim(hp, (int)hp->histind - maxlines); } sfdisc(hp->histfp, &hp->histdisc); STORE_VT((HISTCUR)->nvalue, i32p, &hp->histind); sh_timeradd(1000L * (HIST_RECENT - 30), 1, hist_touch, hp->histname); hp->auditfp = NULL; char buff[SF_BUFSIZE]; if (!sh_isstate(shp, SH_INTERACTIVE)) return 1; hp->auditmask = sh_checkaudit(hp, AUDIT_FILE, buff, sizeof(buff)); if (!hp->auditmask) return 1; if ((fd = sh_open(buff, O_BINARY | O_WRONLY | O_APPEND | O_CREAT | O_CLOEXEC, S_IRUSR | S_IWUSR)) >= 0 && fd < 10) { int n; if ((n = sh_fcntl(fd, F_DUPFD_CLOEXEC, 10)) >= 0) { sh_close(fd); fd = n; } } if (fd >= 0) { (void)fcntl(fd, F_SETFD, FD_CLOEXEC); hp->tty = strdup(isatty(2) ? ttyname(2) : "notty"); hp->auditfp = sfnew(NULL, NULL, -1, fd, SF_WRITE); } return 1; }
/* * open the history file * if HISTNAME is not given and userid==0 then no history file. * if login_sh and HISTFILE is longer than HIST_MAX bytes then it is * cleaned up. * hist_open() returns 1, if history file is open */ int sh_histinit(void *sh_context) { Shell_t *shp = (Shell_t*)sh_context; register int fd; register History_t *hp; register char *histname; char *fname=0; int histmask, maxlines, hist_start=0; register char *cp; register off_t hsize = 0; if(shgd->hist_ptr=hist_ptr) return(1); if(!(histname = nv_getval(HISTFILE))) { int offset = staktell(); if(cp=nv_getval(HOME)) stakputs(cp); stakputs(hist_fname); stakputc(0); stakseek(offset); histname = stakptr(offset); } #ifdef future if(hp=wasopen) { /* reuse history file if same name */ wasopen = 0; shgd->hist_ptr = hist_ptr = hp; if(strcmp(histname,hp->histname)==0) return(1); else hist_free(); } #endif retry: cp = path_relative(shp,histname); if(!histinit) histmode = S_IRUSR|S_IWUSR; if((fd=open(cp,O_BINARY|O_APPEND|O_RDWR|O_CREAT,histmode))>=0) { hsize=lseek(fd,(off_t)0,SEEK_END); } if((unsigned)fd <=2) { int n; if((n=fcntl(fd,F_DUPFD,10))>=0) { close(fd); fd=n; } } /* make sure that file has history file format */ if(hsize && hist_check(fd)) { close(fd); hsize = 0; if(unlink(cp)>=0) goto retry; fd = -1; } if(fd < 0) { #if KSHELL /* don't allow root a history_file in /tmp */ if(shgd->userid) #endif /* KSHELL */ { if(!(fname = pathtmp(NIL(char*),0,0,NIL(int*)))) return(0); fd = open(fname,O_BINARY|O_APPEND|O_CREAT|O_RDWR,S_IRUSR|S_IWUSR); } } if(fd<0) return(0); /* set the file to close-on-exec */ fcntl(fd,F_SETFD,FD_CLOEXEC); if(cp=nv_getval(HISTSIZE)) maxlines = (unsigned)strtol(cp, (char**)0, 10); else maxlines = HIST_DFLT; for(histmask=16;histmask <= maxlines; histmask <<=1 ); if(!(hp=new_of(History_t,(--histmask)*sizeof(off_t)))) { close(fd); return(0); } shgd->hist_ptr = hist_ptr = hp; hp->histshell = (void*)shp; hp->histsize = maxlines; hp->histmask = histmask; hp->histfp= sfnew(NIL(Sfio_t*),hp->histbuff,HIST_BSIZE,fd,SF_READ|SF_WRITE|SF_APPENDWR|SF_SHARE); memset((char*)hp->histcmds,0,sizeof(off_t)*(hp->histmask+1)); hp->histind = 1; hp->histcmds[1] = 2; hp->histcnt = 2; hp->histname = strdup(histname); hp->histdisc = hist_disc; if(hsize==0) { /* put special characters at front of file */ sfwrite(hp->histfp,(char*)hist_stamp,2); sfsync(hp->histfp); } /* initialize history list */ else { int first,last; off_t mark,size = (HIST_MAX/4)+maxlines*HIST_LINE; hp->histind = first = hist_nearend(hp,hp->histfp,hsize-size); histinit = 1; hist_eof(hp); /* this sets histind to last command */ if((hist_start = (last=(int)hp->histind)-maxlines) <=0) hist_start = 1; mark = hp->histmarker; while(first > hist_start) { size += size; first = hist_nearend(hp,hp->histfp,hsize-size); hp->histind = first; } histinit = hist_start; hist_eof(hp); if(!histinit) { sfseek(hp->histfp,hp->histcnt=hsize,SEEK_SET); hp->histind = last; hp->histmarker = mark; } histinit = 0; } if(fname) { unlink(fname); free((void*)fname); } if(hist_clean(fd) && hist_start>1 && hsize > HIST_MAX) { #ifdef DEBUG sfprintf(sfstderr,"%d: hist_trim hsize=%d\n",getpid(),hsize); sfsync(sfstderr); #endif /* DEBUG */ hp = hist_trim(hp,(int)hp->histind-maxlines); } sfdisc(hp->histfp,&hp->histdisc); #if KSHELL (HISTCUR)->nvalue.lp = (&hp->histind); #endif /* KSHELL */ sh_timeradd(1000L*(HIST_RECENT-30), 1, hist_touch, (void*)hp->histname); #if SHOPT_ACCTFILE if(sh_isstate(SH_INTERACTIVE)) acctinit(hp); #endif /* SHOPT_ACCTFILE */ #if SHOPT_AUDIT { char buff[SF_BUFSIZE]; hp->auditfp = 0; if(sh_isstate(SH_INTERACTIVE) && (hp->auditmask=sh_checkaudit(hp,SHOPT_AUDITFILE, buff, sizeof(buff)))) { if((fd=sh_open(buff,O_BINARY|O_WRONLY|O_APPEND|O_CREAT,S_IRUSR|S_IWUSR))>=0 && fd < 10) { int n; if((n = sh_fcntl(fd,F_DUPFD, 10)) >= 0) { sh_close(fd); fd = n; } } if(fd>=0) { fcntl(fd,F_SETFD,FD_CLOEXEC); hp->tty = strdup(ttyname(2)); hp->auditfp = sfnew((Sfio_t*)0,NULL,-1,fd,SF_WRITE); } } } #endif return(1); }