View previous topic :: View next topic |
Author |
Message |
mv Watchman
Joined: 20 Apr 2005 Posts: 6747
|
Posted: Sun Oct 19, 2014 9:03 am Post subject: [SOLVED] How to use perl IO::Socket::INET with inetd |
|
|
This is a perl programming question which came up in some systemd discussion:
I have a daemon in perl which currently uses $socket = IO::Socket::INET->new(...) to create a TCP socket.
When such a daemon should be used with inetd or systemd socket activation, it should be able to use STDIN/STDOUT (or other passed filedescriptors) as a socket.
Is it possible to "transform" STDIN/STDOUT into a corresponding perl object? The intention is to replace only the above "new"-command by some code so that afterwards all of the rest of the daemon would work unchanged with inetd (so that e.g. $socket->accept(), $socket->recv(...), $socket->send(...) work afterwards with inetd by reading/writing appropriate data to STDIN/STDOUT).
Last edited by mv on Tue Oct 21, 2014 7:17 pm; edited 1 time in total |
|
Back to top |
|
|
RazielFMX l33t
Joined: 23 Apr 2005 Posts: 835 Location: NY, USA
|
Posted: Tue Oct 21, 2014 4:41 pm Post subject: |
|
|
STDOUT/STDIN are default filehandles. You can use them in an OO fashion by including "use FileHandle" at the top of your code.
Then you can do things like:
Code: |
#!/usr/bin/perl -w
use strict;
use FileHandle;
#Don't buffer writes
STDOUT->autoflush(1);
#Read 256 bytes
my $buffer = '';
my $read = STDIN->sysread($buffer, 256);
|
I don't think you can perform socket operations on them though, but I could be wrong.
Check out this: http://www.perlmonks.org/?node_id=544341
EDIT:
I think for what you are trying to do is to have a command line switch that can be invoked by inetd to turn on inetd functionality. I would then either as a standalone PM or a nested class, do something like this:
Code: |
my $socket = ($inetdEnabled) ? InetdWrapper->new() : IO::Socket::INET->new(%args)
|
You then just implement what you need:
Code: | package InetdWrapper;
use strict;
use FileHandle;
sub new {
my $pkg = shift;
return bless({}, $pkg);
}
sub close {
# You might want this as a no-op, not sure
}
sub syswrite {
my $self = shift;
return STDOUT->syswrite(@_);
}
sub sysread {
my $self = shift;
return STDIN->sysread(@_);
}
|
You get the idea. _________________ I am not anti-systemd; I am pro-choice. If being the latter makes you feel that I am the former, then so be it. |
|
Back to top |
|
|
mv Watchman
Joined: 20 Apr 2005 Posts: 6747
|
Posted: Tue Oct 21, 2014 7:15 pm Post subject: |
|
|
The point is that I want to do socket operations on them, in particular accept() (and use the sockets obtained by that).
In German USEnet, I got now a simple receipt which I have just tested and which works:
Code: | $socket = new IO::Socket::INET();
$socket->fdopen(0, 'r'); |
It is a little bit hackish, since theoretically the missing argument list of IO::Socket::INET might mean that also some other important information is not initialized, but so far it works without any issues. |
|
Back to top |
|
|
RazielFMX l33t
Joined: 23 Apr 2005 Posts: 835 Location: NY, USA
|
Posted: Thu Oct 23, 2014 12:48 pm Post subject: |
|
|
That is effectively duping the file descriptor, so it should be perfectly reasonable to use. Nifty trick. _________________ I am not anti-systemd; I am pro-choice. If being the latter makes you feel that I am the former, then so be it. |
|
Back to top |
|
|
|