1

I am experimenting with understanding terminal emulators by looking at the different pieces of the puzzle.

I am trying to start a pty pair and shell process with socat, and then connect to it with picocom.

This is what I have figured out for the socat command:

$ socat -d -d PTY,raw,echo=0 EXEC:"/bin/sh",pty,stderr,setsid,sane
2024/03/12 08:12:16 socat[9106] N PTY is /dev/pts/5
2024/03/12 08:12:16 socat[9106] N forking off child, using pty for reading and writing
2024/03/12 08:12:16 socat[9106] N forked off child process 9107
2024/03/12 08:12:16 socat[9106] N forked off child process 9107
2024/03/12 08:12:16 socat[9106] N starting data transfer loop with FDs [5,5] and [7,7]
2024/03/12 08:12:16 socat[9107] N execvp'ing "/bin/sh"

and now try to connect with picocom. It seems to work, but signals don't work.

$ picocom /dev/pts/5
picocom v3.1

port is        : /dev/pts/5
flowcontrol    : none
baudrate is    : 9600
parity is      : none
databits are   : 8
stopbits are   : 1
escape is      : C-a
local echo is  : no
noinit is      : no
noreset is     : no
hangup is      : no
nolock is      : no
send_cmd is    : sz -vv
receive_cmd is : rz -vv -E
imap is        : 
omap is        : 
emap is        : crcrlf,delbs,
logfile is     : none
initstring     : none
exit_after is  : not set
exit is        : no

Type [C-a] [C-h] to see available commands
Terminal ready

$ tty # make sure I'm hooked up to the right thing
/dev/pts/6
$ sleep 10 # see if signals are working
^C$ sh # signals are not working - so opening a new shell which will show the error message that picocom hid
sh: 0: can't access tty; job control turned off
$ 

here are the terminal settings from a third terminal in case that helps

$ stty -a -F /dev/pts/5
speed 9600 baud; rows 0; columns 0; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>; eol2 = <undef>; swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R;
werase = ^W; lnext = ^V; discard = ^O; min = 1; time = 0;
-parenb -parodd -cmspar cs8 hupcl -cstopb cread clocal -crtscts
-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr -icrnl -ixon -ixoff -iuclc -ixany -imaxbel -iutf8
-opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
-isig -icanon -iexten -echo echoe echok -echonl -noflsh -xcase -tostop -echoprt echoctl echoke -flusho -extproc
$ stty -a -F /dev/pts/6
speed 38400 baud; rows 0; columns 0; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>; eol2 = <undef>; swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R;
werase = ^W; lnext = ^V; discard = ^O; min = 1; time = 0;
-parenb -parodd -cmspar cs8 -hupcl -cstopb cread -clocal -crtscts
-ignbrk brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff -iuclc -ixany imaxbel -iutf8
opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt echoctl echoke -flusho -extproc

I had a similar problem when setting up getty last experiment: job control doesn't work when I try to set up getty over serial

The problem there was that getty doesn't like to run inside an existing tty. Is it the same problem here? Is there a way to tell socat not to run inside a tty? Terminal emulators that set up a shell process aren't using systemd, so how do they do it? and how can I do the same thing that terminal emulators do to set up a shell process that I can connect to?


update:

I have tried running socat in systemd just in case, and the result was the same.


answer to a comment:

this is with the socat command running in systemd

$ ps j $$
 PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND
16170 16171 16170 16170 ?           -1 S     1000   0:00 /bin/sh

and this is with socat running in the foreground in another terminal

$ ps j $$
 PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND
19215 19216 19216 19216 ?           -1 Ss    1000   0:00 /bin/sh
$ tty
/dev/pts/11

(10/11 is the pair that I created with the socat command)


There has been a bit of a twist. This only happens with dash. If you put in bash instead, or even bash --noediting --posix or ln -s /bin/bash sh and then use that sh to turn on posix mode, job control seems to work. And if you go into bash first, and then open dash from there, job control works, but if you open dash originally, and then open bash from inside dash, it doesn't work. The terminal settings are the same as long as you choose --noediting. So there must be something different about how dash starts up.

5
  • Who owns /dev/pts/5 or 6 (that you're using)? It should be the same user as the one running socat Mar 12 at 7:41
  • 1
    yeah same user. The user that runs socat is the user that runs picocom, and both ptses are owned by [me]:tty with perms 620
    – Alex028502
    Mar 12 at 10:55
  • I'm not able to reproduce the problem here. What does ps j $$ show in the shell? (Aside from that, there are two pty pairs involved here, with socat being the 'master' of both and forwarding data from one side to another. I don't know whether that has anything to do with the problem, but it's definitely not the same as the way terminal emulators work.) Mar 12 at 16:35
  • You mean when you run this socat command, you are able to connect to the pty and job control works? I have run the socat command in systemd to get rid of the other pty, and the result is the same. One sec I'll asnwer you other question
    – Alex028502
    Mar 12 at 17:13
  • sorry for the confusion @u1686_grawity it seems this issue is only with dash
    – Alex028502
    Mar 12 at 21:11

1 Answer 1

1

What worked for me was to use bash instead of sh:

socat -d -d PTY,raw,echo=0 EXEC:"/bin/bash",pty,stderr,setsid,sane
2024/03/12 18:32:09 socat[24732] N PTY is /dev/pts/2
2024/03/12 18:32:09 socat[24732] N forking off child, using pty for reading and writing
2024/03/12 18:32:09 socat[24732] N forked off child process 24733
2024/03/12 18:32:09 socat[24732] N forked off child process 24733
2024/03/12 18:32:09 socat[24732] N starting data transfer loop with FDs [5,5] and [7,7]
2024/03/12 18:32:09 socat[24733] N execvp'ing "/bin/bash"

And then in a parallel session,

picocom /dev/pts/2; echo EXIT FROM PICOCOM
picocom v3.1
[…]
Type [C-a] [C-h] to see available commands
Terminal ready

pi$ sleep 5
^C
$ sleep 5
^Z
[1]+  Stopped                 sleep 5
$ jobs
[1]+  Stopped                 sleep 5
$ exit
exit

FATAL: read zero bytes from port
term_exitfunc: reset failed for dev UNKNOWN: Input/output error
EXIT FROM PICOCOM

I couldn't get /bin/sh (/bin/dash) to work with signals such as Ctrl/C or Ctrl/Z at all.

2
  • 1
    strange - I thought I tried that. even when I try sh symlinked to bash or bash --noediting --posix, job control seems to work, so I guess it's something with dash. When you put in bash --noediting, the terminal settings are the same as with dash. I will update the question.
    – Alex028502
    Mar 12 at 21:05
  • @Alex028502 I also tried with -sh and -bash, to get a login shell, but that didn't seem to make a relevant difference to job control Mar 12 at 21:22

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .