Commit graph

315 commits

Author SHA1 Message Date
ridiculousfish
632e150152 Introduce notion of "wait handles"
This is preparing to address the problem where fish cannot wait on a
reaped job, because it only looks at the active job list. Introduce the
idea of a "wait handle," which is a thing that `wait` can use to check if
a job is finished. A job may produce its wait handle on demand, and
parser_t will save the wait handle from wait-able jobs at the point they
are reaped.

This change merely introduces the idea; the next change makes builtin_wait
start using it.
2021-05-15 20:20:50 -07:00
ridiculousfish
0a559ac457 Reformat source files with clang-format 2021-04-21 13:31:58 -07:00
ridiculousfish
467755bf4a Bravely optimize job_reap
job_reap is now called more often. This optimizes it by doing an
early-out if there are no running jobs (common at the prompt) and also
skipping the save/restore status, since by inspection we also save and
restore the status when running event handlers.
2021-04-17 16:43:28 -07:00
ridiculousfish
3b32a32dda Replace some format_strings with to_string
This is hopefully a little faster and a little safer as there's
no format string involved.
2021-04-17 16:43:27 -07:00
ridiculousfish
be9579418f Refactor to use has_external_proc instead of a manual loop
No functional change here.
2021-04-17 16:43:27 -07:00
ridiculousfish
e299f89db3 Rename print_job_summary to call_job_summary
No functional change; this is simply a less misleading name.
2021-04-17 16:43:27 -07:00
ridiculousfish
a69e94d954 add_disowned_job to accept its parameter by const pointer
It never modified the job.
2021-04-03 21:05:32 -07:00
ridiculousfish
b44f40547b Rationalize exit codes for failed execs
This cleans up some exit code processing. Previously a failed exec
would produce exit code 125 unconditionally, while a failed posix_spawn
would produce exit code 1 (!).

With this change, fish reports exit code 126 for not-executable, and 127
for file-not-found. This matches bash.
2021-03-27 21:37:46 -07:00
Fabian Homborg
371516382d Create job-exit caller events inside event handlers
f7e2e7d26b forbid any job exit events
from happening inside jobs that were themselves event handlers, but
that causes e.g.

```fish
function f --on-event fish_prompt
source (echo "echo hello world" | psub)
end
```

to not trigger psub's cleanup, so it leaves files in $TMPDIR behind.

This was hit by pyenv, because that still uses `source (thing |
psub)`.

Fixes #7792.
2021-03-07 10:00:52 +01:00
ridiculousfish
2caeec24f7 Tighten up pipeline-aborting errors
Prior to this change, the functions in exec.cpp would return true or false
and it was not clear what significance that value had.

Switch to an enum to make this more explicit. In particular we have the
idea of a "pipeline breaking" error which should us to skip processes
which have not yet launched; if no process launches then we can bail out
to a different path which avoids reaping processes.
2020-12-13 17:30:26 -08:00
ridiculousfish
a2e486966a Always become pgroup leader in interactive mode
Prior to this change, if fish were launched connected to a tty but not as
pgroup leader, it would attempt to become pgroup leader only if
--interactive is explicitly passed. But bash will unconditionally attempt
to become pgroup leader if launched interactively. This can result in
scenarios where fish is running interactively but in another pgroup. The
most obvious impact is that control-C will result in the pgroup leader
(not fish) exiting and make fish orphaned.

Switch to matching the bash behavior here - we will always try to become
pgroup leader if interactive.

Fixes #7060.
2020-12-06 13:42:35 -08:00
ridiculousfish
7c4891407f Remove restore_attrs from terminal_return_from_job_group function
Previously this parameter was used to more-eagerly restore the terminal
mode. This was the basis for #2214. However now we restore the mode
from the reader instead, so we can remove this unused parameter.
2020-11-23 19:36:55 -08:00
ridiculousfish
db514df95b Stop setting tty back to shell mode when a fg proc completes
Prior to this change, when a process resumes because it is brought back
to the foreground, we would reset the terminal attributes to shell mode.
This fixed #2114 but subtly introduced #7483.

This backs out 9fd9f70346, re-introducing #2114 and re-fixing #7483.
A followup fix will re-fix #2114; these are broken out separately for
bisecting purposes.

Fixes #7483.
2020-11-23 19:36:39 -08:00
Fabian Homborg
b32540f346 proc: Remove unused function 2020-11-15 11:26:45 +01:00
ridiculousfish
2a8e104cc8 Relax some main thread requirements around waiting for jobs
This is now correctly per-parser so the thread should no longer matter.
2020-09-13 17:54:52 -07:00
Johannes Altmanninger
fbaa5d193d Declare functions in headers or use internal linkage (static)
Found with gcc's -Wmissing-declarations which gives warnings like

	../src/tinyexpr.cpp:61:5: warning: no previous declaration for ‘int get_arity(int)’ [-Wmissing-declarations]
	   61 | int get_arity(const int type) {

The same warnings show up for builtin functions like builtin_bg because they
currently don't include their own headers. I left that.
Also reformat the touched files.
2020-09-08 22:44:03 +02:00
ridiculousfish
3062994645 Implement cancel groups
This concerns how "internal job groups" know to stop executing when an
external command receives a "cancel signal" (SIGINT or SIGQUIT). For
example:

    while true
        sleep 1
    end

The intent is that if any 'sleep' exits from a cancel signal, then so would
the while loop. This is why you can hit control-C to end the loop even
if the SIGINT is delivered to sleep and not fish.

Here the 'while' loop is considered an "internal job group" (no separate
pgid, bash would not fork) while each 'sleep' is a separate external
command with its own job group, pgroup, etc. Prior to this change, after
running each 'sleep', parse_execution_context_t would check to see if its
exit status was a cancel signal, and if so, stash it into an int that the
cancel checker would check. But this became unwieldy: now there were three
sources of cancellation signals (that int, the job group, and fish itself).

Introduce the notion of a "cancellation group" which is a set of job
groups that should cancel together. Even though the while loop and sleep
are in different job groups, they are in the same cancellation group. When
any job gets a SIGINT or SIGQUIT, it marks that signal in its cancellation
group, which prevents running new jobs in that group.

This reduces the number of signals to check from 3 to 2; eventually we can
teach cancellation groups how to check fish's own signals and then it will
just be 1.
2020-09-03 11:01:27 -07:00
ridiculousfish
0b075fce88 Factor the exit state to make exit handlers more explicit
This adds a new type 'exit_state_t' which encapsulates where fish is in
the process of exiting. This makes it explicit when fish wants to cancel
"ordinary" fish script but still run exit handlers.

There should be no user-visible behavior change here; this is just
refactoring in preparation for the next commit.
2020-08-30 15:09:31 -07:00
Johannes Altmanninger
09f189870e Trigger prompt repaint after printing parser error or background job warning
See #7289
2020-08-27 21:18:26 +02:00
ridiculousfish
d50c0c2b85 Prevent certain 100% CPU loops
We weren't correctly updating the internal exit generation value. This
meant that if one internal process exits, every other internal process
that has not exited will continually check, leading to 100% CPU usage.

I think this mainly affects concurrent mode, but it may be reproducible
if you have a command which refuses to consume its input.
2020-08-16 12:56:42 -07:00
Fabian Homborg
103a4ece81 Add parens to silence warning
This triggered -Wparentheses in gcc 10.1.0
2020-08-08 09:14:47 +02:00
ridiculousfish
2cd336376e Refactor process_mark_finished_children
Reduce the level of nesting and the loop complexity.
2020-08-07 12:34:53 -07:00
ridiculousfish
206b2d0a26 Simplify topic monitoring
The topic monitor allows a client to wait for multiple events, e.g. sigchld
or an internal process exit. Prior to this change a client had to specify
the list of generations and the list of topics they are interested in.
Simplify this to just the list of generations, with a max-value generation
meaning the topic is not interesting.

Also remove the use of enum_set and enum_array, it was too complex for what
it offered.
2020-08-06 19:01:30 -07:00
Soumya
8dd2d4f15d Change builtins to return maybe_t<int> instead of int 2020-08-05 12:23:49 -07:00
Soumya
a2b2bcef6e Add a $status_generation variable that's incremented for each interactive command that produces a status.
This can be used to determine whether the previous command produced a real status, or just carried over the status from the command before it. Backgrounded commands and variable assignments will not increment status_generation, all other commands will.
2020-08-05 12:23:49 -07:00
ridiculousfish
87d049edd8 Remove redirect_tty_output call from tcgetattr return
tcgetattr cannot return EIO.
2020-08-03 16:42:27 -07:00
ridiculousfish
c9b42c6f1f Stop #include-ing wcstringutil.h in flog.h
This is a header dependency that we can break.
2020-07-29 17:04:18 -07:00
ridiculousfish
3506274ccf Make in_foreground an explicit param to continue_job
This moves us slightly closer towards fish code in the background. The idea is
that a background job may still have "foreground" sub-jobs, example:

    begin ; sleep 5 ; end &

The begin/end job runs in the background but should wait for `sleep`.

Prior to this fix, fish would see the overall job group is in the background
and not wait for any of its processes. With this change we detach waiting from
is_foreground.
2020-07-27 15:56:24 -07:00
ridiculousfish
3382bc70d2 Fix a stale comment
[ci skip]
2020-07-27 15:36:43 -07:00
ridiculousfish
c35fe879c7 Bravely remove reclaim... param from continue_job, and rework tcsetpgrp calls
This changes how fish attempts to protect itself from calling tcsetpgrp() too
aggressively. Recall that tcsetpgrp() will "force" itself, if SIGTTOU is
ignored (which it is in fish when job control is enabled).

Prior to this fix, we avoided SIGTTINs by only transferring the tty ownership
if fish was already the owner. This dated from a time before we had really
nailed down how pgroups should be assigned. Now we more deliberately assign a
job's pgroup so we don't need this conservative check.

However we still need logic to avoid transferring the tty if fish is not the
owner. The bad case is when job control is enabled while fish is running in the
background - here fish would transfer the tty and "steal" from the foreground
process.

So retain the checks of the current tty owner but migrate them to the point of
calling tcsetpgrp() itself.
2020-07-27 14:51:37 -07:00
ridiculousfish
1823f5d95f Remove the send_sigcont from continue_job
We can just send sigcont if the job is stopped; no need to make this an
explicit param.
2020-07-27 10:48:32 -07:00
Mahmoud Al-Qudsi
d46b9ff9be Remove repeated acquire of disowned pid lock in a loop 2020-07-25 20:45:08 -05:00
David Adam
2720f3d2ef proc: disown PIDs, not just PGIDs
add_disowned_pgid skipped jobs that have a PGID equal to the running
process. However, this includes processes started in config.fish or when
job control is turned off, so they never get waited on.

Instead, refactor this function to add_disowned_job, and add either the PGID or
all the PIDs of the job to the list of disowned PIDs/PGIDs.

Fixes #7183.
2020-07-25 20:38:59 -05:00
David Adam
025a0d3cf5 proc: add log message for reaped disowned IDs 2020-07-25 20:35:54 -05:00
ridiculousfish
54b642bc6f Factor job groups into their own file
Migrate out of proc.h, which has become too long.
2020-07-19 16:42:29 -07:00
ridiculousfish
ba8b89873e Teach a job its command at constructor time
No point in allowing this to be set later.
2020-07-18 12:42:44 -07:00
ridiculousfish
f30ce21aaa terminal_maybe_give_to_job to operate on groups, not jobs
Assigning the tty is really a function of a job group, not an individual
job. Reflect that in terminal_maybe_give_to_job_group and also
terminal_return_from_job_group.
2020-07-18 12:42:44 -07:00
ridiculousfish
40c9bda7fd Store the command that produced a job group in the group
This will enable us to replace more uses of jobs with job groups.
2020-07-18 12:42:44 -07:00
ridiculousfish
37dc554fe1 Revert "Remove unnecessary owning_lock usages"
This reverts commit 3a5585df95.

This reverts a change that removed a lock. It's indeed true that in master,
fish script is bound to the main thread. But I'm working to remove that
limitation and these locks are important in that future.
2020-07-12 18:56:39 -07:00
Mahmoud Al-Qudsi
3a5585df95 Remove unnecessary owning_lock usages
The owning locks were added after the original code and decorated with
comments indicating they are thread-safe, even though they're only ever
used from the main thread. Presuming the intent was to make future
manipulation of the code safer rather than to actually make use of any
thread safety guarantees, these have been wrapped in a new
`thread_exclusive` type which always calls ASSERT_IS_MAIN_THREAD.

The benefit is that this does not perform a syscall to lock a mutex
each time the variables are accessed.
2020-07-12 20:21:28 -05:00
ridiculousfish
2a4c545b21 Rework how signals trigger cancellation
When fish receives a "cancellation inducing" signal (SIGINT in particular)
it has to unwind execution - for example while loops or whatever else that
is executing. There are two ways this may come about:

1. The fish process received the signal
2. A child process received the signal

An example of the second case is:

    some_command | some_function

Here `some_command` is the tty owner and so will receive control-C, but
then fish has to cancel function execution.

Prior to this change, these were handled uniformly: both would just set a
cancellation signal inside the parser. However in the future we will have
multiple parsers and it may not be obvious which one to set the flag in.
So instead distinguish these cases: if a process receives SIGINT we mark
the signal in its job group, and if fish receives it we set a global
variable.
2020-07-12 12:16:01 -07:00
ridiculousfish
2e5222ffe8 Finish renaming job tree to job group
Some "tree" terminology was still there.
2020-07-11 17:05:42 -07:00
ridiculousfish
765c48afa4 Migrate the notion of 'foreground' from job to job group
Whether a job is foreground is a property of its pgid, so it belongs
naturally on the job group.
2020-07-11 17:01:52 -07:00
Mahmoud Al-Qudsi
34b918d0a0 Reduce unneeded calls to tcgetpgrp
After profiling bottlenecks in job execution, the calls to `tcgetpgrp`
were identified to take a good amount of the execution time. Collecting
metrics on which branches were taken revealed that in all "normal"
cases, there is no benefit to calling `tcgetpgrp` before calling
`tcsetpgrp` as it can instead be called only in the error case to
determine what sort of error handling behavior should be applied.

This makes the best-case scenario of a single syscall much more likely
than in the previous situation.
2020-06-25 22:46:09 -05:00
ridiculousfish
7cc99a2d80 Rename job_tree to job_group
Initially I wanted to pick a different name to avoid confusion with
process groups, but really job trees *are* process groups. So name them
to reflect that fact.

Also rename "placeholder" to "internal" which is clearer.
2020-05-30 14:22:44 -07:00
ridiculousfish
b119c4b3bb Eliminate pgroup_provenance_t
Now that job trees are a single source of truth for a job's pgid, we no
longer need fancy logic around how the pgroup is assigned.
2020-05-30 14:22:44 -07:00
ridiculousfish
f37a44db16 Migrate job pgid from job to job tree
Prior to this, jobs all had a pgid, and fish has to work hard to ensure
that pgids were inherited properly for nested jobs. But now the job tree
is the source of truth and there is only one location for the pgid.
2020-05-30 14:22:44 -07:00
ridiculousfish
a4b66d948b Add a property describing when a job is initially backgrounded
Track separately whether a job is in the background now, and whether
it was constructed in the background via the & syntax.
2020-05-30 14:22:44 -07:00
ridiculousfish
123f3e6f93 Put job_id into job_tree
Job IDs are really a property of a job tree, not individual jobs. Reflect
that fact by migrating job IDs into job_tree.
2020-05-30 14:22:44 -07:00
ridiculousfish
e95bcfb074 Teach a job to decide its job tree
Job trees come in two flavors: “placeholders” for jobs which are only fish
functions, and non-placeholders which need to track a pgid. This adds
logic to allow a job to decide if its parent's job tree is appropriate,
and allocating a new tree if not.
2020-05-30 14:22:43 -07:00