Forum OpenACS Development: Problems with psql and passwords in the APM

I do not like the 'open to all local users' policy of Postgres so I enabled passwords on the backend, and now psql also requires them of course. The AOLServer driver handles this perfectly, but the APM does not...

psql has the nasty habit of reporting all interesting information on stderr, including the password prompt, there is no option to send it to stdout instead, so I use redirecting. Tcl exec doesn't seem to be able to redirect stderr to stdout, but bash can so I wrap the call to psql in a bash -c "|psql -U nsadmin -W -f some.sql myacsdb 2>&1". This works perfectly, all stderr goes to stdout, which I can read with, well, read $fd.

The biggest problem I have at the moment is that there seems to be no simple way to ask how many bytes are available in the pipe. I am currently using this code, which works to the point of entering the password but then comes to a full stop.

ad_proc db_source_sql_file { {-callback apm_ns_write_callback} file 
} {
 
    Sources a SQL file (in psql format).
 
} {
 
    set file_name [file tail $file]
 
    set pguser [db_get_username]
 
    set pgport [db_get_port]
    if { ![string equal $pgport ""] } {
        set pgport "--port $pgport"
    }
 
    cd [file dirname $file]
 
    #Tcl-Exec can't redirect stderr to a the new pipe, so we use bash
    #We need this because psql likes to write a lot of things to 
stderr and
    #has no option to divert it to stdout (because they expect the 
shell can do it ?!?)

    set fp [open "|/bin/bash -c "[file join [db_get_pgbin] psql] 
[db_get_database] $pgport -U $pguser -W -f $file_name 2>&1"" "r+"]
 
    #This is pretty tricky, we expect exactly this string: 
"Password: "
    #(-W on psql makes it ALWAYS ask for the password (I checked 
psql's source)
    #scan till password:

    set line ""
    while { ![eof $fp] } {
        append line [read $fp 1]
        puts stderr $line
        if { [string first "Password:" $line] != -1 } {
            break
        }
    }
 
    if { [string first "Password:" $line] == -1 } {
        return -code error -errorinfo "Didn't get 'Password:' from 
psql (result '[ad_quotehtml $line]') " -errorcode 3
    }
 
    puts $fp [db_get_password]

#this is where it hangs. psql doesn't give me anymore new lines,
#so [gets $fp line] blocks 'till the end of days.
#I am certain psql is running as it shows up the the process list.

    set error_found 0
    while { [gets $fp line] >= 0 } {
        if { ![string is space $line] } {
            apm_callback_and_log $callback "[ad_quotehtml $line]
"
 
            set error_line [expr { [string first ERROR $line] != -1 
|| 
                    [string first FATAL $line] != -1 } ]
 
            if { $error_line } {
                set error_found $error_line
                append error_lines "$line
"
            }
        }
    }

    if { $error_found } {
        global errorCode
        return -code error -errorinfo $error_lines -errorcode 
$errorCode
    }
}

Who can give me some suggestions of how to make it work and make it a bit more fault tolerant?