commit 58fdc083addda3f95eb8895f474da5a52f145be0 from: Russ Cox date: Mon May 18 00:15:41 2020 UTC lib9: merge create, open, dirread into open.c Preparation for using opendir. commit - bd6f12068b28ba7eb96a3cd495e2201c852682b7 commit + 58fdc083addda3f95eb8895f474da5a52f145be0 blob - e4e3c715e963ee843bcbb0a6c03f09fd41f52ebe (mode 644) blob + /dev/null --- src/lib9/create.c +++ /dev/null @@ -1,75 +0,0 @@ -#define _GNU_SOURCE /* for Linux O_DIRECT */ -#include -#define NOPLAN9DEFINES -#include -#include -#include -#include -#include -#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; -} blob - c232eb8d819deb45820822f2f0bafc6a018fcaa5 (mode 644) blob + /dev/null --- src/lib9/dirread.c +++ /dev/null @@ -1,207 +0,0 @@ -#include -#define NOPLAN9DEFINES -#include -#include -#include - -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; id_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; id_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; -} blob - 7c37de4207a392f8f308ff80b44504494b64d5aa blob + 6fb3d4a7a82079acd0fec398e5ea362c33fed74d --- src/lib9/mkfile +++ 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\ blob - a0573ae7ff61c527fee4b8def9728c5330deb296 blob + 44a4feeef76a545790b467ea350dfb2927807292 --- src/lib9/open.c +++ src/lib9/open.c @@ -2,12 +2,80 @@ #include #define NOPLAN9DEFINES #include +#include +#include #include +#include +#include #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; id_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; id_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; +} blob - 0d52d3f929b758e9e10595b0fc282d8fd91c31bd blob + 8094c3eabcef60964ce373d3c30021248b4bbfc6 --- src/mkmk.sh +++ 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 ..