where is the point the client command is executed?
Darren Tucker
dtucker at zip.com.au
Tue Apr 17 15:35:52 EST 2007
Zhang Kexin wrote:
> On Tue, 2007-04-17 at 13:45 +1000, Darren Tucker wrote:
>> Zhang Kexin wrote:
>>> Hi,
>>>
>>> I met some difficult in reading ssh/sshd souce code, I want to
>>> find out how the command that user input in client is executed on the
>>> server. I only found out the process_input function put the command in a
>>> buffer,but can not find how it is executed. Could you please help me on
>>> that?
>> You mean when you run "ssh someserver echo foo" or similar?
> I mean after I have connected to server successfully, when I input "ls"
> in client, how the command is executed. Your explain is exactly what i'm
> looking for. But I need more explain.
It works differently depending on whether or not you specify a command
on the command line.
When you run "ssh yoursever" without a command, sshd allocates a pty
then starts up an interactive login shell. This shell receives commands
on its standard input (via the pty) and executes them. The output is
returned via the pty to sshd, which sends it back to the client.
For example, if we look at my login shell:
$ pstree -a -p 16714
sshd,16714
`-bash,16715
`-pstree,11185 -a -p 16714
$ lsof -p 16715
COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME
[...]
bash 16715 dtucker 0u CHR 136,1 3 /dev/pts/1
bash 16715 dtucker 1u CHR 136,1 3 /dev/pts/1
bash 16715 dtucker 2u CHR 136,1 3 /dev/pts/1
bash 16715 dtucker 255u CHR 136,1 3 /dev/pts/1
The shell's standard input, output and error are connected to the pty
pts/1...
$ sudo lsof -p 16714
COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME
[...]
sshd 16714 dtucker 7u CHR 5,2 889 /dev/ptmx
sshd 16714 dtucker 8u CHR 5,2 889 /dev/ptmx
sshd 16714 dtucker 9u CHR 5,2 889 /dev/ptmx
and the corresponding sshd is reading from and writing to that pty (via
the pseudo terminal multiplexer). If I then strace the shell while I
type "ls[CR]" in it, you can see the keystrokes flowing in descriptor 0
(stdin):
$ strace -p 16715
Process 16715 attached - interrupt to quit
read(0, "l", 1) = 1
write(2, "l", 1) = 1
rt_sigprocmask(SIG_BLOCK, NULL, [], 8) = 0
read(0, "s", 1) = 1
write(2, "s", 1) = 1
rt_sigprocmask(SIG_BLOCK, NULL, [], 8) = 0
read(0, "\r", 1) = 1
write(2, "\n", 1) = 1
rt_sigprocmask(SIG_BLOCK, [INT], [], 8) = 0
[lots of output]
>> Look in session.c in do_exec() and do_exec_no_pty(). Ultimately it will
>> end up running the command via the user's shell via execve(1) after
>> setting up its environment, descriptors and such.
> I looked do_exec_no_pty, is do_child(s, command) the place the command is executed?
> There are two execve's in do_child, one is for fork a shell, the other
> execve, it seems never invoked. So I still do not know how where
> command is executed.
The first is executed if you don't supply a command on the ssh client
command line (it's preceded by "if (!command)") the second is used if
you do supply a command and effectively runs /bin/sh -c "commands you
specified".
--
Darren Tucker (dtucker at zip.com.au)
GPG key 8FF4FA69 / D9A3 86E9 7EEE AF4B B2D4 37C9 C982 80C7 8FF4 FA69
Good judgement comes with experience. Unfortunately, the experience
usually comes from bad judgement.
More information about the openssh-unix-dev
mailing list