If stdin is non-blocking, many tools (e.g. cat(1), read(1)) which assume
that stdin is blocking, will break in odd ways:
read: read error: 0: Resource temporarily unavailable
cat: -: Resource temporarily unavailable
rm: error closing file
libuv puts stdin in nonblocking mode, and leaves it that way at exit
(this is apparently by design). So, before this commit, this always
works (because the shell clobbers O_NONBLOCK):
$ nvim --cmd q
$ read
...but these forms do _not_ work:
$ nvim --cmd q && read
$ echo foo | nvim --cmd q && read
$ nvim && read
After this commit, all of the above forms work.
Background:
437b4397b9 (diff-41f4d294430cd8c36538999d62681ae2)https://github.com/fish-shell/fish-shell/issues/176#issuecomment-15800155
- bash (and other shells: zsh, tcsh, fish), upon returning to the
foreground, always sets fd 0 back to blocking mode. This practice only
applies to stdin, _not_ stdout or stderr (in practice these fds may be
affected anyways).
- bash/zsh/tcsh/fish do _not_ restore the non-blocking status of stdin
when _resuming a job_.
- We do _not_ save/restore the original flags visible to
fcntl(F_[SG]ETFL), because (counterintuitively) that isn't expected.
Helped-by: oni-link <knil.ino@gmail.com>
Closes#2086Closes#2377
---
Note: The following implementation of stream_set_blocking() was
discarded, because it resulted in a failed libuv assertion[1]:
int stream_set_blocking(int fd, bool blocking)
{
uv_pipe_t stream;
uv_pipe_init(uv_default_loop(), &stream, 0);
uv_pipe_open(&stream, fd);
int retval = uv_stream_set_blocking((uv_stream_t *)&stream, blocking);
uv_close((uv_handle_t *)&stream, NULL);
return retval;
}
[1] .deps/build/src/libuv/src/unix/core.c:833: uv__io_stop: Assertion `loop->watchers[w->fd] == w' failed.
We already use wrappers for allocation, the new `xfree` function is the
equivalent for deallocation and provides a way to fully replace the malloc
implementation used by Neovim.
This commit pulls the some environment-variable handling functions out of
misc1.c and in to os/env.c. Previously submited as #1231, this is the start of
a patch series that does that work based on a more up-to-date master branch.
Major tasks accomplished:
- move functions and fix includes
- fix clint/clang analysis warnings
- correct documentation comments
Even though assuming nvim is busy most times is simpler, it has a problem: A lot
of unnecessary busy_start/busy_stop notifications are sent to the UI. That's
because in the majority of scenarios almost no time is spent between
`event_poll` calls.
This restores the normal behavior which is to call busy_start only when nvim is
going to perform some task that can take a significant amount of time. Also
improve the usage of buffering in the TUI when changing the cursor state.
Switching cursor off is only necessary in two occasions:
- When redrawing to avoid terminal flickering
- When the editor is busy
The first can now be handled by the TUI, so most calls to ui_cursor_off can be
removed from the core.
So, before this commit it was only necessary to switch the cursor off to notify
the user that nvim was running some long operation. Now the cursor_{on,off}
functions have been replaced by busy_{stop,start} which can be handled in a
UI-specific way(turning the cursor off or showing a busy indicator, for
example).
To make things even more simpler, nvim is always busy except when waiting for
user input or other asynchronous events: It automatically switches to a non-busy
state when the event loop is about to be entered for more than 100 milliseconds.
`ui_busy_start` can be called when its not desired to change the busy state in
the event loop (As its now done by functions that perform blocking shell
invocations).
- Removed term.c, term.h and term_defs.h
- Tests for T_* values were removed. screen.c was simplified as a
consequence(the best strategy for drawing is implemented in the UI layer)
- Redraw functions now call ui.c functions directly. Updates are flushed with
`ui_flush()`
- Removed all termcap options(they now return empty strings for compatibility)
- &term/&ttybuiltin options return a constant value(nvim)
- &t_Co is still available, but it mirrors t_colors directly
- Remove cursor tracking from screen.c and the `screen_start` function. Now the
UI is expected to maintain cursor state across any call, and reset it when
resized.
- Remove unused code
- Remove abstract_ui global, now it is always active
- Remove some terminal handling code
- Remove unused functions
- Remove HAVE_TGETENT/TERMINFO/TERMIOS/IOCTL #ifdefs
- Remove tgetent/terminfo from version.c
- Remove curses/terminfo dependencies
- Only start/stop termcap when starting/exiting the program
- msg_use_printf will return true if there are no attached UIs(
messages will be written to stdout)
- Remove `ex_winpos`(implement `:winpos` with `ex_ni`)
Regarding dict_lookup() in eval.c: both definitions are the same, the
only difference being the spacing between the indirection operator and
the indentation level.
Problem : getdigits() currently returns a long, but at most places,
return value is casted (unsafely) into an int. Making casts
safe would introduce a lot of fuss in the form of assertions
checking for limits.
Note : We cannot just change return type to int, because, at some
places, legitimate long values are used. For example, in
diff.c, for line numbers.
Solution : Introduce new functions:
- get_digits() : Gets an intmax_t from a string.
- get_int_digits() : Wrapper for ints.
- get_long_digits() : Wrapper for longs.
And replace getdigits() invocations by the appropiate
wrapper invocations.
Nvim now relies much less on setting terminal mode to cooked mode, remove most
calls to settmode, except for those that happen on startup or when suspending.
Eventually even those will be handled by the UI layer.
Also:
- Remove NO_CONSOLE_INPUT/NO_CONSULE preprocessor conditionals
- Remove ctrl_c_interrupts variable, check for mapped_ctrl_c directly in
process_interrupts()
- Move ui_inchar profiling to input_poll which is where Nvim blocks for input.
Though this module is relatively small it has very clear boundaries.
The last argument for extracting `tempfile` was the errors which I got
when I was writing unittests for it: `cimport './src/nvim/fileio.h'`
does not work for some reason.
- temp_count is uint32_t now instead of long because it supposed to be
at most 999999999 (comment on line 5227) temporary files. The most
probably it was a long for compatibility with systems where int is
16-bit.
- Use "nvim" as prefix for temp folder name instead of "v"
- Remove unused parameter from vim_tempname
I know it could be 0 sometimes. Running the tests with
`assert(gap->ga_growsize > 0)` in ga_grow() crashes nvim while running the
tests.
- Add a setter for ga_growsize that checks whether the value passed is >=1 (log
in case it's not)
- log when ga_grow() tries to use a ga_growsize that's not >=1
- use GA_EMPTY_INIT_VALUE is many places