summary refs log tree commit diff
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2020-05-07 23:42:12 +1000
committerHerbert Xu <herbert@gondor.apana.org.au>2020-05-15 16:24:38 +1000
commit3e3e7af1a49273a5e49d50565b3b079a2ab19142 (patch)
treee39ad4bc65d7d7cb13f0d0c8d2b2b595bff40be4
parentinput: Fix compiling against libedit with -fno-common (diff)
downloaddash-3e3e7af1a49273a5e49d50565b3b079a2ab19142.tar.gz
dash-3e3e7af1a49273a5e49d50565b3b079a2ab19142.zip
shell: Always use explicit large file API
There are some remaining stat/readdir calls in dash that may lead
to spurious EOVERFLOW errors on 32-bit platforms.  This patch changes
them (as well as open(2)) to use the explicit large file API.

Reported-by: Tatsuki Sugiura <sugi@nemui.org>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to '')
-rw-r--r--configure.ac5
-rw-r--r--src/bltin/test.c26
-rw-r--r--src/cd.c4
-rw-r--r--src/expand.c4
-rw-r--r--src/input.c2
-rw-r--r--src/jobs.c4
-rw-r--r--src/main.c4
-rw-r--r--src/var.c4
8 files changed, 29 insertions, 24 deletions
diff --git a/configure.ac b/configure.ac
index 5dab5aa..dbd97d8 100644
--- a/configure.ac
+++ b/configure.ac
@@ -144,8 +144,13 @@ AC_CHECK_FUNC(stat64,, [
 	AC_DEFINE(fstat64, fstat, [64-bit operations are the same as 32-bit])
 	AC_DEFINE(lstat64, lstat, [64-bit operations are the same as 32-bit])
 	AC_DEFINE(stat64, stat, [64-bit operations are the same as 32-bit])
+	AC_DEFINE(readdir64, readdir,
+		  [64-bit operations are the same as 32-bit])
+	AC_DEFINE(dirent64, dirent,
+		  [64-bit operations are the same as 32-bit])
 ])
 
+dnl OS X apparently has stat64 but not open64.
 AC_CHECK_FUNC(open64,, [
 	AC_DEFINE(open64, open, [64-bit operations are the same as 32-bit])
 ])
diff --git a/src/bltin/test.c b/src/bltin/test.c
index b7188df..c7fc479 100644
--- a/src/bltin/test.c
+++ b/src/bltin/test.c
@@ -473,17 +473,17 @@ static int isoperand(char **tp)
 static int
 newerf (const char *f1, const char *f2)
 {
-	struct stat b1, b2;
+	struct stat64 b1, b2;
 
 #ifdef HAVE_ST_MTIM
-	return (stat (f1, &b1) == 0 &&
-		stat (f2, &b2) == 0 &&
+	return (stat64(f1, &b1) == 0 &&
+		stat64(f2, &b2) == 0 &&
 		( b1.st_mtim.tv_sec > b2.st_mtim.tv_sec ||
 		 (b1.st_mtim.tv_sec == b2.st_mtim.tv_sec && (b1.st_mtim.tv_nsec > b2.st_mtim.tv_nsec )))
 	);
 #else
-	return (stat (f1, &b1) == 0 &&
-		stat (f2, &b2) == 0 &&
+	return (stat64(f1, &b1) == 0 &&
+		stat64(f2, &b2) == 0 &&
 		b1.st_mtime > b2.st_mtime);
 #endif
 }
@@ -491,17 +491,17 @@ newerf (const char *f1, const char *f2)
 static int
 olderf (const char *f1, const char *f2)
 {
-	struct stat b1, b2;
+	struct stat64 b1, b2;
 
 #ifdef HAVE_ST_MTIM
-	return (stat (f1, &b1) == 0 &&
-		stat (f2, &b2) == 0 &&
+	return (stat64(f1, &b1) == 0 &&
+		stat64(f2, &b2) == 0 &&
 		(b1.st_mtim.tv_sec < b2.st_mtim.tv_sec ||
 		 (b1.st_mtim.tv_sec == b2.st_mtim.tv_sec && (b1.st_mtim.tv_nsec < b2.st_mtim.tv_nsec )))
 	);
 #else
-	return (stat (f1, &b1) == 0 &&
-		stat (f2, &b2) == 0 &&
+	return (stat64(f1, &b1) == 0 &&
+		stat64(f2, &b2) == 0 &&
 		b1.st_mtime < b2.st_mtime);
 #endif
 }
@@ -509,10 +509,10 @@ olderf (const char *f1, const char *f2)
 static int
 equalf (const char *f1, const char *f2)
 {
-	struct stat b1, b2;
+	struct stat64 b1, b2;
 
-	return (stat (f1, &b1) == 0 &&
-		stat (f2, &b2) == 0 &&
+	return (stat64(f1, &b1) == 0 &&
+		stat64(f2, &b2) == 0 &&
 		b1.st_dev == b2.st_dev &&
 		b1.st_ino == b2.st_ino);
 }
diff --git a/src/cd.c b/src/cd.c
index b6742af..1ef1dc5 100644
--- a/src/cd.c
+++ b/src/cd.c
@@ -96,7 +96,7 @@ cdcmd(int argc, char **argv)
 	const char *path;
 	const char *p;
 	char c;
-	struct stat statb;
+	struct stat64 statb;
 	int flags;
 	int len;
 
@@ -132,7 +132,7 @@ dotdot:
 		c = *p;
 		p = stalloc(len);
 
-		if (stat(p, &statb) >= 0 && S_ISDIR(statb.st_mode)) {
+		if (stat64(p, &statb) >= 0 && S_ISDIR(statb.st_mode)) {
 			if (c && c != ':')
 				flags |= CD_PRINT;
 docd:
diff --git a/src/expand.c b/src/expand.c
index 985cd70..1730670 100644
--- a/src/expand.c
+++ b/src/expand.c
@@ -1284,7 +1284,7 @@ expmeta(char *name, unsigned name_len, unsigned expdir_len)
 	int metaflag;
 	struct stat64 statb;
 	DIR *dirp;
-	struct dirent *dp;
+	struct dirent64 *dp;
 	int atend;
 	int matchdot;
 	int esc;
@@ -1361,7 +1361,7 @@ expmeta(char *name, unsigned name_len, unsigned expdir_len)
 		p++;
 	if (*p == '.')
 		matchdot++;
-	while (! int_pending() && (dp = readdir(dirp)) != NULL) {
+	while (! int_pending() && (dp = readdir64(dirp)) != NULL) {
 		if (dp->d_name[0] == '.' && ! matchdot)
 			continue;
 		if (pmatch(start, dp->d_name)) {
diff --git a/src/input.c b/src/input.c
index 4a9b267..17544e7 100644
--- a/src/input.c
+++ b/src/input.c
@@ -393,7 +393,7 @@ setinputfile(const char *fname, int flags)
 	int fd;
 
 	INTOFF;
-	if ((fd = open(fname, O_RDONLY)) < 0) {
+	if ((fd = open64(fname, O_RDONLY)) < 0) {
 		if (flags & INPUT_NOFILE_OK)
 			goto out;
 		exitstatus = 127;
diff --git a/src/jobs.c b/src/jobs.c
index a9e6524..f65435d 100644
--- a/src/jobs.c
+++ b/src/jobs.c
@@ -196,7 +196,7 @@ setjobctl(int on)
 		return;
 	if (on) {
 		int ofd;
-		ofd = fd = open(_PATH_TTY, O_RDWR);
+		ofd = fd = open64(_PATH_TTY, O_RDWR);
 		if (fd < 0) {
 			fd += 3;
 			while (!isatty(fd))
@@ -887,7 +887,7 @@ static void forkchild(struct job *jp, union node *n, int mode)
 		ignoresig(SIGQUIT);
 		if (jp->nprocs == 0) {
 			close(0);
-			if (open(_PATH_DEVNULL, O_RDONLY) != 0)
+			if (open64(_PATH_DEVNULL, O_RDONLY) != 0)
 				sh_error("Can't open %s", _PATH_DEVNULL);
 		}
 	}
diff --git a/src/main.c b/src/main.c
index 36431fc..7a28534 100644
--- a/src/main.c
+++ b/src/main.c
@@ -298,7 +298,7 @@ find_dot_file(char *basename)
 {
 	char *fullname;
 	const char *path = pathval();
-	struct stat statb;
+	struct stat64 statb;
 	int len;
 
 	/* don't try this for absolute or relative paths */
@@ -308,7 +308,7 @@ find_dot_file(char *basename)
 	while ((len = padvance(&path, basename)) >= 0) {
 		fullname = stackblock();
 		if ((!pathopt || *pathopt == 'f') &&
-		    !stat(fullname, &statb) && S_ISREG(statb.st_mode)) {
+		    !stat64(fullname, &statb) && S_ISREG(statb.st_mode)) {
 			/* This will be freed by the caller. */
 			return stalloc(len);
 		}
diff --git a/src/var.c b/src/var.c
index b146018..ef9c2bd 100644
--- a/src/var.c
+++ b/src/var.c
@@ -125,7 +125,7 @@ INIT {
 	char **envp;
 	static char ppid[32] = "PPID=";
 	const char *p;
-	struct stat st1, st2;
+	struct stat64 st1, st2;
 
 	initvar();
 	for (envp = environ ; *envp ; envp++) {
@@ -143,7 +143,7 @@ INIT {
 
 	p = lookupvar("PWD");
 	if (p)
-		if (*p != '/' || stat(p, &st1) || stat(".", &st2) ||
+		if (*p != '/' || stat64(p, &st1) || stat64(".", &st2) ||
 		    st1.st_dev != st2.st_dev || st1.st_ino != st2.st_ino)
 			p = 0;
 	setpwd(p, 0);