aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRuss Cox <rsc@swtch.com>2020-05-17 12:35:03 -0400
committerRuss Cox <rsc@swtch.com>2020-05-17 20:15:41 -0400
commit58fdc083addda3f95eb8895f474da5a52f145be0 (patch)
treebd34a8ffeddbb56f19a1d9d8382f54a4811e459d
parentbd6f12068b28ba7eb96a3cd495e2201c852682b7 (diff)
downloadplan9port-58fdc083addda3f95eb8895f474da5a52f145be0.tar.gz
plan9port-58fdc083addda3f95eb8895f474da5a52f145be0.tar.bz2
plan9port-58fdc083addda3f95eb8895f474da5a52f145be0.zip
lib9: merge create, open, dirread into open.c
Preparation for using opendir.
-rw-r--r--src/lib9/create.c75
-rw-r--r--src/lib9/dirread.c207
-rw-r--r--src/lib9/mkfile2
-rw-r--r--src/lib9/open.c270
-rw-r--r--src/mkmk.sh11
5 files changed, 273 insertions, 292 deletions
diff --git a/src/lib9/create.c b/src/lib9/create.c
deleted file mode 100644
index e4e3c715..00000000
--- a/src/lib9/create.c
+++ /dev/null
@@ -1,75 +0,0 @@
-#define _GNU_SOURCE /* for Linux O_DIRECT */
-#include <u.h>
-#define NOPLAN9DEFINES
-#include <sys/file.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <libc.h>
-#include <sys/stat.h>
-#ifndef O_DIRECT
-#define O_DIRECT 0
-#endif
-
-int
-p9create(char *path, int mode, ulong perm)
-{
- int fd, cexec, umode, rclose, lock, rdwr;
- struct flock fl;
-
- rdwr = mode&3;
- lock = mode&OLOCK;
- cexec = mode&OCEXEC;
- rclose = mode&ORCLOSE;
- mode &= ~(ORCLOSE|OCEXEC|OLOCK);
-
- /* XXX should get mode mask right? */
- fd = -1;
- if(perm&DMDIR){
- if(mode != OREAD){
- werrstr("bad mode in directory create");
- goto out;
- }
- if(mkdir(path, perm&0777) < 0)
- goto out;
- fd = open(path, O_RDONLY);
- }else{
- umode = (mode&3)|O_CREAT|O_TRUNC;
- mode &= ~(3|OTRUNC);
- if(mode&ODIRECT){
- umode |= O_DIRECT;
- mode &= ~ODIRECT;
- }
- if(mode&OEXCL){
- umode |= O_EXCL;
- mode &= ~OEXCL;
- }
- if(mode&OAPPEND){
- umode |= O_APPEND;
- mode &= ~OAPPEND;
- }
- if(mode){
- werrstr("unsupported mode in create");
- goto out;
- }
- fd = open(path, umode, perm);
- }
-out:
- if(fd >= 0){
- if(lock){
- fl.l_type = (rdwr==OREAD) ? F_RDLCK : F_WRLCK;
- fl.l_whence = SEEK_SET;
- fl.l_start = 0;
- fl.l_len = 0;
- if(fcntl(fd, F_SETLK, &fl) < 0){
- close(fd);
- werrstr("lock: %r");
- return -1;
- }
- }
- if(cexec)
- fcntl(fd, F_SETFL, FD_CLOEXEC);
- if(rclose)
- remove(path);
- }
- return fd;
-}
diff --git a/src/lib9/dirread.c b/src/lib9/dirread.c
deleted file mode 100644
index c232eb8d..00000000
--- a/src/lib9/dirread.c
+++ /dev/null
@@ -1,207 +0,0 @@
-#include <u.h>
-#define NOPLAN9DEFINES
-#include <libc.h>
-#include <sys/stat.h>
-#include <dirent.h>
-
-extern int _p9dir(struct stat*, struct stat*, char*, Dir*, char**, char*);
-
-#if defined(__linux__)
-static int
-mygetdents(int fd, struct dirent *buf, int n)
-{
- off_t off;
- int nn;
-
- /* This doesn't match the man page, but it works in Debian with a 2.2 kernel */
- off = p9seek(fd, 0, 1);
- nn = getdirentries(fd, (void*)buf, n, &off);
- return nn;
-}
-#elif defined(__APPLE__)
-static int
-mygetdents(int fd, struct dirent *buf, int n)
-{
- long off;
- return getdirentries(fd, (void*)buf, n, &off);
-}
-#elif defined(__FreeBSD__) || defined(__DragonFly__)
-static int
-mygetdents(int fd, struct dirent *buf, int n)
-{
- off_t off;
- return getdirentries(fd, (void*)buf, n, &off);
-}
-#elif defined(__sun__) || defined(__NetBSD__) || defined(__OpenBSD__)
-static int
-mygetdents(int fd, struct dirent *buf, int n)
-{
- return getdents(fd, (void*)buf, n);
-}
-#elif defined(__AIX__)
-static int
-mygetdents(int fd, struct dirent *buf, int n)
-{
- return getdirent(fd, (void*)buf, n);
-}
-#endif
-
-#if defined(__DragonFly__)
-static inline int d_reclen(struct dirent *de) { return _DIRENT_DIRSIZ(de); }
-#else
-static inline int d_reclen(struct dirent *de) { return de->d_reclen; }
-#endif
-
-static int
-countde(char *p, int n)
-{
- char *e;
- int m;
- struct dirent *de;
-
- e = p+n;
- m = 0;
- while(p < e){
- de = (struct dirent*)p;
- if(d_reclen(de) <= 4+2+2+1 || p+d_reclen(de) > e)
- break;
- if(de->d_name[0]=='.' && de->d_name[1]==0)
- de->d_name[0] = 0;
- else if(de->d_name[0]=='.' && de->d_name[1]=='.' && de->d_name[2]==0)
- de->d_name[0] = 0;
- m++;
- p += d_reclen(de);
- }
- return m;
-}
-
-static int
-dirpackage(int fd, char *buf, int n, Dir **dp)
-{
- int oldwd;
- char *p, *str, *estr;
- int i, nstr, m;
- struct dirent *de;
- struct stat st, lst;
- Dir *d;
-
- n = countde(buf, n);
- if(n <= 0)
- return n;
-
- if((oldwd = open(".", O_RDONLY)) < 0)
- return -1;
- if(fchdir(fd) < 0)
- return -1;
-
- p = buf;
- nstr = 0;
-
- for(i=0; i<n; i++){
- de = (struct dirent*)p;
- memset(&lst, 0, sizeof lst);
- if(de->d_name[0] == 0)
- /* nothing */ {}
- else if(lstat(de->d_name, &lst) < 0)
- de->d_name[0] = 0;
- else{
- st = lst;
- if(S_ISLNK(lst.st_mode))
- stat(de->d_name, &st);
- nstr += _p9dir(&lst, &st, de->d_name, nil, nil, nil);
- }
- p += d_reclen(de);
- }
-
- d = malloc(sizeof(Dir)*n+nstr);
- if(d == nil){
- fchdir(oldwd);
- close(oldwd);
- return -1;
- }
- str = (char*)&d[n];
- estr = str+nstr;
-
- p = buf;
- m = 0;
- for(i=0; i<n; i++){
- de = (struct dirent*)p;
- if(de->d_name[0] != 0 && lstat(de->d_name, &lst) >= 0){
- st = lst;
- if((lst.st_mode&S_IFMT) == S_IFLNK)
- stat(de->d_name, &st);
- _p9dir(&lst, &st, de->d_name, &d[m++], &str, estr);
- }
- p += d_reclen(de);
- }
-
- fchdir(oldwd);
- close(oldwd);
- *dp = d;
- return m;
-}
-
-long
-dirread(int fd, Dir **dp)
-{
- char *buf;
- struct stat st;
- int n;
-
- *dp = 0;
-
- if(fstat(fd, &st) < 0)
- return -1;
-
- if(st.st_blksize < 8192)
- st.st_blksize = 8192;
-
- buf = malloc(st.st_blksize);
- if(buf == nil)
- return -1;
-
- n = mygetdents(fd, (void*)buf, st.st_blksize);
- if(n < 0){
- free(buf);
- return -1;
- }
- n = dirpackage(fd, buf, n, dp);
- free(buf);
- return n;
-}
-
-
-long
-dirreadall(int fd, Dir **d)
-{
- uchar *buf, *nbuf;
- long n, ts;
- struct stat st;
-
- if(fstat(fd, &st) < 0)
- return -1;
-
- if(st.st_blksize < 8192)
- st.st_blksize = 8192;
-
- buf = nil;
- ts = 0;
- for(;;){
- nbuf = realloc(buf, ts+st.st_blksize);
- if(nbuf == nil){
- free(buf);
- return -1;
- }
- buf = nbuf;
- n = mygetdents(fd, (void*)(buf+ts), st.st_blksize);
- if(n <= 0)
- break;
- ts += n;
- }
- if(ts >= 0)
- ts = dirpackage(fd, (char*)buf, ts, d);
- free(buf);
- if(ts == 0 && n < 0)
- return -1;
- return ts;
-}
diff --git a/src/lib9/mkfile b/src/lib9/mkfile
index 7c37de42..6fb3d4a7 100644
--- a/src/lib9/mkfile
+++ b/src/lib9/mkfile
@@ -86,14 +86,12 @@ LIB9OFILES=\
convM2D.$O\
convM2S.$O\
convS2M.$O\
- create.$O\
crypt.$O\
ctime.$O\
dial.$O\
dirfstat.$O\
dirfwstat.$O\
dirmodefmt.$O\
- dirread.$O\
dirstat.$O\
dirwstat.$O\
dup.$O\
diff --git a/src/lib9/open.c b/src/lib9/open.c
index a0573ae7..44a4feee 100644
--- a/src/lib9/open.c
+++ b/src/lib9/open.c
@@ -2,12 +2,80 @@
#include <u.h>
#define NOPLAN9DEFINES
#include <sys/file.h>
+#include <unistd.h>
+#include <fcntl.h>
#include <libc.h>
+#include <sys/stat.h>
+#include <dirent.h>
#ifndef O_DIRECT
#define O_DIRECT 0
#endif
int
+p9create(char *path, int mode, ulong perm)
+{
+ int fd, cexec, umode, rclose, lock, rdwr;
+ struct flock fl;
+
+ rdwr = mode&3;
+ lock = mode&OLOCK;
+ cexec = mode&OCEXEC;
+ rclose = mode&ORCLOSE;
+ mode &= ~(ORCLOSE|OCEXEC|OLOCK);
+
+ /* XXX should get mode mask right? */
+ fd = -1;
+ if(perm&DMDIR){
+ if(mode != OREAD){
+ werrstr("bad mode in directory create");
+ goto out;
+ }
+ if(mkdir(path, perm&0777) < 0)
+ goto out;
+ fd = open(path, O_RDONLY);
+ }else{
+ umode = (mode&3)|O_CREAT|O_TRUNC;
+ mode &= ~(3|OTRUNC);
+ if(mode&ODIRECT){
+ umode |= O_DIRECT;
+ mode &= ~ODIRECT;
+ }
+ if(mode&OEXCL){
+ umode |= O_EXCL;
+ mode &= ~OEXCL;
+ }
+ if(mode&OAPPEND){
+ umode |= O_APPEND;
+ mode &= ~OAPPEND;
+ }
+ if(mode){
+ werrstr("unsupported mode in create");
+ goto out;
+ }
+ fd = open(path, umode, perm);
+ }
+out:
+ if(fd >= 0){
+ if(lock){
+ fl.l_type = (rdwr==OREAD) ? F_RDLCK : F_WRLCK;
+ fl.l_whence = SEEK_SET;
+ fl.l_start = 0;
+ fl.l_len = 0;
+ if(fcntl(fd, F_SETLK, &fl) < 0){
+ close(fd);
+ werrstr("lock: %r");
+ return -1;
+ }
+ }
+ if(cexec)
+ fcntl(fd, F_SETFL, FD_CLOEXEC);
+ if(rclose)
+ remove(path);
+ }
+ return fd;
+}
+
+int
p9open(char *name, int mode)
{
int cexec, rclose;
@@ -60,3 +128,205 @@ p9open(char *name, int mode)
}
return fd;
}
+
+extern int _p9dir(struct stat*, struct stat*, char*, Dir*, char**, char*);
+
+#if defined(__linux__)
+static int
+mygetdents(int fd, struct dirent *buf, int n)
+{
+ off_t off;
+ int nn;
+
+ /* This doesn't match the man page, but it works in Debian with a 2.2 kernel */
+ off = p9seek(fd, 0, 1);
+ nn = getdirentries(fd, (void*)buf, n, &off);
+ return nn;
+}
+#elif defined(__APPLE__)
+static int
+mygetdents(int fd, struct dirent *buf, int n)
+{
+ long off;
+ return getdirentries(fd, (void*)buf, n, &off);
+}
+#elif defined(__FreeBSD__) || defined(__DragonFly__)
+static int
+mygetdents(int fd, struct dirent *buf, int n)
+{
+ off_t off;
+ return getdirentries(fd, (void*)buf, n, &off);
+}
+#elif defined(__sun__) || defined(__NetBSD__) || defined(__OpenBSD__)
+static int
+mygetdents(int fd, struct dirent *buf, int n)
+{
+ return getdents(fd, (void*)buf, n);
+}
+#elif defined(__AIX__)
+static int
+mygetdents(int fd, struct dirent *buf, int n)
+{
+ return getdirent(fd, (void*)buf, n);
+}
+#endif
+
+#if defined(__DragonFly__)
+static inline int d_reclen(struct dirent *de) { return _DIRENT_DIRSIZ(de); }
+#else
+static inline int d_reclen(struct dirent *de) { return de->d_reclen; }
+#endif
+
+static int
+countde(char *p, int n)
+{
+ char *e;
+ int m;
+ struct dirent *de;
+
+ e = p+n;
+ m = 0;
+ while(p < e){
+ de = (struct dirent*)p;
+ if(d_reclen(de) <= 4+2+2+1 || p+d_reclen(de) > e)
+ break;
+ if(de->d_name[0]=='.' && de->d_name[1]==0)
+ de->d_name[0] = 0;
+ else if(de->d_name[0]=='.' && de->d_name[1]=='.' && de->d_name[2]==0)
+ de->d_name[0] = 0;
+ m++;
+ p += d_reclen(de);
+ }
+ return m;
+}
+
+static int
+dirpackage(int fd, char *buf, int n, Dir **dp)
+{
+ int oldwd;
+ char *p, *str, *estr;
+ int i, nstr, m;
+ struct dirent *de;
+ struct stat st, lst;
+ Dir *d;
+
+ n = countde(buf, n);
+ if(n <= 0)
+ return n;
+
+ if((oldwd = open(".", O_RDONLY)) < 0)
+ return -1;
+ if(fchdir(fd) < 0)
+ return -1;
+
+ p = buf;
+ nstr = 0;
+
+ for(i=0; i<n; i++){
+ de = (struct dirent*)p;
+ memset(&lst, 0, sizeof lst);
+ if(de->d_name[0] == 0)
+ /* nothing */ {}
+ else if(lstat(de->d_name, &lst) < 0)
+ de->d_name[0] = 0;
+ else{
+ st = lst;
+ if(S_ISLNK(lst.st_mode))
+ stat(de->d_name, &st);
+ nstr += _p9dir(&lst, &st, de->d_name, nil, nil, nil);
+ }
+ p += d_reclen(de);
+ }
+
+ d = malloc(sizeof(Dir)*n+nstr);
+ if(d == nil){
+ fchdir(oldwd);
+ close(oldwd);
+ return -1;
+ }
+ str = (char*)&d[n];
+ estr = str+nstr;
+
+ p = buf;
+ m = 0;
+ for(i=0; i<n; i++){
+ de = (struct dirent*)p;
+ if(de->d_name[0] != 0 && lstat(de->d_name, &lst) >= 0){
+ st = lst;
+ if((lst.st_mode&S_IFMT) == S_IFLNK)
+ stat(de->d_name, &st);
+ _p9dir(&lst, &st, de->d_name, &d[m++], &str, estr);
+ }
+ p += d_reclen(de);
+ }
+
+ fchdir(oldwd);
+ close(oldwd);
+ *dp = d;
+ return m;
+}
+
+long
+dirread(int fd, Dir **dp)
+{
+ char *buf;
+ struct stat st;
+ int n;
+
+ *dp = 0;
+
+ if(fstat(fd, &st) < 0)
+ return -1;
+
+ if(st.st_blksize < 8192)
+ st.st_blksize = 8192;
+
+ buf = malloc(st.st_blksize);
+ if(buf == nil)
+ return -1;
+
+ n = mygetdents(fd, (void*)buf, st.st_blksize);
+ if(n < 0){
+ free(buf);
+ return -1;
+ }
+ n = dirpackage(fd, buf, n, dp);
+ free(buf);
+ return n;
+}
+
+
+long
+dirreadall(int fd, Dir **d)
+{
+ uchar *buf, *nbuf;
+ long n, ts;
+ struct stat st;
+
+ if(fstat(fd, &st) < 0)
+ return -1;
+
+ if(st.st_blksize < 8192)
+ st.st_blksize = 8192;
+
+ buf = nil;
+ ts = 0;
+ for(;;){
+ nbuf = realloc(buf, ts+st.st_blksize);
+ if(nbuf == nil){
+ free(buf);
+ return -1;
+ }
+ buf = nbuf;
+ n = mygetdents(fd, (void*)(buf+ts), st.st_blksize);
+ if(n <= 0)
+ break;
+ ts += n;
+ }
+ if(ts >= 0)
+ ts = dirpackage(fd, (char*)buf, ts, d);
+ free(buf);
+ if(ts == 0 && n < 0)
+ return -1;
+ return ts;
+}
diff --git a/src/mkmk.sh b/src/mkmk.sh
index 0d52d3f9..8094c3ea 100644
--- a/src/mkmk.sh
+++ b/src/mkmk.sh
@@ -20,14 +20,12 @@ echo cd `pwd`
9c convM2D.c
9c convM2S.c
9c convS2M.c
-9c create.c
9c crypt.c
9c ctime.c
9c dial.c
9c dirfstat.c
9c dirfwstat.c
9c dirmodefmt.c
-9c dirread.c
9c dirstat.c
9c dirwstat.c
9c dup.c
@@ -109,6 +107,7 @@ echo cd `pwd`
9c -Ifmt fmt/fmtstr.c
9c -Ifmt fmt/fmtvprint.c
9c -Ifmt fmt/fprint.c
+9c frexp.c
9c -Ifmt fmt/nan64.c
9c -Ifmt fmt/print.c
9c -Ifmt fmt/runefmtstr.c
@@ -150,7 +149,7 @@ echo cd `pwd`
9c utf/utfrrune.c
9c utf/utfrune.c
9c utf/utfutf.c
-9ar rsc $PLAN9/lib/lib9.a _exits.o _p9dialparse.o _p9dir.o announce.o argv0.o atexit.o atoi.o atol.o atoll.o atnotify.o await.o cistrcmp.o cistrncmp.o cistrstr.o cleanname.o convD2M.o convM2D.o convM2S.o convS2M.o create.o crypt.o ctime.o dial.o dirfstat.o dirfwstat.o dirmodefmt.o dirread.o dirstat.o dirwstat.o dup.o encodefmt.o errstr.o exec.o execl.o exitcode.o fcallfmt.o frand.o get9root.o getcallerpc.o getenv.o getfields.o getnetconn.o getns.o getuser.o getwd.o jmp.o lrand.o lnrand.o main.o malloc.o malloctag.o mallocz.o nan.o needsrcquote.o needstack.o netcrypt.o netmkaddr.o notify.o nrand.o nulldir.o open.o opentemp.o pin.o pipe.o post9p.o postnote.o qlock.o quote.o rand.o read9pmsg.o readcons.o readn.o rfork.o searchpath.o seek.o sendfd.o sleep.o strdup.o strecpy.o sysfatal.o syslog.o sysname.o time.o tm2sec.o tokenize.o truerand.o u16.o u32.o u64.o unsharp.o wait.o waitpid.o write.o zoneinfo.o dofmt.o fltfmt.o fmt.o fmtfd.o fmtfdflush.o fmtlocale.o fmtlock2.o fmtnull.o fmtprint.o fmtquote.o fmtrune.o fmtstr.o fmtvprint.o fprint.o nan64.o print.o runefmtstr.o runeseprint.o runesmprint.o runesnprint.o runesprint.o runevseprint.o runevsmprint.o runevsnprint.o seprint.o smprint.o snprint.o sprint.o strtod.o vfprint.o vseprint.o vsmprint.o vsnprint.o charstod.o pow10.o rune.o runestrcat.o runestrchr.o runestrcmp.o runestrcpy.o runestrdup.o runestrlen.o runestrecpy.o runestrncat.o runestrncmp.o runestrncpy.o runestrrchr.o runestrstr.o runetype.o utfecpy.o utflen.o utfnlen.o utfrrune.o utfrune.o utfutf.o
+9ar rsc $PLAN9/lib/lib9.a _exits.o _p9dialparse.o _p9dir.o announce.o argv0.o atexit.o atoi.o atol.o atoll.o atnotify.o await.o cistrcmp.o cistrncmp.o cistrstr.o cleanname.o convD2M.o convM2D.o convM2S.o convS2M.o crypt.o ctime.o dial.o dirfstat.o dirfwstat.o dirmodefmt.o dirstat.o dirwstat.o dup.o encodefmt.o errstr.o exec.o execl.o exitcode.o fcallfmt.o frand.o get9root.o getcallerpc.o getenv.o getfields.o getnetconn.o getns.o getuser.o getwd.o jmp.o lrand.o lnrand.o main.o malloc.o malloctag.o mallocz.o nan.o needsrcquote.o needstack.o netcrypt.o netmkaddr.o notify.o nrand.o nulldir.o open.o opentemp.o pin.o pipe.o post9p.o postnote.o qlock.o quote.o rand.o read9pmsg.o readcons.o readn.o rfork.o searchpath.o seek.o sendfd.o sleep.o strdup.o strecpy.o sysfatal.o syslog.o sysname.o time.o tm2sec.o tokenize.o truerand.o u16.o u32.o u64.o unsharp.o wait.o waitpid.o write.o zoneinfo.o dofmt.o fltfmt.o fmt.o fmtfd.o fmtfdflush.o fmtlocale.o fmtlock2.o fmtnull.o fmtprint.o fmtquote.o fmtrune.o fmtstr.o fmtvprint.o fprint.o frexp.o nan64.o print.o runefmtstr.o runeseprint.o runesmprint.o runesnprint.o runesprint.o runevseprint.o runevsmprint.o runevsnprint.o seprint.o smprint.o snprint.o sprint.o strtod.o vfprint.o vseprint.o vsmprint.o vsnprint.o charstod.o pow10.o rune.o runestrcat.o runestrchr.o runestrcmp.o runestrcpy.o runestrdup.o runestrlen.o runestrecpy.o runestrncat.o runestrncmp.o runestrncpy.o runestrrchr.o runestrstr.o runetype.o utfecpy.o utflen.o utfnlen.o utfrrune.o utfrune.o utfutf.o
cd ..
cd libbio
echo cd `pwd`
@@ -211,9 +210,5 @@ echo cd `pwd`
9c word.c
9c unix.c
9l -o o.mk arc.o archive.o bufblock.o env.o file.o graph.o job.o lex.o main.o match.o mk.o parse.o recipe.o rc.o rule.o run.o sh.o shell.o shprint.o symtab.o var.o varsub.o word.o unix.o
-if [ `uname` = AIX ]; then
- installbsd o.mk $PLAN9/bin/mk
-else
- install o.mk $PLAN9/bin/mk
-fi
+install o.mk $PLAN9/bin/mk
cd ..