Commit graph

166 commits

Author SHA1 Message Date
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
ridiculousfish
0ff4046b8c Remove signal blocks from terminal_return_from_job
There's nothing justifying having these here.
2019-02-23 13:45:26 -08:00
ridiculousfish
f1b208997c Cleanup events
Prior to this fix, an "event" was used as both a predicate on which events
to match, and also as the event itself. Re-express these concepts
distinctly: an event is something that happened, an event_handler is the
predicate and name of the function to execute.
2019-02-23 13:33:12 -08:00
ridiculousfish
780b53ba73 Convert event_type_t to an enum class 2019-02-23 13:17:28 -08:00
ridiculousfish
1b8ddacfed Reimplement signal handling event machinery
Prior to this fix, fish had a signal_list_t that accumulated signals.
Signals were added to an array of integers, with an overflow flag.
The event machinery would attempt to atomically "swap in" the other list.

After this fix, there is a single list of pending signal events, as an array
of atomic booleans. The signal handler sets the boolean corresponding to its
signal.
2019-02-23 13:03:33 -08:00
ridiculousfish
da04f757f9 Minor cleanup to process_clean_after_marking 2019-02-22 22:50:52 -08:00
ridiculousfish
4a2fd443b2 Use internal processes to write builtin output
This uses the new internal process mechanism to write output for builtins.
After this the only reason fish ever forks is to execute external processes.
2019-02-17 13:08:00 -08:00
ridiculousfish
ada8ea954e Use "internal" processes to write buffered output
This introduces "internal processes" which are backed by a pthread instead
of a normal process. Internal processes are reaped using the topic
machinery, plugging in neatly alongside the sigchld topic; this means that
process_mark_finished_children() can wait for internal and external
processes simultaneously.

Initially internal processes replace the forked process that fish uses to
write out the output of blocks and functions.
2019-02-17 13:05:20 -08:00
ridiculousfish
ebe2dc2766 Processes to record topic generations before execution
The sigchld generation expresses the idea that, if we receive a sigchld
signal, the generation will be different than when we last recorded it. A
process cannot exit before it has launched, so check the generation count
before process launch. This is an optimization that reduces failing
waitpid calls.
2019-02-17 13:01:59 -08:00
ridiculousfish
a95bc849c5 Rewrite process_mark_finished_children using topics
This is a big change to how process reaping works, reimplenting it using
topics. The idea is to simplify the logic in
process_mark_finished_children around blocking, and also prepare for
"internal processes" which do not correspond to real processes.

Before this change, fish would use waitpid() to wait for a process group,
OR would individually poll processes if the process group leader was
unreapable.

After this change, fish no longer ever calls blocking waitpid(). Instead
fish uses the topic mechanism. For each reapable process, fish checks if
it has received a SIGCHLD since last poll; if not it waits until the next
SIGCHLD, and then polls them all.
2019-02-17 13:01:59 -08:00
Aaron Gyes
717718353e Remove unused macros 2019-02-12 16:10:18 -08:00
ridiculousfish
1701e2c558 Revert "add $pipestatus support"
This reverts commit ec290209db.
2019-02-10 13:46:58 -08:00
ridiculousfish
6da9d96241 Revert "Make $pipestatus thread safe and other misc cleanup"
This reverts commit 34c1f24716.
2019-02-10 13:46:49 -08:00
ridiculousfish
34c1f24716 Make $pipestatus thread safe and other misc cleanup 2019-02-10 13:43:02 -08:00
zabereer
ec290209db add $pipestatus support 2019-02-10 13:30:40 -08:00
ridiculousfish
d3fa58d621 Cleanup common.h
Remove a bunch of headers, simplify lots of code, migrate it into .cpp files.

Debug build time improves by ~3 seconds on my Mac.
2019-02-03 18:22:38 -08:00
ridiculousfish
6f682c8405 Fill io_buffer via background thread
This is a large change to how io_buffers are filled. The essential problem
comes about with code like (example):

    echo ( /bin/pwd )

The output of /bin/pwd must go to fish, not the tty. To arrange for this,
fish does the following:

1. Invoke pipe() to create a pipe.
2. Add an io_bufferfill_t redirection that owns the write end of the pipe.
3. After fork (or equiv), call dup2() to replace pwd's stdout with this  pipe.

Now when /bin/pwd writes, it will send output to the read end of the pipe.
But who reads it?

Prior to this fix, fish would do the following in a loop:

1. select() on the pipe with a 10 msec timeout
2. waitpid(WNOHANG) on the pwd proc

This polling is ugly and confusing and is what is replaced here.

With this new change, fish now reads from the pipe via a background thread:

1. Spawn a background pthread, which select()s on the pipe's read end with
a long (100 msec) timeout.
2. In the foreground, waitpid() (allowing hanging) on the pwd proc.

The big win here is a major simplification of job_t::continue_job() since
it no longer has to worry about filling buffers. This will make things
easier for concurrent execution.

It may not be obvious why the background thread still needs a poll (100 msec).
The answer is for cases where the write end of the fd escapes, in particular
background processes invoked inside command substitutions. psub is perhaps
the only important case of this (other shells typically just hang here).
2019-02-03 01:58:49 -08:00
ridiculousfish
178b72b2fd io_buffer_t becomes io_bufferfill_t
This makes some significant architectual improvements to io_pipe_t and
io_buffer_t.

Prior to this fix, io_buffer_t subclassed io_pipe_t. io_buffer_t is now
replaced with a class io_bufferfill_t, which does not subclass pipe.

io_pipe_t no longer remembers both fds. Instead it has an autoclose_fd_t,
so that the file descriptor ownership is clear.
2019-02-03 01:58:49 -08:00
ridiculousfish
6ba0d4c88a Revert io_bufferfill_t stack
This reverts commit 88dc484858 onwards.
2019-02-02 17:53:40 -08:00
ridiculousfish
9a4153f5e2 Fill io_buffer via background thread
This is a large change to how io_buffers are filled. The essential problem
comes about with code like (example):

    echo ( /bin/pwd )

The output of /bin/pwd must go to fish, not the tty. To arrange for this,
fish does the following:

1. Invoke pipe() to create a pipe.
2. Add an io_bufferfill_t redirection that owns the write end of the pipe.
3. After fork (or equiv), call dup2() to replace pwd's stdout with this  pipe.

Now when /bin/pwd writes, it will send output to the read end of the pipe.
But who reads it?

Prior to this fix, fish would do the following in a loop:

1. select() on the pipe with a 10 msec timeout
2. waitpid(WNOHANG) on the pwd proc

This polling is ugly and confusing and is what is replaced here.

With this new change, fish now reads from the pipe via a background thread:

1. Spawn a background pthread, which select()s on the pipe's read end with
a long (100 msec) timeout.
2. In the foreground, waitpid() (allowing hanging) on the pwd proc.

The big win here is a major simplification of job_t::continue_job() since
it no longer has to worry about filling buffers. This will make things
easier for concurrent execution.

It may not be obvious why the background thread still needs a poll (100 msec).
The answer is for cases where the write end of the fd escapes, in particular
background processes invoked inside command substitutions. psub is perhaps
the only important case of this (other shells typically just hang here).
2019-02-02 14:21:46 -08:00
ridiculousfish
78bbcef356 io_buffer_t becomes io_bufferfill_t
This makes some significant architectual improvements to io_pipe_t and
io_buffer_t.

Prior to this fix, io_buffer_t subclassed io_pipe_t. io_buffer_t is now
replaced with a class io_bufferfill_t, which does not subclass pipe.

io_pipe_t no longer remembers both fds. Instead it has an autoclose_fd_t,
so that the file descriptor ownership is clear.
2019-02-02 14:21:46 -08:00
Mahmoud Al-Qudsi
b54f1842d5 Switch to wait_by_process when waitpid without WNOHANG returns nothing
By exclusively waiting by pgrp, we can fail to reap processes that
change their own pgrp then either crash or close their fds. If we wind
up in a situation where `waitpid(2)` returns 0 or ECHLD even though we
did not specify `WNOHANG` but we still have unreaped child processes,
wait on them by pid.

Closes #5596.
2019-02-02 16:05:57 -06:00
ridiculousfish
a2aab24db7 Switch io_mode to an enum class 2019-01-31 12:12:46 -08:00
ridiculousfish
fec10830d3 Correctly handle exited jobs in process_mark_finished_children
This is effectively a pick of 2ebdcf82ee
and the subsequent fixup. However we also avoid setting WNOHANG unless
waitpid() indicates a process was reaped.

Fixes #5438
2019-01-20 15:07:08 -08:00
ridiculousfish
391af6af0c Introduce class environment_t
This will be used as a base class for variable snapshots and variable stacks.
2019-01-10 20:29:10 -08:00
ridiculousfish
895c2c4af0 Minor cleanup of parser interface 2019-01-10 20:29:10 -08:00
Mahmoud Al-Qudsi
d1913f0df0 Add workaround for Cygwin process management and job control bugs
We cannot wait by pgroup under Cygwin for unknown reasons. Always
wait on jobs by individual processes. See code for more information.
2019-01-02 00:14:07 -06:00
Mahmoud Al-Qudsi
803619b19b Convert some old-school int booleans to bool 2018-12-31 00:46:31 -06:00
Mahmoud Al-Qudsi
0337588979 fixup! Do not use up the ~WNOHANG waitpid call on completed processes 2018-12-30 21:44:14 -06:00
Mahmoud Al-Qudsi
2ebdcf82ee Do not use up the ~WNOHANG waitpid call on completed processes
This is the more correct fix for #5447, as regardless of which process
in the job (be it the first or the last) finished first, once we have
waited on a process without ~WNOHANG we don't do that for any subsequent
processes in the job.

It is also a waste to call into the kernel to wait for a process we
already know is completed!
2018-12-30 20:53:25 -06:00
Mahmoud Al-Qudsi
259cf02aac Wait on individual processes in a job in reverse order
This fixes #5438 by having fish block while waiting on a foreground job
via its individual processes by enumerating the procs in reverse order,
such that we hang waiting for the last job in the IO chain to terminate,
rather than the first.
2018-12-30 19:02:38 -06:00
Mahmoud Al-Qudsi
040d921fa1 Fix check for valid disowned pgids
The function `add_disowned_pgid` adds process *group* ids and not
process ids. It multiplies the value by negative 1 to indicate a wait
on a process group, so the original value must be positive.
2018-12-30 10:15:07 -06:00
Fabian Homborg
4a3ac6e91e Don't wait for disowned pgids if they are special
If a job is disowned that, for some reason, has a pgid that is special
to waitpid, like 0 (process with pgid of the calling process), -1 (any
process), or our actual pgid, that would lead to us waiting for too
many processes when we later try to reap the disowned processes (to
stop zombies from appearing).

And that means we'd snag away the processes we actually do want to
wait for, which would end with us in a waiting loop.

This is tough to reproduce, the easiest I've found was

    fish -ic 'sleep 5 &; disown; set -g __fish_git_prompt_showupstream auto; __fish_git_prompt'

in a git repo.

What we do is to not allow special pgids in the disowned_pids list.
That means we might leave a zombie around (though we probably wait on
0 somewhere), but that's preferable to infinitely looping.

See #5426.
2018-12-30 16:04:57 +01:00
Fabian Homborg
88f7d50633 Acquire terminal even if our pgroup is 0
`tcsetpgrp` still works.

[ci skip]

(This isn't tested)
2018-12-08 16:21:52 +01:00
Fabian Homborg
0a0060481f Guard against pgid == 0
This happens in firejail, and it means that we can't use it as an
argument to most pgid-taking functions.

E.g. `wait(0)` means to wait for the _current_ process group,
`tcsetpgrp(0)` doesn't work etc.

So we just stop doing this stuff and hope it works.

Fixes #5295.
2018-12-08 16:21:52 +01:00
Aaron Gyes
fe67cc4f6e Revert "Show how fish was executed, using argv[0] for program_name"
This reverts commit 1cb8b2a87b.

argv[0] has the full path in it for a user when he executes it
out of $PATH. This is really annoying in the title which uses $_.
2018-11-28 06:08:24 -08:00