Failed non-blocking connect returns incorrect errno on AF_UNIX protocol.
See attached test program.

On cygwin:
$ ./afunix
EINPROGRESS: Operation now in progress

On
Linux 2.4 (Debian 2.2)
Linux 2.4 (Redhat 7.3)
Sun Solaris (8):
$ ./afunix
ECONNREFUSED: Connection refused

When i comment following code:
//      if (fcntl (fd2, F_SETFL, O_NONBLOCK) < 0)
//              printf ("Failed to set fd non-blocking");
The result is
ECONNREFUSED: Connection refused

It seems an old bug.
I don't know whether it effect others address/protocol families.


Thanks.


#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/errno.h>
#include <sys/stat.h>

int
main()
{
        char file[] = "/tmp/.afunix";
        int fd, fd2;
        int len;
        struct sockaddr_un address, address2;
        int status;
        int i = 0;

        status = unlink(file);
        if (status < 0 && errno != ENOENT) {
                printf("unlink() failed with %d\n", errno);
                return 1;
        }

        fd = socket(AF_UNIX, SOCK_STREAM, 0);
        if (fd < 0) {
                printf("socket() failed with %d\n", errno);
                return 1;
        }

        memset(&address, 0, sizeof(address));
        address.sun_family = AF_UNIX;
        strcpy(address.sun_path, file);
        len = sizeof(address);
        
        status = bind(fd, (struct sockaddr*) &address, len);
        if (status < 0) {
                printf("bind() failed with %d\n", errno);
                return 1;
        }
        
        close(fd);

        // 
        fd2 = socket(AF_UNIX, SOCK_STREAM, 0);
        if (fd2 < 0) {
                printf("socket() failed with %d\n", errno);
                return 1;
        }

        memset(&address2, 0, sizeof(address2));
        address2.sun_family = AF_UNIX;
        strcpy(address2.sun_path, file);
        len = sizeof(address2.sun_family) + strlen(address2.sun_path) + 1;

        // set non-blocking
        if (fcntl (fd2, F_SETFL, O_NONBLOCK) < 0)
                printf ("Failed to set fd non-blocking");

        do {
                status = connect (fd2, (struct sockaddr*)&address2, len);
        } while (status < 0 && errno == EINTR);
        
        if (status >= 0)
                printf("SOCKET_ALIVE\n");
        else {
                switch (errno) {
                case EINPROGRESS:
                        perror("EINPROGRESS");
                        break;
                case ECONNREFUSED:
                        perror("ECONNREFUSED");
                        break;
                case EAGAIN:
                        perror("EAGAIN\n");
                        break;
                case EBADF:
                        printf("EBADF - Bad bug fd %d\n", fd);
                        break;
                default:
                        printf("Error '%s' on socket %d",
                                   strerror (errno), fd);
                        break;
                }
        }

        return 0;
}


--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Bug reporting:         http://cygwin.com/bugs.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/

Reply via email to