Commit graph

249 commits

Author SHA1 Message Date
ridiculousfish
59c6663a16 Migrate the "are you sure you want to exit" logic from parse_execution to exec
This feels more like the sort of logic that should live in the point where
jobs are executed, instead of where jobs are created from parse trees.
2020-02-19 18:25:36 -07:00
Fabian Homborg
65883e0e40 Restyle
Mostly line breaks, one instance of tabs!

For some reason clang-format insists on two spaces before a same-line comment?

(I continue to be unimpressed with super-strict line length limits,
but I continue to believe in automatic styling, so it is what it is)

[ci skip]
2020-02-17 14:14:05 +01:00
ridiculousfish
6bf9ae9aeb Fix up --on-job-exit caller
The `function --on-job-exit caller` feature allows a command substitution
to observe when the parent job exits. This has never worked very well - in
particular it is based on job IDs, so a function that observes this will
run multiple times. Implement it properly.

Do this by having a not-recycled "internal job id".

This is only used by psub, but ensure it works properly none-the-less.
2020-02-08 16:23:25 -08:00
ridiculousfish
93fc0d06d4 Rename event_type_t::job_exit to event_type_t::caller_exit
"job_exit" events, despite their name, can only be created via
the '--on-job-exit caller' misfeature of function. Rename it to make it
clear that this event type is specifically for caller-exit.
2020-02-08 16:08:26 -08:00
ridiculousfish
fba3c83ba5 Eliminate yet more calls to principal_parser()
In particular, remove job_t::from_job_id
2020-02-08 12:47:13 -08:00
ridiculousfish
f1f97b6476 Eliminate more calls to principal_parser()
Require a parser to get a job from its pgid.
2020-02-08 12:46:56 -08:00
ridiculousfish
8d8bcb7d8a Stop acquiring the terminal before running builtins
fish has some unprincipled code that attempts to tcsetpgrp() to own the
terminal before running a builtin; this was added because 'read' might
want to read from the terminal. I added this code before fully
understanding how process groups and terminals work. A better fix would
be to ensure that fish is marked as the pgroup leader in the job when
the builtin is the first process in the job, and we do that now.

Courageously back out the changes to grab the terminal; see #5147 and
also #5133.
2020-01-31 10:42:21 -08:00
ridiculousfish
97c456a986 Improve support for job control in non-interactive scenarios
Avoid complaining about ENOTTY results from tcsetpgrp, and ensure we
ignore SIGTTOU the first time job control is enabled.
2020-01-30 15:18:10 -08:00
Fabian Homborg
9735a18add Always return a value, even in unreachable code
To placate dumb compilers, we sometimes have to include code that will
never be executed.

Should fix the build when -Werror=return-type is in effect.
2020-01-30 20:39:42 +01:00
ridiculousfish
10da6df506 Factor out logic about how pgroups are assigned
Introduce pgroup_provenance_t, a type which captures "where the pgroup
comes from." This centralizes some logic around how pgroups are
assigned, and it anticipates concurrent execution.
2020-01-30 10:50:16 -08:00
ridiculousfish
d22c6af7a3 clang-format all C++ files 2020-01-30 10:50:11 -08:00
ridiculousfish
fc4557c784 Eliminate wopen()
It was large and mostly unnecessary. Prefer wopen() followed by
fdopen().
2020-01-28 10:43:37 -08:00
ridiculousfish
ae77f1b163 Make locked_consumed_job_ids heap allocated rather than static
This prevents its destructor from running during normal exit.
Fixes #6539
2020-01-26 20:33:50 -08:00
Fabian Homborg
246882b52d Add proc-pgroup flog category
I'm not *super*-happy with this, because pgroups and terminal
ownership and such are quite entertwined.

But hey, if all fails just use `proc'*'`
2020-01-19 14:55:24 +01:00
Fabian Homborg
fe931aeea7 Add more messages to termowner flog category 2020-01-19 14:55:24 +01:00
Fabian Homborg
024e03ab1e Replace debug(1) with FLOGF(warning) 2020-01-19 14:22:39 +01:00
ridiculousfish
1da09f2c52 Ensure new job IDs are never smaller than existing running jobs
This makes job IDs "monotone" in the sense that newly spawned jobs
always have larger IDs than existing jobs, as requested in #6053
2020-01-16 16:01:29 -08:00
ridiculousfish
7e1270ae70 Be more disciplined about cancellation signals
Rather than storing a "should cancel" flag in the parser, store the
actual signal which triggered cancellation.
2020-01-14 15:20:04 -08:00
ridiculousfish
8d598dcffc Use handle_child_status when reaping internal procs
This reduces the number of distinct locations where we mark a process as
completed.
2020-01-13 14:12:05 -08:00
Dan Zimmerman
8e17d29e04 Introduce the internal jobs for functions
This PR is aimed at improving how job ids are assigned. In particular,
previous to this commit, a job id would be consumed by functions (and
thus aliases). Since it's usual to use functions as command wrappers
this results in awkward job id assignments.

For example if the user is like me and just made the jump from vim -> neovim
then the user might create the following alias:
```
alias vim=nvim
```
Previous to this commit if the user ran `vim` after setting up this
alias, backgrounded (^Z) and ran `jobs` then the output might be:
```
Job	Group	State	Command
2	60267	stopped	nvim  $argv
```
If the user subsequently opened another vim (nvim) session, backgrounded
and ran jobs then they might see what follows:
```
Job	Group	State	Command
4	70542	stopped	nvim  $argv
2	60267	stopped	nvim  $argv
```
These job ids feel unnatural, especially when transitioning away from
e.g. bash where job ids are sequentially incremented (and aliases/functions
don't consume a job id).

See #6053 for more details.

As @ridiculousfish pointed out in
https://github.com/fish-shell/fish-shell/issues/6053#issuecomment-559899400,
we want to elide a job's job id if it corresponds to a single function in the
foreground. This translates to the following prerequisites:

- A job must correspond to a single process (i.e. the job continuation
    must be empty)
- A job must be in the foreground (i.e. `&` wasn't appended)
- The job's single process must resolve to a function invocation

If all of these conditions are true then we should mark a job as
"internal" and somehow remove it from consideration when any
infrastructure tries to interact with jobs / job ids.

I saw two paths to implement these requirements:

- At the time of job creation calculate whether or not a job is
  "internal" and use a separate list of job ids to track their ids.
  Additionally introduce a new flag denoting that a job is internal so
  that e.g. `jobs` doesn't list internal jobs
  - I started implementing this route but quickly realized I was
    computing the same information that would be computed later on (e.g.
    "is this job a single process" and "is this jobs statement a
    function"). Specifically I was computing data that populate_job_process
    would end up computing later anyway. Additionally this added some
    weird complexities to the job system (after the change there were two
    job id lists AND an additional flag that had to be taken into
    consideration)
- Once a function is about to be executed we release the current jobs
  job id if the prerequisites are satisfied (which at this point have
  been fully computed).
  - I opted for this solution since it seems cleaner. In this
  implementation "releasing a job id" is done by both calling
  `release_job_id` and by marking the internal job_id member variable to
  -1. The former operation allows subsequent child jobs to reuse that
  same job id (so e.g. the situation described in Motivation doesn't
  occur), and the latter ensures that no other job / job id
  infrastructure will interact with these jobs because valid jobs have
  positive job ids. The second operation causes job_id to become
  non-const which leads to the list of code changes outside of `exec.c`
  (i.e. a codemod from `job_t::job_id` -> `job_t::job_id()` and moving the
   old member variable to a non-const private `job_t::job_id_`)

Note: Its very possible I missed something and setting the job id to -1
will break some other infrastructure, please let me know if so!

I tried to run `make/ninja lint`, but a bunch of non-relevant issues
appeared (e.g. `fatal error: 'config.h' file not found`). I did
successfully clang-format (`git clang-format -f`) and run tests, though.
This PR closes #6053.
2019-12-31 10:08:50 -08:00
Rosen Penev
06cb0bbe9a
[clang-tidy] Add several references
Found with performance-unnecessary-value-param

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2019-12-26 21:55:53 -08:00
ridiculousfish
df0681d393 Remove process_generation_count_t
It was unused.
2019-12-26 13:33:14 -08:00
Mathieu Duponchelle
15c1b3ed4b Place fish in its own process group when launched with -i
Fixes #5909
2019-12-23 10:32:37 +01:00
ridiculousfish
c0b3be9fb4 Stop storing block_io in job_t
Prior to this fix, a job would hold onto any IO redirections from its
parent. For example:

    begin
        echo a
    end < file.txt

The "echo a" job would hold a reference to the I/O redirection.
The problem is that jobs then extend the life of pipes until the job is
cleaned up. This can prevent pipes from closing, leading to hangs.

Fix this by not storing the block IO; this ensures that jobs do not
prolong the life of pipes.

Fixes #6397
2019-12-11 16:34:20 -08:00
ridiculousfish
0b1af1ace4 Correct the use of the constructed pointer in job lineage
This was always being set to a different pointer. Ensure the root job
shares its constructed pointer with its children.
2019-12-10 18:32:56 -08:00
ridiculousfish
f136d634eb Collapse a job's "parent stuff" into a new type job_lineage_t
Currently a job needs to know three things about its "parents:"

1. Any IO redirections for the block or function containing this job
2. The pgid for the parent job
3. Whether the parent job has been fully constructed (to defer self-disown)

These are all tracked in somewhat separate awkward ways. Collapse them
into a single new type job_lineage_t.
2019-12-08 15:03:07 -08:00
Rosen Penev
6f4a9d527c [clang-tidy] Use C++ using instead of C typedef
Found with modernize-use-using

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2019-11-29 23:46:51 -08:00
Rosen Penev
1055ff321c [clang-tidy] Replace NULL with nullptr
Found with modernize-use-nullptr

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2019-11-25 14:23:03 -08:00
Rosen Penev
0dfa7421f3 [clang-tidy] Convert C casts to C++ ones
Found with google-readability-casting

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2019-11-25 14:17:49 -08:00
ridiculousfish
cc1c973025 Remove job_flags as an enum, just use a struct
This removes an over-complicated flag implementation, replacing it with
just a plain struct.
2019-10-15 14:40:58 -07:00
ridiculousfish
82eca4bc86 Run clang-format on all files
The main change here is to reorder headers.
2019-10-13 15:50:48 -07:00
ridiculousfish
9fd9f70346 Restore terminal modes after sending SIGCONT
Fixes #2214

Thanks to @bruce-hill for the patch.
2019-09-01 17:24:23 -07:00
ridiculousfish
a33f0eb636 Clean up some logic around when process exit events are sent 2019-07-28 14:36:57 -07:00
ridiculousfish
8181883111 Minor refactoring of logic around when a job wants to claim the terminal
Introduce should_claim_terminal() which encapsulates an && exprsesion which
was previously repeated a lot.
2019-07-12 13:31:56 -07:00
ridiculousfish
09e4f8ff42 Refactor how the terminal is transferred to jobs
Centralize the logic around when a job acquires the terminal.
2019-06-29 15:58:36 -07:00
ridiculousfish
4a2c709fb1 Eliminate shell_is_interactive
We used to have a global notion of "is the shell interactive" but soon we
will want to have multiple independent execution threads, only some of
which may be interactive. Start tracking this data per-parser.
2019-06-29 11:28:26 -07:00
ridiculousfish
f7e2e7d26b Don't generate exit events for jobs created from within event handlers
Add a new job property from_event_handler, and do not create exit events for
such jobs. This prevents easy accidental infinite recursion.
2019-06-26 17:30:51 -07:00
Fabian Homborg
caedf01c00 Revert "Latch signal handlers"
This reverts commit 7ed1022cf4.

Fixes #5962.
2019-06-25 11:25:09 +02:00
ridiculousfish
89fb408eb6 Migrate some job flags into const properties struct
This helps clarify which parts of a job are mutable, and which are constant.
2019-06-23 12:42:44 -07:00
ridiculousfish
1c66d56d3a Add debug categories for reaping processes 2019-06-13 14:29:13 -07:00
ridiculousfish
fc99d6c7af clang-format all files 2019-06-03 20:30:48 -07:00
ridiculousfish
ff55249447 Make events per-parser
This makes the following changes:

1. Events in background threads are executed in those threads, instead of
being silently dropped

2. Blocked events are now per-parser instead of global

3. Events are posted in builtin_set instead of within the environment stack

The last one means that we no longer support event handlers for implicit
sets like (example) argv. Instead only the `set` builtin (and also `cd`)
post variable-change events.

Events from universal variable changes are still not fully rationalized.
2019-06-03 02:48:35 -07:00
Fabian Homborg
87971e1f2e Widen the rest of the FLOGs
Fixes #5900.
2019-05-30 13:08:35 +02:00
Fabian Homborg
d73ee4d54b More using FLOGF when formatting is needed
sed-patched, every time a "%" is used in a call to `FLOG`, we use
`FLOGF` instead.
2019-05-30 11:54:09 +02:00
ridiculousfish
f3ee6a99c3 Add some FLOG logging around internal processes 2019-05-29 12:34:11 -07:00
Fabian Homborg
66e238fad0 More wide IO for FLOG
This widens the remaining ones that don't take a char
anywhere.

The rest either use a char _variable_ or __FUNCTION__, which from my
reading is narrow and needs to be widened manually. I've been unable
to test it, though.

See #5900.
2019-05-29 08:07:04 +02:00
ridiculousfish
ea9d1ad82f Convert debug(0) calls to FLOG 2019-05-27 17:31:17 -07:00
ridiculousfish
46a9da83e8 Convert terminal ownership logging from debug to flog 2019-05-27 17:24:52 -07:00
ridiculousfish
8774860468 Convert job logging from debug to FLOG 2019-05-27 17:24:52 -07:00
ridiculousfish
7ed1022cf4 Latch signal handlers
Now that our interactive signal handlers are a strict superset of
non-interactive ones, there is no reason to "reset" signals or take action
when becoming non-interactive. Clean up how signal handlers get installed.
2019-05-26 18:04:03 -07:00