- New libuv/pty process abstraction with simplified API and no globals.
- Remove nvim/os/job*. Jobs are now a concept that apply only to programs
spawned by vimscript job* functions.
- Refactor shell.c/channel.c to use the new module, which brings a number of
advantages:
- Simplified API, less code
- No slots in the user job table are used
- Not possible to acidentally receive data from vimscript
- Implement job table in eval.c, which is now a hash table with unilimited job
slots and unique job ids.
- Simplify RStream/WStream API and make it more consistent with libuv.
- Move into the event loop layer(event subdirectory)
- Remove uv_helpers module.
- Simplify job/process internal modules/API.
- Unify RStream and WStream into a single structure. This is necessary because
libuv streams can be readable and writable at the same time(and because the
uv_helpers.c hack to associate multiple streams with libuv handle was removed)
- Make struct definition public, allowing more flexible/simple memory
management by users of the module.
- Adapt channel/job modules to cope with the changes.
- Add event loop abstraction module under src/nvim/event. The
src/nvim/event/loop module replaces src/nvim/os/event
- Remove direct dependency on libuv signal/timer API and use the new abstraction
instead.
- Replace all references to uv_default_loop() by &loop.uv, a new global variable
that wraps libuv main event loop but allows the event loop functions to be
reused in other contexts.
Extract the RBuffer class from rstream.c and reimplement it as a ring buffer,
a more efficient version that doesn't need to relocate memory.
The old rbuffer_read/rbuffer_write interfaces are kept for simple
reading/writing, and the RBUFFER_UNTIL_{FULL,EMPTY} macros are introduced to
hide wrapping logic when more control is required(such as passing the buffer
pointer to a library function that writes directly to the pointer)
Also add a basic infrastructure for writing helper C files that are only
compiled in the unit test library, and use this to write unit tests for RBuffer
which contains some macros that can't be accessed directly by luajit.
Helped-by: oni-link <knil.ino@gmail.com>
Reviewed-by: oni-link <knil.ino@gmail.com>
Reviewed-by: Scott Prager <splinterofchaos@gmail.com>
Reviewed-by: Justin M. Keyes <justinkz@gmail.com>
Reviewed-by: Michael Reed <m.reed@mykolab.com>
suspicious_sizeof: Passing argument 168UL /* sizeof (ufunc_T) */ * todo
to function xmalloc and then casting the return value to ufunc_T ** is
suspicious.
For any of these functions, if {cmd} is a string, execute
"&shell &shellcmdflag '{cmd}'", or simply {cmd} if it's a list.
In termopen(), if the 'name' option is not supplied, try to guess using
'{cmd}' (string) or {cmd}[0] (list). Simplify ex_terminal to use the
string form of termopen().
termopen: get name from argument
Convert list_to_argv to tv_to_argv.
Helped-by: Björn Linse <@bfredl>
Helped-by: oni-link <knil.ino@gmail.com>
Helped-by: Thiago de Arruda <@tarruda>
Old behaviour: termopen('cmd') would run `&shell &shcf "cmd"`, which
caused the functional tests to fail on some systems due to the process
not "owning" the terminal. Also, it is inconsistent with jobstart().
Modify termopen() so that &shell is not invoked, but maintain the old
behaviour with :terminal. Factor the common code for building the
argument vector from jobstart() and modify the functional tests to call
termopen() instead of :terminal (fixes#2354).
Also:
* Add a 'name' option for termopen() so that `:terminal {cmd}` produces
a buffer named "term//{cwd}/{cmd}" and termopen() users can customize
the name.
* Update the documentation.
* Add functional tests for `:terminal` sinse its behaviour now differs
from termopen(). Add "test/functional/fixtures/shell-test.c" and move
"test/functional/job/tty-test.c" there, too.
Helped-by: Justin M. Keyes <@justinmk>
Without the casts*, the compiler rightly warns about the os_getenv
losing the qualifier. This refactor adds a variable to manage this
properly, and renames the original variables to increase clarity.
This spares some work and also prevents list_join() from calling ga_init()
with a growsize of 0 which would lead to the nvimlog being littered with:
[warning @ ga_set_growsize:64] 17675 - trying to set an invalid ga_growsize: 0
Also in Vim 7.4.702
5216f767d4
Implement functions for spawning, destroying, and listing active
servers, and add server_address_list() to msgpack_rpc/server.c for the
serverlist() vimL function.
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.
Klib pools were used to improve allocation efficiency for some small objects,
but it is not a thread-safe approach. Thread safety in allocations will be
required for implementing #2371).
- Properly save job event deferring state for recursive calls
- Disable breakcheck while running. Breakcheck can invoke job callbacks
in unexpected places.
Regarding |script-here|: despite being a language agnostic piece of
advice, it was in `if_perl.txt`. Regardless, we now only have one
support for one legacy plugin interface, so put it in `if_pyth.txt`
Problem : Use-after-free @ 15081.
Diagnostic : Multithreading issue.
Rationale : `get_dict_callback` can return NULL on two different
cases: 1) when the dict doesn't contain the given key;
this case is not considered an error. 2) when the key
exists but there's some problem with its value; this is
considered an error.
Then, code calling `get_dict_callback` in
`common_job_callbacks`, as well as code calling
`common_job_callbacks`, uses `did_emsg` to distinguish
between error/non-error cases.
Suggested error path presumes an error condition within
`common_job_callbacks`, with `did_emsg` being true, but
then being false just after returning to calling code in
`f_termopen`.
That, clearly, could only happen if another thread run in
between those points.
Resolution : Refactor `get_dict_callback` and `common_job_callbacks`, so
that they clearly distinguish between error/non-error
situations, without recurring to globals.
Problem : Dereference of null pointer @ 10812.
Diagnostic : False positive.
Rationale : `args->lv_first` can't be NULL, as we have just stated
above that that there's at least one item.
Resolution : Assert.
Due to the way vimscript garbage collection handles cyclic references, its not
possible to rely on incrementing `dv_refcount` to prevent dicts still used
internally from being collected: If a object with dv_refcount > 0 isn't
reachable by vimscript code, it will be freed when `garbage_collect()` is
called. Add the `internal_refcount` field to prevent this.
Use os_scandir().
fname_case() only gets used when `defined(USE_FNAME_CASE)` (on operating
systems with case-insensitive file systems), but may be useful in other
contexts, so move it to path.c. (See the TODO.)
Remove the unused parameter, len.