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 $@ $<
next prev parent 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