oils-for-unix / oils

Oils is our upgrade path from bash to a better language and runtime. It's also for Python and JavaScript users who avoid shell!
http://www.oilshell.org/
Other
2.81k stars 154 forks source link

Implement the rest of job control #360

Closed andychu closed 1 year ago

andychu commented 5 years ago

Forked from #176

jyn514 commented 5 years ago

More things for the list:

About bg: this is used for jobs that were started in the background, it's effectively the same as kill -SIGTSTP $!

jyn514 commented 5 years ago

I think controlling terminals are somehow related to the fact that python -c input() & shouldn't be able to read stdin: http://curiousthing.org/sigttin-sigttou-deep-dive-linux https://www.gnu.org/software/libc/manual/html_node/Access-to-the-Terminal.html#Access-to-the-Terminal

andychu commented 5 years ago
jyn514 commented 5 years ago

This is a little strange ... I could swear it was working this morning, but now when I suspend vim, it immediately restarts. Here's an strace, 4991 is osh and 5080 is vim:

$ strace -p 4991 -f
...
[pid  5080] kill(0, SIGTSTP)            = 0
[pid  4991] <... wait4 resumed> 0x7fffd8896434, WSTOPPED, NULL) = ? ERESTARTSYS (To be restarted if SA_RESTART is set)
[pid  5080] --- SIGTSTP {si_signo=SIGTSTP, si_code=SI_USER, si_pid=5080, si_uid=1000} ---
[pid  4991] --- SIGTSTP {si_signo=SIGTSTP, si_code=SI_USER, si_pid=5080, si_uid=1000} ---
[pid  5080] recvmsg(5,  <unfinished ...>
[pid  4991] wait4(-1,  <unfinished ...>
[pid  5080] <... recvmsg resumed> {msg_namelen=0}, 0) = -1 EAGAIN (Resource temporarily unavailable)
... lots of `recvmsg` calls ...

Not really sure what's going on. Here's a comparison with bash, 5508 is vim and 5199 is bash:

[pid  5508] write(1, "\33[?1002l\33[?2004l", 16) = 16
[pid  5508] ioctl(0, TCGETS, {B38400 opost -isig -icanon -echo ...}) = 0
[pid  5508] ioctl(0, SNDCTL_TMR_START or TCSETS, {B38400 opost isig icanon echo ...}) = 0
[pid  5508] ioctl(0, TCGETS, {B38400 opost isig icanon echo ...}) = 0
[pid  5508] kill(0, SIGTSTP)            = 0
[pid  5508] --- SIGTSTP {si_signo=SIGTSTP, si_code=SI_USER, si_pid=5508, si_uid=1000} ---
[pid  5508] --- stopped by SIGTSTP ---
[pid  5199] <... wait4 resumed> [{WIFSTOPPED(s) && WSTOPSIG(s) == SIGTSTP}], WSTOPPED|WCONTINUED, NULL) = 5508
[pid  5199] rt_sigprocmask(SIG_BLOCK, [CHLD], [CHLD], 8) = 0
[pid  5199] rt_sigprocmask(SIG_SETMASK, [CHLD], NULL, 8) = 0
[pid  5199] rt_sigprocmask(SIG_BLOCK, [CHLD], [CHLD], 8) = 0
[pid  5199] rt_sigprocmask(SIG_SETMASK, [CHLD], NULL, 8) = 0
[pid  5199] rt_sigprocmask(SIG_BLOCK, [CHLD TSTP TTIN TTOU], [CHLD], 8) = 0
[pid  5199] ioctl(255, TIOCSPGRP, [5199]) = 0
[pid  5199] rt_sigprocmask(SIG_SETMASK, [CHLD], NULL, 8) = 0
[pid  5199] ioctl(255, TCGETS, {B38400 opost isig icanon echo ...}) = 0
[pid  5199] ioctl(255, SNDCTL_TMR_STOP or TCSETSW, {B38400 opost isig icanon echo ...}) = 0
[pid  5199] ioctl(255, TCGETS, {B38400 opost isig icanon echo ...}) = 0
[pid  5199] ioctl(255, TIOCGWINSZ, {ws_row=49, ws_col=93, ws_xpixel=0, ws_ypixel=0}) = 0
[pid  5199] write(2, "\n", 1)           = 1
[pid  5199] write(2, "[1]+  Stopped                 vi"..., 34) = 34
jyn514 commented 4 years ago

Resume/suspend with vim is now working with a fresh install of 0.8.pre4 :)

andychu commented 2 years ago

Note: Ctrl-Z and fg works with processes, but not pipelines!

glyh commented 2 years ago

Why this is low priority given that job control is an essential part of shells?

And BTW, on osh-0.9.8, I can't suspend vim with Ctrl+Z, I would get this:

osh-0.9.8$ vim
# Presses Ctrl+Z
[PID 275157] Stopped
osh-0.9.8$ jobs
# Nothing returned, neither this command nor `jobs -l` works
# Presses Ctrl+D
^Dh-0.9.8$ 
Vim: Caught deadly signal HUP
Vim: Finished.
glyh commented 2 years ago

I also find this is not intuitive:

osh-0.9.8$ sleep 1023113231 & 
osh-0.9.8$ jobs
%1 282227 Running [subprog] command.Simple

It doesn't show which command you're running.

andychu commented 2 years ago

Yeah this is very rough, and is related to #1082 -- we need a way of printing source code

The way I would view it is that almost everything else is higher priority than job control :-/

That includes the Oil language, OSH language, documentation, other parts of interactive shell, etc. We have to deprioritize something

This has been discussed on Zulip, but the basic view is that job control is a primitive multiplexer, and tmux/screen or a windowing system are much better multiplexers

These two blog posts explain the state of the project:

http://www.oilshell.org/blog/2021/12/backlog-project.html

http://www.oilshell.org/blog/2021/12/backlog-assess.html


Help is definitely appreciated ! We have the test/stateful suite now which could help with job control if you are interested

I'm basically deprioritizing it for myself but if anyone is really excited about it, it's up for grabs. However I think it is fairly difficult and intrusive

The APUE book by Stevens talks about that

glyh commented 2 years ago

Note that bash's default jobs control output seems bugged. e.g.

sleep 10 & 
jobs

Bash would output:

[1]+  Running                 sleep 10 &

While mksh, ash, dash would output:

[1]+  Running                 sleep 10

And actually the spaces are placed pretty arbitrarily

andychu commented 1 year ago

@melvinw just did this, will be out with the next release!

This was a huge effort!

andychu commented 1 year ago

Released - https://www.oilshell.org/blog/2023/05/release-0.15.0.html