[prev in list] [next in list] [prev in thread] [next in thread] 

List:       debian-hurd
Subject:    Bug#752237: libc0.3: send() asked to transmit 0 chars still triggers recv() on Hurd
From:       Andreas Cadhalpun <andreas.cadhalpun () googlemail ! com>
Date:       2014-06-21 13:56:46
Message-ID: 53A58F1E.8020902 () googlemail ! com
[Download RAW message or body]

Package: libc0.3
Version: 2.19-3
Severity: normal
X-Debbugs-CC: debian-hurd@lists.debian.org

Dear Maintainer,

it seems send() on Hurd doesn't work like it does everywhere else.

Attached is a simple test case.
To reproduce the problem, execute make in a folder with the attached 
client.c, server.c and Makefile.
Then run ./server, open another terminal and run ./client.

The usual output is:
$ ./server
Message: 'TEST'

$ ./client
Socket works.
Answer: 'ANSWER'

But on Hurd one gets:
$ ./server
Message: ''

$ ./client
Socket works.
Answer: 'ANSWER'

This is because the client is calling:
	send(sockfd, "", 0, 0)

Normally this doesn't trigger recv() in the server and thus can be used 
to test, whether the socket is working.
But on Hurd it actually sends an empty message, so that the real 
message, which is sent later, is not received.

As a workaround, one can comment out this test, which is done in the 
server, so that the ANSWER reaches the client.

This should be handled on Hurd in the same way as on other platforms.

I noticed this bug, because it breaks the communication between clamd 
and clamdscan on Hurd, thus leading to test failures and ultimately a FTBFS.

Best regards,
Andreas


-- System Information:
Debian Release: jessie/sid
   APT prefers unstable
   APT policy: (500, 'unstable')
Architecture: hurd-i386 (i686-AT386)

Kernel: GNU-Mach 1.4-486/Hurd-0.5
Locale: LANG=C, LC_CTYPE=C (charmap=ANSI_X3.4-1968)
Shell: /bin/sh linked to /bin/dash

Versions of packages libc0.3 depends on:
ii  hurd-libs0.3  1:0.5.git20140526-2
ii  libgcc1       1:4.9.0-7

Versions of packages libc0.3 recommends:
pn  libc0.3-i686  <none>

Versions of packages libc0.3 suggests:
ii  debconf [debconf-2.0]  1.5.53
pn  glibc-doc              <none>

["client.c" (text/x-csrc)]

#include <errno.h>
#include <stdio.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/unistd.h>

char sock_name[] = "TEST.ctl";

int connect_socket()
{
	struct sockaddr_un server;
	int sockfd;

	memset(&server, 0, sizeof(server));
	server.sun_family = AF_UNIX;
	strncpy(server.sun_path, sock_name, sizeof(server.sun_path));
	server.sun_path[sizeof(server.sun_path) - 1] = '\0';

	sockfd = socket(AF_UNIX, SOCK_STREAM, 0);

	if (sockfd < 0) {
		printf("Can't create socket %s: %s\n", sock_name, strerror(errno));
		return -1;
	}

	if (connect(sockfd, (struct sockaddr *) &server, sizeof(struct sockaddr_un)) < 0) {
		printf("Can't connect to socket %s: %s\n", sock_name, strerror(errno));
		close(sockfd);
		return -2;
	}

	return sockfd;
}

int main()
{
	char buff[20];
	int sockfd = connect_socket();
	if (sockfd < 0) {
		return sockfd;
	}

	if (send(sockfd, "", 0, 0) < 0) {
		printf("Socket not working: %s\n", strerror(errno));
	} else {
		printf("Socket works.\n");
	}

	if (send(sockfd, "TEST", 4, 0) < 0) {
		printf("Could not write to socket: %s\n", strerror(errno));
		close(sockfd);
		return 1;
	}

	memset(buff, 0, sizeof (buff));
	if (recv(sockfd, buff, sizeof (buff), 0) < 0) {
		printf("Error receiving answer: %s\n", strerror(errno));
		close(sockfd);
		return 2;
	}
	printf("Answer: '%s'\n", buff);
	close(sockfd);
	return 0;
}

["Makefile" (text/plain)]

#! /usr/bin/make -f

CC ?= gcc
CFLAGS ?= -g -pedantic -Wall -Wextra

all: server client
	

%:
	$(CC) $(CFLAGS) $@.c -o $@

["server.c" (text/x-csrc)]

#include <errno.h>
#include <stdio.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/unistd.h>

char sock_name[] = "TEST.ctl";

int create_socket()
{
	struct sockaddr_un server;
	int sockfd;

	memset(&server, 0, sizeof(server));
	server.sun_family = AF_UNIX;
	strncpy(server.sun_path, sock_name, sizeof(server.sun_path));
	server.sun_path[sizeof(server.sun_path) - 1] = '\0';

	sockfd = socket(AF_UNIX, SOCK_STREAM, 0);

	if (sockfd < 0) {
		printf("Can't create socket %s: %s\n", sock_name, strerror(errno));
		return -1;
	}

	if (bind(sockfd, (struct sockaddr *) &server, sizeof(struct sockaddr_un)) < 0) {
		printf("Socket file %s could not be bound: %s\n", server.sun_path, strerror(errno));
		close(sockfd);
		return -2;
	}

	if (listen(sockfd, 20) < 0) {
		printf("listen() error: %s\n", strerror(errno));
		close(sockfd);
		return -3;
	}

	return sockfd;
}

int main()
{
	int ret, con;
	char buff[20];
	int sockfd = create_socket();
	if (sockfd < 0) {
		return sockfd;
	}

	con = accept(sockfd, 0, 0);

	memset(buff, 0, sizeof(buff));
	if (recv(con, buff, sizeof (buff), 0) >= 0) {
		printf("Message: '%s'\n", buff);
	}
/*
	if (write(con, "", 0) < 0) {
		printf("Socket not working: %s\n", strerror(errno));
		return 1;
	} else {
		printf("Socket works.\n");
	}
 */
	if (write(con, "ANSWER", 6) < 0) {
		printf("Could not write to socket: %s\n", strerror(errno));
		ret = 2;
	}

	close(con);

	if (unlink(sock_name) == -1) {
		printf("Socket file %s could not be removed: %s\n", sock_name, strerror(errno));
		ret = 3;
	}
	close(sockfd);
	return ret;
}

-- 
To UNSUBSCRIBE, email to debian-hurd-REQUEST@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org
Archive: https://lists.debian.org/53A58F1E.8020902@googlemail.com


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic