6 typedef struct Opl Opl;
19 static Opl *locktab[64];
22 getopl(char **path, int (*namecmp)(char *, char *), int dacc, int sacc)
28 for(pp = &locktab[h % nelem(locktab)]; *pp; pp=&((*pp)->next)){
30 if(namecmp(opl->path, *path))
32 if(sacc == FILE_SHARE_COMPAT){
35 if((opl->dacc | dacc) & WRITEMASK)
38 if(opl->sacc == FILE_SHARE_COMPAT)
40 if((dacc & READMASK) && (opl->sacc & FILE_SHARE_READ)==0)
42 if((dacc & WRITEMASK) && (opl->sacc & FILE_SHARE_WRITE)==0)
44 if((dacc & FILE_DELETE) && (opl->sacc & FILE_SHARE_DELETE)==0)
48 if(strcmp(opl->path, *path)){
50 *path = strdup(opl->path);
55 opl = mallocz(sizeof(*opl), 1);
69 if(opl==nil || --opl->ref)
71 for(pp = &locktab[opl->hash % nelem(locktab)]; *pp; pp=&((*pp)->next)){
78 if(opl->path && opl->delete){
80 fprint(2, "remove on close: %s\n", opl->path);
81 if(remove(opl->path) < 0)
82 logit("remove %s: %r", opl->path);
89 createfile(char *path, int (*namecmp)(char *, char *),
90 int dacc, int sacc, int cdisp, int copt, vlong csize, int fattr, int *pact, Dir **pdir, int *perr)
92 int err, act, fd, mode, perm, isdir, delete;
103 if(copt & FILE_OPEN_BY_FILE_ID){
105 err = STATUS_NOT_SUPPORTED;
108 if((o = getopl(&path, namecmp, dacc, sacc)) == nil){
109 err = STATUS_SHARING_VIOLATION;
118 if(d = xdirstat(&path, namecmp)){
119 if(mode >= 0 && d->type != '/' && d->type != 'M'){
121 err = STATUS_ACCESS_DENIED;
125 isdir = (d->qid.type & QTDIR) != 0;
128 act = FILE_SUPERSEDED;
129 if(remove(path) < 0){
137 case FILE_OVERWRITE_IF:
138 act = FILE_OVERWRITTEN;
139 if(isdir || (mode != OWRITE && mode != ORDWR))
149 err = STATUS_OBJECT_NAME_COLLISION;
154 if((copt & FILE_DIRECTORY_FILE) && !isdir)
156 if((copt & FILE_NON_DIRECTORY_FILE) && isdir){
157 err = STATUS_FILE_IS_A_DIRECTORY;
160 if(copt & FILE_DELETE_ON_CLOSE){
161 if(isdir || (dacc & FILE_DELETE)==0)
165 if(mode >= 0 && !isdir)
166 if((fd = open(path, mode)) < 0)
173 case FILE_OVERWRITE_IF:
186 if(fattr & ATTR_READONLY)
188 if(copt & FILE_DIRECTORY_FILE){
189 perm |= DMDIR | 0111;
195 if(copt & FILE_DELETE_ON_CLOSE){
196 if(isdir || (dacc & FILE_DELETE)==0)
200 if((fd = create(path, mode, perm)) < 0){
205 if(!splitpath(path, &base, &name))
207 if((t = xdirstat(&base, namecmp)) == nil){
208 free(base); free(name);
212 free(path); path = conspath(base, name);
213 free(base); free(name);
214 if((fd = create(path, mode, perm)) < 0)
217 if(csize > 0 && !isdir){
222 if(dirfwstat(fd, &nd) < 0)
226 if((d = dirfstat(fd)) == nil)
234 f = mallocz(sizeof(*f), 1);
237 f->rtype = FileTypeDisk;
272 return dirfstat(f->fd);
274 return dirstat(f->path);
281 if(opl->locked && opl->locked != f)
288 deletefile(File *f, int delete)
291 if(opl->delete == delete)
293 opl->delete = delete;
309 if(f == nil || --f->ref)