File * matchfile(String *r) { File *f; File *match = 0; int i; for(i = 0; i<file.nused; i++){ f = file.filepptr[i]; if(f == cmd) continue; if(filematch(f, r)){ if(match) error(Emanyfiles); match = f; } } if(!match) error(Efsearch); return match; }
void filelooper(Cmd *cp, int XY) { File *f, *cur; int i; if(Glooping++) error(EnestXY); nest++; settempfile(); cur = curfile; for(i = 0; i<tempfile.nused; i++){ f = tempfile.filepptr[i]; if(f==cmd) continue; if(cp->re==0 || filematch(f, cp->re)==XY) cmdexec(f, cp->ccmd); } if(cur && whichmenu(cur)>=0) /* check that cur is still a file */ current(cur); --Glooping; --nest; }
/** * ByteRangeIndex::trunc_edit_nz: edit droppings to shrink container * to a non-zero size. if we are truncating an open file and we * edit the current index dropping, then update the filehandle for * it since the offsets may have changed. * * @param ppip pathinfo for container * @param nzo the non-zero offset * @param openidrop filename of currently open index dropping * @return PLFS_SUCCESS or error code */ plfs_error_t ByteRangeIndex::trunc_edit_nz(struct plfs_physpathinfo *ppip, off_t nzo, string openidrop) { plfs_error_t ret = PLFS_SUCCESS; size_t slashoff; string openifn, indexfile; struct plfs_backend *indexback; IOSDirHandle *candir, *subdir; string hostdirpath; int dropping; mlog(IDX_DAPI, "%s on %s to %ld", __FUNCTION__, ppip->canbpath.c_str(), (unsigned long)nzo); /* * isolate the filename in openidrop. in theory we should be * able to just compare the whole thing, but PLFS sometimes * puts in extra "/" chars in filenames and that could mess * us up: e.g. /m/plfs/dir/file vs /m/plfs/dir//file * should be the same, but the "//" will fool strcmps. */ if (openidrop.size() == 0) { openifn = ""; } else { slashoff = openidrop.rfind("/"); if (slashoff == string::npos) { openifn = openidrop; } else { openifn = openidrop.substr(slashoff + 1, string::npos); } } /* * this code goes through each index dropping and rewrites it * preserving only entries that contain data prior to truncate * offset... */ candir = subdir = NULL; while ((ret = nextdropping(ppip->canbpath, ppip->canback, &indexfile, &indexback, INDEXPREFIX, &candir, &subdir, &hostdirpath, &dropping)) == PLFS_SUCCESS) { if (dropping != 1) { break; } /* read dropping file into a tmp index map */ map<off_t,ContainerEntry> tmpidx; vector<ChunkFile> tmpcnk; off_t eof, bytes; IOSHandle *fh; eof = bytes = 0; ret = ByteRangeIndex::merge_dropping(tmpidx, tmpcnk, &eof, &bytes, indexfile, indexback); if (ret != PLFS_SUCCESS) { mlog(IDX_CRIT, "Failed to read index file %s: %s", indexfile.c_str(), strplfserr( ret )); break; } /* we have to rewrite only if it had data past our new eof (nzo) */ if (eof > nzo) { mlog(IDX_DCOMMON, "%s %s at %ld", __FUNCTION__, indexfile.c_str(), (unsigned long)nzo); ByteRangeIndex::trunc_map(tmpidx, nzo); /* * XXX: copied from old code. should this write to a tmp * file and then rename? */ ret = indexback->store->Open(indexfile.c_str(), O_TRUNC|O_WRONLY, &fh); if ( ret != PLFS_SUCCESS ) { mlog(IDX_CRIT, "Couldn't overwrite index file %s: %s", indexfile.c_str(), strplfserr( ret )); return(ret); } ret = ByteRangeIndex::trunc_writemap(tmpidx, fh); /* * if we just rewrote our currently open index, swap our * iwritefh to be the rewritten fh and let the old one get * closed off (below). we do this because we've edited * the open write index dropping (made it smaller) and * the old filehandle is now pointing to a bad spot in * the file. */ if (openifn.size() > 0 && indexback == this->iwriteback && filematch(indexfile, openifn)) { IOSHandle *tmp; tmp = this->iwritefh; this->iwritefh = fh; fh = tmp; } /* XXX: do we care about return value from Close? */ indexback->store->Close(fh); } } mlog(IDX_DAPI, "%s on %s to %ld ret: %d", __FUNCTION__, ppip->canbpath.c_str(), (long)nzo, ret); return(ret); }