Remote whitespace at the ends of lines. Remove blank lines from the ends of files. Change modes on source files so that they are not executable. Signed-off-by: Dan Cross <cross@gajendra.net>
169 lines
2.7 KiB
C
169 lines
2.7 KiB
C
#include <u.h>
|
|
#include <libc.h>
|
|
#include <auth.h>
|
|
#include <fcall.h>
|
|
#include "dat.h"
|
|
#include "fns.h"
|
|
|
|
static Xfile* clean(Xfile*);
|
|
|
|
#define FIDMOD 127 /* prime */
|
|
|
|
static Xdata* xhead;
|
|
static Xfile* xfiles[FIDMOD];
|
|
static Xfile* freelist;
|
|
|
|
Xdata*
|
|
getxdata(char *name)
|
|
{
|
|
int fd;
|
|
Dir *dir;
|
|
Xdata *xf, *fxf;
|
|
int flag;
|
|
|
|
if(name[0] == 0)
|
|
name = deffile;
|
|
if(name == 0)
|
|
error(Enofile);
|
|
flag = (access(name, 6) == 0) ? ORDWR : OREAD;
|
|
fd = open(name, flag);
|
|
if(fd < 0)
|
|
error(Enonexist);
|
|
dir = nil;
|
|
if(waserror()){
|
|
close(fd);
|
|
free(dir);
|
|
nexterror();
|
|
}
|
|
if((dir = dirfstat(fd)) == nil)
|
|
error("I/O error");
|
|
if((dir->qid.type & ~QTTMP) != QTFILE)
|
|
error("attach name not a plain file");
|
|
for(fxf=0,xf=xhead; xf; xf=xf->next){
|
|
if(xf->name == 0){
|
|
if(fxf == 0)
|
|
fxf = xf;
|
|
continue;
|
|
}
|
|
if(xf->qid.path != dir->qid.path || xf->qid.vers != dir->qid.vers)
|
|
continue;
|
|
if(xf->type != dir->type || xf->fdev != dir->dev)
|
|
continue;
|
|
xf->ref++;
|
|
chat("incref=%d, \"%s\", dev=%d...", xf->ref, xf->name, xf->dev);
|
|
close(fd);
|
|
poperror();
|
|
free(dir);
|
|
return xf;
|
|
}
|
|
if(fxf==0){
|
|
fxf = ealloc(sizeof(Xfs));
|
|
fxf->next = xhead;
|
|
xhead = fxf;
|
|
}
|
|
chat("alloc \"%s\", dev=%d...", name, fd);
|
|
fxf->ref = 1;
|
|
fxf->name = strcpy(ealloc(strlen(name)+1), name);
|
|
fxf->qid = dir->qid;
|
|
fxf->type = dir->type;
|
|
fxf->fdev = dir->dev;
|
|
fxf->dev = fd;
|
|
free(dir);
|
|
poperror();
|
|
return fxf;
|
|
}
|
|
|
|
static void
|
|
putxdata(Xdata *d)
|
|
{
|
|
if(d->ref <= 0)
|
|
panic(0, "putxdata");
|
|
d->ref--;
|
|
chat("decref=%d, \"%s\", dev=%d...", d->ref, d->name, d->dev);
|
|
if(d->ref == 0){
|
|
chat("purgebuf...");
|
|
purgebuf(d);
|
|
close(d->dev);
|
|
free(d->name);
|
|
d->name = 0;
|
|
}
|
|
}
|
|
|
|
void
|
|
refxfs(Xfs *xf, int delta)
|
|
{
|
|
xf->ref += delta;
|
|
if(xf->ref == 0){
|
|
if(xf->d)
|
|
putxdata(xf->d);
|
|
if(xf->ptr)
|
|
free(xf->ptr);
|
|
free(xf);
|
|
}
|
|
}
|
|
|
|
Xfile*
|
|
xfile(int fid, int flag)
|
|
{
|
|
int k = fid%FIDMOD;
|
|
Xfile **hp=&xfiles[k], *f, *pf;
|
|
|
|
for(f=*hp,pf=0; f; pf=f,f=f->next)
|
|
if(f->fid == fid)
|
|
break;
|
|
if(f && pf){
|
|
pf->next = f->next;
|
|
f->next = *hp;
|
|
*hp = f;
|
|
}
|
|
switch(flag){
|
|
default:
|
|
panic(0, "xfile");
|
|
case Asis:
|
|
if(f == 0)
|
|
error("unassigned fid");
|
|
return f;
|
|
case Clean:
|
|
break;
|
|
case Clunk:
|
|
if(f){
|
|
*hp = f->next;
|
|
clean(f);
|
|
f->next = freelist;
|
|
freelist = f;
|
|
}
|
|
return 0;
|
|
}
|
|
if(f)
|
|
return clean(f);
|
|
if(f = freelist) /* assign = */
|
|
freelist = f->next;
|
|
else
|
|
f = ealloc(sizeof(Xfile));
|
|
f->next = *hp;
|
|
*hp = f;
|
|
f->xf = 0;
|
|
f->fid = fid;
|
|
f->flags = 0;
|
|
f->qid = (Qid){0,0,0};
|
|
f->len = 0;
|
|
f->ptr = 0;
|
|
return f;
|
|
}
|
|
|
|
static Xfile *
|
|
clean(Xfile *f)
|
|
{
|
|
if(f->xf){
|
|
refxfs(f->xf, -1);
|
|
f->xf = 0;
|
|
}
|
|
if(f->len){
|
|
free(f->ptr);
|
|
f->len = 0;
|
|
}
|
|
f->ptr = 0;
|
|
f->flags = 0;
|
|
f->qid = (Qid){0,0,0};
|
|
return f;
|
|
}
|