Issues with ssh2 extension and closing stdin

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



I've been having issues trying to use a command over ssh2_exec. The
command takes input over standard input, waits for it to be closed,
then writes back to standard output. Unfortunate, the ssh2 API seems
deficient in multiple ways:

First, the stream returned by ssh2_exec is for /both/ standard input
and error. Closing means theoretically closing them both. This isn't
/too/ bad, because I believe my program doesn't use standard error, so
I just reassign the FDs at the shell level so that standard output is
now on the separate standard error stream.

Second, closing the stream doesn't actually seem to close standard
input. The program (and cat, for the example below) still seems to
think it should read from standard input and thus keeps standard output
(well, error) open.

This is annoying because it effectively means stream_get_contents is
useless for me, because it'll block forever or with non-blocking, spit
out a bunch of spurious zeros as it gets nothing constantly. cat will
write back after the flush, but not immediately (some spurious zero
reads, then a read with data, then more spurious), and my program
relies on having standard input closed before it'll write.

It appears others have tried to deal with this, but failed:
https://stackoverflow.com/questions/19898351/php-close-input-channel-of-bidirectional-stream-from-ssh2-exec

As with that person, I would /really/ not want to create a temporary
file on the remote server if I can get away with it.

I'm using PHP 7.4.8 w/ the PECL SSH2 extension that's shipped by
Fedora.

-- code --

<?php

$server = "redact";
$user = "redact";
$password = "redact";

// no error handling in the sample program (real one does)
$conn = ssh2_connect($server, 22);
ssh2_auth_password($conn, $user, $password);

// redirect stdout to stderr, because closing stdin also closes stdout
// use cat as a surrogate (the program I'm calling takes all of stdin
// and writes back to stdout on stdin EOF; cat will have to do to show
// the broken behaviour)
$ssh_stdio = ssh2_exec($conn, "cat 1>&2");
$ssh_stderr = ssh2_fetch_stream($ssh_stdio, SSH2_STREAM_STDERR);
stream_set_blocking($ssh_stdio, true);
stream_set_blocking($ssh_stderr, true);
$written = fwrite($ssh_stdio, "the quick brown fox");
// attempt to close stdin (using stderr afterwards, explained above)
fflush($ssh_stdio);
fclose($ssh_stdio);
// stderr blocking behaviour:
// blocking: blocks forever because cat doesn't know it closed?
// non-blocking: gets an empty string because cat hasn't written
//               back in time
$out = stream_get_contents($ssh_stderr);
var_dump($out);



[Index of Archives]     [PHP Home]     [Apache Users]     [PHP on Windows]     [Kernel Newbies]     [PHP Install]     [PHP Classes]     [Pear]     [Postgresql]     [Postgresql PHP]     [PHP on Windows]     [PHP Database Programming]     [PHP SOAP]

  Powered by Linux