Re: dup2() Problem
Re: dup2() Problem
- Subject: Re: dup2() Problem
- From: Terry Lambert <email@hidden>
- Date: Sat, 7 Jul 2007 01:00:11 -0700
On Jul 6, 2007, at 3:39 PM, Norm Green wrote:
Thanks Mark. Yes the code below is short snipet.
I ran the program under ktrace and see that the system() call causes
a call to dup2(), which is failing with errno EBADF:
5738 sh CALL open(0x303f50,0x601,0x1b6)
5738 sh NAMI "testfile"
5738 sh RET open 5
5738 sh CALL dup2(0x5,0x1)
5738 sh RET dup2 -1 errno 9 Bad file descriptor
5738 sh CALL write(0x2,0x1800400,0x28)
5738 sh GIO fd 2 wrote 40 bytes
"/bin/sh: line 1: 1: Bad file descriptor
"
5738 sh RET write 40/0x28
5738 sh CALL exit(0x1)
This seems to indicate that all is well with the new file I opened
since it returned fd 5. So does that mean something's wrong with
stdout?have put traces in to check the value of fileno(stdout) and
it's always 1.
This isn't code, it's a system call trace, so we can't compile it up
and see it fail for ourselves. Nevertheless, we can gain the insight
that you are using file:
"testfile" (relative to the current directory).
and flags:
O_CREAT | O_TRUNC | O_WRONLY
and mode:
0666
So we know that you haven't dropped yourself into an owner exclusion
or exclusion group situation, and you haven't picked a mode
incompatible with being able to dup2 it (i.e. a dup2 is morally
equivalent to an open; so for example, if you had specified an open
falg of O_EXCL, you would be attempting to open the file in violation
of the exclusive use warranty made by the system to the other
decriptor).
So I write a small regression test that results in an identical ktrace
(except it doesn't fail, of course):
#include <fcntl.h> /* open */
#include <unistd.h> /* dup2 */
#include <stdio.h> /* perror, fprintf */
#include <stdlib.h> /* exit */
int
main(int ac, char *av[])
{
int fd;
if ((fd = open("testfile", O_CREAT | O_TRUNC | O_WRONLY,
0666)) == -1) {
perror("FAIL: open");
exit(1);
}
if (dup2(fd, 1) < 0) {
perror("FAIL: dup2");
exit(2);
}
fprintf(stderr, "PASS\n");
exit(0);
}
...I run it, and it prints "PASS" (try this code yourself).
So we look in the publically published Tiger sources (which you can
also look at, if you are motivated) in the dup2 implementation in
kern_descrip.c:
if (new < 0 ||
new >= p->p_rlimit[RLIMIT_NOFILE].rlim_cur ||
new >= maxfiles) {
fp_drop(p, old, fp, 1);
proc_fdunlock(p);
return (EBADF);
}
Translation: If I exceed the maximum number of open files according to
my resource limit, return EBADF. You might be doing this, but you
didn't priint the output of getrlimit() for RLIMIT_NOFILE and a list
of the other fd's you have open, so we haven't given us enough
information to know.
flags = fdp->fd_ofileflags[new];
if ((flags & (UF_RESERVED | UF_CLOSING)) ==
UF_RESERVED) {
fp_drop(p, old, fp, 1);
proc_fdunlock(p);
return (EBADF);
}
Translation: If the fd 1 is already in the process of being opened,
but has hung in this process (e.g. an NFS server went away out from
under us, etc.), then return EBADF. You might be doing this, but
since you didn't fstat fd 1 and report the output and we don't have
enough information to know.
if ((ofp = fdp->fd_ofiles[old]) == NULL ||
(fdp->fd_ofileflags[old] & UF_RESERVED)) {
_fdrelse(fdp, new);
return (EBADF);
}
Translation: If the thing I'm dup'ing is not open, or is in the
process of being opened, but has hung (e.g. it's a socket that has not
yet finished connecting, etc.), then return EBADF. You might be doing
this, but since you didn't give us information about your filesystem
topogy (which MUST be odd: we don't ship by default with a "/usr/tmp"
directory, yet your open in the previous posting succeeded), and you
didn't fstat fd 5 immediately following the open, we don't have enough
information to know.
--
So without source code that I too can make fail, and without answers
to the other questions, I'd have to say this is "pilot error" on your
part.
I am one of the primary maintainers of the particular kernel code in
question, and could resolve this question in an instant, if you had
provided a failing C source code example, and tell you the specific
pilot error involved. If it wasn't pilot error, and was in fact a
MacOS X specific problem, I could actually fix it on our end. But
only IF there was a bug report to which I could attach the code
changes in order to demonstrate that I wasn't just adding risk of
breaking someone depending on the current behaviour, and there was
actually a customer impact involved in not fixing the code.
As it is, you will need to answer the specific requests for
information above for an accurate diagnosis.
Thanks,
-- Terry
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Darwin-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden