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