public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Paolo Ornati <ornati@fastwebnet.it>
To: Paolo Ornati <ornati@fastwebnet.it>
Cc: "Theodore Ts'o" <tytso@mit.edu>,
	Linux Kernel Mailing List <linux-kernel@vger.kernel.org>
Subject: Re: Lack of Documentation about SA_RESTART...
Date: Tue, 12 Jul 2005 12:10:34 +0200	[thread overview]
Message-ID: <20050712121034.3f0e84c8@localhost> (raw)
In-Reply-To: <20050712103811.0087a7e3@localhost>

[-- Attachment #1: Type: text/plain, Size: 1259 bytes --]

On Tue, 12 Jul 2005 10:38:11 +0200
Paolo Ornati <ornati@fastwebnet.it> wrote:

> The particular case you analized (blocking connect interrupted by a
> SA_RESTART signal) is interesting... and since SUSV3 says
> 	"but the connection request shall not be aborted, and the
> 	connection shall be established asynchronously" (with select()
> 	or poll()...)
> both for EINPROGRESS and EINTR, I think it's quite stupit to
> automatically restart it and then return EALREADY.
> 
> The logically correct behaviur with blocking connect interrupted and
> then restarted should be to continue the blocking wait... IHMO.

it seems that Linux is doing the Right Thing... see the attached
program...

$ make
gcc -O2 -Wall -o conntest connect_test.c


FROM ANOTHER CONSOLE: this is needed to block connect()...
# iptables -A OUTPUT -p tcp --dport 3500 -m state --state NEW -j DROP


$ ./conntest WITHOUT_SA_RESTART
connect(): errno = 4		# EINTR, as expected
Cannot setup client!


$ ./conntest	# connect is restarted after SIGALRM, and then it blocks again


FROM ANOTHER CONSOLE:
# iptables -D OUTPUT -p tcp --dport 3500 -m state --state NEW -j DROP


and then "conntest" (thanks to TCP protocol retries) will terminate.



:-)

-- 
	Paolo Ornati
	Linux 2.6.12.2 on x86_64

[-- Attachment #2: connect_test.c --]
[-- Type: text/x-csrc, Size: 1692 bytes --]

#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netinet/tcp.h>
#include <signal.h>
#include <unistd.h> 

void sighandler(int sig)
{
	/* nothing :) */
}

int setup_alarm_handler(int flags)
{
	struct sigaction sa = {
		.sa_handler = &sighandler,
		.sa_flags = flags
	};
	return sigaction(SIGALRM, &sa, NULL);
}

int setup_server(int port)
{
	int sock;
	struct sockaddr_in sa = {
		.sin_family = AF_INET,
		.sin_port = htons(port),
		.sin_addr.s_addr = htonl(INADDR_ANY)
	};

	if ((sock=socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
		goto error;
	if (bind(sock, (struct sockaddr*)&sa, sizeof(sa)) < 0)
		goto error_clean;
	if (listen(sock, 16) < 0)
		goto error_clean;
	return sock;

 error_clean:
	close(sock);
 error:
	return -1;
}

int setup_client(const char *server, int port)
{
	int sock;
	struct sockaddr_in sa = {
		.sin_family = AF_INET,
		.sin_port = htons(port),
		.sin_addr.s_addr = inet_addr(server)
	};

	if ((sock=socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
		goto error;
	if (connect(sock, (struct sockaddr*)&sa, sizeof(sa)) < 0) {
		printf("connect(): errno = %d\n", errno);
		goto error_clean;
	}
	return sock;

 error_clean:
	close(sock);
 error:
	return -1;
}

int main(int argc, char *argv[])
{
	int server, client;
	int flags = SA_RESTART;

	if (argc > 1)
		flags = 0;

	if (setup_alarm_handler(flags))
		return 1;
	
	server = setup_server(3500);
	if (server < 0) {
		printf("Cannot setup server!\n");
		return 1;
	}
	alarm(1);
	client = setup_client("127.0.0.1", 3500);
	if (client < 0) {
		printf("Cannot setup client!\n");
		return 1;
	}
	printf("Ok!\n");
	return 0;
}

[-- Attachment #3: Makefile --]
[-- Type: application/octet-stream, Size: 49 bytes --]

conntest: connect_test.c
	gcc -O2 -Wall -o $@ $<

  reply	other threads:[~2005-07-12 10:13 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-07-11 10:32 Lack of Documentation about SA_RESTART Paolo Ornati
2005-07-11 14:34 ` Theodore Ts'o
2005-07-12  3:30   ` Philippe Troin
2005-07-12  8:43     ` Paolo Ornati
2005-07-12  8:38   ` Paolo Ornati
2005-07-12 10:10     ` Paolo Ornati [this message]
2005-07-12 12:04     ` Theodore Ts'o
2005-07-12 15:25       ` Paolo Ornati
2005-07-12 18:16         ` Theodore Ts'o
2005-07-13  7:45           ` Paolo Ornati
2005-07-24  0:30   ` Linus Torvalds
2005-07-24  7:28     ` Paolo Ornati
2005-07-24 14:56     ` Theodore Ts'o
2005-07-25  8:02       ` Paolo Ornati

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20050712121034.3f0e84c8@localhost \
    --to=ornati@fastwebnet.it \
    --cc=linux-kernel@vger.kernel.org \
    --cc=tytso@mit.edu \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox