summary refs log tree commit diff
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2007-05-12 18:00:57 +1000
committerHerbert Xu <herbert@gondor.apana.org.au>2007-05-12 18:00:57 +1000
commitf393ff40ef49c582f614ff44107d1132753693a1 (patch)
treee4b50109b87c269a41b0a9d924ea58c8a1edda12
parent[EVAL] Use dup2 instead of copyfd in evalbackcmd (diff)
downloaddash-f393ff40ef49c582f614ff44107d1132753693a1.tar.gz
dash-f393ff40ef49c582f614ff44107d1132753693a1.zip
[REDIR] Replace copyfd by savefd and use dup2 elsewhere
There are two kinds of users to copyfd, those that want to copy an fd to
an exact value and those that want to move an fd to a value >= 10.  The
former can simply use dup2 directly while the latter share a lot of common
code that now constitutes savefd.
-rw-r--r--ChangeLog1
-rw-r--r--src/input.c8
-rw-r--r--src/jobs.c14
-rw-r--r--src/redir.c65
-rw-r--r--src/redir.h2
5 files changed, 44 insertions, 46 deletions
diff --git a/ChangeLog b/ChangeLog
index 20c55d1..a7635fb 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -3,6 +3,7 @@
 	* Removed unnecessary inclusion of redir.h from parser.c.
 	* Invoke sh_error on error in copyfd.
 	* Use dup2 instead of copyfd in evalbackcmd.
+	* Replace copyfd by savefd and dup2.
 
 2007-05-05  Herbert Xu <herbert@gondor.apana.org.au>
 
diff --git a/src/input.c b/src/input.c
index 49a2972..7f99d4a 100644
--- a/src/input.c
+++ b/src/input.c
@@ -428,7 +428,6 @@ int
 setinputfile(const char *fname, int flags)
 {
 	int fd;
-	int fd2;
 
 	INTOFF;
 	if ((fd = open(fname, O_RDONLY)) < 0) {
@@ -436,11 +435,8 @@ setinputfile(const char *fname, int flags)
 			goto out;
 		sh_error("Can't open %s", fname);
 	}
-	if (fd < 10) {
-		fd2 = copyfd(fd, 10);
-		close(fd);
-		fd = fd2;
-	}
+	if (fd < 10)
+		fd = savefd(fd);
 	setinputfd(fd, flags & INPUT_PUSH_FILE);
 out:
 	INTON;
diff --git a/src/jobs.c b/src/jobs.c
index 9e28adb..7285d0d 100644
--- a/src/jobs.c
+++ b/src/jobs.c
@@ -188,18 +188,14 @@ setjobctl(int on)
 	if (on == jobctl || rootshell == 0)
 		return;
 	if (on) {
-		int ofd;
-		ofd = fd = open(_PATH_TTY, O_RDWR);
+		fd = open(_PATH_TTY, O_RDWR);
 		if (fd < 0) {
 			fd += 3;
-			while (!isatty(fd) && --fd >= 0)
-				;
+			while (!isatty(fd))
+				if (--fd < 0)
+					goto out;
 		}
-		fd = fcntl(fd, F_DUPFD, 10);
-		close(ofd);
-		if (fd < 0)
-			goto out;
-		fcntl(fd, F_SETFD, FD_CLOEXEC);
+		fd = savefd(fd);
 		do { /* while we are in the background */
 			if ((pgrp = tcgetpgrp(fd)) < 0) {
 out:
diff --git a/src/redir.c b/src/redir.c
index aab1585..9e0fae5 100644
--- a/src/redir.c
+++ b/src/redir.c
@@ -138,21 +138,10 @@ redirect(union node *redir, int flags)
 		if (fd == newfd)
 			continue;
 		if (sv && *(p = &sv->renamed[fd]) == EMPTY) {
-			int i = fcntl(fd, F_DUPFD, 10);
-			if (i == -1) {
-				i = errno;
-				if (i != EBADF) {
-					const char *m = strerror(i);
-					close(newfd);
-					sh_error("%d: %s", fd, m);
-					/* NOTREACHED */
-				}
-			} else {
+			int i = savefd(fd);
+
+			if (i >= 0)
 				*p = i;
-				close(fd);
-			}
-		} else {
-			close(fd);
 		}
 #ifdef notyet
 		dupredirect(n, newfd, memory);
@@ -244,6 +233,7 @@ dupredirect(redir, f)
 #endif
 	{
 	int fd = redir->nfile.fd;
+	int err = 0;
 
 #ifdef notyet
 	memory[fd] = 0;
@@ -255,16 +245,24 @@ dupredirect(redir, f)
 				memory[fd] = 1;
 			else
 #endif
-				copyfd(redir->ndup.dupfd, fd);
+				if (dup2(f, fd) < 0) {
+					err = errno;
+					goto err;
+				}
+			return;
 		}
-		return;
-	}
+		f = fd;
+	} else if (dup2(f, fd) < 0)
+		err = errno;
+
+	close(f);
+	if (err < 0)
+		goto err;
 
-	if (f != fd) {
-		copyfd(f, fd);
-		close(f);
-	}
 	return;
+
+err:
+	sh_error("%d: %s", f, strerror(err));
 }
 
 
@@ -327,10 +325,8 @@ popredir(int drop)
 	rp = redirlist;
 	for (i = 0 ; i < 10 ; i++) {
 		if (rp->renamed[i] != EMPTY) {
-			if (!drop) {
-				close(i);
-				copyfd(rp->renamed[i], i);
-			}
+			if (!drop)
+				dup2(rp->renamed[i], i);
 			close(rp->renamed[i]);
 		}
 	}
@@ -372,17 +368,26 @@ clearredir(int drop)
 
 
 /*
- * Copy a file descriptor to be >= to.  Invokes sh_error on error.
+ * Move a file descriptor to > 10.  Invokes sh_error on error unless
+ * the original file dscriptor is not open.
  */
 
 int
-copyfd(int from, int to)
+savefd(int from)
 {
 	int newfd;
+	int err;
+
+	newfd = fcntl(from, F_DUPFD, 10);
+	err = newfd < 0 ? errno : 0;
+	if (err != EBADF) {
+		close(from);
+		if (err)
+			sh_error("%d: %s", from, strerror(err));
+		else
+			fcntl(newfd, F_SETFD, FD_CLOEXEC);
+	}
 
-	newfd = fcntl(from, F_DUPFD, to);
-	if (newfd < 0)
-		sh_error("%d: %s", from, strerror(errno));
 	return newfd;
 }
 
diff --git a/src/redir.h b/src/redir.h
index f4347ce..2c43511 100644
--- a/src/redir.h
+++ b/src/redir.h
@@ -45,6 +45,6 @@ union node;
 void redirect(union node *, int);
 void popredir(int);
 void clearredir(int);
-int copyfd(int, int);
+int savefd(int);
 int redirectsafe(union node *, int);