HANDLE allocfile(const TCHAR *filename, size_w length) { HANDLE hFile; hFile = CreateFile(filename, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ, 0, OPEN_ALWAYS, 0, 0); if(allocfile(hFile, length)) return hFile; CloseHandle(hFile); return 0; }
static File * getfile(char *fname) { File *f = allocfile(); if (f == nil) return nil; if (strcmp(fname, "/hello.txt") == 0) { initfile(f, hello, strlen(hello)); } else if (strcmp(fname, "/dev/cons") == 0) { consfile(f); } else { releasefile(f); f = nil; } return f; }
Tree* alloctree(char *uid, char *gid, uint32_t mode, void (*destroy)(File*)) { char *muid; Tree *t; File *f; t = emalloc9p(sizeof *t); f = allocfile(); f->Dir.name = estrdup9p("/"); if(uid == nil){ uid = getuser(); if(uid == nil) uid = "none"; } uid = estrdup9p(uid); if(gid == nil) gid = estrdup9p(uid); else gid = estrdup9p(gid); muid = estrdup9p(uid); f->Dir.qid = (Qid){0, 0, QTDIR}; f->Dir.length = 0; f->Dir.atime = f->Dir.mtime = time(0); f->Dir.mode = DMDIR | mode; f->tree = t; f->parent = f; f->Dir.uid = uid; f->Dir.gid = gid; f->Dir.muid = muid; incref(&f->Ref); t->root = f; t->qidgen = 0; t->dirqidgen = 1; if(destroy == nil) destroy = nop; t->destroy = destroy; return t; }
HANDLE alloctmpfile(TCHAR *tmpfilename, int namelen, size_w length) { HANDLE hFile; if(namelen < MAX_PATH) return 0; if(GetTempPath(namelen, tmpfilename)) { if(GetTempFileName(tmpfilename, TEXT("~HX"), 0, tmpfilename)) { hFile = allocfile(tmpfilename, length); if(hFile != INVALID_HANDLE_VALUE) { return hFile; } DeleteFile(tmpfilename); } } return 0; }
bool sequence::save(const TCHAR * filename /* = 0*/) { HANDLE hFile = 0; bool quicksave = true; TCHAR newname[MAX_PATH] = { '\0' }; // can't overwrite existing file if it doesn't exist if(origfile_id == -1 && filename == 0) return false; // // We can only 'quicksave' if no inserts/deletes have // occurred and we are saving back to the current file // if(can_quicksave && origfile_id == -1 && filename == 0) { // if we *can* quicksave, then write back to the // original file handle hFile = buffer_list[origfile_id]->hFile; // do we need more space?? // quicksave = true; } else { // has a new filename been specified? if(filename) { // open the new file? hFile = allocfile(filename, sequence_length); } // overwriting current file? else { // create a temporary file and return the 'newname' hFile = alloctmpfile(newname, MAX_PATH, sequence_length); } quicksave = false; } if(hFile == 0) return false; // save the file to the specified HANDLE // if quicksave is 'true' then only those portions that // have changed will be written if(saveto(hFile, quicksave)) { // reallocate the file??? truncate file if necessary allocfile(hFile, sequence_length); if(quicksave == false) CloseHandle(hFile); // clear the sequence clear(); // if we had to create a temporary, then move it back over the original if(newname[0])// == '\0') MoveFileEx(newname, origfile_name, MOVEFILE_REPLACE_EXISTING|MOVEFILE_COPY_ALLOWED); // reinitialize with the new file if(filename == 0) { _tcscpy_s(newname, MAX_PATH, origfile_name); filename = newname; } return open(filename, false); } return false; }
File* createfile(File *fp, char *name, char *uid, uint32_t perm, void *aux) { File *f; Filelist **l, *fl; Tree *t; if((fp->Dir.qid.type&QTDIR) == 0){ werrstr("create in non-directory"); return nil; } wlock(&fp->RWLock); /* * We might encounter blank spots along the * way due to deleted files that have not yet * been flushed from the file list. Don't reuse * those - some apps (e.g., omero) depend on * the file order reflecting creation order. * Always create at the end of the list. */ for(l=&fp->filelist; (fl=*l) != nil; l=&fl->link){ if(fl->f && strcmp(fl->f->Dir.name, name) == 0){ wunlock(&fp->RWLock); werrstr("file already exists"); return nil; } } fl = emalloc9p(sizeof *fl); *l = fl; f = allocfile(); f->Dir.name = estrdup9p(name); f->Dir.uid = estrdup9p(uid ? uid : fp->Dir.uid); f->Dir.gid = estrdup9p(fp->Dir.gid); f->Dir.muid = estrdup9p(uid ? uid : "unknown"); f->aux = aux; f->Dir.mode = perm; t = fp->tree; lock(&t->genlock); f->Dir.qid.path = t->qidgen++; unlock(&t->genlock); if(perm & DMDIR) f->Dir.qid.type |= QTDIR; if(perm & DMAPPEND) f->Dir.qid.type |= QTAPPEND; if(perm & DMEXCL) f->Dir.qid.type |= QTEXCL; f->Dir.mode = perm; f->Dir.atime = f->Dir.mtime = time(0); f->Dir.length = 0; f->parent = fp; incref(&fp->Ref); f->tree = fp->tree; incref(&f->Ref); /* being returned */ incref(&f->Ref); /* for the tree */ fl->f = f; fp->nchild++; wunlock(&fp->RWLock); return f; }