|
From: Nick B. <Nic...@po...> - 2001-12-20 12:33:15
|
I figured out the "Socket command type N unknown" problem. Here's
what is going on:
For some reason, my Apache (2.0.28) runs CGI with stderr closed. So
when Perl opens a connection to Postgres, it gets file descriptor 2,
which would ordinarily be stderr. The "create table chart" command
generates this notice from Postgres:
NOTICE: CREATE TABLE/UNIQUE will create implicit index 'chart_accno_key' for table 'chart'
Either DBI or DBD::Pg decides that the best thing to do with a message
like this is to write it out on STDERR. But STDERR now points back at
Postgres, so this message goes to Postgres, which doesn't like it at
all, and says so:
FATAL 1: Socket command type N unknown
(the 'N' is just the first character of the message).
Here's a cut-down database creation test:
#!/usr/bin/perl
use DBI;
sub dberror {
print "<h2>Error!</h2><p><b>";
print DBI::errstr;
print "</b></p></body></html>";
die(DBI::errstr);
}
print "Content-Type: text/html\n\n\n";
print "<html><head></head><body>";
$dbh = DBI->connect("dbi:Pg:dbname=template1", "nb", "") || dberror();
$dbh->do("CREATE DATABASE slt") || dberror();
$dbh->disconnect;
$dbh = DBI->connect("dbi:Pg:dbname=slt", "nb", "");
open FH, "sql/Pg-tables.sql";
$query = "";
while (<FH>) {
next if (/^(--|\s*$)/);
$query .= $_;
if (/;\s*$/) {
$dbh->do($query) || dberror();
$query = "";
}
}
close FH;
$dbh->disconnect;
print "</body></html>";
This works when run from the shell, but as CGI or run from the shell
with stderr closed (using "2<&-" in /bin/sh), I get the same fatal
error.
My work-around is to add this code at the head of the script:
if (! -w STDERR) {
open (STDERR, ">/dev/null") || die("Can't open stderr to /dev/null");
}
I'm not sure where I should add code like this to sql-ledger.
Nick B
|