summary refs log tree commit diff
diff options
context:
space:
mode:
Diffstat (limited to '')
-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);