kernel&all: create() syscall only sends Tcreate

In Plan9 the create syscall fallback on a open(OTRUNC) if the
path provided already exists. This is actually a common requirement
as most programs (editors, cat...) simply requires that a file is
there and is empty, and doesn't care overwriting existing contents
(note that this is particularily sensible with something like fossil).

In Jehanne the application is responsible of actually handle this
"file exists" error but libc provides ocreate() to mimic the Plan9
behaviour. Note that ocreate introduce a subtle race too: the path
is walked several times if the file exists, thus it could misbehave
on concurrent namespace changes. However I guess this is not going to
happen often enough to care now.

NOTE we will probably address this rare race too, with a more drammatic change
to syscalls: a new walk() syscall that will provide an unopen fd.
This commit is contained in:
Giacomo Tesio 2016-12-24 21:25:20 +01:00
parent 0c094289e6
commit b862596737
78 changed files with 271 additions and 289 deletions

View File

@ -28,7 +28,7 @@ main(void)
static Rune r[16] = L"Ciao Mondo!";
static Rune buf[16];
if((fd = create("/tmp/runetest.txt", OWRITE, 0666L)) < 0) {
if((fd = ocreate("/tmp/runetest.txt", OWRITE, 0666L)) < 0) {
print("FAIL: open: %r\n");
exits("FAIL");
}

View File

@ -16,7 +16,7 @@ fdfork(int fd, int post)
pipe(ch);
len = snprint(path, sizeof path, "hcube.%d.%d", getpid(), seq++);
pfd = create(path, OWRITE|ORCLOSE, 0666);
pfd = ocreate(path, OWRITE|ORCLOSE, 0666);
if(pfd == -1)
sysfatal("fdfork: create: %r");
snprint(buf, sizeof buf, "%d", ch[0]);

View File

@ -20,10 +20,11 @@
#define NP_ORDWR 2 /* read and write */
#define NP_OEXEC 3 /* execute, == read but check execute permission */
#define NP_OTRUNC 16 /* or'ed in (except for exec), truncate file first */
#define NP_OCEXEC 32 /* or'ed in, close on exec */
#define NP_ORCLOSE 64 /* or'ed in, remove on close */
/* bits that must be zero in open/create mode */
#define NP_OZEROES ~(NP_OREAD|NP_OWRITE|NP_ORDWR|NP_OEXEC|NP_OTRUNC|NP_ORCLOSE)
#define NP_OZEROES ~(NP_OREAD|NP_OWRITE|NP_ORDWR|NP_OEXEC|NP_OTRUNC|NP_OCEXEC|NP_ORCLOSE)
typedef enum NinepMsgType
{

View File

@ -396,6 +396,7 @@ extern void longjmp(jmp_buf, int);
extern char* mktemp(char*);
extern double modf(double, double*);
extern void notejmp(void*, jmp_buf, int);
extern int ocreate(const char* path, unsigned int omode, unsigned int perm);
extern void perror(const char*);
extern int pipe(int pipes[2]);
extern int postnote(int, int, const char *);
@ -565,14 +566,12 @@ extern void freenetconninfo(NetConnInfo*);
/* Open modes: Popular flags among filesystems */
#define OTRUNC 0x0100 /* or'ed in (except for exec), truncate file first */
#define OEXCL 0x0200 /* or'ed in, exclusive create */
/* Access modes */
#define AEXIST OSTAT /* accessible: exists */
#define AREAD OREAD /* read access */
#define AWRITE OWRITE /* write access */
#define AEXEC OEXEC /* execute access */
#define AMASK (OSTAT|OREAD|OWRITE|OEXEC)
#define AEXIST 0 /* accessible: exists */
#define AREAD 4 /* read access */
#define AWRITE 2 /* write access */
#define AEXEC 1 /* execute access */
/* Segattch */
#define SG_RONLY 0040 /* read only */
@ -654,58 +653,23 @@ struct Waitmsg
char *msg;
} Waitmsg;
//extern void _exits(const char*) __attribute__ ((noreturn));
extern int access(const char*, int);
//extern int64_t alarm(uint64_t);
//extern int await(char*, int);
//extern int64_t awake(int64_t);
extern int awakened(int64_t);
//extern int bind(const char*, const char*, int);
extern int brk(void*);
//extern int chdir(const char*);
//extern int close(int);
//extern int create(const char*, int, uint32_t);
//extern int dup(int, int);
//extern int errstr(char*, uint32_t);
//extern int exec(const char*, char* const[]);
extern int execl(const char*, ...);
extern int forgivewkp(int64_t);
extern pid_t fork(void);
//extern pid_t rfork(int);
//extern int fauth(int, const char*);
//extern int fstat(int, uint8_t*, int);
//extern int fwstat(int, uint8_t*, int);
//extern int fversion(int, int, char*, int);
//extern int mount(int, int, const char*, int, const char*, int);
//extern int unmount(const char*, const char*);
//extern int noted(int);
//extern int notify(void(*)(void*, char*));
//extern int open(const char*, int);
//extern int fd2path(int, char*, int);
// extern int fdflush(int);
//extern int pipe(int*);
//extern int32_t pread(int, void*, int32_t, int64_t);
//extern int32_t pwrite(int, const void*, int32_t, int64_t);
//extern int32_t read(int, void*, int32_t);
extern int32_t readn(int, void*, int32_t);
//extern int remove(const char*);
extern void* sbrk(uint32_t);
extern int32_t oseek(int, int32_t, int);
//extern int64_t seek(int, int64_t, int);
extern void* segattach(int, const char*, void*, unsigned long);
extern int segdetach(void*);
extern int segfree(void*, unsigned long);
//extern int semacquire(int32_t*, int);
//extern int32_t semrelease(int32_t*, int32_t);
extern void sleep(int32_t);
extern int stat(const char*, uint8_t*, int);
//extern int tsemacquire(int32_t*, uint64_t);
extern Waitmsg* wait(void);
extern int waitpid(void);
//extern int32_t write(int, const void*, int32_t);
extern int wstat(const char*, uint8_t*, int);
//extern void* rendezvous(void*, void*);
extern Dir* dirstat(const char*);
extern Dir* dirfstat(int);

View File

@ -334,10 +334,10 @@ acmeerrorinit(void)
if(pipe(pfd) < 0)
error("can't create pipe");
sprint(acmeerrorfile, "/srv/acme.%s.%d", getuser(), mainpid);
fd = create(acmeerrorfile, OWRITE, 0666);
fd = ocreate(acmeerrorfile, OWRITE, 0666);
if(fd < 0){
remove(acmeerrorfile);
fd = create(acmeerrorfile, OWRITE, 0666);
fd = ocreate(acmeerrorfile, OWRITE, 0666);
if(fd < 0)
error("can't create acmeerror file");
}

View File

@ -33,7 +33,7 @@ tempfile(void)
buf[5] = i;
if(access(buf, AEXIST) == 0)
continue;
fd = create(buf, ORDWR|ORCLOSE|OCEXEC, 0600);
fd = ocreate(buf, ORDWR|ORCLOSE|OCEXEC, 0600);
if(fd >= 0)
return fd;
}

View File

@ -594,7 +594,7 @@ putfile(File *f, int q0, int q1, Rune *namer, int nname)
goto Rescue1;
}
}
fd = create(name, OWRITE, 0666);
fd = ocreate(name, OWRITE, 0666);
if(fd < 0){
warning(nil, "can't create file %s: %r\n", name);
goto Rescue1;
@ -1379,7 +1379,7 @@ Hard:
n += i;
memmove(buf+n, "/cmd", 5);
n += 5;
fd = create("/env/path", OWRITE, 0666);
fd = ocreate("/env/path", OWRITE, 0666);
write(fd, buf, n);
close(fd);
}

View File

@ -548,7 +548,7 @@ fsysopen(Xfid *x, Fid *f)
int m;
/* can't truncate anything, so just disregard */
x->mode &= ~(NP_OTRUNC);
x->mode &= ~(NP_OTRUNC|NP_OCEXEC);
/* can't execute or remove anything */
if(x->mode==NP_OEXEC || (x->mode&NP_ORCLOSE))
goto Deny;

View File

@ -322,7 +322,7 @@ rowdump(Row *row, char *file)
sprint(buf, "%s/acme.dump", home);
file = buf;
}
fd = create(file, OWRITE, 0600);
fd = ocreate(file, OWRITE, 0600);
if(fd < 0){
warning(nil, "can't open %s: %r\n", file);
goto Rescue;
@ -666,7 +666,7 @@ rowload(Row *row, char *file, int initing)
if(ndumped >= 0){
/* simplest thing is to put it in a file and load that */
sprint(buf, "/tmp/d%d.%.4sacme", getpid(), getuser());
fd = create(buf, OWRITE|ORCLOSE, 0600);
fd = ocreate(buf, OWRITE|ORCLOSE, 0600);
if(fd < 0){
free(r);
warning(nil, "can't create temp file: %r\n");

View File

@ -78,11 +78,11 @@ int
sleepuntil(uint32_t tm)
{
uint32_t now = time(0);
if (now < tm) {
sleep((tm - now)*1000);
}
return 0;
}
@ -117,7 +117,7 @@ fatal(char *fmt, ...)
static int
openlock(char *file)
{
return create(file, ORDWR, 0600);
return ocreate(file, ORDWR, 0600);
}
static int
@ -258,7 +258,7 @@ createuser(void)
dirfwstat(fd, &d);
close(fd);
snprint(file, sizeof file, "/cron/%s/cron", user);
fd = create(file, OREAD, 0644);
fd = ocreate(file, OREAD, 0644);
if(fd < 0)
fatal("couldn't create %s: %r", file);
nulldir(&d);
@ -626,7 +626,7 @@ initcap(void)
}
/*
* create a change uid capability
* create a change uid capability
*/
char*
mkcap(char *from, char *to)

View File

@ -770,7 +770,7 @@ writeusers(void)
}
/* write file */
fd = create(userkeys, OWRITE, 0660);
fd = ocreate(userkeys, OWRITE, 0660);
if(fd < 0){
free(buf);
fprint(2, "keyfs: can't write keys file\n");

View File

@ -13,7 +13,7 @@ wrbio(char *file, Acctbio *a)
fd = open(file, OWRITE);
if(fd < 0){
fd = create(file, OWRITE, 0660);
fd = ocreate(file, OWRITE, 0660);
if(fd < 0)
error("can't create %s", file);
}

View File

@ -71,7 +71,7 @@ setenv(char *var, char *val)
{
int fd;
fd = create(var, OWRITE, 0644);
fd = ocreate(var, OWRITE, 0644);
if(fd < 0)
print("init: can't open %s\n", var);
else{

View File

@ -86,7 +86,7 @@ getfile(SConn *conn, char *gf, uint8_t **buf, uint32_t *buflen, uint8_t *key, in
* conn is already encrypted against wiretappers, but gf is also
* encrypted against server breakin.
*/
if(buf == nil && (fd = create(gf, OWRITE, 0600)) < 0){
if(buf == nil && (fd = ocreate(gf, OWRITE, 0600)) < 0){
fprint(2, "secstore: can't open %s: %r\n", gf);
return -1;
}

View File

@ -142,7 +142,7 @@ putfile(SConn *conn, char *id, char *pf)
}
snprint(s, Maxmsg, "%s/store/%s/%s", SECSTORE_DIR, id, pf);
pd = create(s, OWRITE, 0660);
pd = ocreate(s, OWRITE, 0660);
if(pd < 0){
syslog(0, LOG, "can't open %s: %r", s);
return -1;

View File

@ -18,7 +18,7 @@ ensure_exists(char *f, uint32_t perm)
return;
if(verbose)
fprint(2,"first time setup for secstore: create %s %lo\n", f, perm);
fd = create(f, OREAD, perm);
fd = ocreate(f, OREAD, perm);
if(fd < 0)
sysfatal("unable to create %s: %r", f);
close(fd);

View File

@ -125,7 +125,7 @@ copy(char *from, char *to, int todir)
failed = 1;
return;
}
fdt=create(to, OWRITE, mode);
fdt=ocreate(to, OWRITE, mode);
if(fdt<0){
fprint(2, "cp: can't create %s: %r\n", to);
close(fdf);
@ -145,7 +145,7 @@ copy(char *from, char *to, int todir)
dirt.gid = dirb->gid;
if(dirfwstat(fdt, &dirt) < 0)
fprint(2, "cp: warning: can't wstat %s: %r\n", to);
}
}
free(dirb);
close(fdf);
close(fdt);

View File

@ -216,7 +216,7 @@ main(int argc, char *argv[])
}
if(ofile){
if(dotrunc)
obf = create(ofile, OWRITE, 0664);
obf = ocreate(ofile, OWRITE, 0664);
else
obf = open(ofile, OWRITE);
if(obf < 0) {

View File

@ -262,7 +262,7 @@ main(int argc, char **argv)
disk = opendisk(argv[0], 0, 0);
if(disk == nil) {
if(fflag) {
if((fd = create(argv[0], ORDWR, 0666)) >= 0) {
if((fd = ocreate(argv[0], ORDWR, 0666)) >= 0) {
file = argv[0];
close(fd);
disk = opendisk(argv[0], 0, 0);
@ -334,7 +334,7 @@ sanitycheck(Disk *disk)
bad = 0;
if(dos && nresrv < 2 && seek(disk->fd, disk->secsize, 0) == disk->secsize
&& read(disk->fd, buf, sizeof(buf)) >= 5 && strncmp(buf, "part ", 5) == 0) {
fprint(2,
fprint(2,
"there's a plan9 partition on the disk\n"
"and you didn't specify -r 2 (or greater).\n"
"either specify -r 2 or -x to disable this check.\n");
@ -370,9 +370,9 @@ getdriveno(Disk *disk)
return 0x80;
/*
* The name is of the format #SsdC0/foo
* The name is of the format #SsdC0/foo
* or /dev/sdC0/foo.
* So that we can just look for /sdC0, turn
* So that we can just look for /sdC0, turn
* #SsdC0/foo into #/sdC0/foo.
*/
if(buf[0] == '#' && buf[1] == 'S')
@ -382,7 +382,7 @@ getdriveno(Disk *disk)
if(p[0] == 's' && p[1] == 'd' && (p[2]=='C' || p[2]=='D') &&
(p[3]=='0' || p[3]=='1'))
return 0x80 + (p[2]-'C')*2 + (p[3]-'0');
return 0x80;
}
@ -496,7 +496,7 @@ dosfs(int dofat, int dopbs, Disk *disk, char *label, int argc, char *argv[], int
b->magic[1] = 0x3C;
b->magic[2] = 0x90;
memmove(b->version, "Plan9.00", sizeof(b->version));
/*
* Add bootstrapping code; offset is
* determined from short jump (0xEB 0x??)
@ -550,7 +550,7 @@ if(chatty) print("clustersize %d\n", clustersize);
/*
* the number of fat bits depends on how much disk is left
* over after you subtract out the space taken up by the fat tables.
* over after you subtract out the space taken up by the fat tables.
* try both. what a crock.
*/
fatbits = 12;
@ -589,7 +589,7 @@ Tryagain:
clusters, newclusters);
if(chatty) print("clusters %d\n", clusters);
}
if(chatty) print("try %d fatbits => %d clusters of %d\n", fatbits, clusters, clustersize);
switch(fatbits){
case 12:
@ -621,7 +621,7 @@ if(chatty) print("try %d fatbits => %d clusters of %d\n", fatbits, clusters, clu
PUTSHORT(b->nheads, t->heads);
PUTLONG(b->nhidden, disk->offset);
PUTLONG(b->bigvolsize, volsecs);
sprint(r, "FAT%d ", fatbits);
if(fatbits == 32){
Dosboot32 *bb;
@ -714,7 +714,7 @@ if(chatty) print("files @%lluX\n", seek(disk->wfd, 0LL, 1));
/*
* Now positioned at the Files Area.
* If we have any arguments, process
* If we have any arguments, process
* them and write out.
*/
for(p = root; argc > 0; argc--, argv++, p += sizeof(Dosdir)){
@ -745,7 +745,7 @@ if(chatty) print("files @%lluX\n", seek(disk->wfd, 0LL, 1));
length *= secsize*clustersize;
if((buf = malloc(length)) == 0)
fatal("out of memory");
if(readn(sysfd, buf, d->length) != d->length)
fatal("read %s: %r", *argv);
memset(buf+d->length, 0, length-d->length);
@ -755,7 +755,7 @@ if(chatty) print("%s @%lluX\n", d->name, seek(disk->wfd, 0LL, 1));
free(buf);
close(sysfd);
/*
* Allocate the FAT clusters.
* We're assuming here that where we
@ -796,7 +796,7 @@ fprint(2, "add %s at clust %lux\n", d->name, x);
PUTLONG(fi->sig, FATINFOSIG);
PUTLONG(fi->freeclust, clusters - fatlast);
PUTLONG(fi->nextfree, fatlast);
if(seek(disk->wfd, (nresrv-1)*secsize, 0) < 0)
fatal("seek to fatinfo: %r\n");
if(write(disk->wfd, fi, secsize) < 0)
@ -853,7 +853,7 @@ clustalloc(int flag)
fat[o+3] = x>>24;
}
}
if(flag == Eof)
return 0;
else{

View File

@ -62,7 +62,7 @@ main(int argc, char **argv)
default:
usage();
}ARGEND
Binits(&bin, 0, OREAD, binbuf, sizeof binbuf);
while(p = Brdline(&bin, '\n')){
p[Blinelen(&bin)-1] = '\0';
@ -142,7 +142,7 @@ mkdirs(char *name, char *namep)
if(p[1] == '\0')
return;
*p = 0;
fd = create(buf, OREAD, 0775|DMDIR);
fd = ocreate(buf, OREAD, 0775|DMDIR);
close(fd);
*p = '/';
}
@ -156,7 +156,7 @@ mkdir(char *name, uint32_t mode, uint32_t mtime, char *uid, char *gid)
char *p;
char olderr[256];
fd = create(name, OREAD, mode);
fd = ocreate(name, OREAD, mode);
if(fd < 0){
rerrstr(olderr, sizeof(olderr));
if((d = dirstat(name)) == nil || !(d->mode & DMDIR)){

View File

@ -179,7 +179,7 @@ copy(Dir *d)
if(!p)
error("internal temporary file error");
strcpy(p+1, "__mkfstmp");
t = create(cptmp, OWRITE, 0666);
t = ocreate(cptmp, OWRITE, 0666);
if(t < 0){
warn("can't create %q: %r", newfile);
close(f);
@ -261,7 +261,7 @@ mkdir(Dir *d)
arch(d);
return;
}
fd = create(newfile, OREAD, d->mode);
fd = ocreate(newfile, OREAD, d->mode);
nulldir(&nd);
nd.mode = d->mode;
nd.gid = d->gid;

View File

@ -233,7 +233,7 @@ main(int argc, char *argv[])
sysfatal("pipe: %r");
if(srv){
snprint(buf, sizeof buf, "#s/%s", srvname);
fd = create(buf, OWRITE, 0666);
fd = ocreate(buf, OWRITE, 0666);
if(fd < 0)
sysfatal("create %s: %r", buf);
if(fprint(fd, "%d", pfd[0]) < 0)

View File

@ -106,7 +106,7 @@ main(int argc, char **argv)
open("/dev/null", OWRITE);
if(pipe(pipefd) < 0)
panic("pipe");
srvfd = create(srvfile, OWRITE|ORCLOSE, 0600);
srvfd = ocreate(srvfile, OWRITE|ORCLOSE, 0600);
if(srvfd < 0)
panic(srvfile);
fprint(srvfd, "%d", pipefd[0]);

View File

@ -382,7 +382,7 @@ commands(void)
if(!wrapp ||
((io = open(file, OWRITE)) == -1) ||
((seek(io, 0L, 2)) == -1))
if((io = create(file, OWRITE, 0666)) < 0)
if((io = ocreate(file, OWRITE, 0666)) < 0)
error(file);
Binit(&iobuf, io, OWRITE);
wrapp = 0;
@ -681,7 +681,7 @@ rescue(void)
if(dol > zero) {
addr1 = zero+1;
addr2 = dol;
io = create("ed.hup", OWRITE, 0666);
io = ocreate("ed.hup", OWRITE, 0666);
if(io > 0){
Binit(&iobuf, io, OWRITE);
putfile();
@ -1110,7 +1110,7 @@ init(void)
iblock = -1;
oblock = -1;
ichanged = 0;
if((tfile = create(tfname, ORDWR, 0600)) < 0){
if((tfile = ocreate(tfname, ORDWR, 0600)) < 0){
error1(T);
exits(0);
}

View File

@ -229,7 +229,7 @@ main(int argc, char **argv)
remote = na;
if((fd = dial(netmkaddr(na, 0, "importfs"), 0, 0, 0)) < 0)
sysfatal("can't dial %s: %r", na);
ai = auth_proxy(fd, auth_getkey, "proto=p9any role=client %s", keyspec);
if(ai == nil)
sysfatal("%r: %s", na);
@ -242,7 +242,7 @@ main(int argc, char **argv)
exclusions();
if(dbg) {
n = create(dbfile, OWRITE|OTRUNC, 0666);
n = ocreate(dbfile, OWRITE|OTRUNC, 0666);
dup(n, DFD);
close(n);
}
@ -328,12 +328,12 @@ main(int argc, char **argv)
if (n == 0)
fatal("connection closed while reading arguments\n");
if (*p == '\n')
if (*p == '\n')
*p = '\0';
if (*p++ == '\0')
break;
}
if (tokenize(buf, args, nelem(args)) != 2)
fatal("impo arguments invalid: impo%s...\n", buf);
@ -367,7 +367,7 @@ main(int argc, char **argv)
for(i = 0; i < 4; i++)
key[i+12] = rand();
if (initial)
if (initial)
fatal("Protocol botch: old import\n");
if(readn(netfd, key, 4) != 4)
fatal("can't read key part; %r\n");
@ -385,7 +385,7 @@ main(int argc, char **argv)
switch (encproto) {
case Encssl:
netfd = pushssl(netfd, ealgs, fromserversecret,
netfd = pushssl(netfd, ealgs, fromserversecret,
fromclientsecret, nil);
break;
case Enctls:
@ -397,7 +397,7 @@ main(int argc, char **argv)
fatal("can't establish ssl connection: %r");
}
else if (filterp) {
if (initial)
if (initial)
fatal("Protocol botch: don't know how to deal with this\n");
netfd = filter(netfd, filterp);
}
@ -409,7 +409,7 @@ main(int argc, char **argv)
r = getsbuf();
if(r == 0)
fatal("Out of service buffers");
n = localread9pmsg(netfd, r->buf, messagesize, &initial);
if(n <= 0)
fatal(nil);
@ -423,7 +423,7 @@ main(int argc, char **argv)
}
/*
* WARNING: Replace this with the original version as soon as all
* WARNING: Replace this with the original version as soon as all
* _old_ imports have been replaced with negotiating imports. Also
* cpu relies on this (which needs to be fixed!) -- pb.
*/
@ -473,7 +473,7 @@ reply(Fcall *r, Fcall *t, char *err)
t->type = Rerror;
t->ename = err;
}
else
else
t->type = r->type + 1;
DEBUG(DFD, "\t%F\n", t);
@ -531,7 +531,7 @@ freefid(int nr)
l = &f->next;
}
return 0;
return 0;
}
Fid *
@ -564,7 +564,7 @@ newfid(int nr)
new->fid = -1;
new->mid = 0;
return new;
return new;
}
Fsrpc *
@ -869,7 +869,7 @@ fatal(char *s, ...)
postnote(PNPROC, m->pid, "kill");
DEBUG(DFD, "%s\n", buf);
if (s)
if (s)
sysfatal("%s", buf); /* caution: buf could contain '%' */
else
exits(nil);
@ -920,7 +920,7 @@ filter(int fd, char *cmd)
if ((s = strchr(newport, '\n')) != nil)
*s = '\0';
if ((nb = write(fd, newport, len)) < 0)
if ((nb = write(fd, newport, len)) < 0)
sysfatal("getport; cannot write port; %r");
assert(nb == len);
@ -952,7 +952,7 @@ filter(int fd, char *cmd)
close(fd);
close(p[0]);
}
return p[1];
return p[1];
}
static void

View File

@ -311,7 +311,7 @@ Xcreate(Fsrpc *t)
path = makepath(f->f, t->work.name);
f->fid = create(path, t->work.mode, t->work.perm);
f->fid = ocreate(path, t->work.mode, t->work.perm);
free(path);
if(f->fid < 0) {
errstr(err, sizeof err);

View File

@ -131,7 +131,7 @@ copy(char *from, char *to, int todir)
failed = 1;
return;
}
fdt=create(to, OWRITE, mode);
fdt=ocreate(to, OWRITE, mode);
if(fdt<0){
fprint(2, "fcp: can't create %s: %r\n", to);
close(fdf);
@ -151,7 +151,7 @@ copy(char *from, char *to, int todir)
dirt.gid = dirb->gid;
if(dirfwstat(fdt, &dirt) < 0)
fprint(2, "fcp: warning: can't wstat %s: %r\n", to);
}
}
free(dirb);
close(fdf);
close(fdt);

View File

@ -152,7 +152,7 @@ main(int argc, char **argv)
else
p = seprint(p, e, "%s", t);
u.postbody = postbody;
break;
default:
usage();
@ -168,7 +168,7 @@ main(int argc, char **argv)
if(argc != 1)
usage();
out.fd = 1;
out.written = 0;
out.offset = 0;
@ -177,7 +177,7 @@ main(int argc, char **argv)
if(ofile != nil){
d = dirstat(ofile);
if(d == nil){
out.fd = create(ofile, OWRITE, 0664);
out.fd = ocreate(ofile, OWRITE, 0664);
if(out.fd < 0)
sysfatal("creating %s: %r", ofile);
} else {
@ -238,7 +238,7 @@ crackurl(URL *u, char *s)
u->page = nil;
}
/* get type */
/* get type */
for(p = s; *p; p++){
if(*p == '/'){
p = s;
@ -288,7 +288,7 @@ crackurl(URL *u, char *s)
if(p = strchr(u->host, ':')) {
*p++ = 0;
u->port = p;
} else
} else
u->port = method[u->method].name;
if(*(u->host) == 0){
@ -425,7 +425,7 @@ dohttp(URL *u, URL *px, Range *r, Out *out, int32_t mtime)
cfd = -1;
}
}
dfprint(fd, "\r\n", u->host);
if(u->postbody)
dfprint(fd, "%s", u->postbody);
@ -498,7 +498,7 @@ dohttp(URL *u, URL *px, Range *r, Out *out, int32_t mtime)
case 503: /* Service unavailable */
sysfatal("Service unavailable");
default:
sysfatal("Unknown response code %d", code);
}
@ -891,7 +891,7 @@ doftp(URL *u, URL *px, Range *r, Out *out, int32_t mtime)
close(ctl);
return Eof;
}
/* first try passive mode, then active */
data = passive(ctl, u);
if(data < 0){
@ -1207,7 +1207,7 @@ active(int ctl, URL *u)
}
close(afd);
close(lcfd);
return dfd;
}

View File

@ -359,7 +359,7 @@ consproc(void *v)
char *s;
char *args[MAXARGS];
int rc;
in = (Biobuf *) v;
for(;;){
s = Brdstr(in, '\n', 1);
@ -398,7 +398,7 @@ initcons(char *service)
char buf[512];
snprint(buf, sizeof(buf), "/srv/%s.cmd", service);
fd = create(buf, OWRITE|ORCLOSE, 0600);
fd = ocreate(buf, OWRITE|ORCLOSE, 0600);
if(fd < 0)
return;
pipe(pfd);

View File

@ -58,7 +58,7 @@ enabledebug(const char *file)
if (!debugging) {
if((fd = open(file, OCEXEC|OTRUNC|OWRITE)) < 0){
debug("open: %r\n");
if((fd = create(file, OCEXEC|OWRITE, 0666)) < 0)
if((fd = ocreate(file, OCEXEC|OWRITE, 0666)) < 0)
sysfatal("create %r");
}
dup(fd, 2);
@ -211,9 +211,9 @@ post(char *srv, int fd)
fprint(2, "post %s...\n", srv);
sprint(buf, "#s/%s", srv);
f = create(buf, OWRITE, 0666);
f = ocreate(buf, OWRITE, 0666);
if(f < 0)
sysfatal("create(%s)", srv);
sysfatal("ocreate(%s)", srv);
sprint(buf, "%d", fd);
if(write(f, buf, strlen(buf)) != strlen(buf))
sysfatal("write");

View File

@ -23,7 +23,7 @@ void warning(char*, char*);
%token <sym> FUNCTION PROCEDURE RETURN FUNC PROC READ
%type <formals> formals
%type <inst> expr stmt asgn prlist stmtlist
%type <inst> cond while for if begin end
%type <inst> cond while for if begin end
%type <sym> procname
%type <narg> arglist
%right '=' ADDEQ SUBEQ MULEQ DIVEQ MODEQ
@ -39,7 +39,7 @@ list: /* nothing */
| list '\n'
| list defn '\n'
| list asgn '\n' { code2(xpop, STOP); return 1; }
| list stmt '\n' { code(STOP); return 1; }
| list stmt '\n' { code(STOP); return 1; }
| list expr '\n' { code2(printtop, STOP); return 1; }
| list error '\n' { yyerrok; }
;
@ -357,7 +357,7 @@ moreinput(void)
expr = infile+2;
sprint(buf, "/tmp/hocXXXXXXX");
infile = mktemp(buf);
fd = create(infile, ORDWR|ORCLOSE, 0600);
fd = ocreate(infile, ORDWR|ORCLOSE, 0600);
if(fd < 0){
fprint(2, "%s: can't create temp. file: %r\n", progname);
return 0;

View File

@ -75,7 +75,7 @@ post(char *name, char *envname, int srvfd)
int fd;
char buf[32];
fd = create(name, OWRITE, 0600);
fd = ocreate(name, OWRITE, 0600);
if(fd < 0)
return;
sprint(buf, "%d",srvfd);

View File

@ -220,7 +220,7 @@ setenv(char *name, char *val)
{
int fd;
fd = create(name, OWRITE, 0644);
fd = ocreate(name, OWRITE, 0644);
if(fd < 0)
fprint(2, "init: can't create %s: %r\n", name);
else{

View File

@ -106,7 +106,7 @@ lockopen(char *file)
}
if(strstr(err, "exist")){
/* no file, create an exclusive access file */
fd = create(file, ORDWR, DMEXCL|0664);
fd = ocreate(file, ORDWR, DMEXCL|0664);
if(fd >= 0)
return fd;
}
@ -400,7 +400,7 @@ commitbinding(Binding *b)
}
setbinding(b, b->offeredto, now + b->offer);
b->lasttouched = now;
if(writebinding(fd, b) < 0){
close(fd);
return -1;
@ -429,7 +429,7 @@ releasebinding(Binding *b, char *id)
}
b->lease = 0;
b->expoffer = 0;
if(writebinding(fd, b) < 0){
close(fd);
return -1;

View File

@ -1306,7 +1306,7 @@ openfreqfile(void)
}
fd = open(p, ORDWR);
if(fd < 0)
fd = create(p, ORDWR, 0666);
fd = ocreate(p, ORDWR, 0666);
free(p);
if(fd < 0)
return -1;

View File

@ -129,7 +129,7 @@ main(int argc, char *argv[])
case -1:
error("fork");
case 0:
fd = create("/env/prompt", OWRITE, 0666);
fd = ocreate("/env/prompt", OWRITE, 0666);
if (fd >= 0) {
fprint(fd, "%s%% ", lock);
close(fd);

View File

@ -38,7 +38,7 @@ main(int argc, char *argv[])
dirfrom = nil;
if(argc == 3
&& (dirfrom = dirstat(argv[1])) != nil
&& (dirfrom->mode & DMDIR))
&& (dirfrom->mode & DMDIR))
split(argv[argc-1], &todir, &toelem); /* mv dir1 dir2 */
else{ /* mv file... dir */
todir = argv[argc-1];
@ -150,7 +150,7 @@ mv1(char *from, Dir *dirb, char *todir, char *toelem)
hardremove(toname); /* because create() won't truncate file */
free(dirt);
fdt = create(toname, OWRITE, dirb->mode);
fdt = ocreate(toname, OWRITE, dirb->mode);
if(fdt < 0){
fprint(2, "mv: can't create %s: %r\n", toname);
close(fdf);

View File

@ -308,7 +308,7 @@ mountinit(char *service, char *mntpt)
/*
* make a /srv/cs
*/
f = create(service, OWRITE|ORCLOSE, 0666);
f = ocreate(service, OWRITE|ORCLOSE, 0666);
if(f < 0)
error(service);
snprint(buf, sizeof(buf), "%d", p[1]);

View File

@ -257,7 +257,7 @@ dnstats(char *file)
{
int i, fd;
fd = create(file, OWRITE, 0666);
fd = ocreate(file, OWRITE, 0666);
if(fd < 0)
return;
@ -301,7 +301,7 @@ dndump(char *file)
DN *dp;
RR *rp;
fd = create(file, OWRITE, 0666);
fd = ocreate(file, OWRITE, 0666);
if(fd < 0)
return;
@ -786,7 +786,7 @@ rrattach1(RR *new, int auth)
if(rp->negative != new->negative) {
/* rp == *l before; *l == rp->next after */
rrdelhead(l);
continue;
continue;
}
/* all things equal, pick the newer one */
else if(rp->arg0 == new->arg0 && rp->arg1 == new->arg1){

View File

@ -267,7 +267,7 @@ mountinit(char *service, char *mntpt)
/*
* make a /srv/dns
*/
if((f = create(service, OWRITE|ORCLOSE, 0666)) < 0)
if((f = ocreate(service, OWRITE|ORCLOSE, 0666)) < 0)
sysfatal("create %s failed: %r", service);
snprint(buf, sizeof buf, "%d", p[1]);
if(write(f, buf, strlen(buf)) != strlen(buf))

View File

@ -68,7 +68,7 @@ main(int argc, char **argv)
{
Ndbtuple *t, *nt;
int n;
Dir *d;
Dir *d;
uint8_t buf[8];
char file[128];
int fd;
@ -125,7 +125,7 @@ main(int argc, char **argv)
/* create the hash file */
snprint(file, sizeof(file), "%s.%s", argv[1], argv[2]);
fd = create(file, ORDWR, 0664);
fd = ocreate(file, ORDWR, 0664);
if(fd < 0){
fprint(2, "mkhash: can't create %s\n", file);
exits(syserr());

View File

@ -188,9 +188,9 @@ main(int argc, char *argv[])
parse("/cfg/ndb/local");
parse("/cfg/ndb/friends");
}
sprint(fn, "/cfg/ndb/db.%-.24s", domname);
fd = create(fn, OWRITE, 0664);
fd = ocreate(fn, OWRITE, 0664);
if(fd < 0){
fprint(2, "can't create %s: %r\n", fn);
exits("boom");
@ -201,7 +201,7 @@ main(int argc, char *argv[])
close(fd);
sprint(fn, "/cfg/ndb/equiv.%-.21s", domname);
fd = create(fn, OWRITE, 0664);
fd = ocreate(fn, OWRITE, 0664);
if(fd < 0){
fprint(2, "can't create %s: %r\n", fn);
exits("boom");
@ -211,7 +211,7 @@ main(int argc, char *argv[])
close(fd);
sprint(fn, "/cfg/ndb/txt.%-.23s", domname);
fd = create(fn, OWRITE, 0664);
fd = ocreate(fn, OWRITE, 0664);
if(fd < 0){
fprint(2, "can't create %s: %r\n", fn);
exits("boom");

View File

@ -207,7 +207,7 @@ main(int argc, char *argv[])
if(defmnt == 0){
char buf[64];
snprint(buf, sizeof buf, "#s/%s", service);
fd = create(buf, OWRITE|ORCLOSE, 0666);
fd = ocreate(buf, OWRITE|ORCLOSE, 0666);
if(fd < 0)
error("create failed");
sprint(buf, "%d", p[1]);

View File

@ -562,7 +562,7 @@ Executable(char *file)
int
Creat(char *file)
{
return create(file, OWRITE, 0666L);
return ocreate(file, OWRITE, 0666L);
}
int

View File

@ -89,7 +89,7 @@ post(char *name, char *envname, int srvfd)
int fd;
char buf[32];
fd = create(name, OWRITE|ORCLOSE|OCEXEC, 0600);
fd = ocreate(name, OWRITE|ORCLOSE|OCEXEC, 0600);
if(fd < 0)
error(name);
snprint(buf, sizeof(buf), "%d", srvfd);

View File

@ -1,4 +1,4 @@
/*
/*
* This file is part of the UCB release of Plan 9. It is subject to the license
* terms in the LICENSE file found in the top-level directory of this
* distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
@ -22,7 +22,7 @@ tempdisk(void)
buf[5] = i;
if(access(buf, AEXIST) == 0)
continue;
fd = create(buf, ORDWR|ORCLOSE|OCEXEC, 0600);
fd = ocreate(buf, ORDWR|ORCLOSE|OCEXEC, 0600);
if(fd >= 0)
return fd;
}

View File

@ -1,4 +1,4 @@
/*
/*
* This file is part of the UCB release of Plan 9. It is subject to the license
* terms in the LICENSE file found in the top-level directory of this
* distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
@ -55,7 +55,7 @@ writef(File *f)
if(genc)
free(genc);
genc = Strtoc(&genstr);
if((io=create(genc, OWRITE, 0666L)) < 0)
if((io=ocreate(genc, OWRITE, 0666L)) < 0)
error_r(Ecreate, genc);
dprint("%s: ", genc);
if(statfd(io, 0, 0, 0, &length, &appendonly) > 0 && appendonly && length>0)
@ -232,7 +232,7 @@ connectto(char *machine, char **argv)
int p1[2], p2[2];
char **av;
int ac;
// count args
for(av = argv; *av; av++)
;

View File

@ -1,4 +1,4 @@
/*
/*
* This file is part of the UCB release of Plan 9. It is subject to the license
* terms in the LICENSE file found in the top-level directory of this
* distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
@ -98,7 +98,7 @@ journal(int out, char *s)
static int fd = 0;
if(fd <= 0)
fd = create("/tmp/sam.out", OWRITE, 0666L);
fd = ocreate("/tmp/sam.out", OWRITE, 0666L);
fprint(fd, "%s%s\n", out? "out: " : "in: ", s);
}
@ -622,7 +622,7 @@ vlong
invlong(void)
{
vlong v;
v = (inp[7]<<24) | (inp[6]<<16) | (inp[5]<<8) | inp[4];
v = (v<<16) | (inp[3]<<8) | inp[2];
v = (v<<16) | (inp[1]<<8) | inp[0];
@ -785,7 +785,7 @@ void
outshort(int s)
{
*outp++ = s;
*outp++ = s>>8;
*outp++ = s>>8;
}
void

View File

@ -1,4 +1,4 @@
/*
/*
* This file is part of the UCB release of Plan 9. It is subject to the license
* terms in the LICENSE file found in the top-level directory of this
* distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
@ -47,7 +47,7 @@ void main(int argc, char *argv[])
int i;
String *t;
char *termargs[10], **ap;
ap = termargs;
*ap++ = "samterm";
ARGBEGIN{
@ -75,7 +75,7 @@ void main(int argc, char *argv[])
break;
}ARGEND
*ap = nil;
Strinit(&cmdstr);
Strinit0(&lastpat);
Strinit0(&lastregexp);
@ -137,7 +137,7 @@ rescue(void)
continue;
if(io == -1){
sprint(buf, "%s/sam.save", home);
io = create(buf, OWRITE, 0777);
io = ocreate(buf, OWRITE, 0777);
if(io<0)
return;
}

View File

@ -1,4 +1,4 @@
/*
/*
* This file is part of the UCB release of Plan 9. It is subject to the license
* terms in the LICENSE file found in the top-level directory of this
* distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
@ -41,9 +41,9 @@ plan9(File *f, int type, String *s, int nest)
snarf(f, addr.r.p1, addr.r.p2, &plan9buf, 1);
if((pid=fork()) == 0){
if(downloaded){ /* also put nasty fd's into errfile */
fd = create(errfile, OWRITE, 0666L);
fd = ocreate(errfile, OWRITE, 0666L);
if(fd < 0)
fd = create("/dev/null", OWRITE, 0666L);
fd = ocreate("/dev/null", OWRITE, 0666L);
dup(fd, 2);
close(fd);
/* 2 now points at err file */

View File

@ -1,4 +1,4 @@
/*
/*
* This file is part of the UCB release of Plan 9. It is subject to the license
* terms in the LICENSE file found in the top-level directory of this
* distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
@ -107,7 +107,7 @@ snarfswap(char *fromsam, int nc, char **tosam)
free(s1);
} else
s1[n] = 0;
f = create("/dev/snarf", OWRITE, 0666);
f = ocreate("/dev/snarf", OWRITE, 0666);
if(f >= 0){
write(f, fromsam, nc);
close(f);
@ -167,7 +167,7 @@ extstart(void)
if(pipe(p) < 0)
return;
sprint(exname, "/srv/sam.%s", getuser());
fd = create(exname, OWRITE, 0600);
fd = ocreate(exname, OWRITE, 0600);
if(fd < 0){ /* assume existing guy is more important */
Err:
close(p[0]);

View File

@ -616,7 +616,7 @@ open_file(char *name)
if ((bp = malloc(sizeof(Biobuf))) == 0)
quit("Out of memory");
if ((fd = open(name, OWRITE)) < 0 &&
(fd = create(name, OWRITE, 0666)) < 0)
(fd = ocreate(name, OWRITE, 0666)) < 0)
quit("Cannot create %s", name);
Binit(bp, fd, OWRITE);
Bseek(bp, 0, 2);

View File

@ -191,7 +191,7 @@ main(int argc, char *argv[])
f = 1;
if(args.ofile) {
f = create(args.ofile, OWRITE, 0666);
f = ocreate(args.ofile, OWRITE, 0666);
if(f < 0) {
fprint(2, "sort: create %s: %r\n", args.ofile);
done("create");
@ -334,7 +334,7 @@ tempout(void)
sort4(args.linep, args.nline);
tf = tempfile(args.ntemp);
args.ntemp++;
f = create(tf, OWRITE, 0666);
f = ocreate(tf, OWRITE, 0666);
if(f < 0) {
fprint(2, "sort: create %s: %r\n", tf);
done("create");
@ -410,7 +410,7 @@ mergeout(Biobuf *b)
if(n > Nmerge) {
tf = tempfile(args.ntemp);
args.ntemp++;
f = create(tf, OWRITE, 0666);
f = ocreate(tf, OWRITE, 0666);
if(f < 0) {
fprint(2, "sort: create %s: %r\n", tf);
done("create");

View File

@ -110,7 +110,7 @@ main(int argc, char *argv[])
}
/*
* in case we didn't end with a newline, tack whatever's
* in case we didn't end with a newline, tack whatever's
* left onto the last file
*/
while((n = Bread(b, buf, sizeof(buf))) > 0)
@ -132,7 +132,7 @@ nextfile(void)
canopen = 0;
} else {
snprint(name, sizeof name, "%s%s", stem, suff);
if(++suff[1] > 'z')
if(++suff[1] > 'z')
suff[1] = 'a', ++suff[0];
openf();
}
@ -149,7 +149,7 @@ matchfile(Resub *match)
strcpy(name+len, suffix);
openf();
return 1;
}
}
return nextfile();
}
@ -162,7 +162,7 @@ openf(void)
Bterm(output);
if(fd > 0)
close(fd);
fd = create(name,OWRITE,0666);
fd = ocreate(name,OWRITE,0666);
if(fd < 0) {
fprint(2, "grep: can't create %s: %r\n", name);
exits("create");

View File

@ -228,7 +228,7 @@ post(char *srv, int fd)
char buf[128];
fprint(2, "post...\n");
f = create(srv, OWRITE, 0666);
f = ocreate(srv, OWRITE, 0666);
if(f < 0){
sprint(buf, "create(%s)", srv);
error(buf);

View File

@ -91,7 +91,7 @@ main(int argc, char **argv)
strecpy(buf, buf+sizeof buf, argv[0]);
else
snprint(buf, sizeof buf, "/srv/%s", argv[0]);
fd = create(buf, OWRITE, perm);
fd = ocreate(buf, OWRITE, perm);
if(fd < 0){
fprint(2, "can't create %s: %r\n", buf);
exits("create");

View File

@ -882,7 +882,7 @@ replace(char **argv)
Pushstate ps;
if (usefile && docreate)
ar = create(usefile, OWRITE, 0666);
ar = ocreate(usefile, OWRITE, 0666);
else if (usefile)
ar = open(usefile, ORDWR);
else
@ -1065,10 +1065,10 @@ openfname(Hdr *hp, char *fname, int dir, int mode)
if (!keepexisting || access(fname, AEXIST) < 0) {
int rw = (dir? OREAD: OWRITE);
fd = create(fname, rw, mode);
fd = ocreate(fname, rw, mode);
if (fd < 0) {
mkpdirs(fname);
fd = create(fname, rw, mode);
fd = ocreate(fname, rw, mode);
}
if (fd < 0 && (!dir || xaccess(fname, AEXIST) < 0))
cantcreate(fname, mode);

View File

@ -56,10 +56,10 @@ main(int argc, char **argv)
if(aflag) {
openf[n] = open(argv[0], OWRITE);
if(openf[n] < 0)
openf[n] = create(argv[0], OWRITE, 0666);
openf[n] = ocreate(argv[0], OWRITE, 0666);
seek(openf[n], 0L, 2);
} else
openf[n] = create(argv[0], OWRITE, 0666);
openf[n] = ocreate(argv[0], OWRITE, 0666);
if(openf[n] < 0) {
fprint(2, "tee: cannot open %s: %r\n", argv[0]);
} else

View File

@ -38,7 +38,7 @@ main(int argc, char **argv)
case 'c':
nocreate = 1;
break;
default:
default:
usage();
}ARGEND
@ -65,7 +65,7 @@ touch(int nocreate, char *name)
fprint(2, "touch: %s: cannot wstat: %r\n", name);
return 1;
}
if((fd = create(name, OREAD|OEXCL, 0666)) < 0){
if((fd = create(name, OREAD, 0666)) < 0){
fprint(2, "touch: %s: cannot create: %r\n", name);
return 1;
}

View File

@ -53,7 +53,7 @@ static void
fulfill(Req *req, Event *e)
{
int n;
n = e->len;
if(n > req->ifcall.count)
n = req->ifcall.count;
@ -124,7 +124,7 @@ static void
pushevent(Dev *d, char *data)
{
Event *e;
qlock(&evlock);
e = evlast;
evlast = emallocz(sizeof(Event), 1);
@ -225,7 +225,7 @@ formatdev(Dev *d, int type)
Usbdev *u = d->usb;
return smprint("%s %d %.4x %.4x %.6lx %s\n",
type ? "detach" : "attach",
d->id, u->vid, u->did, u->csp,
d->id, u->vid, u->did, u->csp,
d->hname != nil ? d->hname : "");
}
@ -239,7 +239,7 @@ enumerate(Event **l)
Port *p;
Dev *d;
int i;
for(h = hubs; h != nil; h = h->next){
for(i = 1; i <= h->nport; i++){
p = &h->port[i];
@ -447,7 +447,7 @@ main(int argc, char **argv)
break;
} ARGEND;
busyfd = create("/env/usbbusy", ORCLOSE, 0600);
busyfd = ocreate("/env/usbbusy", ORCLOSE, 0600);
quotefmtinstall();
initevent();
rfork(RFNOTEG);

View File

@ -609,7 +609,8 @@ faultamd64(Ureg* ureg, void* _1)
insyscall = up->insyscall;
up->insyscall = 1;
if(iskaddr(addr)){
print("kaddr %#llux pc %#p\n", addr, ureg->ip); prflush();
print("kaddr %#llux pc %#p\n", addr, ureg->ip);
// prflush();
dumpregs(ureg);
}
if(fault(addr, ureg->ip, ftype) < 0){

View File

@ -30,7 +30,7 @@ savelogsproc(void)
out = open("/sys/log/kernel", OWRITE);
if(out < 0){
out = create("/sys/log/kernel", OWRITE, 0600);
out = ocreate("/sys/log/kernel", OWRITE, 0600);
if(out < 0){
fprint(2, "savelogs: cannot create /sys/log/kernel: %r\n");
return;
@ -139,7 +139,7 @@ setenv(char *name, char *val)
char ename[64];
snprint(ename, sizeof ename, "#e/%s", name);
f = create(ename, OWRITE, 0666);
f = ocreate(ename, OWRITE, 0666);
if(f < 0){
fprint(2, "create %s: %r\n", ename);
return;
@ -162,7 +162,7 @@ srvcreate(char *name, int fd)
srvname = name;
snprint(buf, sizeof buf, "#s/%s", srvname);
f = create(buf, OWRITE, 0600);
f = ocreate(buf, OWRITE, 0600);
if(f < 0)
fatal(buf);
sprint(buf, "%d", fd);

View File

@ -1222,7 +1222,7 @@ namec(char *aname, int amode, int omode, int perm)
Elemlist e;
Rune r;
Mhead *mh;
char *createerr, tmperrbuf[ERRMAX];
char tmperrbuf[ERRMAX];
char *name;
Dev *dev;
@ -1309,13 +1309,7 @@ namec(char *aname, int amode, int omode, int perm)
dev = devtabget(r, 1); //XDYNX
if(dev == nil)
error(Ebadsharp);
//if(waserror()){
// devtabdecr(dev);
// nexterror();
//}
c = dev->attach(nil, nil, up->genbuf+n, 0);
//poperror();
//devtabdecr(dev);
break;
default:
@ -1403,7 +1397,6 @@ namec(char *aname, int amode, int omode, int perm)
case Aaccess:
case Aremove:
case Aopen:
Open:
/* save&update the name; domount might change c */
path = c->path;
incref(&path->r);
@ -1482,58 +1475,13 @@ namec(char *aname, int amode, int omode, int perm)
case Acreate:
/*
* We've already walked all but the last element.
* If the last exists, try to open it OTRUNC.
* If omode&OEXCL is set, just give up.
* If the last exists just give up.
*/
e.nelems++;
e.nerror++;
if(walk(&c, e.elems+e.nelems-1, 1, nomount, nil) == 0){
if(omode&OEXCL)
error(Eexist);
omode |= OTRUNC;
goto Open;
}
if(walk(&c, e.elems+e.nelems-1, 1, nomount, nil) == 0)
error(Eexist);
/*
* The semantics of the create(2) system call are that if the
* file exists and can be written, it is to be opened with truncation.
* On the other hand, the create(5) message fails if the file exists.
* If we get two create(2) calls happening simultaneously,
* they might both get here and send create(5) messages, but only
* one of the messages will succeed. To provide the expected create(2)
* semantics, the call with the failed message needs to try the above
* walk again, opening for truncation. This correctly solves the
* create/create race, in the sense that any observable outcome can
* be explained as one happening before the other.
* The create/create race is quite common. For example, it happens
* when two rc subshells simultaneously update the same
* environment variable.
*
* The implementation still admits a create/create/remove race:
* (A) walk to file, fails
* (B) walk to file, fails
* (A) create file, succeeds, returns
* (B) create file, fails
* (A) remove file, succeeds, returns
* (B) walk to file, return failure.
*
* This is hardly as common as the create/create race, and is really
* not too much worse than what might happen if (B) got a hold of a
* file descriptor and then the file was removed -- either way (B) can't do
* anything with the result of the create call. So we don't care about this race.
*
* Applications that care about more fine-grained decision of the races
* can use the OEXCL flag to get at the underlying create(5) semantics;
* by default we provide the common case.
*
* We need to stay behind the mount point in case we
* need to do the first walk again (should the create fail).
*
* We also need to cross the mount point and find the directory
* in the union in which we should be creating.
*
* The channel staying behind is c, the one moving forward is cnew.
*/
mh = nil;
cnew = nil; /* is this assignment necessary? */
if(!waserror()){ /* try create */
@ -1555,7 +1503,7 @@ namec(char *aname, int amode, int omode, int perm)
cnew->path = c->path;
incref(&cnew->path->r);
cnew = cnew->dev->create(cnew, e.elems[e.nelems-1], omode&~(OEXCL|OCEXEC), perm);
cnew = cnew->dev->create(cnew, e.elems[e.nelems-1], omode&~(OCEXEC), perm);
poperror();
if(omode & OCEXEC)
cnew->flag |= CCEXEC;
@ -1570,19 +1518,7 @@ namec(char *aname, int amode, int omode, int perm)
/* create failed */
cclose(cnew);
putmhead(mh);
if(omode & OEXCL)
nexterror();
/* save error */
createerr = up->errstr;
up->errstr = tmperrbuf;
/* note: we depend that walk does not error */
if(walk(&c, e.elems+e.nelems-1, 1, nomount, nil) < 0){
up->errstr = createerr;
error(createerr); /* report true error */
}
up->errstr = createerr;
omode |= OTRUNC;
goto Open;
nexterror();
default:
panic("unknown namec access %d", amode);

View File

@ -498,7 +498,7 @@ ninep2mode(int omode9p)
if((omode9p&~0xff) || (omode9p&NP_OZEROES))
error("invalid 9P2000 open mode");
switch(omode9p & ~(NP_OTRUNC|NP_ORCLOSE)){
switch(omode9p & ~(NP_OTRUNC|NP_ORCLOSE|NP_OCEXEC)){
case NP_OREAD:
return OREAD;
case NP_OWRITE:
@ -513,10 +513,12 @@ ninep2mode(int omode9p)
default:
error("invalid 9P2000 open mode");
}
if(omode9p & NP_OTRUNC)
mode |= OTRUNC;
if(omode9p & NP_OCEXEC)
mode |= OCEXEC;
if(omode9p & NP_ORCLOSE)
mode |= ORCLOSE;
if(omode9p & NP_OTRUNC)
mode |= OTRUNC;
return mode;
}
@ -542,6 +544,8 @@ mode2ninep(unsigned long mode)
omode9p |= NP_OEXEC;
if(mode & ORCLOSE)
omode9p |= NP_ORCLOSE;
if(mode & OCEXEC)
omode9p |= NP_OCEXEC;
/* this is an approssimation: in Jehanne this bit might means
* something different to a server, but then the

View File

@ -245,11 +245,9 @@ void
prflush(void)
{
unsigned long now;
// uint32_t now;
now = sys->ticks;
while(consactive())
// uartpush();
if(sys->ticks - now >= 30*HZ)
break;
}
@ -365,7 +363,6 @@ print(char *fmt, ...)
n = vseprint(buf, buf+sizeof(buf), fmt, arg) - buf;
va_end(arg);
putstrn(buf, n);
if(strchr(buf, '\n') != nil)prflush();
return n;
}
@ -452,7 +449,7 @@ panic(char *fmt, ...)
buf[n] = '\n';
putstrn(buf, n+1);
// dumpstack();
prflush();
// prflush();
// dump();
exit(1);

View File

@ -157,7 +157,7 @@ srvcreate(Chan *c, char *name, unsigned long omode, unsigned long perm)
{
Srv *sp;
if(openmode(omode & ~ORCLOSE) != OWRITE){
if(openmode(omode & ~(ORCLOSE|OTRUNC)) != OWRITE){
errorf("srvcreate: omode %#p openmode %#p", omode, openmode(omode & ~ORCLOSE));
//error(Eperm);
}

View File

@ -204,7 +204,6 @@ extern uint64_t strtoull(char*, char**, int);
/* OPEN MODES: Popular flags among filesystems */
#define OTRUNC 0x0100 /* or'ed in (except for exec), truncate file first */
#define OEXCL 0x0200 /* or'ed in, exclusive create */
#define NCONT 0 /* continue after note */
#define NDFLT 1 /* terminate after note */

View File

@ -1030,7 +1030,7 @@ syscreate(char* aname, uint32_t omode, uint32_t perm)
int fd;
Chan *c;
openmode(omode & ~OEXCL); /* error check only; OEXCL okay here */
openmode(omode); /* error check only; OEXCL okay here */
c = nil;
if(waserror()) {
if(c != nil)

View File

@ -410,7 +410,7 @@ sopen(Srv *srv, Req *r)
respond(r, Ebotch);
return;
}
if((r->fid->qid.type&QTDIR) && (r->ifcall.mode&~ORCLOSE) != NP_OREAD){
if((r->fid->qid.type&QTDIR) && (r->ifcall.mode&~NP_ORCLOSE) != NP_OREAD){
respond(r, Eisdir);
return;
}
@ -537,7 +537,7 @@ sread(Srv *srv, Req *r)
r->ifcall.count = srv->msize - IOHDRSZ;
r->rbuf = emalloc9p(r->ifcall.count);
r->ofcall.data = r->rbuf;
o = r->fid->omode & 7;
o = r->fid->omode & 3;
if(o != NP_OREAD && o != NP_ORDWR && o != NP_OEXEC){
respond(r, Ebotch);
return;
@ -579,7 +579,7 @@ swrite(Srv *srv, Req *r)
}
if(r->ifcall.count > srv->msize - IOHDRSZ)
r->ifcall.count = srv->msize - IOHDRSZ;
o = r->fid->omode & 7;
o = r->fid->omode & 3;
if(o != NP_OWRITE && o != NP_ORDWR){
snprint(e, sizeof e, "write on fid with open mode 0x%ux", r->fid->omode);
respond(r, e);
@ -952,7 +952,7 @@ postfd(char *name, int pfd)
snprint(buf, sizeof buf, "/srv/%s", name);
if(chatty9p)
fprint(2, "postfd %s\n", buf);
fd = create(buf, OWRITE|ORCLOSE|OCEXEC, 0600);
fd = ocreate(buf, OWRITE|ORCLOSE|OCEXEC, 0600);
if(fd < 0){
if(chatty9p)
fprint(2, "create fails: %r\n");
@ -981,7 +981,7 @@ sharefd(char *name, char *desc, int pfd)
snprint(buf, sizeof buf, "#σc/%s/%s", name, desc);
if(chatty9p)
fprint(2, "sharefd %s\n", buf);
fd = create(buf, OWRITE, 0600);
fd = ocreate(buf, OWRITE, 0600);
if(fd < 0){
if(chatty9p)
fprint(2, "create fails: %r\n");

View File

@ -340,7 +340,7 @@ setenv(char *name, char *val)
int32_t s;
sprint(ename, "#e/%s", name);
f = create(ename, OWRITE, 0664);
f = ocreate(ename, OWRITE, 0664);
if(f < 0)
return -1;
s = strlen(val);

View File

@ -133,7 +133,7 @@ Bopen(char *name, int mode)
f = open(name, mode);
break;
case OWRITE:
f = create(name, mode, 0666);
f = ocreate(name, mode, 0666);
break;
}
if(f < 0)

View File

@ -15,7 +15,17 @@ access(const char *name, int mode)
{
int fd;
Dir *db;
mode &= AMASK;
static char omode[] = {
0,
OEXEC,
OWRITE,
ORDWR,
OREAD,
OEXEC, /* only approximate */
ORDWR,
ORDWR /* only approximate */
};
if(mode == AEXIST){
db = dirstat(name);
@ -24,7 +34,7 @@ access(const char *name, int mode)
return 0;
return -1;
}
fd = open(name, mode);
fd = open(name, omode[mode&7]);
if(fd >= 0){
close(fd);
return 0;

View File

@ -0,0 +1,69 @@
/*
* This file is part of Jehanne.
*
* Copyright (C) 2016 Giacomo Tesio <giacomo@tesio.it>
*
* Jehanne is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 2 of the License.
*
* Jehanne is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Jehanne. If not, see <http://www.gnu.org/licenses/>.
*/
#include <u.h>
#include <libc.h>
/* ocreate works like the Plan 9 create(2) syscall, but with different races.
* In Plan 9 tjere os a race due to the different behaviour between the
* create syscall and the Tcreate message in 9P2000 when the file already exists:
* see https://github.com/brho/plan9/blob/master/sys/src/9/port/chan.c#L1564-L1603
* for details.
*
* In Jehanne the create syscall fails on existing files just like the Tcreate message.
* However the Plan 9/UNIX semantic is often useful, thus ocreate mimic it in userspace.
* As wisely noted by Charles Forsyth, such implementation introduce a different race
* due to the multiple evaluations of the path: on concurrent namespace changes, the
* different syscalls here could be handled by different devices/fileservers.
* However, given the user is responsible of such namespace changes, we prefer this race
* to the original Plan 9 one.
*
* For more info see http://marc.info/?t=146412533100003&r=1&w=2
*/
int
ocreate(const char *path, unsigned int omode, unsigned int perm)
{
int fd;
Dir *s;
fd = open(path, omode|OTRUNC);
if(fd < 0){
fd = create(path, omode, perm);
if(fd < 0){
fd = open(path, omode|OTRUNC);
if(fd < 0)
goto Done;
} else {
goto Done;
}
}
s = dirfstat(fd);
if(s == nil){
close(fd);
return -1;
}
if(s->mode != perm){
s->mode = perm;
dirfwstat(fd, s); /* we ignore the return value, the device/server is allowed to ignore us */
}
free(s);
Done:
return fd;
}

View File

@ -24,12 +24,12 @@ putenv(const char *name, const char *val)
snprint(ename, sizeof ename, "/env/%s", name);
if(strcmp(ename+5, name) != 0)
return -1;
f = create(ename, OWRITE, 0664);
f = ocreate(ename, OWRITE, 0664);
if(f < 0){
/* try with #e, in case of a previous rfork(RFCNAMEG)
*/
snprint(ename, sizeof ename, "#e/%s", name);
f = create(ename, OWRITE, 0664);
f = ocreate(ename, OWRITE, 0664);
if(f < 0)
return -1;
return -1;

View File

@ -59,6 +59,7 @@
"9sys/getwd.c",
"9sys/iounit.c",
"9sys/nulldir.c",
"9sys/ocreate.c",
"9sys/pipe.c",
"9sys/postnote.c",
"9sys/privalloc.c",

View File

@ -102,7 +102,7 @@ geninitdraw(char *devdir, void(*error)(Display*, char*),
if(fd >= 0){
read(fd, display->oldlabel, (sizeof display->oldlabel)-1);
close(fd);
fd = create(buf, OWRITE, 0666);
fd = ocreate(buf, OWRITE, 0666);
if(fd >= 0){
write(fd, label, strlen(label));
close(fd);

View File

@ -20,7 +20,7 @@ plumbopen(char *name, int omode)
if(name[0] == '/')
return open(name, omode);
/* find elusive plumber */
if(access("/mnt/plumb/send", AWRITE) >= 0)
plumber = "/mnt/plumb";
@ -51,7 +51,7 @@ plumbopen(char *name, int omode)
/* try creating port; used by non-standard plumb implementations */
rerrstr(err, sizeof err);
fd = create(buf, omode, 0600);
fd = ocreate(buf, omode, 0600);
if(fd >= 0)
return fd;
errstr(err, sizeof err);

View File

@ -42,13 +42,13 @@ FILE *freopen(const char *name, const char *mode, FILE *f){
f->fd=open(name, (*mode == '+'? ORDWR: OREAD));
break;
case 'w':
f->fd=create(name, (*mode == '+'? ORDWR: OWRITE), 0666);
f->fd=ocreate(name, (*mode == '+'? ORDWR: OWRITE), 0666);
break;
case 'a':
m = (*mode == '+'? ORDWR: OWRITE);
f->fd=open(name, m);
if(f->fd<0)
f->fd=create(name, m, 0666);
f->fd=ocreate(name, m, 0666);
seek(f->fd, 0LL, 2);
break;
}