$SIG{IO} example

  • Thread starter Sébastien Cottalorda
  • Start date
S

Sébastien Cottalorda

Hi all,

I'm planning to make a script that, on socket reception, do reception, but
the rest of time do something else.

#======================================================================
#!/usr/bin/perl -w
use IO::Select;
use IO::Socket;
unless ($socket = IO::Socket::INET->new(PeerAddr=> $adr_ip,
PeerPort=> $port,
Proto=> "tcp",
Timeout=>10,
Type=> SOCK_STREAM)){
die "Unable to create a tcp server $!";
}
$s->add($socket);
$SIG{IO}=\$do_reception;
while(1) {
#
# do something ...
# even sending datas throught the socket
#
}

sub do_reception{
if ($s->can_read(10)){
&logmsg("Reception ...\n");
if (defined $socket->recv($data_work,1024,0)){
print "< $data_work\n";
}
else {
print "Unable to receive\n";
}
}
else {
print "Timeout Receiving\n";
}
}


I've made that but it doesn't seem to work.
Do you have a SIG{IO} exemple program

Thanks in advance for any kind of help.

Sébastien Cottalorda
 
A

Anno Siegel

Sébastien Cottalorda said:
Hi all,

I'm planning to make a script that, on socket reception, do reception, but
the rest of time do something else.
[...]

$SIG{IO}=\$do_reception;

What makes you think $SIG{IO} does anything useful?

Anno
 
S

Sébastien Cottalorda

Anno said:
Sébastien Cottalorda said:
Hi all,

I'm planning to make a script that, on socket reception, do reception,
but the rest of time do something else.
[...]

$SIG{IO}=\$do_reception;

What makes you think $SIG{IO} does anything useful?

Anno

Someone, who as used SIG{IO} in C programming, told me that catching that
signal can solve my problem.

How can I manage to do want I need ?
using IO::Select to check, in non blocking mode, if I can read ?

Thanks for you help.

Sébastien Cottalorda
 
A

Anno Siegel

Sébastien Cottalorda said:
Anno said:
Sébastien Cottalorda said:
Hi all,

I'm planning to make a script that, on socket reception, do reception,
but the rest of time do something else.
[...]

$SIG{IO}=\$do_reception;

What makes you think $SIG{IO} does anything useful?

Anno

Someone, who as used SIG{IO} in C programming, told me that catching that
signal can solve my problem.

Huh? SIGIO doesn't exist on any system I know.
How can I manage to do want I need ?
using IO::Select to check, in non blocking mode, if I can read ?

Read perldoc IO::Select. If you have specific questions, ask.

Anno
 
C

Christopher Nehren

Huh? SIGIO doesn't exist on any system I know.

% kill -l
hup int quit ill trap abrt emt fpe kill bus segv sys pipe alrm term urg
stop tstp cont chld ttin ttou io xcpu xfsz vtalrm prof winch info usr1
^^
usr2
% uname -rs
FreeBSD 5.3-STABLE

Same on OpenBSD 3.6-STABLE, except tr[a-z][A-Z].
 
S

Sébastien Cottalorda

Anno said:
Sébastien Cottalorda said:
Anno said:
comp.lang.perl.misc:
Hi all,

I'm planning to make a script that, on socket reception, do reception,
but the rest of time do something else.

[...]

$SIG{IO}=\$do_reception;

What makes you think $SIG{IO} does anything useful?

Anno

Someone, who as used SIG{IO} in C programming, told me that catching that
signal can solve my problem.

Huh? SIGIO doesn't exist on any system I know.
How can I manage to do want I need ?
using IO::Select to check, in non blocking mode, if I can read ?

Read perldoc IO::Select. If you have specific questions, ask.

Anno

# uname -a
Linux pc_seb 2.4.21-0.13mdk #1 Fri Mar 14 15:08:06 EST 2003 i686 unknown
unknown GNU/Linux

# kill -l
[snip]
29) SIGIO
[snip]

My program is a real time program:
- it need to receive asynchronous datas and reply immediately.
- it need to send regularily datas throught the socket (equipment check)
My problem is:
* If I wait for reading datas, I cannot send regularily anymore.
* If I make a non blocking loop:
while (1) {
if ($s->can_read(1)){
# ...
}
if ($s->can_write(1)){
# process that can take time
}
}
I'm frightened to make a infinite loop if I did'nt have nothing to send and
if I don't have to receive something.
That solution could not work either because if I take too long time to send
datas, I lost the real time on the reception.
That's why the best idea is, if possible, to catch a signal (I though
SIG{IO}), and make the reception immediately, then return to the normal
process.

Regards

Sebastien Cottalorda
 
A

Arndt Jonasson

Christopher Nehren said:
Huh? SIGIO doesn't exist on any system I know.

% kill -l
hup int quit ill trap abrt emt fpe kill bus segv sys pipe alrm term urg
stop tstp cont chld ttin ttou io xcpu xfsz vtalrm prof winch info usr1
^^
usr2
% uname -rs
FreeBSD 5.3-STABLE

Same on OpenBSD 3.6-STABLE, except tr[a-z][A-Z].

For what it's worth, SIGIO exists on HP-UX and AIX too. Of course, it
remains the case that using SIGIO is not a portable way to do I/O.
 
A

Anno Siegel

Arndt Jonasson said:
Christopher Nehren said:
Huh? SIGIO doesn't exist on any system I know.

% kill -l
hup int quit ill trap abrt emt fpe kill bus segv sys pipe alrm term urg
stop tstp cont chld ttin ttou io xcpu xfsz vtalrm prof winch info usr1
^^
usr2
% uname -rs
FreeBSD 5.3-STABLE

Same on OpenBSD 3.6-STABLE, except tr[a-z][A-Z].

For what it's worth, SIGIO exists on HP-UX and AIX too.

I see. I never noticed.
Of course, it
remains the case that using SIGIO is not a portable way to do I/O.

Maybe a good reason not to notice :)

Anno
 
P

Peter Wyzl

: Anno Siegel wrote:

<snip>
:
: My program is a real time program:
: - it need to receive asynchronous datas and reply immediately.
: - it need to send regularily datas throught the socket (equipment
check)
: My problem is:
: * If I wait for reading datas, I cannot send regularily anymore.
: * If I make a non blocking loop:
: while (1) {
: if ($s->can_read(1)){
: # ...
: }
: if ($s->can_write(1)){
: # process that can take time
: }
: }
: I'm frightened to make a infinite loop if I did'nt have nothing to
send and
: if I don't have to receive something.
: That solution could not work either because if I take too long time
to send
: datas, I lost the real time on the reception.
: That's why the best idea is, if possible, to catch a signal (I though
: SIG{IO}), and make the reception immediately, then return to the normal
: process.

I would approach this as two separate programs communicating with each other
with some form of IPC (perhaps even simple file updating).

The reading program can handle the 'instant response' and the writing
program can be regular.

Then I would look at possible threads (one for each task) or maybe a forked
process once I had the other part working fine.
 
S

Scott W Gifford

[...]
I've made that but it doesn't seem to work.
Do you have a SIG{IO} exemple program

You have to set the file descriptor to asynchronous to get SIGIO when
data becomes available. See the O_ASYNC flag in fcntl(2) and open(2).

IIRC, Stevens talks about this technique in Advanced Programming in
the Unix Environment, so you can find sample code in C there.

According to the manpages, this is specific to BSD-derived systems and
Linux.

----ScottG.
 
J

Joe Smith

Sébastien Cottalorda said:
My problem is:
* If I wait for reading datas, I cannot send regularily anymore.
* If I make a non blocking loop:
while (1) {
if ($s->can_read(1)){
# ...
}
if ($s->can_write(1)){
# process that can take time
}
}
I'm frightened to make a infinite loop if I did'nt have nothing to send and
if I don't have to receive something.
That solution could not work either because if I take too long time to send
datas, I lost the real time on the reception.

The IO::Select::select() method returns when it is possible to
either read or write. The values it returns are what you use
to determine whether reading or writing is appropriate.

while (1) {
($reads,$writes,$errors) = IO::Select::select($s,$s,$s);
foreach $obj (@$reads) {
read from the object
}
foreach $obj (@$writes) {
write to the object
}
foreach $obj (@$errors) {
handle exception
}
}
 
S

Sébastien Cottalorda

Scott said:
[...]
I've made that but it doesn't seem to work.
Do you have a SIG{IO} exemple program

You have to set the file descriptor to asynchronous to get SIGIO when
data becomes available. See the O_ASYNC flag in fcntl(2) and open(2).

IIRC, Stevens talks about this technique in Advanced Programming in
the Unix Environment, so you can find sample code in C there.

According to the manpages, this is specific to BSD-derived systems and
Linux.

----ScottG.

Hi Scott,
I have one of those specific system : Linux.

I've read the fcntl manpage, it seems to be good for me:

F_SETOWN :
Set the process ID or process group that will receive SIGIO and SIGURG
signals for events on file descriptor fd. Process groups are specified
using negative values. (F_SETSIG can be used to specify a different signal
instead of SIGIO).
If you set the O_ASYNC status flag on a file descriptor (either by providing
this flag with the open(2) call, or by using the F_SETFL command of fcntl),
a SIGIO signal is sent whenever input or output becomes possible on that
file descriptor.
The process or process group to receive the signal can be selected by using
the F_SETOWN command to the fcntl function. If the file descriptor is a
socket, this also selects the recipient of SIGURG signals that are
delivered when out-of-band data arrives on that socket. (SIGURG is sent in
any situation where select(2) would report the socket as having an
"exceptional condition".) If the file descriptor corresponds to a terminal
device, then SIGIO signals are sent to the foreground process group of the
terminal.

that exactly what I want to do.

Thanks a lot

Sébastien
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,968
Messages
2,570,152
Members
46,697
Latest member
AugustNabo

Latest Threads

Top