* even if libc receives EBADF on write attempts, it feels determined
* to output data no matter what. So it will try later,
* and possibly will clobber future output. Not good. */
- if (dup2(1, 1) != 1)
- return -1;
+// TODO: check fcntl() & O_ACCMODE == O_WRONLY or O_RDWR?
+ if (fcntl(1, F_GETFL) == -1)
+ return 1; /* match coreutils 6.10 (sans error msg to stderr) */
+ //if (dup2(1, 1) != 1) - old way
+ // return 1;
arg = *++argv;
if (!arg)
char eflag = 0;
/* We must check that stdout is not closed. */
- if (dup2(1, 1) != 1)
- return -1;
+ if (fcntl(1, F_GETFL) == -1)
+ return 1;
while (1) {
arg = *++argv;
* even if libc receives EBADF on write attempts, it feels determined
* to output data no matter what. So it will try later,
* and possibly will clobber future output. Not good. */
- if (dup2(1, 1) != 1)
- return -1;
+// TODO: check fcntl() & O_ACCMODE == O_WRONLY or O_RDWR?
+ if (fcntl(1, F_GETFL) == -1)
+ return 1; /* match coreutils 6.10 (sans error msg to stderr) */
+ //if (dup2(1, 1) != 1) - old way
+ // return 1;
/* bash builtin errors out on "printf '-%s-\n' foo",
* coreutils-6.9 works. Both work with "printf -- '-%s-\n' foo".
{
int i;
- if (!rp) /* remebering was not requested */
+ if (!rp) /* remembering was not requested */
return 0;
for (i = 0; i < rp->pair_count; i++) {
return 1;
}
+/* "hidden" fd is a fd used to read scripts, or a copy of such */
+static int is_hidden_fd(struct redirtab *rp, int fd)
+{
+ int i;
+ struct parsefile *pf = g_parsefile;
+ while (pf) {
+ if (fd == pf->fd) {
+ return 1;
+ }
+ pf = pf->prev;
+ }
+ if (!rp)
+ return 0;
+ fd |= COPYFD_RESTORE;
+ for (i = 0; i < rp->pair_count; i++) {
+ if (rp->two_fd[i].copy == fd) {
+ return 1;
+ }
+ }
+ return 0;
+}
+
/*
* Process a list of redirection commands. If the REDIR_PUSH flag is set,
* old file descriptors are stashed away so that the redirection can be
do {
fd = redir->nfile.fd;
if (redir->nfile.type == NTOFD || redir->nfile.type == NFROMFD) {
- if (redir->ndup.dupfd == fd)
- continue; /* redirect from/to same file descriptor */
+ int right_fd = redir->ndup.dupfd;
+ /* redirect from/to same file descriptor? */
+ if (right_fd == fd)
+ continue;
+ /* echo >&10 and 10 is a fd opened to the sh script? */
+ if (is_hidden_fd(sv, right_fd)) {
+ errno = EBADF; /* as if it is closed */
+ ash_msg_and_raise_error("%d: %m", right_fd);
+ }
newfd = -1;
} else {
newfd = openredirect(redir); /* always >= 0 */
/* "exec fd>&-" should not close fds
* which point to script file(s).
* Force them to be restored afterwards */
- struct parsefile *pf = g_parsefile;
- while (pf) {
- if (fd == pf->fd) {
- i |= COPYFD_RESTORE;
- break;
- }
- pf = pf->prev;
- }
+ if (is_hidden_fd(sv, fd))
+ i |= COPYFD_RESTORE;
}
if (fd == 2)
copied_fd2 = i;
preadfd(void)
{
int nr;
- char *buf = g_parsefile->buf;
+ char *buf = g_parsefile->buf;
parsenextc = buf;
#if ENABLE_FEATURE_EDITING