my ($new_sock, $pid, $buf); while ($new_sock = $main_sock->accept()) { $new_sock->autoflush(1); # In theory, new sockets are always non-blocking anyway # with IO::Socket::INET, which I am using here. $pid = fork(); die "Cannot fork: $!" unless defined $pid; if ($pid == 0) { # Child unless ($new_sock->peerhost eq $allowed_ip) { shutdown $new_sock, 2; exit 0; } print $new_sock $greeting; while (defined($buf = <$new_sock>)) { process($buf, $new_sock); # shutdown($new_sock, 1); # Works, but shuts down the whole session } exit 0; } # Else 'tis the parent process, which goes back to accept() } close $main_sock; my ($error, $output); sub process { my $line = shift; $line =~ tr/\r\n//d; # fancy chomp return if $line eq ''; # What's that again? my ($command, @args) = split /\s+/, $line; undef $error; undef $output; if ($command =~ /^BYE/) { print $new_sock "OK disconnecting . . . \n"; shutdown $new_sock, 2; exit 0; } unless (exists $dispatch{$command}) { return unless defined $command; # Ignore blank lines print $new_sock "ERROR unknown command \"$command\"\n"; return; } $dispatch{$command}->(@args); if ($error) { # main scope variable set by the dispatch command print $new_sock <