This is the mail archive of the cygwin@cygwin.com mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Failed non-blocking connect returns incorrect errno on AF_UNIX protocol


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/

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]