Commit graph

301 commits

Author SHA1 Message Date
Rosen Penev
aae9ebfbd4 [clang-tidy] use using instead of typedef
Found with modernize-use-using

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2020-02-22 09:33:16 +01:00
ridiculousfish
05b8d4de97 Make hup_background_jobs accept the job list directly 2020-02-19 20:35:04 -07:00
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
ridiculousfish
84febe8f2e Make disowned pid reaping thread-safe 2019-05-22 17:10:33 -07:00
ridiculousfish
508c3a8005 Make is_event and other globals part of parser_t libdata 2019-05-18 19:03:45 -07:00
ridiculousfish
c44dae2d73 Migrate certain runtime flags to atomics hidden behind functions 2019-05-18 18:50:28 -07:00
ridiculousfish
4fcb9d1fed Hide no_exec behind a function 2019-05-18 18:50:28 -07:00
ridiculousfish
be41407610 Make have_proc_stat an ordinary function
Removes a mutable global variable.
2019-05-18 18:50:28 -07:00
ridiculousfish
234c97e6d2 Remove some unused variables 2019-05-12 18:23:00 -07:00
ridiculousfish
1719d6f136 Make $status and $pipestatus per-parser
Another step towards allowing multiple parsers to execute in parallel.
2019-05-12 14:00:44 -07:00
ridiculousfish
8a8b2513b5 Eliminate the global jobs() function
All job lists are attached to a parser now.
2019-05-05 11:33:08 -07:00
Fabian Homborg
c2970f9618 Reformat all files
This runs build_tools/style.fish, which runs clang-format on C++, fish_indent on fish and (new) black on python.

If anything is wrong with the formatting, we should fix the tools, but automated formatting is worth it.
2019-05-05 12:09:25 +02:00
ridiculousfish
e10838d5d6 Make job_control_mode a static variable with accessors 2019-05-04 20:58:35 -07:00
ridiculousfish
9fb98baba6 Thread the parser into process_clean_after_marking 2019-05-04 20:58:35 -07:00
ridiculousfish
f66e010949 Turn a lot of common.h variables into getter functions
Improves thread safety.
2019-05-04 20:58:35 -07:00
ridiculousfish
55e3270ac4 Remove erase_list from process_clean_after_marking
We don't need to maintain an erase_list in this function any more.
Simply remove jobs that are completed.
2019-05-01 16:32:14 -07:00
ridiculousfish
3dfaa192da Put back process and job exit events
These were removed in f8b2e818ed under a
belief that they were unused. But they are documented and supported.
2019-05-01 16:32:14 -07:00
ridiculousfish
43d668bdc8 Continue to refactor internal loop of process_clean_after_marking
Factor our logic around when to print a message.
2019-05-01 16:32:14 -07:00
ridiculousfish
b5d3fadf44 Factor out the individual process handling in process_clean_after_marking
Helps break up this monolith.
2019-05-01 16:32:14 -07:00
ridiculousfish
b8170ec1ce Clarify return value of job_reap and process_clean_after_marking 2019-05-01 16:32:14 -07:00
ridiculousfish
9700800ecf Factor disowned job removal into its own function
This helps break up process_clean_after_marking.
2019-05-01 16:31:21 -07:00
ridiculousfish
c05e72749a Rename PENDING_REMOVAL to DISOWN_REQUESTED
A commend implied that PENDING_REMOVAL was broader than it was. In practice
only disown() sets this flag. Rename the flag for clarity.
2019-05-01 15:37:53 -07:00
David Adam
665ae3787a Switch to runtime check for /proc/self/stat
Removes a compile-time check that may have affected cross-compilation.

Work on #1067.
2019-04-30 16:23:28 +08:00
ridiculousfish
a597b0e6e1 Remove get_proc_had_barrier
Prior to this change, fish used a global flag to decide if we should check
for changes to universal variables. This flag was then checked at arbitrary
locations, potentially triggering variable updates and event handlers for
those updates; this was very hard to reason about.

Switch to triggering a universal variable update at a fixed location,
after running an external command.  The common case is that the variable
file has not changed, which we can identify with just a stat() call, so
this is pretty cheap.
2019-04-13 12:40:57 -07:00
Mahmoud Al-Qudsi
2fe2169065 Make eval a decorator
`eval` has always been implemented as a function, which was always a bit
of a hack that caused some issues such as triggering the creation of a
new scope. This turns `eval` into a decorator.

The scoping issues with eval prevented it from being usable to actually
implement other shell components in fish script, such as the problems
described in #4442, which should now no longer be the case.

Closes #4443.
2019-04-11 10:36:49 -05:00
Mahmoud Al-Qudsi
04a96f6c6e Change when PENDING_REMOVAL jobs are removed
Followup to 394623b.

Doing it in the parser meant only top-level jobs would be reaped after
being `disown`ed, as subjobs aren't directly handled by the parser.

This is also much cleaner, as now job removal is centralized in
`process_clean_after_marking()`.

Closes #5803.
2019-04-10 11:00:48 -05:00
ridiculousfish
39a9740997 Be less aggressive about reclaiming the foreground pgrp
Prior to this fix, in every call to job_continue, fish would reclaim the
foreground pgrp. This would cause other jobs in the pipeline (which may
have another pgrp) to receive SIGTTIN / SIGTTOU.

Only reclaim the foreground pgrp if it was held at the point of job_continue.

This partially addresses #5765
2019-04-07 09:20:32 -07:00
Mahmoud Al-Qudsi
eb2d829bc5 Use explicit lock.exchange()
There's really no point in using std::atomic if we're not going to
actually guarantee the entire read & write process is atomic.
2019-03-31 18:17:33 -05:00
Mahmoud Al-Qudsi
b5b9406711 Use explicit atomic/CAS to prevent race conditions
They are probably equivalent on x86/64 being single-byte reads/writes,
but it never hurts to be safe.
2019-03-31 18:09:59 -05:00
Mahmoud Al-Qudsi
f8b2e818ed Remove legacy generic process/job exit events 2019-03-28 18:55:36 -05:00
Mahmoud Al-Qudsi
7f5e58ae69 Only send JOB_EXIT after the job has been actually erased 2019-03-28 18:55:36 -05:00
Mahmoud Al-Qudsi
06adb1dc38 Store jobs to erase in separate list 2019-03-28 18:55:36 -05:00
Mahmoud Al-Qudsi
36f3a6d7e0 Use const auto for all jobs 2019-03-28 18:55:36 -05:00
Mahmoud Al-Qudsi
1f59976c2c Further clean up job list manipulation 2019-03-28 18:55:36 -05:00
Mahmoud Al-Qudsi
6fab783647 Convert job_list to a dequeue again
Now that we have cleaned up access to the job list and removed
transparent invalidation of iterators, it is safe to convert it to a
dequeue.
2019-03-28 18:55:36 -05:00
Mahmoud Al-Qudsi
f8e0e0ef82 Remove abstractions around job list
Directly access the job list without the intermediate job_iterator_t,
and remove functions that are ripe for abuse by modifying a local
enumeration of the same list instead of operating on the iterators
directly (e.g. proc.cpp iterates jobs, and mid-iteration calls
parser::job_remove(j) with the job (and not the iterator to the job),
causing an invisible invalidation of the pre-existing local iterators.
2019-03-28 18:55:36 -05:00
ridiculousfish
165c82e68a Promote process_type_t to an enum class 2019-03-24 12:29:25 -07:00
ridiculousfish
96b8ac7013 Promote job_control_t to an enum class 2019-03-24 12:12:44 -07:00
Aaron Gyes
f92c2921d2 Remove mini() and maxi()
C++11 provides std::min/std::max which we're using all over,
obviating the need for our own templates for this.

util.h now only provides two things: get_time and wcsfilecmp.
This commit removes everything that includes it which doesn't
use either; most because they no longer need mini or maxi from
it but some others were #including it unnecessarily.
2019-03-12 23:25:15 -07:00
Aaron Gyes
d5ac239f68 This commit changes wchar.h includes to cwchar, and uses std::
for everything it provides.
2019-03-12 15:09:36 -07:00
ridiculousfish
e11c3f352f Clean up handle_child_status
Now that we only call waitpid() on specific processes, we no longer need
to search to find the process returned by waitpid.
2019-03-03 11:47:32 -08:00
ridiculousfish
dac5d79059 Switch wait command to use topics
Prior to this fix, the wait command used waitpid() directly. Switch it to
calling process_mark_finished_children() along with the rest of the job
machinery. This centralizes the waitpid call to a single location.
2019-03-02 16:58:27 -08:00
ridiculousfish
dc27de8190 Rename reader_interrupted to reader_test_and_clear_interrupted 2019-03-02 15:17:00 -08:00
ridiculousfish
1a4bb50cd5 Combine status and pipestatus into statuses_t
In most places where we set one, we want to set both. Make this less
error-prone by combining them into a single type statuses_t.
2019-02-26 20:07:37 -08:00
Fabian Homborg
92b1f4df07 Include wait.h in proc.h, not proc.cpp
Should fix the build in FreeBSD - https://builds.sr.ht/~faho/job/33304.
2019-02-25 22:12:09 +01:00
zabereer
a5659132f6 Compilation error on gcc8.2.1 2019-02-25 20:19:52 +01:00
ridiculousfish
bb36274e6b Introduce proc_status_t
In fish we play fast and loose with status codes as set directly (e.g. on
failed redirections), vs status codes returned from waitpid(), versus the
value $status. Introduce a new value type proc_status_t to encapsulate
this logic.
2019-02-25 10:14:45 -08:00
ridiculousfish
2c3214cabd Make $pipestatus thread safe and other misc cleanup 2019-02-24 23:29:33 -08:00
zabereer
2c8abdf5cb add $pipestatus support 2019-02-24 21:46:52 -08:00
ridiculousfish
5134949a14 Factor color and terminal sequence outputting into outputter_t
Removes some static variables and simplifies the behavior of the tputs
singletone receiver.
2019-02-23 20:07:29 -08:00
ridiculousfish
ec65ba3427 Remove signal_block_t
Bravely removing more signal blocks, now that our signal handling is so
simple.
2019-02-23 13:48:16 -08:00