shithub: riscv

Download patch

ref: 5debddf8aff9cc647cd9eeb89c06a550fbf816e7
parent: a8ffbcabead96e4ebaab861b2837c2d770409702
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Sat Aug 27 23:39:49 EDT 2016

ape: add d_stat struct in dirent struct allowing the avoidance of stats

--- a/sys/include/ape/dirent.h
+++ b/sys/include/ape/dirent.h
@@ -1,6 +1,11 @@
 #ifndef	__DIRENT_H
 #define	__DIRENT_H
 #pragma lib "/$M/lib/ape/libap.a"
+
+#ifndef __STAT_H
+#include <sys/stat.h>
+#endif
+
 /*
  * this must be a power of 2 and a multiple of all the ones in the system
  */
@@ -8,6 +13,7 @@
 
 struct	dirent {
 	char	d_name[MAXNAMLEN + 1];
+	struct stat d_stat;
 };
 
 typedef struct _dirdesc {
--- a/sys/src/ape/lib/ap/plan9/opendir.c
+++ b/sys/src/ape/lib/ap/plan9/opendir.c
@@ -13,23 +13,23 @@
 DIR *
 opendir(const char *filename)
 {
-	int f;
+	int f, n;
 	DIR *d;
-	struct stat sb;
-	Dir *d9;
+	char *s;
 
-	if((d9 = _dirstat(filename)) == nil){
-		_syserrno();
-		return NULL;
-	}
-	_dirtostat(&sb, d9, 0);
-	free(d9);
-	if(S_ISDIR(sb.st_mode) == 0) {
-		errno = ENOTDIR;
-		return NULL;
-	}
-
-	f = open(filename, O_RDONLY);
+	n = strlen(filename);
+	if(n > 0 && filename[n-1] != '/'){
+		s = malloc(n+2);
+		if(s == NULL)
+			goto Nomem;
+		memcpy(s, filename, n);
+		s[n++] = '/';
+		s[n] = 0;
+	} else
+		s = filename;
+	f = open(s, O_RDONLY);
+	if(s != filename)
+		free(s);
 	if(f < 0){
 		_syserrno();
 		return NULL;
@@ -36,7 +36,8 @@
 	}
 	_fdinfo[f].flags |= FD_CLOEXEC;
 	d = (DIR *)malloc(sizeof(DIR) + DBLOCKSIZE*sizeof(struct dirent));
-	if(!d){
+	if(d == NULL){
+Nomem:
 		errno = ENOMEM;
 		return NULL;
 	}
@@ -44,7 +45,7 @@
 	d->dd_fd = f;
 	d->dd_loc = 0;
 	d->dd_size = 0;
-	d->dirs = nil;
+	d->dirs = NULL;
 	d->dirsize = 0;
 	d->dirloc = 0;
 	return d;
@@ -53,21 +54,22 @@
 int
 closedir(DIR *d)
 {
-	if(!d){
+	int fd;
+
+	if(d == NULL){
 		errno = EBADF;
 		return -1;
 	}
-	if(close(d->dd_fd) < 0)
-		return -1;
+	fd = d->dd_fd;
 	free(d->dirs);
 	free(d);
-	return 0;
+	return close(fd);
 }
 
 void
 rewinddir(DIR *d)
 {
-	if(!d)
+	if(d == NULL)
 		return;
 	d->dd_loc = 0;
 	d->dd_size = 0;
@@ -74,7 +76,7 @@
 	d->dirsize = 0;
 	d->dirloc = 0;
 	free(d->dirs);
-	d->dirs = nil;
+	d->dirs = NULL;
 	if(_SEEK(d->dd_fd, 0, 0) < 0){
 		_syserrno();
 		return;
@@ -86,9 +88,9 @@
 {
 	int i;
 	struct dirent *dr;
-	Dir *dirs;
+	Dir *dirs, *dir;
 
-	if(!d){
+	if(d == NULL){
 		errno = EBADF;
 		return NULL;
 	}
@@ -109,8 +111,10 @@
 		dr = (struct dirent *)d->dd_buf;
 		dirs = d->dirs;
 		for(i=0; i<DBLOCKSIZE && d->dirloc < d->dirsize; i++){
-			strncpy(dr[i].d_name, dirs[d->dirloc++].name, MAXNAMLEN);
+			dir = &dirs[d->dirloc++];
+			strncpy(dr[i].d_name, dir->name, MAXNAMLEN);
 			dr[i].d_name[MAXNAMLEN] = 0;
+			_dirtostat(&dr[i].d_stat, dir, NULL);
 		}
 		d->dd_loc = 0;
 		d->dd_size = i*sizeof(struct dirent);