Commit graph

109 commits

Author SHA1 Message Date
Johannes Altmanninger
25816627de Port redirection.cpp to Rust 2023-02-09 00:37:22 +01:00
ridiculousfish
d843b67d2d Initial Rust commit 2023-02-02 19:34:47 -07:00
Mahmoud Al-Qudsi
83636fa599 Silently handle fd_output_stream_t append errors in case of SIGINT
If EINTR caused by SIGINT is encountered while writing to the
`fd_output_stream_t` output fd, mark the output stream as errored and return
false to the caller but do not visibly complain.

Addressing the outstanding TODO notwithstanding, this is needed to avoid
littering the tty with spurious errors when the user hits Ctrl-C to abort a
long-running builtin's output (w/ the primary example being `history`).
2022-10-16 15:38:11 -05:00
Mahmoud Al-Qudsi
8e97fcb22c Make output_stream_t::append() fallible
Allow errors encountered by certain implementations of `output_stream_t` when
writing to the output sink to be bubbled back to the caller.
2022-10-16 15:38:11 -05:00
Fabian Boehm
5ada59996f Reduce write() calls for explicitly separated buffers
This can improve performance for `string split ""` for up to 1.8x.
2022-09-27 16:33:47 +02:00
ridiculousfish
5f4583b52d Revert "Re-implement macro to constexpr transition"
This reverts commit 3d8f98c395.

In addition to the issues mentioned on the GitHub page for this commit,
it also broke the CentOS 7 build.

Note one can locally test the CentOS 7 build via:

    ./docker/docker_run_tests.sh ./docker/centos7.Dockerfile
2022-09-20 11:58:37 -07:00
Mahmoud Al-Qudsi
3d8f98c395 Re-implement macro to constexpr transition
Be more careful with sign extension issues stemming from the differences in how
an untyped literal is promoted to an integer vs how a typed (and signed) `char`
is promoted to an integer.
2022-09-19 18:10:41 -05:00
Mahmoud Al-Qudsi
7c3e4a7ccb Revert "Convert constant macros to constexpr expressions"
This reverts commit e1626818f7.
2022-09-19 17:42:11 -05:00
Mahmoud Al-Qudsi
e1626818f7 Convert constant macros to constexpr expressions
Also convert some `const[expr] static xxx` to `const[expr] xxx` where it makes
sense to let the compiler deduce on its own whether or not to allocate storage
for a constant variable rather than imposing our view that it should have STATIC
storage set aside for it.

A few call sites were not making use of the `XXX_LEN` definitions and were
calling `strlen(XXX)` - these have been updated to use `const_strlen(XXX)`
instead.

I'm not sure if any toolchains will have raise any issues with these changes...
CI will tell!
2022-09-19 17:17:09 -05:00
Aaron Gyes
14d2a6d8ff IWYU-guided #include rejiggering.
Let's hope this doesn't causes build failures for e.g. musl: I just
know it's good on macOS and our Linux CI.

It's been a long time.

One fix this brings, is I discovered we #include assert.h or cassert
in a lot of places. If those ever happen to be in a file that doesn't
include common.h, or we are before common.h gets included, we're
unawaringly working with the system 'assert' macro again, which
may get disabled for debug builds or at least has different
behavior on crash. We undef 'assert' and redefine it in common.h.

Those were all eliminated, except in one catch-22 spot for
maybe.h: it can't include common.h. A fix might be to
make a fish_assert.h that *usually* common.h exports.
2022-08-20 23:55:18 -07:00
Fabian Boehm
a98301b021 Allow for EWOULDBLOCK instead of EAGAIN
Posix allows this as an alternative with the same semantics for read.

Found in conjunction with #9067.

Should be no functional difference on other systems.
2022-07-23 23:16:44 +02:00
ridiculousfish
1127d7d68f clang-format C++ files
No functional change (hopefully!)
2022-06-01 10:02:09 -07:00
Aaron Gyes
b514ec5fe6 append_narrow_buffer takes const reference 2022-04-07 09:25:16 -07:00
Johannes Altmanninger
745129e825 builtin string: don't print final newline if it's missing from stdin
A command like "printf nonewline | sed s/x/y/" does not print a
concluding newline, whereas "printf nnl | string replace x y" does.
This is an edge case -- usually the user input does have a newline at
the end -- but it seems still better for this command to just forward
the user's data.

Teach most string subcommands to check if stdin is missing the trailing
newline, and stop adding one in that case.
This does not apply when input is read from commandline arguments.

* Most subcommands stop adding the final newline, because they don't
  really care about newlines, so besides their normal processing,
  they just want to preserve user input. They are:
  * string collect
  * string escape/unescape
  * string join¹
  * string lower/upper
  * string pad
  * string replace
  * string repeat
  * string sub
  * string trim

* string match keeps adding the newline, following "grep". Additionally,
  for string match --regex, it's important to output capture groups
  separated by newlines, resulting in multiple output lines for an
  input line. So it is not obvious where to leave out the newline.

* string split/split0 keep adding the newline for the same reason --
  they are meant to output multiple elements for a single input line.

¹) string join0 is not changed because it already printed a trailing
   zero byte instead of the trailing newline. This is consistent
   with other tools like "find -print0".

Closes #3847
2021-11-27 19:11:24 +01:00
Fabian Homborg
8391f94081 Improve error for redirections to invalid paths
This finds the first broken component, to help people figure out where
they misspelt something.

E.g.

```
echo foo >/usr/lob/systemd/system/machines.target.wants/var-lib-machines.mount
```

will now show:

```
warning: Path '/usr/lob' does not exist
```

which would help with seeing that it should be "/usr/lib".
2021-11-20 17:44:05 +01:00
Rosen Penev
ffa3e0b4f4 convert const ref to value
clang-tidy wrongly sees an std::move to a const ref parameter and
believes it to be pointless. The copy constructor however is deleted.

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2021-08-20 01:16:24 +02:00
ridiculousfish
8abc8315de Remove some more ASSERT_IS_MAIN_THREADs
These aren't helping and are blocking testing of concurrent execution.
No functional change here.
2021-07-17 12:20:54 -07:00
ridiculousfish
8bed818039 Remove some main thread assertions that are not helping
This is to make experimenting with concurrent execution easier.
No functional change in this commit.
2021-07-15 10:49:27 -07:00
Fabian Homborg
3e473b9f37 io: Silence write error with EPIPE
With something like

```
history | head -n 1
```

this would error "write: Broken pipe", which is just annoying. There
is no *problem* here, `head` closes this on purpose.

Fixes #7924.
2021-04-13 10:38:17 +02:00
ridiculousfish
36ad116b34 Properly report errors when builtin output fails
This correctly sets $status when a builtin succeeds but its output fails;
for example if the output is redirected to a file and that write fails.

Fixes #7857
2021-04-03 16:11:25 -07:00
ridiculousfish
98b0ef532f io_buffer_t to store a promise, not a future, to satisfy TSan
io_buffer_t is a buffer that fills itself by reading from a file
descriptor (typically a pipe). When the file descriptor is widowed, the
operation completes, and it reports completion by marking a
`std::promise<void>`. The "main thread" waits for this by waiting on the
promise's future. However TSan was reporting that the future's destructor
races with its promise's wait method. It's not obvious if this is valid,
but we can fix it by keeping the promise alive until the io_buffer_t is
deallocated.

This fixes the TSan issues reported under
`complete_background_fillthread_and_take_buffer` for #7681 (but there
are other unresolved issues).
2021-02-06 13:28:01 -08:00
ridiculousfish
b5716e97cc Remove fd_set_t
Now that we no longer need to worry about pipes conflicting with
user-specified redirections, we can remove fd_set_t.
2021-02-05 18:14:50 -08:00
ridiculousfish
97f29b1f4d Pipe fds to move to the "high range"
This concerns how fish prevents its own fds from interfering with
user-defined fd redirections, like `echo hi >&5`. fish has historically
done this by tracking all user defined redirections when running a job,
and ensuring that pipes are not assigned the same fds. However this is
annoying to pass around - it means that we have to thread user-defined
redirections into pipe creation.

Take a page from zsh and just ensure that all pipes we create have fds in
the "high range," which here means at least 10. The primary way to do this
is via the F_DUPFD_CLOEXEC syscall, which also sets CLOEXEC, so we aren't
invoking additional syscalls in the common case. This will free us from
having to track which fds are in user-defined redirections.
2021-02-05 17:58:08 -08:00
ridiculousfish
6588cf35f4 Move autoclose_pipes_t from io.h to fds.h 2021-02-05 17:58:08 -08:00
ridiculousfish
97bde2f2bf Further refactoring of io_buffer_t
Previously we sometimes wanted to access an io_buffer_t to append to it
directly, but that's no longer true; all we really care about is its
separated_buffer_t. Make io_bufferfill_t::finish return the
separated_buffer directly, simplifying call sites. No user visible changes
expected here.
2021-02-04 17:14:46 -08:00
ridiculousfish
258149fe2e Improve locking discipline in io_buffer_t
Previously we had a lock that was taken in an ad-hoc manner. Switch to
using owning_lock.
2021-02-04 17:03:54 -08:00
ridiculousfish
8bcc8c1a36 Further cleanup of separated_buffer_t and io_buffer_t
Remove some clinging tendrils of life as a template object.
2021-02-04 16:43:47 -08:00
ridiculousfish
032467f338 separated_buffer_t to stop being a template
Now that we no longer construct wide separated buffers, it doesn't have
to be templatized.
2021-02-04 15:32:11 -08:00
ridiculousfish
7d494eab5c builtins to write to buffers directly
This concerns builtins writing to an io_buffer_t. io_buffer_t is how fish
captures output, especially in command substitutions:

    set STUFF (string upper stuff)

Recall that io_buffer_t fills itself by reading from an fd (typically
connected to stdout of the command). However if our command is a builtin,
then we can write to the buffer directly.

Prior to this change, when a builtin anticipated writing to an
io_buffer_t, it would first write into an internal buffer, and then after
the builtin was finished, we would copy it to the io_buffer_t. This was
because we didn't have a polymorphic receiver for builtin output: we
always buffered it and then directed it to the io_buffer_t or file
descriptor or stdout or whatever.

Now that we have polymorphpic io_streams_t, we can notice ahead of time
that the builtin output is destined for an internal buffer and have it
just write directly to that buffer. This saves a buffering step, which is
a nice simplification.
2021-02-04 15:21:32 -08:00
ridiculousfish
cd9a035f02 Add a string_output_stream_t to collect builtin output
This is used when creating a function; this breaks a dependency on the
more complicated buffered_output_stream_t to ease refactoring.
2021-02-04 14:12:14 -08:00
ridiculousfish
4faebf74e6 Remove 100 msec timeout from io_buffer_t
This removes the 100 msec timeout from io_buffer_t. We no longer need to
periodically wake up to check if a command substitution is finished,
because we get explicitly poked when that happens.
2021-01-07 12:07:06 -08:00
ridiculousfish
d5d09c993e io_buffer_t to explicitly poke its item when closing
io_buffer_t is used to buffer output from a command substitution, so we
can split it into arguments. Typically io_buffer_t reads from its pipe
until it gets EOF and then stops reading. However it may be that the
cmdsub ends but EOF is not delivered because the stdout of the cmdsub
escaped with a background process.

Prior to this change we would wake up every 100 msec (select timeout) to
check if the cmdsub is finished. However this 100 msec adds latency if a
background process is launched from e.g. fish_prompt.

Switch to the new poke() function. Now when the cmdsub is finished, it
pokes its item, which explicitly wakes it up. This removes the extra
latency.

Fixes #7559
2021-01-07 11:54:31 -08:00
ridiculousfish
fd08b660c0 Add a poke function to fd_monitor
In preparation for fixing #7559, add a function poke_item to fd_monitor.

fd_monitor has a list of file descriptors, and invokes a callback when an
fd becomes readable. With this change, we assign each item a unique ID and
return it when the item is added; the ID may then be used to invoke the
callback explicitly.

The idea is that we can stop reading from the pipe associated with the
cmdsub when the job is finished, even if the pipe is still open.
2021-01-07 11:51:04 -08:00
ridiculousfish
d1dab22691 Ensure we don't leak half of a pipe
It was possible though unlikely for make_autoclose_pipes to close only
one side of pipe, if it fails to find a new fd. This would result in an
fd leak. Ensure that doesn't happen.
2020-09-05 13:24:26 -07:00
ridiculousfish
bcfc54fdaa Do not buffer builtin output if avoidable
builtins output to stdout and stderr via io_streams_t. Prior to this fix, it
contained an output_stream_t which just wraps a buffer. So all builtin output
went to this buffer (except for eval).

Switch output_stream_t to become a new abstract class which can output to a
buffer, file descriptor, or nowhere. This allows for example `string` to stream
its output as it is produced, instead of buffering it.
2020-07-30 22:45:44 -07:00
Mahmoud Al-Qudsi
f4ae69a905 fixup! Recover from bad redirections in the middle of a job pipeline
Fix inadvertent early abort (thanks, nested switch-in-for-loop!) that
led to subsequent shell input being broken.
2020-05-30 10:37:46 -05:00
Mahmoud Al-Qudsi
bc756a981e Recover from bad redirections in the middle of a job pipeline
Currently fish aborts execution mid-pipeline if a file redirection
failed, which can leave the shell in a broken state (job abandoned after
giving control of the terminal to an already-executed job in the
pipeline).

This patch replaces a failed fd with a closed fd and continues execution
if the affected process wasn't the first in the pipeline.

While this is a hack to address the regression behind fish-shell/#7038
introduced in d62576c, it can also be argued that this behavior is
actually more correct... right?

Closes #7038.
2020-05-30 00:27:11 -05:00
Rosen Penev
0668513138 Change C casts to C++ ones
Some were kept for compatibility.

Found with -Wold-style-cast

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2020-05-01 13:30:56 -07:00
ridiculousfish
a1f1b9c2d9 builtin_eval to direct output to its iostreams
Prior to this fix, builtin_eval would direct output to the io_chain of the
job. The problem is with pipes: `builtin_eval` might happily attempt to
write unlimited output to the write end of a pipe, but the corresponding
reading process has not yet been launched. This results in deadlock.

The fix is to buffer all the output from `builtin_eval`. This is not fun
but the best that can be done until we have real concurrent processes.

Fixes #6806
2020-04-26 11:05:50 -07:00
ridiculousfish
feb40f0cd6 Make io_file_t::print more useful 2020-04-25 20:25:28 -07:00
Rosen Penev
220f0a132d [clang-tidy] use auto when casting
Found with modernize-use-auto

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2020-04-05 10:13:13 +02:00
ridiculousfish
a765026c4c Adopt fd_monitor in bufferfill
This switches bufferfills from using an exclusively-owned thread, to
sharing an fd_monitor. This allows multiple bufferfills to all use the same
thread.
2020-02-05 12:05:39 -08:00
Fabian Homborg
3bb15defbb
Replace debug() with flog
PR #6511 

Flog has the advantage of having *categories*, not severities, so it'll be easier to get output for a certain subsystem now.
2020-01-26 14:13:17 +01:00
ridiculousfish
4f205f38b4 Clean up a few bits about discarding buffers
We weren't properly propagating the 'discarded' stuff from output
streams to buffers. Fix that.
2020-01-24 16:08:56 -08:00
Fabian Homborg
a48926dee5 Add and use "should_flog" macro
Useful to figure out if a flog category is enabled.

We only use it in one place, but it seems like the sort of thing that
should exist.
2020-01-19 14:55:08 +01:00
Fabian Homborg
024e03ab1e Replace debug(1) with FLOGF(warning) 2020-01-19 14:22:39 +01:00
ridiculousfish
c14d54032f Add a cant_wait parameter to iothread_perform
Sometimes we must spawn a new thread, to avoid the risk of deadlock.
Ensure we always spawn a thread in those cases. In particular this
includes the fillthread.
2020-01-18 11:51:13 -08:00
Fabian Homborg
033a832687
Merge pull request #6447 from neheb/clang2
Several more small clang-tidy cleanups
2019-12-31 18:47:24 +01:00
ridiculousfish
c963442999 Collapse io_data switch statements
Now that each io_data knows its source and target fd, we don't need to switch
on its types any more.
2019-12-29 15:51:22 -08:00
ridiculousfish
0af5608ce8 io_data_t to store the source_fd directly
Now that all io_data_ts know their source fd, just store it directly in
the base class. This will simplify some uses of io_data_t.
2019-12-29 15:14:08 -08:00