|
Home > Archive > Unix Programming > June 2004 > stdout redirection problem
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
stdout redirection problem
|
|
| Rickard 2004-06-15, 5:56 pm |
| Hi,
I have some problems getting this simple C program to work on Linux:
#include <stdio.h> /* fprintf, stderr */
#include <unistd.h> /* fork, pipe, read, write */
#include <sys/poll.h> /* poll */
static void WriteAByte(int fd);
static void ReadAByte(int fd);
int main(void)
{
int pipes[2];
int pipes2[2];
pipe(pipes);
pipe(pipes2);
if (0 == fork())
{
dup2(pipes[0], 0);
dup2(pipes2[0], 1);
ReadAByte(0);
WriteAByte(1);
}
else
{
WriteAByte(pipes[1]);
ReadAByte(pipes2[1]);
}
return (0);
}
void ReadAByte(int fd)
{
struct pollfd fds;
int res;
char byte;
fds.fd = fd;
fds.events = POLLIN;
res = poll(&fds, 1, 100);
if (res != 0)
{
(void)fprintf(stderr,
">>%d Got something (%d)<<\n",
getpid(),
read(fd, &byte, 1));
}
}
void WriteAByte(int fd)
{
char byte = 'x';
(void)fprintf(stderr,
">>%d Wrote something (%d)<<\n",
getpid(),
write(fd, &byte, 1));
}
On solaris (5.6 Generic_105181-31 sun4u sparc SUNW,Ultra-2) the
program works fine:
[vbcol=seagreen]
> ./pipes
)<<
On Linux however (2.4.21-15.ELsmp i686 GNU/Linux) write to stdout
fails with errno 9, Bad file number.
[vbcol=seagreen]
> ./pipes
Any help/input is appreciated.
Regards,
Rickard
| |
| sean larsson 2004-06-15, 5:56 pm |
| On 15 Jun 2004 09:30:26 -0700
r_holgersson@hotmail.com (Rickard) wrote:
> Hi,
>
> I have some problems getting this simple C program to work on Linux:
>
> #include <stdio.h> /* fprintf, stderr */
> #include <unistd.h> /* fork, pipe, read, write */
> #include <sys/poll.h> /* poll */
>
> static void WriteAByte(int fd);
> static void ReadAByte(int fd);
>
> int main(void)
> {
> int pipes[2];
> int pipes2[2];
>
> pipe(pipes);
> pipe(pipes2);
>
> if (0 == fork())
> {
> dup2(pipes[0], 0);
> dup2(pipes2[0], 1);
>
> ReadAByte(0);
> WriteAByte(1);
> }
you are dup'ing the read end of a pipe to STDOUT. stdout is a writing stream, not a reading one. when u call WriteAByte(1) you are now trying to write to the read end of a pipe, on linux this returns EBADF. and you haven't checked the error returns of
functions either.
> else
> {
> WriteAByte(pipes[1]);
> ReadAByte(pipes2[1]);
> }
>
> return (0);
> }
>
> void ReadAByte(int fd)
> {
> struct pollfd fds;
> int res;
> char byte;
>
> fds.fd = fd;
> fds.events = POLLIN;
>
> res = poll(&fds, 1, 100);
> if (res != 0)
> {
> (void)fprintf(stderr,
> ">>%d Got something (%d)<<\n",
> getpid(),
> read(fd, &byte, 1));
> }
> }
>
> void WriteAByte(int fd)
> {
> char byte = 'x';
> (void)fprintf(stderr,
> ">>%d Wrote something (%d)<<\n",
> getpid(),
> write(fd, &byte, 1));
> }
>
> On solaris (5.6 Generic_105181-31 sun4u sparc SUNW,Ultra-2) the
> program works fine:
>
> )<<
>
> On Linux however (2.4.21-15.ELsmp i686 GNU/Linux) write to stdout
> fails with errno 9, Bad file number.
>
>
> Any help/input is appreciated.
>
> Regards,
> Rickard
--
-sean
| |
| Barry Margolin 2004-06-15, 5:56 pm |
| In article <6fd342f2.0406150830.31c5413d@posting.google.com>,
r_holgersson@hotmail.com (Rickard) wrote:
> Hi,
>
> I have some problems getting this simple C program to work on Linux:
>
> #include <stdio.h> /* fprintf, stderr */
> #include <unistd.h> /* fork, pipe, read, write */
> #include <sys/poll.h> /* poll */
>
> static void WriteAByte(int fd);
> static void ReadAByte(int fd);
>
> int main(void)
> {
> int pipes[2];
> int pipes2[2];
>
> pipe(pipes);
> pipe(pipes2);
>
> if (0 == fork())
> {
> dup2(pipes[0], 0);
> dup2(pipes2[0], 1);
>
> ReadAByte(0);
> WriteAByte(1);
> }
> else
> {
> WriteAByte(pipes[1]);
> ReadAByte(pipes2[1]);
> }
>
> return (0);
> }
>
> void ReadAByte(int fd)
> {
> struct pollfd fds;
> int res;
> char byte;
>
> fds.fd = fd;
> fds.events = POLLIN;
>
> res = poll(&fds, 1, 100);
> if (res != 0)
> {
> (void)fprintf(stderr,
> ">>%d Got something (%d)<<\n",
> getpid(),
> read(fd, &byte, 1));
> }
> }
>
> void WriteAByte(int fd)
> {
> char byte = 'x';
> (void)fprintf(stderr,
> ">>%d Wrote something (%d)<<\n",
> getpid(),
> write(fd, &byte, 1));
> }
>
> On solaris (5.6 Generic_105181-31 sun4u sparc SUNW,Ultra-2) the
> program works fine:
>
> )<<
>
> On Linux however (2.4.21-15.ELsmp i686 GNU/Linux) write to stdout
> fails with errno 9, Bad file number.
>
>
> Any help/input is appreciated.
How are you checking errno? You need to check it *before* calling
fprintf(), because this function almost always modifies errno (and EBADF
is a common value that it sets it to). So change your code to something
like:
result = write(fd, &byte, 1);
if (result == -1)
perror(">>%d couldn't write something (%d)<<", getpid(), result);
else
(void)fprintf(stderr, ">>%d Wrote something (%d)<<\n",
getpid, result);
--
Barry Margolin, barmar@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
| |
| sean larsson 2004-06-15, 5:57 pm |
| On Tue, 15 Jun 2004 13:24:26 -0400
Barry Margolin <barmar@alum.mit.edu> wrote:
> In article <6fd342f2.0406150830.31c5413d@posting.google.com>,
> r_holgersson@hotmail.com (Rickard) wrote:
>
>
> How are you checking errno? You need to check it *before* calling
> fprintf(), because this function almost always modifies errno (and EBADF
> is a common value that it sets it to). So change your code to something
> like:
>
> result = write(fd, &byte, 1);
> if (result == -1)
> perror(">>%d couldn't write something (%d)<<", getpid(), result);
> else
> (void)fprintf(stderr, ">>%d Wrote something (%d)<<\n",
> getpid, result);
>
> --
> Barry Margolin, barmar@alum.mit.edu
> Arlington, MA
> *** PLEASE post questions in newsgroups, not directly to me ***
i'm pretty sure the problem is what i said above. he is reopening STDOUT on the read end of a pipe, and then when he writes to STDOUT later he is writing to the read end of the pipe, which is returning EBADF:
/* the function that runs when u write to a read only pipe /linux/fs/pipe.c*/
static ssize_t
bad_pipe_w(struct file *filp, const char *buf, size_t count, loff_t *ppos)
{
return -EBADF;
}
--
-sean
| |
| Barry Margolin 2004-06-15, 5:57 pm |
| In article <20040615161336.70ce1991.infamous42md@ERASEMEhotpop.com>,
sean larsson <infamous42md@ERASEMEhotpop.com> wrote:
> i'm pretty sure the problem is what i said above. he is reopening STDOUT on
> the read end of a pipe, and then when he writes to STDOUT later he is writing
> to the read end of the pipe, which is returning EBADF:
I agree, I hadn't noticed that problem in his code initially.
The reason it's working on Solaris and failing on Linux is because
Solaris's pipes are bidirectional; you can read and write both ends
(essentially, Solaris's pipe() use the same underlying mechanism as
socketpair()). This is not required by POSIX or SUS, and Linux doesn't
do it, so you have to make sure you use the correct ends for each
operation.
--
Barry Margolin, barmar@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
| |
| Kenny McCormack 2004-06-16, 5:57 pm |
| In article <barmar-89E84C.16302415062004@comcast.dca.giganews.com>,
Barry Margolin <barmar@alum.mit.edu> wrote:
....
>Solaris's pipes are bidirectional; you can read and write both ends
>(essentially, Solaris's pipe() use the same underlying mechanism as
>socketpair()). This is not required by POSIX or SUS, and Linux doesn't
>do it, so you have to make sure you use the correct ends for each
>operation.
Or just use socketpair() instead of pipe(), and be done with it.
|
|
|
|
|