poll() returns -1 but errno not set!

poll() returns -1 but errno not set!

Post by Raj Kota » Sat, 30 Oct 2004 07:20:55



Hello all,

I am running a program compiled on a Sun Solaris machine with SunOS
5.7 using the GNU egcs1.1.2 g++ compiler.  The program opens a socket
and uses the poll() system call to see if data is available for
reading.

I specify INFTIM as the timeout parameter to poll() to cause it to
hang until data is available.  I am also guarding against poll() being
interrupted by a signal by checking errno against EINTR and re-issuing
the poll() call if a signal interrupts it.

If I send an interrupt to the program, I find that poll returns -1 but
errno is not set.  A print statement shows that errno remains 0 after
the poll() returns.
truss output shows that within poll() errno is being temporarily set
to ERESTART, but when poll() returns errno is being reset to 0.

According to the Solaris man page on poll(), errno will be set to a
non-zero value any time poll() returns -1.  But this is not happening.
 The really strange part is that even though errno remains set to 0, a
call to perror() results in "Interrupted system call", implying that
errno must be EINTR. Has anyone encountered this bug?  Is there a
patch fix for it?

Thanks
Raj

See code snippet below:

    static char framebuf [MAX_FRAME_SIZE];
    struct pollfd fds[1];
    char *frameptr = framebuf;

    int bytes_read = 0;
    int status = 0;
    int frame_error_flag = 0;

    fds[0].fd = _sock;
    fds[0].events = POLLIN | POLLHUP | POLLPRI | POLLRDBAND;

    for (;;)
    {
        /*
         * use poll () to sleep until there's something to read or
hangup
         */
        fds[0].revents = 0;

        while (((status = poll (fds, 1, INFTIM)) < 0) && (errno ==
EINTR))
        {

           cout << "******* Inside while **********" << endl;
           cout << "status = " << status << endl;
           cout << "errno = " << errno << endl;
           cout << "fds[0].fd = " << fds[0].fd << endl;
           cout << "fds[0].events = " << fds[0].events << endl;
           cout << "fds[0].revents = " << fds[0].revents << endl;
        }


           cout << "status = " << status << endl;
           cout << "errno = " << errno << endl;
           cout << "fds[0].fd = " << fds[0].fd << endl;
           cout << "fds[0].events = " << fds[0].events << endl;
           cout << "fds[0].revents = " << fds[0].revents << endl;
        if (status < 0)
        {
            perror ("poll()");
            terminate (-17);
        }

See program output below:

status = -1
errno = 0
fds[0].fd = 6
fds[0].events = 147
fds[0].revents = 0
poll(): Interrupted system call

See truss output below:

door_return(0x00000000, 0, 0x00000000, 0) (sleeping...)
lwp_sema_wait(0xFF24DF08)       (sleeping...)
signotifywait()                                 = 2
lwp_sigredirect(6, SIGINT)                      = 0
    Received signal #2, SIGINT, in poll() [caught]
poll(0xFF0879B8, 1, -1)                         Err#91 ERESTART
sysconfig(_CONFIG_SIGRT_MIN)                    = 38
sigprocmask(SIG_SETMASK, 0xFF24D520, 0x00000000) = 0
sigaction(SIGINT, 0xFF087280, 0xFF087420)       = 0
sigaction(SIGINT, 0xFF087280, 0xFF087420)       = 0
sysconfig(_CONFIG_SIGRT_MIN)                    = 38
setcontext(0xFF087380)

write(1, " s t a t u s   =   - 1\n", 12)        = 12
write(1, " e r r n o   =   0\n", 10)            = 10
write(1, " f d s [ 0 ] . f d   =  ".., 14)      = 14
write(1, " f d s [ 0 ] . e v e n t".., 20)      = 20
write(1, " f d s [ 0 ] . r e v e n".., 19)      = 19
write(2, " p o l l ( )", 6)                     = 6
write(2, " :  ", 2)                             = 2
write(2, " I n t e r r u p t e d  ".., 23)      = 23

 
 
 

poll() returns -1 but errno not set!

Post by Casper H.S. Di » Sat, 30 Oct 2004 07:39:56



>        while (((status = poll (fds, 1, INFTIM)) < 0) && (errno ==
>EINTR))
>        {

After calling *any* function (like "<<" on cout) the value of errno
may change; so save it to a variable before doing anything else.

Casper
--
Expressed in this posting are my opinions.  They are in no way related
to opinions held by my employer, Sun Microsystems.
Statements on Sun products included here are not gospel and may
be fiction rather than truth.

 
 
 

poll() returns -1 but errno not set!

Post by Roger Faulkn » Sat, 30 Oct 2004 12:33:16



> Hello all,

> I am running a program compiled on a Sun Solaris machine with SunOS
> 5.7 using the GNU egcs1.1.2 g++ compiler.  The program opens a socket
> and uses the poll() system call to see if data is available for
> reading.

> I specify INFTIM as the timeout parameter to poll() to cause it to
> hang until data is available.  I am also guarding against poll() being
> interrupted by a signal by checking errno against EINTR and re-issuing
> the poll() call if a signal interrupts it.

> If I send an interrupt to the program, I find that poll returns -1 but
> errno is not set.  A print statement shows that errno remains 0 after
> the poll() returns.
> truss output shows that within poll() errno is being temporarily set
> to ERESTART, but when poll() returns errno is being reset to 0.

> According to the Solaris man page on poll(), errno will be set to a
> non-zero value any time poll() returns -1.  But this is not happening.
>  The really strange part is that even though errno remains set to 0, a
> call to perror() results in "Interrupted system call", implying that
> errno must be EINTR. Has anyone encountered this bug?  Is there a
> patch fix for it?

> Thanks
> Raj

> See code snippet below:
[snippet snipped]
> See truss output below:

> door_return(0x00000000, 0, 0x00000000, 0) (sleeping...)
> lwp_sema_wait(0xFF24DF08)       (sleeping...)
> signotifywait()                                 = 2
> lwp_sigredirect(6, SIGINT)                      = 0
>     Received signal #2, SIGINT, in poll() [caught]
> poll(0xFF0879B8, 1, -1)                         Err#91 ERESTART
> sysconfig(_CONFIG_SIGRT_MIN)                    = 38
> sigprocmask(SIG_SETMASK, 0xFF24D520, 0x00000000) = 0
> sigaction(SIGINT, 0xFF087280, 0xFF087420)       = 0
> sigaction(SIGINT, 0xFF087280, 0xFF087420)       = 0
> sysconfig(_CONFIG_SIGRT_MIN)                    = 38
> setcontext(0xFF087380)

> write(1, " s t a t u s   =   - 1\n", 12)        = 12
> write(1, " e r r n o   =   0\n", 10)            = 10
> write(1, " f d s [ 0 ] . f d   =  ".., 14)      = 14
> write(1, " f d s [ 0 ] . e v e n t".., 20)      = 20
> write(1, " f d s [ 0 ] . r e v e n".., 19)      = 19
> write(2, " p o l l ( )", 6)                     = 6
> write(2, " :  ", 2)                             = 2
> write(2, " I n t e r r u p t e d  ".., 23)      = 23

Your truss output shows that the system is working properly.
It also shows that you are running a multithreaded process.
Your description indicates that you didn't build the program properly.

1. You have to include <errno.h> in your source file.
2. You also have to use -D_REENTRANT on the compile line.

You missed one or both of these things.

As a result, you are not looking at your thread's errno
but rather the main thread's errno.

Correct these mistakes and things will get better.

Roger Faulkner

 
 
 

poll() returns -1 but errno not set!

Post by Raj Kota » Sun, 07 Nov 2004 06:24:16



> Your truss output shows that the system is working properly.
> It also shows that you are running a multithreaded process.
> Your description indicates that you didn't build the program properly.

> 1. You have to include <errno.h> in your source file.
> 2. You also have to use -D_REENTRANT on the compile line.

> You missed one or both of these things.

> As a result, you are not looking at your thread's errno
> but rather the main thread's errno.

> Correct these mistakes and things will get better.

> Roger Faulkner


Roger,

You were right.  Including errno.h and #defining _REENTRANT gives me
the desired and documented poll() functionality.

Thanks much
Raj

 
 
 

poll() returns -1 but errno not set!

Post by Lady Chatterl » Sun, 28 Nov 2004 10:22:48




>> Your truss output shows that the system is working properly.
>> It also shows that you are running a multithreaded process.
>> Your description indicates that you didn't build the program properly.

>> 1. You have to include <errno.h> in your source file.
>> 2. You also have to use -D_REENTRANT on the compile line.

>> You missed one or both of these things.

>> As a result, you are not looking at your thread's errno
>> but rather the main thread's errno.

>> Correct these mistakes and things will get better.

>> Roger Faulkner

>Roger,

Project much?

Quote:>You were right.  Including errno.h and #defining _REENTRANT gives me
>the desired and documented poll() functionality.

Some people never learn. Go figure.

Quote:>Thanks much
>Raj

Touch a nerve?

--
Lady Chatterly

"Oh, look everyone, joooooooooody is chummy with the chatterly -
troll....." -- Rhyanon

 
 
 

1. Q: TCP/IP accept returns -1, errno == ENOBUFS

Hi !
On NCR Unix (OS version 020201)  I'm running a server application,
using TCP/IP sockets for network communications.

On some machines the accept call sometimes returns -1,  and errno is
set to ENOBUFS/132.  

When this has happened the only way out seems to be a system reboot.
An application restart does not solve the problem.  

Any help will be appreciated.

Phone : +47 70 15 08 53          Fax    : +47 70 15 08 53

2. Aironet Arlan radio ethernet?

3. nlist() always returns -1 but errno=0 on Solaris7&8

4. Firewall+FTP Problems HELP!!!

5. shutdown(3N) returns -1 but errno==0 -- wassagoinon ?

6. direct_io mopup

7. msgrcv() returns -1 with errno=0

8. any web base cgi generate iptables chains?

9. recv() on nonblocking TCP socket return -1 with errno=EAGAIN even with FD_ISSET==TRUE

10. signals cause select to return -1 and errno = 0?

11. ioctl() returns -1 with errno=22 (invalid argument)

12. bind() returns -1 with errno == 0

13. system() returns -1 but errno is 0 ?!