aboutsummaryrefslogtreecommitdiff
path: root/src/os
diff options
context:
space:
mode:
authorEliseo Martínez <eliseomarmol@gmail.com>2014-05-12 02:25:17 +0200
committerEliseo Martínez <eliseomarmol@gmail.com>2014-05-15 20:46:01 +0200
commitda51dc9cf202772f60bd2da975dbef257bd9237c (patch)
tree5c16b93238a153f55634e9323077f30c8133970c /src/os
parentffe61e5ba1721340ca51d56bae3ddaca415fb5bc (diff)
downloadrneovim-da51dc9cf202772f60bd2da975dbef257bd9237c.tar.gz
rneovim-da51dc9cf202772f60bd2da975dbef257bd9237c.tar.bz2
rneovim-da51dc9cf202772f60bd2da975dbef257bd9237c.zip
Introduce nvim namespace: Move files.
Move files from src/ to src/nvim/. - src/nvim/ becomes the new root dir for nvim executable sources. - src/libnvim/ is planned to become root dir of the neovim library.
Diffstat (limited to 'src/os')
-rw-r--r--src/os/channel.c175
-rw-r--r--src/os/channel.h29
-rw-r--r--src/os/channel_defs.h8
-rw-r--r--src/os/env.c80
-rw-r--r--src/os/event.c148
-rw-r--r--src/os/event.h18
-rw-r--r--src/os/event_defs.h25
-rw-r--r--src/os/fs.c277
-rw-r--r--src/os/input.c195
-rw-r--r--src/os/input.h23
-rw-r--r--src/os/job.c370
-rw-r--r--src/os/job.h78
-rw-r--r--src/os/job_defs.h15
-rw-r--r--src/os/mem.c10
-rw-r--r--src/os/msgpack_rpc.c408
-rw-r--r--src/os/msgpack_rpc.h107
-rw-r--r--src/os/os.h146
-rw-r--r--src/os/rstream.c297
-rw-r--r--src/os/rstream.h82
-rw-r--r--src/os/rstream_defs.h16
-rw-r--r--src/os/server.c243
-rw-r--r--src/os/server.h30
-rw-r--r--src/os/server_defs.h7
-rw-r--r--src/os/shell.c465
-rw-r--r--src/os/shell.h45
-rw-r--r--src/os/signal.c163
-rw-r--r--src/os/signal.h13
-rw-r--r--src/os/time.c86
-rw-r--r--src/os/time.h35
-rw-r--r--src/os/users.c87
-rw-r--r--src/os/uv_helpers.c70
-rw-r--r--src/os/uv_helpers.h47
-rw-r--r--src/os/wstream.c117
-rw-r--r--src/os/wstream.h40
-rw-r--r--src/os/wstream_defs.h7
35 files changed, 0 insertions, 3962 deletions
diff --git a/src/os/channel.c b/src/os/channel.c
deleted file mode 100644
index 2427db2a14..0000000000
--- a/src/os/channel.c
+++ /dev/null
@@ -1,175 +0,0 @@
-#include <string.h>
-
-#include <uv.h>
-#include <msgpack.h>
-
-#include "lib/klist.h"
-#include "os/channel.h"
-#include "os/channel_defs.h"
-#include "os/rstream.h"
-#include "os/rstream_defs.h"
-#include "os/wstream.h"
-#include "os/wstream_defs.h"
-#include "os/job.h"
-#include "os/job_defs.h"
-#include "os/msgpack_rpc.h"
-#include "vim.h"
-#include "memory.h"
-
-typedef struct {
- ChannelProtocol protocol;
- bool is_job;
- union {
- struct {
- msgpack_unpacker *unpacker;
- msgpack_sbuffer *sbuffer;
- } msgpack;
- } proto;
- union {
- int job_id;
- struct {
- RStream *read;
- WStream *write;
- } streams;
- } data;
-} Channel;
-
-#define _destroy_channel(x)
-
-KLIST_INIT(Channel, Channel *, _destroy_channel)
-
-static klist_t(Channel) *channels = NULL;
-static void on_job_stdout(RStream *rstream, void *data, bool eof);
-static void on_job_stderr(RStream *rstream, void *data, bool eof);
-static void parse_msgpack(RStream *rstream, void *data, bool eof);
-
-void channel_init()
-{
- channels = kl_init(Channel);
-}
-
-void channel_teardown()
-{
- if (!channels) {
- return;
- }
-
- Channel *channel;
-
- while (kl_shift(Channel, channels, &channel) == 0) {
-
- switch (channel->protocol) {
- case kChannelProtocolMsgpack:
- msgpack_sbuffer_free(channel->proto.msgpack.sbuffer);
- msgpack_unpacker_free(channel->proto.msgpack.unpacker);
- break;
- default:
- abort();
- }
-
- if (channel->is_job) {
- job_stop(channel->data.job_id);
- } else {
- rstream_free(channel->data.streams.read);
- wstream_free(channel->data.streams.write);
- }
- }
-}
-
-void channel_from_job(char **argv, ChannelProtocol prot)
-{
- Channel *channel = xmalloc(sizeof(Channel));
- rstream_cb rcb = NULL;
-
- switch (prot) {
- case kChannelProtocolMsgpack:
- rcb = on_job_stdout;
- channel->proto.msgpack.unpacker =
- msgpack_unpacker_new(MSGPACK_UNPACKER_INIT_BUFFER_SIZE);
- channel->proto.msgpack.sbuffer = msgpack_sbuffer_new();
- break;
- default:
- abort();
- }
-
- channel->protocol = prot;
- channel->is_job = true;
- channel->data.job_id = job_start(argv, channel, rcb, on_job_stderr, NULL);
- *kl_pushp(Channel, channels) = channel;
-}
-
-void channel_from_stream(uv_stream_t *stream, ChannelProtocol prot)
-{
- Channel *channel = xmalloc(sizeof(Channel));
- rstream_cb rcb = NULL;
-
- switch (prot) {
- case kChannelProtocolMsgpack:
- rcb = parse_msgpack;
- channel->proto.msgpack.unpacker =
- msgpack_unpacker_new(MSGPACK_UNPACKER_INIT_BUFFER_SIZE);
- channel->proto.msgpack.sbuffer = msgpack_sbuffer_new();
- break;
- default:
- abort();
- }
-
- stream->data = NULL;
- channel->protocol = prot;
- channel->is_job = false;
- // read stream
- channel->data.streams.read = rstream_new(rcb, 1024, channel, true);
- rstream_set_stream(channel->data.streams.read, stream);
- rstream_start(channel->data.streams.read);
- // write stream
- channel->data.streams.write = wstream_new(1024 * 1024);
- wstream_set_stream(channel->data.streams.write, stream);
- // push to channel list
- *kl_pushp(Channel, channels) = channel;
-}
-
-static void on_job_stdout(RStream *rstream, void *data, bool eof)
-{
- Job *job = data;
- parse_msgpack(rstream, job_data(job), eof);
-}
-
-static void on_job_stderr(RStream *rstream, void *data, bool eof)
-{
- // TODO(tarruda): plugin error messages should be sent to the error buffer
-}
-
-static void parse_msgpack(RStream *rstream, void *data, bool eof)
-{
- msgpack_unpacked unpacked;
- Channel *channel = data;
- uint32_t count = rstream_available(rstream);
-
- // Feed the unpacker with data
- msgpack_unpacker_reserve_buffer(channel->proto.msgpack.unpacker, count);
- rstream_read(rstream,
- msgpack_unpacker_buffer(channel->proto.msgpack.unpacker),
- count);
- msgpack_unpacker_buffer_consumed(channel->proto.msgpack.unpacker, count);
-
- msgpack_unpacked_init(&unpacked);
-
- // Deserialize everything we can.
- while (msgpack_unpacker_next(channel->proto.msgpack.unpacker, &unpacked)) {
- // Each object is a new msgpack-rpc request and requires an empty response
- msgpack_packer response;
- msgpack_packer_init(&response,
- channel->proto.msgpack.sbuffer,
- msgpack_sbuffer_write);
- // Perform the call
- msgpack_rpc_call(&unpacked.data, &response);
- wstream_write(channel->data.streams.write,
- xmemdup(channel->proto.msgpack.sbuffer->data,
- channel->proto.msgpack.sbuffer->size),
- channel->proto.msgpack.sbuffer->size,
- true);
-
- // Clear the buffer for future calls
- msgpack_sbuffer_clear(channel->proto.msgpack.sbuffer);
- }
-}
diff --git a/src/os/channel.h b/src/os/channel.h
deleted file mode 100644
index c58e91a0e5..0000000000
--- a/src/os/channel.h
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef NEOVIM_OS_CHANNEL_H
-#define NEOVIM_OS_CHANNEL_H
-
-#include <uv.h>
-
-#include "os/channel_defs.h"
-
-/// Initializes the module
-void channel_init(void);
-
-/// Teardown the module
-void channel_teardown(void);
-
-/// Creates an API channel from a libuv stream representing a tcp or
-/// pipe/socket client connection
-///
-/// @param stream The established connection
-/// @param prot The rpc protocol used
-void channel_from_stream(uv_stream_t *stream, ChannelProtocol prot);
-
-/// Creates an API channel by starting a job and connecting to its
-/// stdin/stdout. stderr is forwarded to the editor error stream.
-///
-/// @param argv The argument vector for the process
-/// @param prot The rpc protocol used
-void channel_from_job(char **argv, ChannelProtocol prot);
-
-#endif // NEOVIM_OS_CHANNEL_H
-
diff --git a/src/os/channel_defs.h b/src/os/channel_defs.h
deleted file mode 100644
index 27ba103fbe..0000000000
--- a/src/os/channel_defs.h
+++ /dev/null
@@ -1,8 +0,0 @@
-#ifndef NEOVIM_OS_CHANNEL_DEFS_H
-#define NEOVIM_OS_CHANNEL_DEFS_H
-
-typedef enum {
- kChannelProtocolMsgpack
-} ChannelProtocol;
-
-#endif // NEOVIM_OS_CHANNEL_DEFS_H
diff --git a/src/os/env.c b/src/os/env.c
deleted file mode 100644
index e6cdb92ea8..0000000000
--- a/src/os/env.c
+++ /dev/null
@@ -1,80 +0,0 @@
-// env.c -- environment variable access
-
-#include <uv.h>
-
-#include "os/os.h"
-#include "misc2.h"
-
-#ifdef HAVE__NSGETENVIRON
-#include <crt_externs.h>
-#endif
-
-#ifdef HAVE_SYS_UTSNAME_H
-#include <sys/utsname.h>
-#endif
-
-const char *os_getenv(const char *name)
-{
- return getenv(name);
-}
-
-int os_setenv(const char *name, const char *value, int overwrite)
-{
- return setenv(name, value, overwrite);
-}
-
-char *os_getenvname_at_index(size_t index)
-{
-# if defined(HAVE__NSGETENVIRON)
- char **environ = *_NSGetEnviron();
-# elif !defined(__WIN32__)
- // Borland C++ 5.2 has this in a header file.
- extern char **environ;
-# endif
- // check if index is inside the environ array
- for (size_t i = 0; i < index; i++) {
- if (environ[i] == NULL) {
- return NULL;
- }
- }
- char *str = environ[index];
- if (str == NULL) {
- return NULL;
- }
- int namesize = 0;
- while (str[namesize] != '=' && str[namesize] != NUL) {
- namesize++;
- }
- char *name = (char *)vim_strnsave((char_u *)str, namesize);
- return name;
-}
-
-
-int64_t os_get_pid()
-{
-#ifdef _WIN32
- return (int64_t)GetCurrentProcessId();
-#else
- return (int64_t)getpid();
-#endif
-}
-
-void os_get_hostname(char *hostname, size_t len)
-{
-#ifdef HAVE_SYS_UTSNAME_H
- struct utsname vutsname;
-
- if (uname(&vutsname) < 0) {
- *hostname = '\0';
- } else {
- strncpy(hostname, vutsname.nodename, len - 1);
- hostname[len - 1] = '\0';
- }
-#else
- // TODO(unknown): Implement this for windows.
- // See the implementation used in vim:
- // https://code.google.com/p/vim/source/browse/src/os_win32.c?r=6b69d8dde19e32909f4ee3a6337e6a2ecfbb6f72#2899
- *hostname = '\0';
-#endif
-}
-
diff --git a/src/os/event.c b/src/os/event.c
deleted file mode 100644
index 2c25852778..0000000000
--- a/src/os/event.c
+++ /dev/null
@@ -1,148 +0,0 @@
-#include <stdint.h>
-#include <stdbool.h>
-#include <stdlib.h>
-
-#include <uv.h>
-
-#include "lib/klist.h"
-#include "os/event.h"
-#include "os/input.h"
-#include "os/channel.h"
-#include "os/server.h"
-#include "os/signal.h"
-#include "os/rstream.h"
-#include "os/job.h"
-#include "vim.h"
-#include "memory.h"
-#include "misc2.h"
-
-// event will be cleaned up after it gets processed
-#define _destroy_event(x) // do nothing
-KLIST_INIT(Event, Event, _destroy_event)
-
-static klist_t(Event) *event_queue;
-static uv_timer_t timer;
-static uv_prepare_t timer_prepare;
-static void timer_cb(uv_timer_t *handle);
-static void timer_prepare_cb(uv_prepare_t *);
-
-void event_init()
-{
- // Initialize the event queue
- event_queue = kl_init(Event);
- // Initialize input events
- input_init();
- // Timer to wake the event loop if a timeout argument is passed to
- // `event_poll`
- // Signals
- signal_init();
- // Jobs
- job_init();
- // Channels
- channel_init();
- // Servers
- server_init();
- uv_timer_init(uv_default_loop(), &timer);
- // This prepare handle that actually starts the timer
- uv_prepare_init(uv_default_loop(), &timer_prepare);
-}
-
-void event_teardown()
-{
- channel_teardown();
- job_teardown();
- server_teardown();
-}
-
-// Wait for some event
-bool event_poll(int32_t ms)
-{
- bool timed_out;
- uv_run_mode run_mode = UV_RUN_ONCE;
-
- if (input_ready()) {
- // If there's a pending input event to be consumed, do it now
- return true;
- }
-
- input_start();
- timed_out = false;
-
- if (ms > 0) {
- // Timeout passed as argument to the timer
- timer.data = &timed_out;
- // We only start the timer after the loop is running, for that we
- // use an prepare handle(pass the interval as data to it)
- timer_prepare.data = &ms;
- uv_prepare_start(&timer_prepare, timer_prepare_cb);
- } else if (ms == 0) {
- // For ms == 0, we need to do a non-blocking event poll by
- // setting the run mode to UV_RUN_NOWAIT.
- run_mode = UV_RUN_NOWAIT;
- }
-
- do {
- // Run one event loop iteration, blocking for events if run_mode is
- // UV_RUN_ONCE
- uv_run(uv_default_loop(), run_mode);
- } while (
- // Continue running if ...
- !input_ready() && // we have no input
- kl_empty(event_queue) && // no events are waiting to be processed
- run_mode != UV_RUN_NOWAIT && // ms != 0
- !timed_out); // we didn't get a timeout
-
- input_stop();
-
- if (ms > 0) {
- // Stop the timer
- uv_timer_stop(&timer);
- }
-
- return input_ready() || event_is_pending();
-}
-
-bool event_is_pending()
-{
- return !kl_empty(event_queue);
-}
-
-// Push an event to the queue
-void event_push(Event event)
-{
- *kl_pushp(Event, event_queue) = event;
-}
-
-// Runs the appropriate action for each queued event
-void event_process()
-{
- Event event;
-
- while (kl_shift(Event, event_queue, &event) == 0) {
- switch (event.type) {
- case kEventSignal:
- signal_handle(event);
- break;
- case kEventRStreamData:
- rstream_read_event(event);
- break;
- case kEventJobExit:
- job_exit_event(event);
- break;
- default:
- abort();
- }
- }
-}
-
-// Set a flag in the `event_poll` loop for signaling of a timeout
-static void timer_cb(uv_timer_t *handle)
-{
- *((bool *)handle->data) = true;
-}
-
-static void timer_prepare_cb(uv_prepare_t *handle)
-{
- uv_timer_start(&timer, timer_cb, *(uint32_t *)timer_prepare.data, 0);
- uv_prepare_stop(&timer_prepare);
-}
diff --git a/src/os/event.h b/src/os/event.h
deleted file mode 100644
index 5ddca46875..0000000000
--- a/src/os/event.h
+++ /dev/null
@@ -1,18 +0,0 @@
-#ifndef NEOVIM_OS_EVENT_H
-#define NEOVIM_OS_EVENT_H
-
-#include <stdint.h>
-#include <stdbool.h>
-
-#include "os/event_defs.h"
-#include "os/job_defs.h"
-
-void event_init(void);
-void event_teardown(void);
-bool event_poll(int32_t ms);
-bool event_is_pending(void);
-void event_push(Event event);
-void event_process(void);
-
-#endif // NEOVIM_OS_EVENT_H
-
diff --git a/src/os/event_defs.h b/src/os/event_defs.h
deleted file mode 100644
index 428ae50f3e..0000000000
--- a/src/os/event_defs.h
+++ /dev/null
@@ -1,25 +0,0 @@
-#ifndef NEOVIM_OS_EVENT_DEFS_H
-#define NEOVIM_OS_EVENT_DEFS_H
-
-#include "os/job_defs.h"
-#include "os/rstream_defs.h"
-
-typedef enum {
- kEventSignal,
- kEventRStreamData,
- kEventJobExit
-} EventType;
-
-typedef struct {
- EventType type;
- union {
- int signum;
- struct {
- RStream *ptr;
- bool eof;
- } rstream;
- Job *job;
- } data;
-} Event;
-
-#endif // NEOVIM_OS_EVENT_DEFS_H
diff --git a/src/os/fs.c b/src/os/fs.c
deleted file mode 100644
index 89eb4c8691..0000000000
--- a/src/os/fs.c
+++ /dev/null
@@ -1,277 +0,0 @@
-// fs.c -- filesystem access
-
-#include "os/os.h"
-#include "memory.h"
-#include "message.h"
-#include "misc1.h"
-#include "misc2.h"
-#include "path.h"
-
-static bool is_executable(const char_u *name);
-static bool is_executable_in_path(const char_u *name);
-
-// Many fs functions from libuv return that value on success.
-static const int kLibuvSuccess = 0;
-
-int os_chdir(const char *path) {
- if (p_verbose >= 5) {
- verbose_enter();
- smsg((char_u *)"chdir(%s)", path);
- verbose_leave();
- }
- return uv_chdir(path);
-}
-
-int os_dirname(char_u *buf, size_t len)
-{
- assert(buf && len);
-
- int errno;
- if ((errno = uv_cwd((char *)buf, &len)) != kLibuvSuccess) {
- vim_strncpy(buf, (char_u *)uv_strerror(errno), len - 1);
- return FAIL;
- }
- return OK;
-}
-
-bool os_isdir(const char_u *name)
-{
- int32_t mode = os_getperm(name);
- if (mode < 0) {
- return false;
- }
-
- if (!S_ISDIR(mode)) {
- return false;
- }
-
- return true;
-}
-
-bool os_can_exe(const char_u *name)
-{
- // If it's an absolute or relative path don't need to use $PATH.
- if (path_is_absolute_path(name) ||
- (name[0] == '.' && (name[1] == '/' ||
- (name[1] == '.' && name[2] == '/')))) {
- return is_executable(name);
- }
-
- return is_executable_in_path(name);
-}
-
-// Return true if "name" is an executable file, false if not or it doesn't
-// exist.
-static bool is_executable(const char_u *name)
-{
- int32_t mode = os_getperm(name);
-
- if (mode < 0) {
- return false;
- }
-
- if (S_ISREG(mode) && (S_IEXEC & mode)) {
- return true;
- }
-
- return false;
-}
-
-/// Check if a file is inside the $PATH and is executable.
-///
-/// @return `true` if `name` is an executable inside $PATH.
-static bool is_executable_in_path(const char_u *name)
-{
- const char *path = getenv("PATH");
- // PATH environment variable does not exist or is empty.
- if (path == NULL || *path == NUL) {
- return false;
- }
-
- int buf_len = STRLEN(name) + STRLEN(path) + 2;
- char_u *buf = alloc((unsigned)(buf_len));
-
- // Walk through all entries in $PATH to check if "name" exists there and
- // is an executable file.
- for (;; ) {
- const char *e = strchr(path, ':');
- if (e == NULL) {
- e = path + STRLEN(path);
- }
-
- // Glue together the given directory from $PATH with name and save into
- // buf.
- vim_strncpy(buf, (char_u *) path, e - path);
- append_path((char *) buf, (const char *) name, buf_len);
-
- if (is_executable(buf)) {
- // Found our executable. Free buf and return.
- free(buf);
- return true;
- }
-
- if (*e != ':') {
- // End of $PATH without finding any executable called name.
- free(buf);
- return false;
- }
-
- path = e + 1;
- }
-
- // We should never get to this point.
- assert(false);
- return false;
-}
-
-int os_stat(const char_u *name, uv_stat_t *statbuf)
-{
- uv_fs_t request;
- int result = uv_fs_stat(uv_default_loop(), &request,
- (const char *)name, NULL);
- *statbuf = request.statbuf;
- uv_fs_req_cleanup(&request);
-
- if (result == kLibuvSuccess) {
- return OK;
- }
-
- return FAIL;
-}
-
-int32_t os_getperm(const char_u *name)
-{
- uv_stat_t statbuf;
- if (os_stat(name, &statbuf) == FAIL) {
- return -1;
- } else {
- return (int32_t)statbuf.st_mode;
- }
-}
-
-int os_setperm(const char_u *name, int perm)
-{
- uv_fs_t request;
- int result = uv_fs_chmod(uv_default_loop(), &request,
- (const char*)name, perm, NULL);
- uv_fs_req_cleanup(&request);
-
- if (result == kLibuvSuccess) {
- return OK;
- }
-
- return FAIL;
-}
-
-bool os_file_exists(const char_u *name)
-{
- uv_stat_t statbuf;
- if (os_stat(name, &statbuf) == OK) {
- return true;
- }
-
- return false;
-}
-
-bool os_file_is_readonly(const char *name)
-{
- return access(name, W_OK) != 0;
-}
-
-int os_file_is_writable(const char *name)
-{
- if (access(name, W_OK) == 0) {
- if (os_isdir((char_u *)name)) {
- return 2;
- }
- return 1;
- }
- return 0;
-}
-
-bool os_get_file_size(const char *name, off_t *size)
-{
- uv_stat_t statbuf;
- if (os_stat((char_u *)name, &statbuf) == OK) {
- *size = statbuf.st_size;
- return true;
- }
- return false;
-}
-
-int os_rename(const char_u *path, const char_u *new_path)
-{
- uv_fs_t request;
- int result = uv_fs_rename(uv_default_loop(), &request,
- (const char *)path, (const char *)new_path, NULL);
- uv_fs_req_cleanup(&request);
-
- if (result == kLibuvSuccess) {
- return OK;
- }
-
- return FAIL;
-}
-
-int os_mkdir(const char *path, int32_t mode)
-{
- uv_fs_t request;
- int result = uv_fs_mkdir(uv_default_loop(), &request, path, mode, NULL);
- uv_fs_req_cleanup(&request);
- return result;
-}
-
-int os_rmdir(const char *path)
-{
- uv_fs_t request;
- int result = uv_fs_rmdir(uv_default_loop(), &request, path, NULL);
- uv_fs_req_cleanup(&request);
- return result;
-}
-
-int os_remove(const char *path)
-{
- uv_fs_t request;
- int result = uv_fs_unlink(uv_default_loop(), &request, path, NULL);
- uv_fs_req_cleanup(&request);
- return result;
-}
-
-bool os_get_file_info(const char *path, FileInfo *file_info)
-{
- if (os_stat((char_u *)path, &(file_info->stat)) == OK) {
- return true;
- }
- return false;
-}
-
-bool os_get_file_info_link(const char *path, FileInfo *file_info)
-{
- uv_fs_t request;
- int result = uv_fs_lstat(uv_default_loop(), &request, path, NULL);
- file_info->stat = request.statbuf;
- uv_fs_req_cleanup(&request);
- if (result == kLibuvSuccess) {
- return true;
- }
- return false;
-}
-
-bool os_get_file_info_fd(int file_descriptor, FileInfo *file_info)
-{
- uv_fs_t request;
- int result = uv_fs_fstat(uv_default_loop(), &request, file_descriptor, NULL);
- file_info->stat = request.statbuf;
- uv_fs_req_cleanup(&request);
- if (result == kLibuvSuccess) {
- return true;
- }
- return false;
-}
-
-bool os_file_info_id_equal(FileInfo *file_info_1, FileInfo *file_info_2)
-{
- return file_info_1->stat.st_ino == file_info_2->stat.st_ino
- && file_info_1->stat.st_dev == file_info_2->stat.st_dev;
-}
-
diff --git a/src/os/input.c b/src/os/input.c
deleted file mode 100644
index 4310edd514..0000000000
--- a/src/os/input.c
+++ /dev/null
@@ -1,195 +0,0 @@
-#include <string.h>
-#include <stdint.h>
-#include <stdbool.h>
-
-#include <uv.h>
-
-#include "os/input.h"
-#include "os/event.h"
-#include "os/rstream_defs.h"
-#include "os/rstream.h"
-#include "vim.h"
-#include "ui.h"
-#include "fileio.h"
-#include "getchar.h"
-#include "term.h"
-
-#define READ_BUFFER_SIZE 256
-
-typedef enum {
- kInputNone,
- kInputAvail,
- kInputEof
-} InbufPollResult;
-
-static RStream *read_stream;
-static bool eof = false, started_reading = false;
-
-static InbufPollResult inbuf_poll(int32_t ms);
-static void stderr_switch(void);
-static void read_cb(RStream *rstream, void *data, bool eof);
-// Helper function used to push bytes from the 'event' key sequence partially
-// between calls to os_inchar when maxlen < 3
-static int push_event_key(uint8_t *buf, int maxlen);
-
-void input_init()
-{
- read_stream = rstream_new(read_cb, READ_BUFFER_SIZE, NULL, false);
- rstream_set_file(read_stream, read_cmd_fd);
-}
-
-// Check if there's pending input
-bool input_ready()
-{
- return rstream_available(read_stream) > 0 || eof;
-}
-
-// Listen for input
-void input_start()
-{
- rstream_start(read_stream);
-}
-
-// Stop listening for input
-void input_stop()
-{
- rstream_stop(read_stream);
-}
-
-// Copies (at most `count`) of was read from `read_cmd_fd` into `buf`
-uint32_t input_read(char *buf, uint32_t count)
-{
- return rstream_read(read_stream, buf, count);
-}
-
-
-// Low level input function.
-int os_inchar(uint8_t *buf, int maxlen, int32_t ms, int tb_change_cnt)
-{
- InbufPollResult result;
-
- if (event_is_pending()) {
- // Return pending event bytes
- return push_event_key(buf, maxlen);
- }
-
- if (ms >= 0) {
- if ((result = inbuf_poll(ms)) == kInputNone) {
- return 0;
- }
- } else {
- if ((result = inbuf_poll(p_ut)) == kInputNone) {
- if (trigger_cursorhold() && maxlen >= 3
- && !typebuf_changed(tb_change_cnt)) {
- buf[0] = K_SPECIAL;
- buf[1] = KS_EXTRA;
- buf[2] = KE_CURSORHOLD;
- return 3;
- }
-
- before_blocking();
- result = inbuf_poll(-1);
- }
- }
-
- // If there are pending events, return the keys directly
- if (event_is_pending()) {
- return push_event_key(buf, maxlen);
- }
-
- // If input was put directly in typeahead buffer bail out here.
- if (typebuf_changed(tb_change_cnt)) {
- return 0;
- }
-
- if (result == kInputEof) {
- read_error_exit();
- return 0;
- }
-
- return read_from_input_buf(buf, (int64_t)maxlen);
-}
-
-// Check if a character is available for reading
-bool os_char_avail()
-{
- return inbuf_poll(0) == kInputAvail;
-}
-
-// Check for CTRL-C typed by reading all available characters.
-// In cooked mode we should get SIGINT, no need to check.
-void os_breakcheck()
-{
- if (curr_tmode == TMODE_RAW && event_poll(0))
- fill_input_buf(false);
-}
-
-bool os_isatty(int fd)
-{
- return uv_guess_handle(fd) == UV_TTY;
-}
-
-// This is a replacement for the old `WaitForChar` function in os_unix.c
-static InbufPollResult inbuf_poll(int32_t ms)
-{
- if (input_available()) {
- return kInputAvail;
- }
-
- if (event_poll(ms)) {
- return eof && rstream_available(read_stream) == 0 ?
- kInputEof :
- kInputAvail;
- }
-
- return kInputNone;
-}
-
-static void stderr_switch()
-{
- int mode = cur_tmode;
- // We probably set the wrong file descriptor to raw mode. Switch back to
- // cooked mode
- settmode(TMODE_COOK);
- // Stop the idle handle
- rstream_stop(read_stream);
- // Use stderr for stdin, also works for shell commands.
- read_cmd_fd = 2;
- // Initialize and start the input stream
- rstream_set_file(read_stream, read_cmd_fd);
- rstream_start(read_stream);
- // Set the mode back to what it was
- settmode(mode);
-}
-
-static void read_cb(RStream *rstream, void *data, bool at_eof)
-{
- if (at_eof) {
- if (!started_reading
- && rstream_is_regular_file(rstream)
- && os_isatty(STDERR_FILENO)) {
- // Read error. Since stderr is a tty we switch to reading from it. This
- // is for handling for cases like "foo | xargs vim" because xargs
- // redirects stdin from /dev/null. Previously, this was done in ui.c
- stderr_switch();
- } else {
- eof = true;
- }
- }
-
- started_reading = true;
-}
-
-static int push_event_key(uint8_t *buf, int maxlen)
-{
- static const uint8_t key[3] = { K_SPECIAL, KS_EXTRA, KE_EVENT };
- static int key_idx = 0;
- int buf_idx = 0;
-
- do {
- buf[buf_idx++] = key[key_idx++];
- key_idx %= 3;
- } while (key_idx > 0 && buf_idx < maxlen);
-
- return buf_idx;
-}
diff --git a/src/os/input.h b/src/os/input.h
deleted file mode 100644
index 9ffd50fd3f..0000000000
--- a/src/os/input.h
+++ /dev/null
@@ -1,23 +0,0 @@
-#ifndef NEOVIM_OS_INPUT_H
-#define NEOVIM_OS_INPUT_H
-
-#include <stdint.h>
-#include <stdbool.h>
-
-void input_init(void);
-bool input_ready(void);
-void input_start(void);
-void input_stop(void);
-uint32_t input_read(char *buf, uint32_t count);
-int os_inchar(uint8_t *, int, int32_t, int);
-bool os_char_avail(void);
-void os_breakcheck(void);
-
-/// Test whether a file descriptor refers to a terminal.
-///
-/// @param fd File descriptor.
-/// @return `true` if file descriptor refers to a terminal.
-bool os_isatty(int fd);
-
-#endif // NEOVIM_OS_INPUT_H
-
diff --git a/src/os/job.c b/src/os/job.c
deleted file mode 100644
index 7940338b70..0000000000
--- a/src/os/job.c
+++ /dev/null
@@ -1,370 +0,0 @@
-#include <stdint.h>
-#include <stdbool.h>
-
-#include <uv.h>
-
-#include "os/uv_helpers.h"
-#include "os/job.h"
-#include "os/job_defs.h"
-#include "os/rstream.h"
-#include "os/rstream_defs.h"
-#include "os/wstream.h"
-#include "os/wstream_defs.h"
-#include "os/event.h"
-#include "os/event_defs.h"
-#include "os/time.h"
-#include "os/shell.h"
-#include "vim.h"
-#include "memory.h"
-#include "term.h"
-
-#define EXIT_TIMEOUT 25
-#define MAX_RUNNING_JOBS 100
-#define JOB_BUFFER_SIZE 1024
-#define JOB_WRITE_MAXMEM 1024 * 1024
-
-struct job {
- // Job id the index in the job table plus one.
- int id;
- // Number of polls after a SIGTERM that will trigger a SIGKILL
- int exit_timeout;
- // exit_cb may be called while there's still pending data from stdout/stderr.
- // We use this reference count to ensure the JobExit event is only emitted
- // when stdout/stderr are drained
- int pending_refs;
- // Same as above, but for freeing the job memory which contains
- // libuv handles. Only after all are closed the job can be safely freed.
- int pending_closes;
- // If the job was already stopped
- bool stopped;
- // Data associated with the job
- void *data;
- // Callbacks
- job_exit_cb exit_cb;
- rstream_cb stdout_cb, stderr_cb;
- // Readable streams(std{out,err})
- RStream *out, *err;
- // Writable stream(stdin)
- WStream *in;
- // Structures for process spawning/management used by libuv
- uv_process_t proc;
- uv_process_options_t proc_opts;
- uv_stdio_container_t stdio[3];
- uv_pipe_t proc_stdin, proc_stdout, proc_stderr;
-};
-
-static Job *table[MAX_RUNNING_JOBS] = {NULL};
-static uint32_t job_count = 0;
-static uv_prepare_t job_prepare;
-
-// Some helpers shared in this module
-static bool is_alive(Job *job);
-static Job * find_job(int id);
-static void free_job(Job *job);
-
-// Callbacks for libuv
-static void job_prepare_cb(uv_prepare_t *handle);
-static void read_cb(RStream *rstream, void *data, bool eof);
-static void exit_cb(uv_process_t *proc, int64_t status, int term_signal);
-static void close_cb(uv_handle_t *handle);
-static void emit_exit_event(Job *job);
-
-void job_init()
-{
- uv_disable_stdio_inheritance();
- uv_prepare_init(uv_default_loop(), &job_prepare);
-}
-
-void job_teardown()
-{
- // 20 tries will give processes about 1 sec to exit cleanly
- uint32_t remaining_tries = 20;
- bool all_dead = true;
- int i;
- Job *job;
-
- // Politely ask each job to terminate
- for (i = 0; i < MAX_RUNNING_JOBS; i++) {
- if ((job = table[i]) != NULL) {
- all_dead = false;
- uv_process_kill(&job->proc, SIGTERM);
- }
- }
-
- if (all_dead) {
- return;
- }
-
- os_delay(10, 0);
- // Right now any exited process are zombies waiting for us to acknowledge
- // their status with `wait` or handling SIGCHLD. libuv does that
- // automatically (and then calls `exit_cb`) but we have to give it a chance
- // by running the loop one more time
- uv_run(uv_default_loop(), UV_RUN_NOWAIT);
-
- // Prepare to start shooting
- for (i = 0; i < MAX_RUNNING_JOBS; i++) {
- if ((job = table[i]) == NULL) {
- continue;
- }
-
- // Still alive
- while (is_alive(job) && remaining_tries--) {
- os_delay(50, 0);
- // Acknowledge child exits
- uv_run(uv_default_loop(), UV_RUN_NOWAIT);
- }
-
- if (is_alive(job)) {
- uv_process_kill(&job->proc, SIGKILL);
- }
- }
-}
-
-int job_start(char **argv,
- void *data,
- rstream_cb stdout_cb,
- rstream_cb stderr_cb,
- job_exit_cb job_exit_cb)
-{
- int i;
- Job *job;
-
- // Search for a free slot in the table
- for (i = 0; i < MAX_RUNNING_JOBS; i++) {
- if (table[i] == NULL) {
- break;
- }
- }
-
- if (i == MAX_RUNNING_JOBS) {
- // No free slots
- return 0;
- }
-
- job = xmalloc(sizeof(Job));
- // Initialize
- job->id = i + 1;
- job->pending_refs = 3;
- job->pending_closes = 4;
- job->data = data;
- job->stdout_cb = stdout_cb;
- job->stderr_cb = stderr_cb;
- job->exit_cb = job_exit_cb;
- job->stopped = false;
- job->exit_timeout = EXIT_TIMEOUT;
- job->proc_opts.file = argv[0];
- job->proc_opts.args = argv;
- job->proc_opts.stdio = job->stdio;
- job->proc_opts.stdio_count = 3;
- job->proc_opts.flags = UV_PROCESS_WINDOWS_HIDE;
- job->proc_opts.exit_cb = exit_cb;
- job->proc_opts.cwd = NULL;
- job->proc_opts.env = NULL;
- job->proc.data = NULL;
- job->proc_stdin.data = NULL;
- job->proc_stdout.data = NULL;
- job->proc_stderr.data = NULL;
-
- // Initialize the job std{in,out,err}
- uv_pipe_init(uv_default_loop(), &job->proc_stdin, 0);
- job->stdio[0].flags = UV_CREATE_PIPE | UV_READABLE_PIPE;
- job->stdio[0].data.stream = (uv_stream_t *)&job->proc_stdin;
-
- uv_pipe_init(uv_default_loop(), &job->proc_stdout, 0);
- job->stdio[1].flags = UV_CREATE_PIPE | UV_WRITABLE_PIPE;
- job->stdio[1].data.stream = (uv_stream_t *)&job->proc_stdout;
-
- uv_pipe_init(uv_default_loop(), &job->proc_stderr, 0);
- job->stdio[2].flags = UV_CREATE_PIPE | UV_WRITABLE_PIPE;
- job->stdio[2].data.stream = (uv_stream_t *)&job->proc_stderr;
-
- // Spawn the job
- if (uv_spawn(uv_default_loop(), &job->proc, &job->proc_opts) != 0) {
- free_job(job);
- return -1;
- }
-
- // Give all handles a reference to the job
- handle_set_job((uv_handle_t *)&job->proc, job);
- handle_set_job((uv_handle_t *)&job->proc_stdin, job);
- handle_set_job((uv_handle_t *)&job->proc_stdout, job);
- handle_set_job((uv_handle_t *)&job->proc_stderr, job);
-
- job->in = wstream_new(JOB_WRITE_MAXMEM);
- wstream_set_stream(job->in, (uv_stream_t *)&job->proc_stdin);
- // Start the readable streams
- job->out = rstream_new(read_cb, JOB_BUFFER_SIZE, job, true);
- job->err = rstream_new(read_cb, JOB_BUFFER_SIZE, job, true);
- rstream_set_stream(job->out, (uv_stream_t *)&job->proc_stdout);
- rstream_set_stream(job->err, (uv_stream_t *)&job->proc_stderr);
- rstream_start(job->out);
- rstream_start(job->err);
- // Save the job to the table
- table[i] = job;
-
- // Start polling job status if this is the first
- if (job_count == 0) {
- uv_prepare_start(&job_prepare, job_prepare_cb);
- }
- job_count++;
-
- return job->id;
-}
-
-bool job_stop(int id)
-{
- Job *job = find_job(id);
-
- if (job == NULL || job->stopped) {
- return false;
- }
-
- job->stopped = true;
-
- return true;
-}
-
-bool job_write(int id, char *data, uint32_t len)
-{
- Job *job = find_job(id);
-
- if (job == NULL || job->stopped) {
- free(data);
- return false;
- }
-
- if (!wstream_write(job->in, data, len, true)) {
- job_stop(job->id);
- return false;
- }
-
- return true;
-}
-
-void job_exit_event(Event event)
-{
- Job *job = event.data.job;
-
- // Free the slot now, 'exit_cb' may want to start another job to replace
- // this one
- table[job->id - 1] = NULL;
-
- if (job->exit_cb) {
- // Invoke the exit callback
- job->exit_cb(job, job->data);
- }
-
- // Free the job resources
- free_job(job);
-
- // Stop polling job status if this was the last
- job_count--;
- if (job_count == 0) {
- uv_prepare_stop(&job_prepare);
- }
-}
-
-int job_id(Job *job)
-{
- return job->id;
-}
-
-void *job_data(Job *job)
-{
- return job->data;
-}
-
-static bool is_alive(Job *job)
-{
- return uv_process_kill(&job->proc, 0) == 0;
-}
-
-static Job * find_job(int id)
-{
- if (id <= 0 || id > MAX_RUNNING_JOBS) {
- return NULL;
- }
-
- return table[id - 1];
-}
-
-static void free_job(Job *job)
-{
- uv_close((uv_handle_t *)&job->proc_stdout, close_cb);
- uv_close((uv_handle_t *)&job->proc_stdin, close_cb);
- uv_close((uv_handle_t *)&job->proc_stderr, close_cb);
- uv_close((uv_handle_t *)&job->proc, close_cb);
-}
-
-/// Iterates the table, sending SIGTERM to stopped jobs and SIGKILL to those
-/// that didn't die from SIGTERM after a while(exit_timeout is 0).
-static void job_prepare_cb(uv_prepare_t *handle)
-{
- Job *job;
- int i;
-
- for (i = 0; i < MAX_RUNNING_JOBS; i++) {
- if ((job = table[i]) == NULL || !job->stopped) {
- continue;
- }
-
- if ((job->exit_timeout--) == EXIT_TIMEOUT) {
- // Job was just stopped, close all stdio handles and send SIGTERM
- uv_process_kill(&job->proc, SIGTERM);
- } else if (job->exit_timeout == 0) {
- // We've waited long enough, send SIGKILL
- uv_process_kill(&job->proc, SIGKILL);
- }
- }
-}
-
-// Wraps the call to std{out,err}_cb and emits a JobExit event if necessary.
-static void read_cb(RStream *rstream, void *data, bool eof)
-{
- Job *job = data;
-
- if (rstream == job->out) {
- job->stdout_cb(rstream, data, eof);
- } else {
- job->stderr_cb(rstream, data, eof);
- }
-
- if (eof && --job->pending_refs == 0) {
- emit_exit_event(job);
- }
-}
-
-// Emits a JobExit event if both rstreams are closed
-static void exit_cb(uv_process_t *proc, int64_t status, int term_signal)
-{
- Job *job = handle_get_job((uv_handle_t *)proc);
-
- if (--job->pending_refs == 0) {
- emit_exit_event(job);
- }
-}
-
-static void emit_exit_event(Job *job)
-{
- Event event;
- event.type = kEventJobExit;
- event.data.job = job;
- event_push(event);
-}
-
-static void close_cb(uv_handle_t *handle)
-{
- Job *job = handle_get_job(handle);
-
- if (--job->pending_closes == 0) {
- // Only free the job memory after all the associated handles are properly
- // closed by libuv
- rstream_free(job->out);
- rstream_free(job->err);
- wstream_free(job->in);
- shell_free_argv(job->proc_opts.args);
- free(job->data);
- free(job);
- }
-}
diff --git a/src/os/job.h b/src/os/job.h
deleted file mode 100644
index db147f2c24..0000000000
--- a/src/os/job.h
+++ /dev/null
@@ -1,78 +0,0 @@
-// Job is a short name we use to refer to child processes that run in parallel
-// with the editor, probably executing long-running tasks and sending updates
-// asynchronously. Communication happens through anonymous pipes connected to
-// the job's std{in,out,err}. They are more like bash/zsh co-processes than the
-// usual shell background job. The name 'Job' was chosen because it applies to
-// the concept while being significantly shorter.
-#ifndef NEOVIM_OS_JOB_H
-#define NEOVIM_OS_JOB_H
-
-#include <stdint.h>
-#include <stdbool.h>
-
-#include "os/event_defs.h"
-#include "os/rstream_defs.h"
-
-/// Initializes job control resources
-void job_init(void);
-
-/// Releases job control resources and terminates running jobs
-void job_teardown(void);
-
-/// Tries to start a new job.
-///
-/// @param argv Argument vector for the process. The first item is the
-/// executable to run.
-/// @param data Caller data that will be associated with the job
-/// @param stdout_cb Callback that will be invoked when data is available
-/// on stdout
-/// @param stderr_cb Callback that will be invoked when data is available
-/// on stderr
-/// @param exit_cb Callback that will be invoked when the job exits. This is
-/// optional.
-/// @return The job id if the job started successfully. If the the first item /
-/// of `argv`(the program) could not be executed, -1 will be returned.
-// 0 will be returned if the job table is full.
-int job_start(char **argv,
- void *data,
- rstream_cb stdout_cb,
- rstream_cb stderr_cb,
- job_exit_cb exit_cb);
-
-/// Terminates a job. This is a non-blocking operation, but if the job exists
-/// it's guaranteed to succeed(SIGKILL will eventually be sent)
-///
-/// @param id The job id
-/// @return true if the stop request was successfully sent, false if the job
-/// id is invalid(probably because it has already stopped)
-bool job_stop(int id);
-
-/// Writes data to the job's stdin. This is a non-blocking operation, it
-/// returns when the write request was sent.
-///
-/// @param id The job id
-/// @param data Buffer containing the data to be written
-/// @param len Size of the data
-/// @return true if the write request was successfully sent, false if the job
-/// id is invalid(probably because it has already stopped)
-bool job_write(int id, char *data, uint32_t len);
-
-/// Runs the read callback associated with the job exit event
-///
-/// @param event Object containing data necessary to invoke the callback
-void job_exit_event(Event event);
-
-/// Get the job id
-///
-/// @param job A pointer to the job
-/// @return The job id
-int job_id(Job *job);
-
-/// Get data associated with a job
-///
-/// @param job A pointer to the job
-/// @return The job data
-void *job_data(Job *job);
-
-#endif // NEOVIM_OS_JOB_H
-
diff --git a/src/os/job_defs.h b/src/os/job_defs.h
deleted file mode 100644
index e98b639154..0000000000
--- a/src/os/job_defs.h
+++ /dev/null
@@ -1,15 +0,0 @@
-#ifndef NEOVIM_OS_JOB_DEFS_H
-#define NEOVIM_OS_JOB_DEFS_H
-
-#include "os/rstream_defs.h"
-
-typedef struct job Job;
-
-/// Function called when the job reads data
-///
-/// @param id The job id
-/// @param data Some data associated with the job by the caller
-typedef void (*job_exit_cb)(Job *job, void *data);
-
-#endif // NEOVIM_OS_JOB_DEFS_H
-
diff --git a/src/os/mem.c b/src/os/mem.c
deleted file mode 100644
index e5549340ff..0000000000
--- a/src/os/mem.c
+++ /dev/null
@@ -1,10 +0,0 @@
-/// Functions for accessing system memory information.
-
-#include <uv.h>
-
-#include "os/os.h"
-
-uint64_t os_get_total_mem_kib(void) {
- // Convert bytes to KiB.
- return uv_get_total_memory() >> 10;
-}
diff --git a/src/os/msgpack_rpc.c b/src/os/msgpack_rpc.c
deleted file mode 100644
index e429bf0519..0000000000
--- a/src/os/msgpack_rpc.c
+++ /dev/null
@@ -1,408 +0,0 @@
-#include <msgpack.h>
-
-#include "msgpack_rpc.h"
-#include "vim.h"
-#include "memory.h"
-
-static bool msgpack_rpc_to_uint16_t(msgpack_object *obj, uint16_t *arg);
-
-void msgpack_rpc_call(msgpack_object *req, msgpack_packer *res)
-{
- // The initial response structure is the same no matter what happens,
- // we set it up here
- // Array of size 4
- msgpack_pack_array(res, 4);
- // Response type is 1
- msgpack_pack_int(res, 1);
-
- // Validate the basic structure of the msgpack-rpc payload
- if (req->type != MSGPACK_OBJECT_ARRAY) {
- msgpack_pack_int(res, 0); // no message id yet
- msgpack_rpc_error("Request is not an array", res);
- return;
- }
-
- if (req->via.array.size != 4) {
- msgpack_pack_int(res, 0); // no message id yet
- char error_msg[256];
- snprintf(error_msg,
- sizeof(error_msg),
- "Request array size is %u, it should be 4",
- req->via.array.size);
- msgpack_rpc_error(error_msg, res);
- }
-
- if (req->via.array.ptr[1].type != MSGPACK_OBJECT_POSITIVE_INTEGER) {
- msgpack_pack_int(res, 0); // no message id yet
- msgpack_rpc_error("Id must be a positive integer", res);
- }
-
- // Set the response id, which is the same as the request
- msgpack_pack_int(res, req->via.array.ptr[1].via.u64);
-
- if (req->via.array.ptr[0].type != MSGPACK_OBJECT_POSITIVE_INTEGER) {
- msgpack_rpc_error("Message type must be an integer", res);
- return;
- }
-
- if (req->via.array.ptr[0].via.u64 != 0) {
- msgpack_rpc_error("Message type must be 0", res);
- return;
- }
-
- if (req->via.array.ptr[2].type != MSGPACK_OBJECT_POSITIVE_INTEGER) {
- msgpack_rpc_error("Method id must be a positive integer", res);
- return;
- }
-
- if (req->via.array.ptr[3].type != MSGPACK_OBJECT_ARRAY) {
- msgpack_rpc_error("Paremeters must be an array", res);
- return;
- }
-
- // dispatch the message
- msgpack_rpc_dispatch(req, res);
-}
-
-void msgpack_rpc_error(char *msg, msgpack_packer *res)
-{
- size_t len = strlen(msg);
-
- // error message
- msgpack_pack_raw(res, len);
- msgpack_pack_raw_body(res, msg, len);
- // Nil result
- msgpack_pack_nil(res);
-}
-
-bool msgpack_rpc_to_bool(msgpack_object *obj, bool *arg)
-{
- *arg = obj->via.boolean;
- return obj->type == MSGPACK_OBJECT_BOOLEAN;
-}
-
-bool msgpack_rpc_to_int64_t(msgpack_object *obj, int64_t *arg)
-{
- *arg = obj->via.i64;
- return obj->type == MSGPACK_OBJECT_POSITIVE_INTEGER
- || obj->type == MSGPACK_OBJECT_NEGATIVE_INTEGER;
-}
-
-bool msgpack_rpc_to_double(msgpack_object *obj, double *arg)
-{
- *arg = obj->via.dec;
- return obj->type == MSGPACK_OBJECT_DOUBLE;
-}
-
-bool msgpack_rpc_to_string(msgpack_object *obj, String *arg)
-{
- arg->data = (char *)obj->via.raw.ptr;
- arg->size = obj->via.raw.size;
- return obj->type == MSGPACK_OBJECT_RAW;
-}
-
-bool msgpack_rpc_to_buffer(msgpack_object *obj, Buffer *arg)
-{
- return msgpack_rpc_to_uint16_t(obj, arg);
-}
-
-bool msgpack_rpc_to_window(msgpack_object *obj, Window *arg)
-{
- return msgpack_rpc_to_uint16_t(obj, arg);
-}
-
-bool msgpack_rpc_to_tabpage(msgpack_object *obj, Tabpage *arg)
-{
- return msgpack_rpc_to_uint16_t(obj, arg);
-}
-
-bool msgpack_rpc_to_object(msgpack_object *obj, Object *arg)
-{
- switch (obj->type) {
- case MSGPACK_OBJECT_NIL:
- arg->type = kObjectTypeNil;
- return true;
-
- case MSGPACK_OBJECT_BOOLEAN:
- arg->type = kObjectTypeBool;
- return msgpack_rpc_to_bool(obj, &arg->data.boolean);
-
- case MSGPACK_OBJECT_POSITIVE_INTEGER:
- case MSGPACK_OBJECT_NEGATIVE_INTEGER:
- arg->type = kObjectTypeInt;
- return msgpack_rpc_to_int64_t(obj, &arg->data.integer);
-
- case MSGPACK_OBJECT_DOUBLE:
- arg->type = kObjectTypeFloat;
- return msgpack_rpc_to_double(obj, &arg->data.floating_point);
-
- case MSGPACK_OBJECT_RAW:
- arg->type = kObjectTypeString;
- return msgpack_rpc_to_string(obj, &arg->data.string);
-
- case MSGPACK_OBJECT_ARRAY:
- arg->type = kObjectTypeArray;
- return msgpack_rpc_to_array(obj, &arg->data.array);
-
- case MSGPACK_OBJECT_MAP:
- arg->type = kObjectTypeDictionary;
- return msgpack_rpc_to_dictionary(obj, &arg->data.dictionary);
-
- default:
- return false;
- }
-}
-
-bool msgpack_rpc_to_stringarray(msgpack_object *obj, StringArray *arg)
-{
- if (obj->type != MSGPACK_OBJECT_ARRAY) {
- return false;
- }
-
- arg->size = obj->via.array.size;
- arg->items = xcalloc(obj->via.array.size, sizeof(String));
-
- for (uint32_t i = 0; i < obj->via.array.size; i++) {
- if (!msgpack_rpc_to_string(obj->via.array.ptr + i, &arg->items[i])) {
- return false;
- }
- }
-
- return true;
-}
-
-bool msgpack_rpc_to_position(msgpack_object *obj, Position *arg)
-{
- // positions are represented by integer arrays of size 2
- if (obj->type != MSGPACK_OBJECT_ARRAY
- || obj->via.array.size != 2
- || obj->via.array.ptr[0].type != MSGPACK_OBJECT_POSITIVE_INTEGER
- || obj->via.array.ptr[1].type != MSGPACK_OBJECT_POSITIVE_INTEGER) {
- return false;
- }
-
- arg->row = obj->via.array.ptr[0].via.u64;
- arg->col = obj->via.array.ptr[1].via.u64;
-
- return true;
-}
-
-
-bool msgpack_rpc_to_array(msgpack_object *obj, Array *arg)
-{
- if (obj->type != MSGPACK_OBJECT_ARRAY) {
- return false;
- }
-
- arg->size = obj->via.array.size;
- arg->items = xcalloc(obj->via.array.size, sizeof(Object));
-
- for (uint32_t i = 0; i < obj->via.array.size; i++) {
- if (!msgpack_rpc_to_object(obj->via.array.ptr + i, &arg->items[i])) {
- return false;
- }
- }
-
- return true;
-}
-
-bool msgpack_rpc_to_dictionary(msgpack_object *obj, Dictionary *arg)
-{
- if (obj->type != MSGPACK_OBJECT_MAP) {
- return false;
- }
-
- arg->size = obj->via.array.size;
- arg->items = xcalloc(obj->via.map.size, sizeof(KeyValuePair));
-
-
- for (uint32_t i = 0; i < obj->via.map.size; i++) {
- if (!msgpack_rpc_to_string(&obj->via.map.ptr[i].key,
- &arg->items[i].key)) {
- return false;
- }
-
- if (!msgpack_rpc_to_object(&obj->via.map.ptr[i].val,
- &arg->items[i].value)) {
- return false;
- }
- }
-
- return true;
-}
-
-void msgpack_rpc_from_bool(bool result, msgpack_packer *res)
-{
- if (result) {
- msgpack_pack_true(res);
- } else {
- msgpack_pack_false(res);
- }
-}
-
-void msgpack_rpc_from_int64_t(int64_t result, msgpack_packer *res)
-{
- msgpack_pack_int64(res, result);
-}
-
-void msgpack_rpc_from_uint64_t(uint64_t result, msgpack_packer *res)
-{
- msgpack_pack_uint64(res, result);
-}
-
-void msgpack_rpc_from_double(double result, msgpack_packer *res)
-{
- msgpack_pack_double(res, result);
-}
-
-void msgpack_rpc_from_string(String result, msgpack_packer *res)
-{
- msgpack_pack_raw(res, result.size);
- msgpack_pack_raw_body(res, result.data, result.size);
-}
-
-void msgpack_rpc_from_buffer(Buffer result, msgpack_packer *res)
-{
- msgpack_rpc_from_uint64_t(result, res);
-}
-
-void msgpack_rpc_from_window(Window result, msgpack_packer *res)
-{
- msgpack_rpc_from_uint64_t(result, res);
-}
-
-void msgpack_rpc_from_tabpage(Tabpage result, msgpack_packer *res)
-{
- msgpack_rpc_from_uint64_t(result, res);
-}
-
-void msgpack_rpc_from_object(Object result, msgpack_packer *res)
-{
- switch (result.type) {
- case kObjectTypeNil:
- msgpack_pack_nil(res);
- break;
-
- case kObjectTypeBool:
- msgpack_rpc_from_bool(result.data.boolean, res);
- break;
-
- case kObjectTypeInt:
- msgpack_rpc_from_int64_t(result.data.integer, res);
- break;
-
- case kObjectTypeFloat:
- msgpack_rpc_from_double(result.data.floating_point, res);
- break;
-
- case kObjectTypeString:
- msgpack_rpc_from_string(result.data.string, res);
- break;
-
- case kObjectTypeArray:
- msgpack_rpc_from_array(result.data.array, res);
- break;
-
- case kObjectTypeDictionary:
- msgpack_rpc_from_dictionary(result.data.dictionary, res);
- break;
-
- default:
- abort();
- }
-}
-
-void msgpack_rpc_from_stringarray(StringArray result, msgpack_packer *res)
-{
- msgpack_pack_array(res, result.size);
-
- for (size_t i = 0; i < result.size; i++) {
- msgpack_rpc_from_string(result.items[i], res);
- }
-}
-
-void msgpack_rpc_from_position(Position result, msgpack_packer *res)
-{
- msgpack_pack_array(res, 2);;
- msgpack_pack_uint16(res, result.row);
- msgpack_pack_uint16(res, result.col);
-}
-
-void msgpack_rpc_from_array(Array result, msgpack_packer *res)
-{
- msgpack_pack_array(res, result.size);
-
- for (size_t i = 0; i < result.size; i++) {
- msgpack_rpc_from_object(result.items[i], res);
- }
-}
-
-void msgpack_rpc_from_dictionary(Dictionary result, msgpack_packer *res)
-{
- msgpack_pack_map(res, result.size);
-
- for (size_t i = 0; i < result.size; i++) {
- msgpack_rpc_from_string(result.items[i].key, res);
- msgpack_rpc_from_object(result.items[i].value, res);
- }
-}
-
-void msgpack_rpc_free_object(Object value)
-{
- switch (value.type) {
- case kObjectTypeNil:
- case kObjectTypeBool:
- case kObjectTypeInt:
- case kObjectTypeFloat:
- break;
-
- case kObjectTypeString:
- msgpack_rpc_free_string(value.data.string);
- break;
-
- case kObjectTypeArray:
- msgpack_rpc_free_array(value.data.array);
- break;
-
- case kObjectTypeDictionary:
- msgpack_rpc_free_dictionary(value.data.dictionary);
- break;
-
- default:
- abort();
- }
-}
-
-void msgpack_rpc_free_stringarray(StringArray value) {
- for (uint32_t i = 0; i < value.size; i++) {
- msgpack_rpc_free_string(value.items[i]);
- }
-
- free(value.items);
-}
-
-void msgpack_rpc_free_array(Array value)
-{
- for (uint32_t i = 0; i < value.size; i++) {
- msgpack_rpc_free_object(value.items[i]);
- }
-
- free(value.items);
-}
-
-void msgpack_rpc_free_dictionary(Dictionary value)
-{
- for (uint32_t i = 0; i < value.size; i++) {
- msgpack_rpc_free_string(value.items[i].key);
- msgpack_rpc_free_object(value.items[i].value);
- }
-
- free(value.items);
-}
-
-static bool msgpack_rpc_to_uint16_t(msgpack_object *obj, uint16_t *arg)
-{
- *arg = obj->via.u64;
- return obj->type == MSGPACK_OBJECT_POSITIVE_INTEGER;
-}
-
diff --git a/src/os/msgpack_rpc.h b/src/os/msgpack_rpc.h
deleted file mode 100644
index 7f754bfca1..0000000000
--- a/src/os/msgpack_rpc.h
+++ /dev/null
@@ -1,107 +0,0 @@
-#ifndef NEOVIM_OS_MSGPACK_RPC_H
-#define NEOVIM_OS_MSGPACK_RPC_H
-
-#include <stdint.h>
-#include <stdbool.h>
-
-#include <msgpack.h>
-
-#include "api/defs.h"
-
-/// Validates the basic structure of the msgpack-rpc call and fills `res`
-/// with the basic response structure.
-///
-/// @param req The parsed request object
-/// @param res A packer that contains the response
-void msgpack_rpc_call(msgpack_object *req, msgpack_packer *res);
-
-/// Dispatches to the actual API function after basic payload validation by
-/// `msgpack_rpc_call`. It is responsible for validating/converting arguments
-/// to C types, and converting the return value back to msgpack types.
-/// The implementation is generated at compile time with metadata extracted
-/// from the api/*.h headers,
-///
-/// @param req The parsed request object
-/// @param res A packer that contains the response
-void msgpack_rpc_dispatch(msgpack_object *req, msgpack_packer *res);
-
-/// Finishes the msgpack-rpc call with an error message.
-///
-/// @param msg The error message
-/// @param res A packer that contains the response
-void msgpack_rpc_error(char *msg, msgpack_packer *res);
-
-/// Functions for validating and converting from msgpack types to C types.
-/// These are used by `msgpack_rpc_dispatch` to validate and convert each
-/// argument.
-///
-/// @param obj The object to convert
-/// @param[out] arg A pointer to the avalue
-/// @return true if the convertion succeeded, false otherwise
-bool msgpack_rpc_to_bool(msgpack_object *obj, bool *arg);
-bool msgpack_rpc_to_int64_t(msgpack_object *obj, int64_t *arg);
-bool msgpack_rpc_to_double(msgpack_object *obj, double *arg);
-bool msgpack_rpc_to_position(msgpack_object *obj, Position *arg);
-bool msgpack_rpc_to_string(msgpack_object *obj, String *arg);
-bool msgpack_rpc_to_buffer(msgpack_object *obj, Buffer *arg);
-bool msgpack_rpc_to_window(msgpack_object *obj, Window *arg);
-bool msgpack_rpc_to_tabpage(msgpack_object *obj, Tabpage *arg);
-bool msgpack_rpc_to_object(msgpack_object *obj, Object *arg);
-bool msgpack_rpc_to_stringarray(msgpack_object *obj, StringArray *arg);
-bool msgpack_rpc_to_array(msgpack_object *obj, Array *arg);
-bool msgpack_rpc_to_dictionary(msgpack_object *obj, Dictionary *arg);
-
-/// Functions for converting from C types to msgpack types.
-/// These are used by `msgpack_rpc_dispatch` to convert return values
-/// from the API
-///
-/// @param result A pointer to the result
-/// @param res A packer that contains the response
-void msgpack_rpc_from_bool(bool result, msgpack_packer *res);
-void msgpack_rpc_from_int64_t(int64_t result, msgpack_packer *res);
-void msgpack_rpc_from_double(double result, msgpack_packer *res);
-void msgpack_rpc_from_position(Position result, msgpack_packer *res);
-void msgpack_rpc_from_string(String result, msgpack_packer *res);
-void msgpack_rpc_from_buffer(Buffer result, msgpack_packer *res);
-void msgpack_rpc_from_window(Window result, msgpack_packer *res);
-void msgpack_rpc_from_tabpage(Tabpage result, msgpack_packer *res);
-void msgpack_rpc_from_object(Object result, msgpack_packer *res);
-void msgpack_rpc_from_stringarray(StringArray result, msgpack_packer *res);
-void msgpack_rpc_from_array(Array result, msgpack_packer *res);
-void msgpack_rpc_from_dictionary(Dictionary result, msgpack_packer *res);
-
-/// Helpers for initializing types that may be freed later
-#define msgpack_rpc_init_bool
-#define msgpack_rpc_init_int64_t
-#define msgpack_rpc_init_double
-#define msgpack_rpc_init_position
-#define msgpack_rpc_init_string
-#define msgpack_rpc_init_buffer
-#define msgpack_rpc_init_window
-#define msgpack_rpc_init_tabpage
-#define msgpack_rpc_init_object = {.type = kObjectTypeNil}
-#define msgpack_rpc_init_stringarray = {.items = NULL, .size = 0}
-#define msgpack_rpc_init_array = {.items = NULL, .size = 0}
-#define msgpack_rpc_init_dictionary = {.items = NULL, .size = 0}
-
-/// Helpers for freeing arguments/return value
-///
-/// @param value The value to be freed
-#define msgpack_rpc_free_bool(value)
-#define msgpack_rpc_free_int64_t(value)
-#define msgpack_rpc_free_double(value)
-#define msgpack_rpc_free_position(value)
-// Strings are not copied from msgpack and so don't need to be freed(they
-// probably "live" in the msgpack streaming buffer)
-#define msgpack_rpc_free_string(value)
-#define msgpack_rpc_free_buffer(value)
-#define msgpack_rpc_free_window(value)
-#define msgpack_rpc_free_tabpage(value)
-void msgpack_rpc_free_object(Object value);
-void msgpack_rpc_free_stringarray(StringArray value);
-void msgpack_rpc_free_array(Array value);
-void msgpack_rpc_free_dictionary(Dictionary value);
-
-
-#endif // NEOVIM_OS_MSGPACK_RPC_H
-
diff --git a/src/os/os.h b/src/os/os.h
deleted file mode 100644
index b30872f06d..0000000000
--- a/src/os/os.h
+++ /dev/null
@@ -1,146 +0,0 @@
-#ifndef NEOVIM_OS_OS_H
-#define NEOVIM_OS_OS_H
-#include <uv.h>
-
-#include "vim.h"
-
-/// Change to the given directory.
-///
-/// @return `0` on success, a libuv error code on failure.
-int os_chdir(const char *path);
-
-/// Get the name of current directory.
-///
-/// @param buf Buffer to store the directory name.
-/// @param len Length of `buf`.
-/// @return `OK` for success, `FAIL` for failure.
-int os_dirname(char_u *buf, size_t len);
-
-/// Check if the given path is a directory or not.
-///
-/// @return `true` if `fname` is a directory.
-bool os_isdir(const char_u *name);
-
-/// Check if the given path represents an executable file.
-///
-/// @return `true` if `name` is executable and
-/// - can be found in $PATH,
-/// - is relative to current dir or
-/// - is absolute.
-///
-/// @return `false` otherwise.
-bool os_can_exe(const char_u *name);
-
-/// Get the file permissions for a given file.
-///
-/// @return `-1` when `name` doesn't exist.
-int32_t os_getperm(const char_u *name);
-
-/// Set the permission of a file.
-///
-/// @return `OK` for success, `FAIL` for failure.
-int os_setperm(const char_u *name, int perm);
-
-/// Check if a file exists.
-///
-/// @return `true` if `name` exists.
-bool os_file_exists(const char_u *name);
-
-/// Check if a file is readonly.
-///
-/// @return `true` if `name` is readonly.
-bool os_file_is_readonly(const char *name);
-
-/// Check if a file is writable.
-///
-/// @return `0` if `name` is not writable,
-/// @return `1` if `name` is writable,
-/// @return `2` for a directory which we have rights to write into.
-int os_file_is_writable(const char *name);
-
-/// Get the size of a file in bytes.
-///
-/// @param[out] size pointer to an off_t to put the size into.
-/// @return `true` for success, `false` for failure.
-bool os_get_file_size(const char *name, off_t *size);
-
-/// Rename a file or directory.
-///
-/// @return `OK` for success, `FAIL` for failure.
-int os_rename(const char_u *path, const char_u *new_path);
-
-/// Make a directory.
-///
-/// @return `0` for success, non-zero for failure.
-int os_mkdir(const char *path, int32_t mode);
-
-/// Remove a directory.
-///
-/// @return `0` for success, non-zero for failure.
-int os_rmdir(const char *path);
-
-/// Remove a file.
-///
-/// @return `0` for success, non-zero for failure.
-int os_remove(const char *path);
-
-/// Get the total system physical memory in KiB.
-uint64_t os_get_total_mem_kib(void);
-const char *os_getenv(const char *name);
-int os_setenv(const char *name, const char *value, int overwrite);
-char *os_getenvname_at_index(size_t index);
-
-/// Get the process ID of the Neovim process.
-///
-/// @return the process ID.
-int64_t os_get_pid(void);
-
-/// Get the hostname of the machine runing Neovim.
-///
-/// @param hostname Buffer to store the hostname.
-/// @param len Length of `hostname`.
-void os_get_hostname(char *hostname, size_t len);
-
-int os_get_usernames(garray_T *usernames);
-int os_get_user_name(char *s, size_t len);
-int os_get_uname(uid_t uid, char *s, size_t len);
-char *os_get_user_directory(const char *name);
-
-/// Get stat information for a file.
-///
-/// @return OK on success, FAIL if an failure occured.
-int os_stat(const char_u *name, uv_stat_t *statbuf);
-
-/// Struct which encapsulates stat information.
-typedef struct {
- // TODO(stefan991): make stat private
- uv_stat_t stat;
-} FileInfo;
-
-/// Get the file information for a given path
-///
-/// @param file_descriptor File descriptor of the file.
-/// @param[out] file_info Pointer to a FileInfo to put the information in.
-/// @return `true` on sucess, `false` for failure.
-bool os_get_file_info(const char *path, FileInfo *file_info);
-
-/// Get the file information for a given path without following links
-///
-/// @param path Path to the file.
-/// @param[out] file_info Pointer to a FileInfo to put the information in.
-/// @return `true` on sucess, `false` for failure.
-bool os_get_file_info_link(const char *path, FileInfo *file_info);
-
-/// Get the file information for a given file descriptor
-///
-/// @param file_descriptor File descriptor of the file.
-/// @param[out] file_info Pointer to a FileInfo to put the information in.
-/// @return `true` on sucess, `false` for failure.
-bool os_get_file_info_fd(int file_descriptor, FileInfo *file_info);
-
-/// Compare the inodes of two FileInfos
-///
-/// @return `true` if the two FileInfos represent the same file.
-bool os_file_info_id_equal(FileInfo *file_info_1, FileInfo *file_info_2);
-
-#endif // NEOVIM_OS_OS_H
diff --git a/src/os/rstream.c b/src/os/rstream.c
deleted file mode 100644
index e14075c8db..0000000000
--- a/src/os/rstream.c
+++ /dev/null
@@ -1,297 +0,0 @@
-#include <stdint.h>
-#include <stdbool.h>
-#include <stdlib.h>
-
-#include <uv.h>
-
-#include "os/uv_helpers.h"
-#include "os/rstream_defs.h"
-#include "os/rstream.h"
-#include "os/event_defs.h"
-#include "os/event.h"
-#include "vim.h"
-#include "memory.h"
-
-struct rstream {
- uv_buf_t uvbuf;
- void *data;
- char *buffer;
- uv_stream_t *stream;
- uv_idle_t *fread_idle;
- uv_handle_type file_type;
- uv_file fd;
- rstream_cb cb;
- size_t buffer_size, rpos, wpos, fpos;
- bool reading, free_handle, async;
-};
-
-// Callbacks used by libuv
-static void alloc_cb(uv_handle_t *, size_t, uv_buf_t *);
-static void read_cb(uv_stream_t *, ssize_t, const uv_buf_t *);
-static void fread_idle_cb(uv_idle_t *);
-static void close_cb(uv_handle_t *handle);
-static void emit_read_event(RStream *rstream, bool eof);
-
-RStream * rstream_new(rstream_cb cb,
- uint32_t buffer_size,
- void *data,
- bool async)
-{
- RStream *rv = xmalloc(sizeof(RStream));
- rv->buffer = xmalloc(buffer_size);
- rv->buffer_size = buffer_size;
- rv->data = data;
- rv->async = async;
- rv->cb = cb;
- rv->rpos = rv->wpos = rv->fpos = 0;
- rv->stream = NULL;
- rv->fread_idle = NULL;
- rv->free_handle = false;
- rv->file_type = UV_UNKNOWN_HANDLE;
-
- return rv;
-}
-
-void rstream_free(RStream *rstream)
-{
- if (rstream->free_handle) {
- if (rstream->fread_idle != NULL) {
- uv_close((uv_handle_t *)rstream->fread_idle, close_cb);
- } else {
- uv_close((uv_handle_t *)rstream->stream, close_cb);
- }
- }
-
- free(rstream->buffer);
- free(rstream);
-}
-
-void rstream_set_stream(RStream *rstream, uv_stream_t *stream)
-{
- handle_set_rstream((uv_handle_t *)stream, rstream);
- rstream->stream = stream;
-}
-
-void rstream_set_file(RStream *rstream, uv_file file)
-{
- rstream->file_type = uv_guess_handle(file);
-
- if (rstream->free_handle) {
- // If this is the second time we're calling this function, free the
- // previously allocated memory
- if (rstream->fread_idle != NULL) {
- uv_close((uv_handle_t *)rstream->fread_idle, close_cb);
- } else {
- uv_close((uv_handle_t *)rstream->stream, close_cb);
- }
- }
-
- if (rstream->file_type == UV_FILE) {
- // Non-blocking file reads are simulated with a idle handle that reads
- // in chunks of rstream->buffer_size, giving time for other events to
- // be processed between reads.
- rstream->fread_idle = xmalloc(sizeof(uv_idle_t));
- uv_idle_init(uv_default_loop(), rstream->fread_idle);
- rstream->fread_idle->data = NULL;
- handle_set_rstream((uv_handle_t *)rstream->fread_idle, rstream);
- } else {
- // Only pipes are supported for now
- assert(rstream->file_type == UV_NAMED_PIPE
- || rstream->file_type == UV_TTY);
- rstream->stream = xmalloc(sizeof(uv_pipe_t));
- uv_pipe_init(uv_default_loop(), (uv_pipe_t *)rstream->stream, 0);
- uv_pipe_open((uv_pipe_t *)rstream->stream, file);
- rstream->stream->data = NULL;
- handle_set_rstream((uv_handle_t *)rstream->stream, rstream);
- }
-
- rstream->fd = file;
- rstream->free_handle = true;
-}
-
-bool rstream_is_regular_file(RStream *rstream)
-{
- return rstream->file_type == UV_FILE;
-}
-
-void rstream_start(RStream *rstream)
-{
- if (rstream->file_type == UV_FILE) {
- uv_idle_start(rstream->fread_idle, fread_idle_cb);
- } else {
- rstream->reading = false;
- uv_read_start(rstream->stream, alloc_cb, read_cb);
- }
-}
-
-void rstream_stop(RStream *rstream)
-{
- if (rstream->file_type == UV_FILE) {
- uv_idle_stop(rstream->fread_idle);
- } else {
- uv_read_stop(rstream->stream);
- }
-}
-
-size_t rstream_read(RStream *rstream, char *buf, uint32_t count)
-{
- size_t read_count = rstream->wpos - rstream->rpos;
-
- if (count < read_count) {
- read_count = count;
- }
-
- if (read_count > 0) {
- memcpy(buf, rstream->buffer + rstream->rpos, read_count);
- rstream->rpos += read_count;
- }
-
- if (rstream->wpos == rstream->buffer_size) {
- // `wpos` is at the end of the buffer, so free some space by moving unread
- // data...
- memmove(
- rstream->buffer, // ...To the beginning of the buffer(rpos 0)
- rstream->buffer + rstream->rpos, // ...From the first unread position
- rstream->wpos - rstream->rpos); // ...By the number of unread bytes
- rstream->wpos -= rstream->rpos;
- rstream->rpos = 0;
-
- if (rstream->wpos < rstream->buffer_size) {
- // Restart reading since we have freed some space
- rstream_start(rstream);
- }
- }
-
- return read_count;
-}
-
-size_t rstream_available(RStream *rstream)
-{
- return rstream->wpos - rstream->rpos;
-}
-
-void rstream_read_event(Event event)
-{
- RStream *rstream = event.data.rstream.ptr;
-
- rstream->cb(rstream, rstream->data, event.data.rstream.eof);
-}
-
-// Called by libuv to allocate memory for reading.
-static void alloc_cb(uv_handle_t *handle, size_t suggested, uv_buf_t *buf)
-{
- RStream *rstream = handle_get_rstream(handle);
-
- if (rstream->reading) {
- buf->len = 0;
- return;
- }
-
- buf->len = rstream->buffer_size - rstream->wpos;
- buf->base = rstream->buffer + rstream->wpos;
-
- // Avoid `alloc_cb`, `alloc_cb` sequences on windows
- rstream->reading = true;
-}
-
-// Callback invoked by libuv after it copies the data into the buffer provided
-// by `alloc_cb`. This is also called on EOF or when `alloc_cb` returns a
-// 0-length buffer.
-static void read_cb(uv_stream_t *stream, ssize_t cnt, const uv_buf_t *buf)
-{
- RStream *rstream = handle_get_rstream((uv_handle_t *)stream);
-
- if (cnt <= 0) {
- if (cnt != UV_ENOBUFS) {
- // Read error or EOF, either way stop the stream and invoke the callback
- // with eof == true
- uv_read_stop(stream);
- emit_read_event(rstream, true);
- }
- return;
- }
-
- // at this point we're sure that cnt is positive, no error occurred
- size_t nread = (size_t) cnt;
-
- // Data was already written, so all we need is to update 'wpos' to reflect
- // the space actually used in the buffer.
- rstream->wpos += nread;
-
- if (rstream->wpos == rstream->buffer_size) {
- // The last read filled the buffer, stop reading for now
- rstream_stop(rstream);
- }
-
- rstream->reading = false;
- emit_read_event(rstream, false);
-}
-
-// Called by the by the 'idle' handle to emulate a reading event
-static void fread_idle_cb(uv_idle_t *handle)
-{
- uv_fs_t req;
- RStream *rstream = handle_get_rstream((uv_handle_t *)handle);
-
- rstream->uvbuf.base = rstream->buffer + rstream->wpos;
- rstream->uvbuf.len = rstream->buffer_size - rstream->wpos;
-
- // the offset argument to uv_fs_read is int64_t, could someone really try
- // to read more than 9 quintillion (9e18) bytes?
- // upcast is meant to avoid tautological condition warning on 32 bits
- uintmax_t fpos_intmax = rstream->fpos;
- assert(fpos_intmax <= INT64_MAX);
-
- // Synchronous read
- uv_fs_read(
- uv_default_loop(),
- &req,
- rstream->fd,
- &rstream->uvbuf,
- 1,
- (int64_t) rstream->fpos,
- NULL);
-
- uv_fs_req_cleanup(&req);
-
- if (req.result <= 0) {
- uv_idle_stop(rstream->fread_idle);
- emit_read_event(rstream, true);
- return;
- }
-
- // no errors (req.result (ssize_t) is positive), it's safe to cast.
- size_t nread = (size_t) req.result;
-
- rstream->wpos += nread;
- rstream->fpos += nread;
-
- if (rstream->wpos == rstream->buffer_size) {
- // The last read filled the buffer, stop reading for now
- rstream_stop(rstream);
- }
-
- emit_read_event(rstream, false);
-}
-
-static void close_cb(uv_handle_t *handle)
-{
- free(handle->data);
- free(handle);
-}
-
-static void emit_read_event(RStream *rstream, bool eof)
-{
- if (rstream->async) {
- Event event;
-
- event.type = kEventRStreamData;
- event.data.rstream.ptr = rstream;
- event.data.rstream.eof = eof;
- event_push(event);
- } else {
- // Invoke the callback passing in the number of bytes available and data
- // associated with the stream
- rstream->cb(rstream, rstream->data, eof);
- }
-}
diff --git a/src/os/rstream.h b/src/os/rstream.h
deleted file mode 100644
index 5eb3e97f55..0000000000
--- a/src/os/rstream.h
+++ /dev/null
@@ -1,82 +0,0 @@
-#ifndef NEOVIM_OS_RSTREAM_H
-#define NEOVIM_OS_RSTREAM_H
-
-#include <stdbool.h>
-#include <stdint.h>
-#include <uv.h>
-
-#include "os/event_defs.h"
-#include "os/rstream_defs.h"
-
-/// Creates a new RStream instance. A RStream encapsulates all the boilerplate
-/// necessary for reading from a libuv stream.
-///
-/// @param cb A function that will be called whenever some data is available
-/// for reading with `rstream_read`
-/// @param buffer_size Size in bytes of the internal buffer.
-/// @param data Some state to associate with the `RStream` instance
-/// @param async Flag that specifies if the callback should only be called
-/// outside libuv event loop(When processing async events with
-/// KE_EVENT). Only the RStream instance reading user input should set
-/// this to false
-/// @return The newly-allocated `RStream` instance
-RStream * rstream_new(rstream_cb cb,
- uint32_t buffer_size,
- void *data,
- bool async);
-
-/// Frees all memory allocated for a RStream instance
-///
-/// @param rstream The `RStream` instance
-void rstream_free(RStream *rstream);
-
-/// Sets the underlying `uv_stream_t` instance
-///
-/// @param rstream The `RStream` instance
-/// @param stream The new `uv_stream_t` instance
-void rstream_set_stream(RStream *rstream, uv_stream_t *stream);
-
-/// Sets the underlying file descriptor that will be read from. Only pipes
-/// and regular files are supported for now.
-///
-/// @param rstream The `RStream` instance
-/// @param file The file descriptor
-void rstream_set_file(RStream *rstream, uv_file file);
-
-/// Tests if the stream is backed by a regular file
-///
-/// @param rstream The `RStream` instance
-/// @return True if the underlying file descriptor represents a regular file
-bool rstream_is_regular_file(RStream *rstream);
-
-/// Starts watching for events from a `RStream` instance.
-///
-/// @param rstream The `RStream` instance
-void rstream_start(RStream *rstream);
-
-/// Stops watching for events from a `RStream` instance.
-///
-/// @param rstream The `RStream` instance
-void rstream_stop(RStream *rstream);
-
-/// Reads data from a `RStream` instance into a buffer.
-///
-/// @param rstream The `RStream` instance
-/// @param buffer The buffer which will receive the data
-/// @param count Number of bytes that `buffer` can accept
-/// @return The number of bytes copied into `buffer`
-size_t rstream_read(RStream *rstream, char *buffer, uint32_t count);
-
-/// Returns the number of bytes available for reading from `rstream`
-///
-/// @param rstream The `RStream` instance
-/// @return The number of bytes available
-size_t rstream_available(RStream *rstream);
-
-/// Runs the read callback associated with the rstream
-///
-/// @param event Object containing data necessary to invoke the callback
-void rstream_read_event(Event event);
-
-#endif // NEOVIM_OS_RSTREAM_H
-
diff --git a/src/os/rstream_defs.h b/src/os/rstream_defs.h
deleted file mode 100644
index 3d1dbec34f..0000000000
--- a/src/os/rstream_defs.h
+++ /dev/null
@@ -1,16 +0,0 @@
-#ifndef NEOVIM_OS_RSTREAM_DEFS_H
-#define NEOVIM_OS_RSTREAM_DEFS_H
-
-#include <stdbool.h>
-
-typedef struct rstream RStream;
-
-/// Type of function called when the RStream receives data
-///
-/// @param rstream The RStream instance
-/// @param data State associated with the RStream instance
-/// @param eof If the stream reached EOF.
-typedef void (*rstream_cb)(RStream *rstream, void *data, bool eof);
-
-#endif // NEOVIM_OS_RSTREAM_DEFS_H
-
diff --git a/src/os/server.c b/src/os/server.c
deleted file mode 100644
index bda9602936..0000000000
--- a/src/os/server.c
+++ /dev/null
@@ -1,243 +0,0 @@
-#include <stdlib.h>
-#include <string.h>
-#include <stdint.h>
-#include <stdbool.h>
-
-#include <uv.h>
-
-#include "os/channel_defs.h"
-#include "os/channel.h"
-#include "os/server.h"
-#include "os/os.h"
-#include "vim.h"
-#include "memory.h"
-#include "message.h"
-#include "fileio.h"
-#include "map.h"
-
-#define MAX_CONNECTIONS 32
-#define ADDRESS_MAX_SIZE 256
-#define NEOVIM_DEFAULT_TCP_PORT 7450
-
-typedef enum {
- kServerTypeTcp,
- kServerTypePipe
-} ServerType;
-
-typedef struct {
- // Protocol for channels established through this server
- ChannelProtocol protocol;
- // Type of the union below
- ServerType type;
-
- // This is either a tcp server or unix socket(named pipe on windows)
- union {
- struct {
- uv_tcp_t handle;
- struct sockaddr_in addr;
- } tcp;
- struct {
- uv_pipe_t handle;
- char addr[ADDRESS_MAX_SIZE];
- } pipe;
- } socket;
-} Server;
-
-static Map *servers = NULL;
-
-static void close_server(Map *map, const char *endpoint, void *server);
-static void connection_cb(uv_stream_t *server, int status);
-static void free_client(uv_handle_t *handle);
-static void free_server(uv_handle_t *handle);
-
-void server_init()
-{
- servers = map_new();
-
- if (!os_getenv("NEOVIM_LISTEN_ADDRESS")) {
- char *listen_address = (char *)vim_tempname('s');
- os_setenv("NEOVIM_LISTEN_ADDRESS", listen_address, 1);
- free(listen_address);
- }
-
- server_start((char *)os_getenv("NEOVIM_LISTEN_ADDRESS"),
- kChannelProtocolMsgpack);
-}
-
-void server_teardown()
-{
- if (!servers) {
- return;
- }
-
- map_foreach(servers, close_server);
-}
-
-void server_start(char *endpoint, ChannelProtocol prot)
-{
- char addr[ADDRESS_MAX_SIZE];
-
- // Trim to `ADDRESS_MAX_SIZE`
- strncpy(addr, endpoint, sizeof(addr));
-
- // Check if the server already exists
- if (map_has(servers, addr)) {
- EMSG2("Already listening on %s", addr);
- return;
- }
-
- ServerType server_type = kServerTypeTcp;
- Server *server = xmalloc(sizeof(Server));
- char ip[16], *ip_end = strrchr(addr, ':');
-
- server->protocol = prot;
-
- if (!ip_end) {
- ip_end = strchr(addr, NUL);
- }
-
- uint32_t addr_len = ip_end - addr;
-
- if (addr_len > sizeof(ip) - 1) {
- // Maximum length of a ip address buffer is 15(eg: 255.255.255.255)
- addr_len = sizeof(ip);
- }
-
- // Extract the address part
- strncpy(ip, addr, addr_len);
-
- int port = NEOVIM_DEFAULT_TCP_PORT;
-
- if (*ip_end == ':') {
- char *port_end;
- // Extract the port
- port = strtol(ip_end + 1, &port_end, 10);
-
- errno = 0;
- if (errno != 0 || port == 0 || port > 0xffff) {
- // Invalid port, treat as named pipe or unix socket
- server_type = kServerTypePipe;
- }
- }
-
- if (server_type == kServerTypeTcp) {
- // Try to parse ip address
- if (uv_ip4_addr(ip, port, &server->socket.tcp.addr)) {
- // Invalid address, treat as named pipe or unix socket
- server_type = kServerTypePipe;
- }
- }
-
- int result;
-
- if (server_type == kServerTypeTcp) {
- // Listen on tcp address/port
- uv_tcp_init(uv_default_loop(), &server->socket.tcp.handle);
- server->socket.tcp.handle.data = server;
- uv_tcp_bind(&server->socket.tcp.handle,
- (const struct sockaddr *)&server->socket.tcp.addr,
- 0);
- result = uv_listen((uv_stream_t *)&server->socket.tcp.handle,
- MAX_CONNECTIONS,
- connection_cb);
- if (result) {
- uv_close((uv_handle_t *)&server->socket.tcp.handle, free_server);
- }
- } else {
- // Listen on named pipe or unix socket
- strcpy(server->socket.pipe.addr, addr);
- uv_pipe_init(uv_default_loop(), &server->socket.pipe.handle, 0);
- server->socket.pipe.handle.data = server;
- uv_pipe_bind(&server->socket.pipe.handle, server->socket.pipe.addr);
- result = uv_listen((uv_stream_t *)&server->socket.pipe.handle,
- MAX_CONNECTIONS,
- connection_cb);
-
- if (result) {
- uv_close((uv_handle_t *)&server->socket.pipe.handle, free_server);
- }
- }
-
- if (result) {
- EMSG2("Failed to start server: %s", uv_strerror(result));
- return;
- }
-
-
- server->type = server_type;
-
- // Add the server to the hash table
- map_put(servers, addr, server);
-}
-
-void server_stop(char *endpoint)
-{
- Server *server;
- char addr[ADDRESS_MAX_SIZE];
-
- // Trim to `ADDRESS_MAX_SIZE`
- strncpy(addr, endpoint, sizeof(addr));
-
- if ((server = map_get(servers, addr)) == NULL) {
- EMSG2("Not listening on %s", addr);
- return;
- }
-
- if (server->type == kServerTypeTcp) {
- uv_close((uv_handle_t *)&server->socket.tcp.handle, free_server);
- } else {
- uv_close((uv_handle_t *)&server->socket.pipe.handle, free_server);
- }
-
- map_del(servers, addr);
-}
-
-static void connection_cb(uv_stream_t *server, int status)
-{
- int result;
- uv_stream_t *client;
- Server *srv = server->data;
-
- if (status < 0) {
- abort();
- }
-
- if (srv->type == kServerTypeTcp) {
- client = xmalloc(sizeof(uv_tcp_t));
- uv_tcp_init(uv_default_loop(), (uv_tcp_t *)client);
- } else {
- client = xmalloc(sizeof(uv_pipe_t));
- uv_pipe_init(uv_default_loop(), (uv_pipe_t *)client, 0);
- }
-
- result = uv_accept(server, client);
-
- if (result) {
- EMSG2("Failed to accept connection: %s", uv_strerror(result));
- uv_close((uv_handle_t *)client, free_client);
- return;
- }
-
- channel_from_stream(client, srv->protocol);
-}
-
-static void close_server(Map *map, const char *endpoint, void *srv)
-{
- Server *server = srv;
-
- if (server->type == kServerTypeTcp) {
- uv_close((uv_handle_t *)&server->socket.tcp.handle, free_server);
- } else {
- uv_close((uv_handle_t *)&server->socket.pipe.handle, free_server);
- }
-}
-
-static void free_client(uv_handle_t *handle)
-{
- free(handle);
-}
-
-static void free_server(uv_handle_t *handle)
-{
- free(handle->data);
-}
diff --git a/src/os/server.h b/src/os/server.h
deleted file mode 100644
index b9459a81af..0000000000
--- a/src/os/server.h
+++ /dev/null
@@ -1,30 +0,0 @@
-#ifndef NEOVIM_OS_SERVER_H
-#define NEOVIM_OS_SERVER_H
-
-#include "os/channel_defs.h"
-
-/// Initializes the module
-void server_init();
-
-/// Teardown the server module
-void server_teardown();
-
-/// Starts listening on arbitrary tcp/unix addresses specified by
-/// `endpoint` for API calls. The type of socket used(tcp or unix/pipe) will
-/// be determined by parsing `endpoint`: If it's a valid tcp address in the
-/// 'ip:port' format, then it will be tcp socket, else it will be a unix
-/// socket or named pipe.
-///
-/// @param endpoint Address of the server. Either a 'ip:port' string or an
-/// arbitrary identifier(trimmed to 256 bytes) for the unix socket or
-/// named pipe.
-/// @param prot The rpc protocol to be used
-void server_start(char *endpoint, ChannelProtocol prot);
-
-/// Stops listening on the address specified by `endpoint`.
-///
-/// @param endpoint Address of the server.
-void server_stop(char *endpoint);
-
-#endif // NEOVIM_OS_SERVER_H
-
diff --git a/src/os/server_defs.h b/src/os/server_defs.h
deleted file mode 100644
index cbaefe3949..0000000000
--- a/src/os/server_defs.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#ifndef NEOVIM_OS_SERVER_DEFS_H
-#define NEOVIM_OS_SERVER_DEFS_H
-
-typedef struct server Server;
-
-#endif // NEOVIM_OS_SERVER_DEFS_H
-
diff --git a/src/os/shell.c b/src/os/shell.c
deleted file mode 100644
index d14e355d19..0000000000
--- a/src/os/shell.c
+++ /dev/null
@@ -1,465 +0,0 @@
-#include <string.h>
-#include <stdbool.h>
-#include <stdlib.h>
-
-#include <uv.h>
-
-#include "os/shell.h"
-#include "os/signal.h"
-#include "types.h"
-#include "vim.h"
-#include "message.h"
-#include "ascii.h"
-#include "memory.h"
-#include "term.h"
-#include "misc2.h"
-#include "screen.h"
-#include "memline.h"
-#include "option_defs.h"
-#include "charset.h"
-
-#define BUFFER_LENGTH 1024
-
-typedef struct {
- bool reading;
- int old_state, old_mode, exit_status, exited;
- char *wbuffer;
- char rbuffer[BUFFER_LENGTH];
- uv_buf_t bufs[2];
- uv_stream_t *shell_stdin;
- garray_T ga;
-} ProcessData;
-
-/// Parses a command string into a sequence of words, taking quotes into
-/// consideration.
-///
-/// @param str The command string to be parsed
-/// @param argv The vector that will be filled with copies of the parsed
-/// words. It can be NULL if the caller only needs to count words.
-/// @return The number of words parsed.
-static int tokenize(char_u *str, char **argv);
-
-/// Calculates the length of a shell word.
-///
-/// @param str A pointer to the first character of the word
-/// @return The offset from `str` at which the word ends.
-static int word_length(char_u *command);
-
-/// Queues selected range for writing to the child process stdin.
-///
-/// @param req The structure containing information to peform the write
-static void write_selection(uv_write_t *req);
-
-/// Cleanup memory and restore state modified by `os_call_shell`.
-///
-/// @param data State shared by all functions collaborating with
-/// `os_call_shell`.
-/// @param opts Process spawning options, containing some allocated memory
-/// @param shellopts Options passed to `os_call_shell`. Used for deciding
-/// if/which messages are displayed.
-static int proc_cleanup_exit(ProcessData *data,
- uv_process_options_t *opts,
- int shellopts);
-// Callbacks for libuv
-static void alloc_cb(uv_handle_t *handle, size_t suggested, uv_buf_t *buf);
-static void read_cb(uv_stream_t *stream, ssize_t cnt, const uv_buf_t *buf);
-static void write_cb(uv_write_t *req, int status);
-static void exit_cb(uv_process_t *proc, int64_t status, int term_signal);
-
-char ** shell_build_argv(char_u *cmd, char_u *extra_shell_opt)
-{
- int i;
- char **rv;
- int argc = tokenize(p_sh, NULL) + tokenize(p_shcf, NULL);
-
- rv = (char **)xmalloc((unsigned)((argc + 4) * sizeof(char *)));
-
- // Split 'shell'
- i = tokenize(p_sh, rv);
-
- if (extra_shell_opt != NULL) {
- // Push a copy of `extra_shell_opt`
- rv[i++] = xstrdup((char *)extra_shell_opt);
- }
-
- if (cmd != NULL) {
- // Split 'shellcmdflag'
- i += tokenize(p_shcf, rv + i);
- rv[i++] = xstrdup((char *)cmd);
- }
-
- rv[i] = NULL;
-
- return rv;
-}
-
-void shell_free_argv(char **argv)
-{
- char **p = argv;
-
- if (p == NULL) {
- // Nothing was allocated, return
- return;
- }
-
- while (*p != NULL) {
- // Free each argument
- free(*p);
- p++;
- }
-
- free(argv);
-}
-
-int os_call_shell(char_u *cmd, ShellOpts opts, char_u *extra_shell_arg)
-{
- uv_stdio_container_t proc_stdio[3];
- uv_process_options_t proc_opts;
- uv_process_t proc;
- uv_pipe_t proc_stdin, proc_stdout;
- uv_write_t write_req;
- int expected_exits = 1;
- ProcessData pdata = {
- .reading = false,
- .exited = 0,
- .old_mode = cur_tmode,
- .old_state = State,
- .shell_stdin = (uv_stream_t *)&proc_stdin,
- .wbuffer = NULL,
- };
-
- out_flush();
- if (opts & kShellOptCooked) {
- // set to normal mode
- settmode(TMODE_COOK);
- }
-
- // While the child is running, ignore terminating signals
- signal_reject_deadly();
-
- // Create argv for `uv_spawn`
- // TODO(tarruda): we can use a static buffer for small argument vectors. 1024
- // bytes should be enough for most of the commands and if more is necessary
- // we can allocate a another buffer
- proc_opts.args = shell_build_argv(cmd, extra_shell_arg);
- proc_opts.file = proc_opts.args[0];
- proc_opts.exit_cb = exit_cb;
- // Initialize libuv structures
- proc_opts.stdio = proc_stdio;
- proc_opts.stdio_count = 3;
- // Hide window on Windows :)
- proc_opts.flags = UV_PROCESS_WINDOWS_HIDE;
- proc_opts.cwd = NULL;
- proc_opts.env = NULL;
-
- // The default is to inherit all standard file descriptors(this will change
- // when the UI is moved to an external process)
- proc_stdio[0].flags = UV_INHERIT_FD;
- proc_stdio[0].data.fd = 0;
- proc_stdio[1].flags = UV_INHERIT_FD;
- proc_stdio[1].data.fd = 1;
- proc_stdio[2].flags = UV_INHERIT_FD;
- proc_stdio[2].data.fd = 2;
-
- if (opts & (kShellOptHideMess | kShellOptExpand)) {
- // Ignore the shell stdio(redirects to /dev/null on unixes)
- proc_stdio[0].flags = UV_IGNORE;
- proc_stdio[1].flags = UV_IGNORE;
- proc_stdio[2].flags = UV_IGNORE;
- } else {
- State = EXTERNCMD;
-
- if (opts & kShellOptWrite) {
- // Write from the current buffer into the process stdin
- uv_pipe_init(uv_default_loop(), &proc_stdin, 0);
- write_req.data = &pdata;
- proc_stdio[0].flags = UV_CREATE_PIPE | UV_READABLE_PIPE;
- proc_stdio[0].data.stream = (uv_stream_t *)&proc_stdin;
- }
-
- if (opts & kShellOptRead) {
- // Read from the process stdout into the current buffer
- uv_pipe_init(uv_default_loop(), &proc_stdout, 0);
- proc_stdout.data = &pdata;
- proc_stdio[1].flags = UV_CREATE_PIPE | UV_WRITABLE_PIPE;
- proc_stdio[1].data.stream = (uv_stream_t *)&proc_stdout;
- ga_init(&pdata.ga, 1, BUFFER_LENGTH);
- }
- }
-
- if (uv_spawn(uv_default_loop(), &proc, &proc_opts)) {
- // Failed, probably due to `sh` not being executable
- if (!emsg_silent) {
- MSG_PUTS(_("\nCannot execute shell "));
- msg_outtrans(p_sh);
- msg_putchar('\n');
- }
-
- return proc_cleanup_exit(&pdata, &proc_opts, opts);
- }
-
- // Assign the flag address after `proc` is initialized by `uv_spawn`
- proc.data = &pdata;
-
- if (opts & kShellOptWrite) {
- // Queue everything for writing to the shell stdin
- write_selection(&write_req);
- expected_exits++;
- }
-
- if (opts & kShellOptRead) {
- // Start the read stream for the shell stdout
- uv_read_start((uv_stream_t *)&proc_stdout, alloc_cb, read_cb);
- expected_exits++;
- }
-
- // Keep running the loop until all three handles are completely closed
- while (pdata.exited < expected_exits) {
- uv_run(uv_default_loop(), UV_RUN_ONCE);
-
- if (got_int) {
- // Forward SIGINT to the shell
- // TODO(tarruda): for now this is only needed if the terminal is in raw
- // mode, but when the UI is externalized we'll also need it, so leave it
- // here
- uv_process_kill(&proc, SIGINT);
- got_int = false;
- }
- }
-
- if (opts & kShellOptRead) {
- if (pdata.ga.ga_len > 0) {
- // If there's an unfinished line in the growable array, append it now.
- append_ga_line(&pdata.ga);
- // remember that the NL was missing
- curbuf->b_no_eol_lnum = curwin->w_cursor.lnum;
- } else {
- curbuf->b_no_eol_lnum = 0;
- }
- ga_clear(&pdata.ga);
- }
-
- if (opts & kShellOptWrite) {
- free(pdata.wbuffer);
- }
-
- return proc_cleanup_exit(&pdata, &proc_opts, opts);
-}
-
-static int tokenize(char_u *str, char **argv)
-{
- int argc = 0, len;
- char_u *p = str;
-
- while (*p != NUL) {
- len = word_length(p);
-
- if (argv != NULL) {
- // Fill the slot
- argv[argc] = xmalloc(len + 1);
- memcpy(argv[argc], p, len);
- argv[argc][len] = NUL;
- }
-
- argc++;
- p += len;
- p = skipwhite(p);
- }
-
- return argc;
-}
-
-static int word_length(char_u *str)
-{
- char_u *p = str;
- bool inquote = false;
- int length = 0;
-
- // Move `p` to the end of shell word by advancing the pointer while it's
- // inside a quote or it's a non-whitespace character
- while (*p && (inquote || (*p != ' ' && *p != TAB))) {
- if (*p == '"') {
- // Found a quote character, switch the `inquote` flag
- inquote = !inquote;
- }
-
- p++;
- length++;
- }
-
- return length;
-}
-
-/// To remain compatible with the old implementation(which forked a process
-/// for writing) the entire text is copied to a temporary buffer before the
-/// event loop starts. If we don't(by writing in chunks returned by `ml_get`)
-/// the buffer being modified might get modified by reading from the process
-/// before we finish writing.
-static void write_selection(uv_write_t *req)
-{
- ProcessData *pdata = (ProcessData *)req->data;
- // TODO(tarruda): use a static buffer for up to a limit(BUFFER_LENGTH) and
- // only after filled we should start allocating memory(skip unnecessary
- // allocations for small writes)
- int buflen = BUFFER_LENGTH;
- pdata->wbuffer = (char *)xmalloc(buflen);
- uv_buf_t uvbuf;
- linenr_T lnum = curbuf->b_op_start.lnum;
- int off = 0;
- int written = 0;
- char_u *lp = ml_get(lnum);
- int l;
- int len;
-
- for (;;) {
- l = strlen((char *)lp + written);
- if (l == 0) {
- len = 0;
- } else if (lp[written] == NL) {
- // NL -> NUL translation
- len = 1;
- if (off + len >= buflen) {
- // Resize the buffer
- buflen *= 2;
- pdata->wbuffer = xrealloc(pdata->wbuffer, buflen);
- }
- pdata->wbuffer[off++] = NUL;
- } else {
- char_u *s = vim_strchr(lp + written, NL);
- len = s == NULL ? l : s - (lp + written);
- while (off + len >= buflen) {
- // Resize the buffer
- buflen *= 2;
- pdata->wbuffer = xrealloc(pdata->wbuffer, buflen);
- }
- memcpy(pdata->wbuffer + off, lp + written, len);
- off += len;
- }
- if (len == l) {
- // Finished a line, add a NL, unless this line
- // should not have one.
- // FIXME need to make this more readable
- if (lnum != curbuf->b_op_end.lnum
- || !curbuf->b_p_bin
- || (lnum != curbuf->b_no_eol_lnum
- && (lnum !=
- curbuf->b_ml.ml_line_count
- || curbuf->b_p_eol))) {
- if (off + 1 >= buflen) {
- // Resize the buffer
- buflen *= 2;
- pdata->wbuffer = xrealloc(pdata->wbuffer, buflen);
- }
- pdata->wbuffer[off++] = NL;
- }
- ++lnum;
- if (lnum > curbuf->b_op_end.lnum) {
- break;
- }
- lp = ml_get(lnum);
- written = 0;
- } else if (len > 0) {
- written += len;
- }
- }
-
- uvbuf.base = pdata->wbuffer;
- uvbuf.len = off;
-
- uv_write(req, pdata->shell_stdin, &uvbuf, 1, write_cb);
-}
-
-// "Allocates" a buffer for reading from the shell stdout.
-static void alloc_cb(uv_handle_t *handle, size_t suggested, uv_buf_t *buf)
-{
- ProcessData *pdata = (ProcessData *)handle->data;
-
- if (pdata->reading) {
- buf->len = 0;
- return;
- }
-
- buf->base = pdata->rbuffer;
- buf->len = BUFFER_LENGTH;
- // Avoid `alloc_cb`, `alloc_cb` sequences on windows
- pdata->reading = true;
-}
-
-static void read_cb(uv_stream_t *stream, ssize_t cnt, const uv_buf_t *buf)
-{
- // TODO(tarruda): avoid using a growable array for this, refactor the
- // algorithm to call `ml_append` directly(skip unecessary copies/resizes)
- int i;
- ProcessData *pdata = (ProcessData *)stream->data;
-
- if (cnt <= 0) {
- if (cnt != UV_ENOBUFS) {
- uv_read_stop(stream);
- uv_close((uv_handle_t *)stream, NULL);
- pdata->exited++;
- }
- return;
- }
-
- for (i = 0; i < cnt; ++i) {
- if (pdata->rbuffer[i] == NL) {
- // Insert the line
- append_ga_line(&pdata->ga);
- } else if (pdata->rbuffer[i] == NUL) {
- // Translate NUL to NL
- ga_append(&pdata->ga, NL);
- } else {
- // buffer data into the grow array
- ga_append(&pdata->ga, pdata->rbuffer[i]);
- }
- }
-
- windgoto(msg_row, msg_col);
- cursor_on();
- out_flush();
-
- pdata->reading = false;
-}
-
-static void write_cb(uv_write_t *req, int status)
-{
- ProcessData *pdata = (ProcessData *)req->data;
- uv_close((uv_handle_t *)pdata->shell_stdin, NULL);
- pdata->exited++;
-}
-
-static int proc_cleanup_exit(ProcessData *proc_data,
- uv_process_options_t *proc_opts,
- int shellopts)
-{
- if (proc_data->exited) {
- if (!emsg_silent && proc_data->exit_status != 0 &&
- !(shellopts & kShellOptSilent)) {
- MSG_PUTS(_("\nshell returned "));
- msg_outnum((int64_t)proc_data->exit_status);
- msg_putchar('\n');
- }
- }
-
- State = proc_data->old_state;
-
- if (proc_data->old_mode == TMODE_RAW) {
- // restore mode
- settmode(TMODE_RAW);
- }
-
- signal_accept_deadly();
-
- // Release argv memory
- shell_free_argv(proc_opts->args);
-
- return proc_data->exit_status;
-}
-
-static void exit_cb(uv_process_t *proc, int64_t status, int term_signal)
-{
- ProcessData *data = (ProcessData *)proc->data;
- data->exited++;
- data->exit_status = status;
- uv_close((uv_handle_t *)proc, NULL);
-}
diff --git a/src/os/shell.h b/src/os/shell.h
deleted file mode 100644
index 776c36d384..0000000000
--- a/src/os/shell.h
+++ /dev/null
@@ -1,45 +0,0 @@
-#ifndef NEOVIM_OS_SHELL_H
-#define NEOVIM_OS_SHELL_H
-
-#include <stdbool.h>
-
-#include "types.h"
-
-// Flags for mch_call_shell() second argument
-typedef enum {
- kShellOptFilter = 1, ///< filtering text
- kShellOptExpand = 2, ///< expanding wildcards
- kShellOptCooked = 4, ///< set term to cooked mode
- kShellOptDoOut = 8, ///< redirecting output
- kShellOptSilent = 16, ///< don't print error returned by command
- kShellOptRead = 32, ///< read lines and insert into buffer
- kShellOptWrite = 64, ///< write lines from buffer
- kShellOptHideMess = 128, ///< previously a global variable from os_unix.c
-} ShellOpts;
-
-/// Builds the argument vector for running the shell configured in `sh`
-/// ('shell' option), optionally with a command that will be passed with `shcf`
-/// ('shellcmdflag').
-///
-/// @param cmd Command string. If NULL it will run an interactive shell.
-/// @param extra_shell_opt Extra argument to the shell. If NULL it is ignored
-/// @return A newly allocated argument vector. It must be freed with
-/// `shell_free_argv` when no longer needed.
-char ** shell_build_argv(char_u *cmd, char_u *extra_shell_arg);
-
-/// Releases the memory allocated by `shell_build_argv`.
-///
-/// @param argv The argument vector.
-void shell_free_argv(char **argv);
-
-/// Calls the user shell for running a command, interactive session or
-/// wildcard expansion. It uses the shell set in the `sh` option.
-///
-/// @param cmd The command to be executed. If NULL it will run an interactive
-/// shell
-/// @param opts Various options that control how the shell will work
-/// @param extra_shell_arg Extra argument to be passed to the shell
-int os_call_shell(char_u *cmd, ShellOpts opts, char_u *extra_shell_arg);
-
-#endif // NEOVIM_OS_SHELL_H
-
diff --git a/src/os/signal.c b/src/os/signal.c
deleted file mode 100644
index d3bedad09c..0000000000
--- a/src/os/signal.c
+++ /dev/null
@@ -1,163 +0,0 @@
-#include <stdbool.h>
-
-#include <uv.h>
-
-#include "types.h"
-#include "vim.h"
-#include "globals.h"
-#include "memline.h"
-#include "eval.h"
-#include "term.h"
-#include "memory.h"
-#include "misc1.h"
-#include "misc2.h"
-#include "os/event_defs.h"
-#include "os/event.h"
-#include "os/signal.h"
-
-static uv_signal_t sint, spipe, shup, squit, sterm, swinch;
-#ifdef SIGPWR
-static uv_signal_t spwr;
-#endif
-
-static bool rejecting_deadly;
-static char * signal_name(int signum);
-static void deadly_signal(int signum);
-static void signal_cb(uv_signal_t *, int signum);
-
-void signal_init()
-{
- uv_signal_init(uv_default_loop(), &sint);
- uv_signal_init(uv_default_loop(), &spipe);
- uv_signal_init(uv_default_loop(), &shup);
- uv_signal_init(uv_default_loop(), &squit);
- uv_signal_init(uv_default_loop(), &sterm);
- uv_signal_init(uv_default_loop(), &swinch);
- uv_signal_start(&sint, signal_cb, SIGINT);
- uv_signal_start(&spipe, signal_cb, SIGPIPE);
- uv_signal_start(&shup, signal_cb, SIGHUP);
- uv_signal_start(&squit, signal_cb, SIGQUIT);
- uv_signal_start(&sterm, signal_cb, SIGTERM);
- uv_signal_start(&swinch, signal_cb, SIGWINCH);
-#ifdef SIGPWR
- uv_signal_init(uv_default_loop(), &spwr);
- uv_signal_start(&spwr, signal_cb, SIGPWR);
-#endif
-}
-
-void signal_stop()
-{
- uv_signal_stop(&sint);
- uv_signal_stop(&spipe);
- uv_signal_stop(&shup);
- uv_signal_stop(&squit);
- uv_signal_stop(&sterm);
- uv_signal_stop(&swinch);
-#ifdef SIGPWR
- uv_signal_stop(&spwr);
-#endif
-}
-
-void signal_reject_deadly()
-{
- rejecting_deadly = true;
-}
-
-void signal_accept_deadly()
-{
- rejecting_deadly = false;
-}
-
-void signal_handle(Event event)
-{
- int signum = event.data.signum;
-
- switch (signum) {
- case SIGINT:
- got_int = true;
- break;
-#ifdef SIGPWR
- case SIGPWR:
- // Signal of a power failure(eg batteries low), flush the swap files to
- // be safe
- ml_sync_all(false, false);
- break;
-#endif
- case SIGPIPE:
- // Ignore
- break;
- case SIGWINCH:
- shell_resized();
- break;
- case SIGTERM:
- case SIGQUIT:
- case SIGHUP:
- if (!rejecting_deadly) {
- deadly_signal(signum);
- }
- break;
- default:
- fprintf(stderr, "Invalid signal %d", signum);
- break;
- }
-}
-
-static char * signal_name(int signum)
-{
- switch (signum) {
- case SIGINT:
- return "SIGINT";
-#ifdef SIGPWR
- case SIGPWR:
- return "SIGPWR";
-#endif
- case SIGPIPE:
- return "SIGPIPE";
- case SIGWINCH:
- return "SIGWINCH";
- case SIGTERM:
- return "SIGTERM";
- case SIGQUIT:
- return "SIGQUIT";
- case SIGHUP:
- return "SIGHUP";
- default:
- return "Unknown";
- }
-}
-
-// This function handles deadly signals.
-// It tries to preserve any swap files and exit properly.
-// (partly from Elvis).
-// NOTE: Avoid unsafe functions, such as allocating memory, they can result in
-// a deadlock.
-static void deadly_signal(int signum)
-{
- // Set the v:dying variable.
- set_vim_var_nr(VV_DYING, 1);
-
- snprintf((char *)IObuff, sizeof(IObuff), "Vim: Caught deadly signal '%s'\n",
- signal_name(signum));
-
- // Preserve files and exit.
- preserve_exit();
-}
-
-static void signal_cb(uv_signal_t *handle, int signum)
-{
- if (rejecting_deadly) {
- if (signum == SIGINT) {
- got_int = true;
- }
-
- return;
- }
-
- Event event = {
- .type = kEventSignal,
- .data = {
- .signum = signum
- }
- };
- event_push(event);
-}
diff --git a/src/os/signal.h b/src/os/signal.h
deleted file mode 100644
index 79fdc8d79c..0000000000
--- a/src/os/signal.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#ifndef NEOVIM_OS_SIGNAL_H
-#define NEOVIM_OS_SIGNAL_H
-
-#include "os/event_defs.h"
-
-void signal_init(void);
-void signal_stop(void);
-void signal_accept_deadly(void);
-void signal_reject_deadly(void);
-void signal_handle(Event event);
-
-#endif // NEOVIM_OS_SIGNAL_H
-
diff --git a/src/os/time.c b/src/os/time.c
deleted file mode 100644
index 1dc7ca68d4..0000000000
--- a/src/os/time.c
+++ /dev/null
@@ -1,86 +0,0 @@
-#include <stdint.h>
-#include <stdbool.h>
-#include <sys/time.h>
-
-#include <uv.h>
-
-#include "os/time.h"
-#include "vim.h"
-#include "term.h"
-
-static uv_mutex_t delay_mutex;
-static uv_cond_t delay_cond;
-
-static void microdelay(uint64_t ms);
-
-void time_init()
-{
- uv_mutex_init(&delay_mutex);
- uv_cond_init(&delay_cond);
-}
-
-void os_delay(uint64_t milliseconds, bool ignoreinput)
-{
- os_microdelay(milliseconds * 1000, ignoreinput);
-}
-
-void os_microdelay(uint64_t microseconds, bool ignoreinput)
-{
- int old_tmode;
-
- if (ignoreinput) {
- // Go to cooked mode without echo, to allow SIGINT interrupting us
- // here
- old_tmode = curr_tmode;
-
- if (curr_tmode == TMODE_RAW)
- settmode(TMODE_SLEEP);
-
- microdelay(microseconds);
-
- settmode(old_tmode);
- } else {
- microdelay(microseconds);
- }
-}
-
-static void microdelay(uint64_t microseconds)
-{
- uint64_t hrtime;
- int64_t ns = microseconds * 1000; // convert to nanoseconds
-
- uv_mutex_lock(&delay_mutex);
-
- while (ns > 0) {
- hrtime = uv_hrtime();
- if (uv_cond_timedwait(&delay_cond, &delay_mutex, ns) == UV_ETIMEDOUT)
- break;
- ns -= uv_hrtime() - hrtime;
- }
-
- uv_mutex_unlock(&delay_mutex);
-}
-
-struct tm *os_localtime_r(const time_t *clock, struct tm *result)
-{
-#ifdef UNIX
- // POSIX provides localtime_r() as a thread-safe version of localtime().
- return localtime_r(clock, result);
-#else
- // Windows version of localtime() is thread-safe.
- // See http://msdn.microsoft.com/en-us/library/bf12f0hc%28VS.80%29.aspx
- struct tm *local_time = localtime(clock); // NOLINT
- *result = *local_time;
-return result;
-#endif
-}
-
-struct tm *os_get_localtime(struct tm *result)
-{
- struct timeval tv;
- if (gettimeofday(&tv, NULL) < 0) {
- return NULL;
- }
-
- return os_localtime_r(&tv.tv_sec, result);
-}
diff --git a/src/os/time.h b/src/os/time.h
deleted file mode 100644
index ef795d03be..0000000000
--- a/src/os/time.h
+++ /dev/null
@@ -1,35 +0,0 @@
-#ifndef NEOVIM_OS_TIME_H
-#define NEOVIM_OS_TIME_H
-
-#include <stdint.h>
-#include <stdbool.h>
-
-/// Initializes the time module
-void time_init(void);
-
-/// Sleeps for a certain amount of milliseconds
-///
-/// @param milliseconds Number of milliseconds to sleep
-/// @param ignoreinput If true, allow a SIGINT to interrupt us
-void os_delay(uint64_t milliseconds, bool ignoreinput);
-
-/// Sleeps for a certain amount of microseconds
-///
-/// @param microseconds Number of microseconds to sleep
-/// @param ignoreinput If true, allow a SIGINT to interrupt us
-void os_microdelay(uint64_t microseconds, bool ignoreinput);
-
-/// Portable version of POSIX localtime_r()
-///
-/// @return NULL in case of error
-struct tm *os_localtime_r(const time_t *clock, struct tm *result);
-
-/// Obtains the current UNIX timestamp and adjusts it to local time
-///
-/// @param result Pointer to a 'struct tm' where the result should be placed
-/// @return A pointer to a 'struct tm' in the current time zone (the 'result'
-/// argument) or NULL in case of error
-struct tm *os_get_localtime(struct tm *result);
-
-#endif // NEOVIM_OS_TIME_H
-
diff --git a/src/os/users.c b/src/os/users.c
deleted file mode 100644
index e7b362637b..0000000000
--- a/src/os/users.c
+++ /dev/null
@@ -1,87 +0,0 @@
-// users.c -- operating system user information
-
-#include <uv.h>
-
-#include "os/os.h"
-#include "garray.h"
-#include "misc2.h"
-#ifdef HAVE_PWD_H
-# include <pwd.h>
-#endif
-
-// Initialize users garray and fill it with os usernames.
-// Return Ok for success, FAIL for failure.
-int os_get_usernames(garray_T *users)
-{
- if (users == NULL) {
- return FAIL;
- }
- ga_init(users, sizeof(char *), 20);
-
-# if defined(HAVE_GETPWENT) && defined(HAVE_PWD_H)
- char *user;
- struct passwd *pw;
-
- setpwent();
- while ((pw = getpwent()) != NULL) {
- // pw->pw_name shouldn't be NULL but just in case...
- if (pw->pw_name != NULL) {
- ga_grow(users, 1);
- user = (char *)vim_strsave((char_u*)pw->pw_name);
- if (user == NULL) {
- return FAIL;
- }
- ((char **)(users->ga_data))[users->ga_len++] = user;
- }
- }
- endpwent();
-# endif
-
- return OK;
-}
-
-// Insert user name in s[len].
-// Return OK if a name found.
-int os_get_user_name(char *s, size_t len)
-{
- return os_get_uname(getuid(), s, len);
-}
-
-// Insert user name for "uid" in s[len].
-// Return OK if a name found.
-// If the name is not found, write the uid into s[len] and return FAIL.
-int os_get_uname(uid_t uid, char *s, size_t len)
-{
-#if defined(HAVE_PWD_H) && defined(HAVE_GETPWUID)
- struct passwd *pw;
-
- if ((pw = getpwuid(uid)) != NULL
- && pw->pw_name != NULL && *(pw->pw_name) != NUL) {
- vim_strncpy((char_u *)s, (char_u *)pw->pw_name, len - 1);
- return OK;
- }
-#endif
- snprintf(s, len, "%d", (int)uid);
- return FAIL; // a number is not a name
-}
-
-// Returns the user directory for the given username.
-// The caller has to free() the returned string.
-// If the username is not found, NULL is returned.
-char *os_get_user_directory(const char *name)
-{
-#if defined(HAVE_GETPWNAM) && defined(HAVE_PWD_H)
- struct passwd *pw;
- if (name == NULL) {
- return NULL;
- }
- pw = getpwnam(name);
- if (pw != NULL) {
- // save the string from the static passwd entry into malloced memory
- char *user_directory = (char *)vim_strsave((char_u *)pw->pw_dir);
- return user_directory;
- }
-#endif
- return NULL;
-}
-
diff --git a/src/os/uv_helpers.c b/src/os/uv_helpers.c
deleted file mode 100644
index 62b021de5e..0000000000
--- a/src/os/uv_helpers.c
+++ /dev/null
@@ -1,70 +0,0 @@
-#include <uv.h>
-
-#include "os/uv_helpers.h"
-#include "vim.h"
-#include "memory.h"
-
-/// Common structure that will always be assigned to the `data` field of
-/// libuv handles. It has fields for many types of pointers, and allow a single
-/// handle to contain data from many sources
-typedef struct {
- WStream *wstream;
- RStream *rstream;
- Job *job;
-} HandleData;
-
-static HandleData *init(uv_handle_t *handle);
-
-RStream *handle_get_rstream(uv_handle_t *handle)
-{
- RStream *rv = init(handle)->rstream;
- assert(rv != NULL);
- return rv;
-}
-
-void handle_set_rstream(uv_handle_t *handle, RStream *rstream)
-{
- init(handle)->rstream = rstream;
-}
-
-WStream *handle_get_wstream(uv_handle_t *handle)
-{
- WStream *rv = init(handle)->wstream;
- assert(rv != NULL);
- return rv;
-}
-
-void handle_set_wstream(uv_handle_t *handle, WStream *wstream)
-{
- HandleData *data = init(handle);
- data->wstream = wstream;
-}
-
-Job *handle_get_job(uv_handle_t *handle)
-{
- Job *rv = init(handle)->job;
- assert(rv != NULL);
- return rv;
-}
-
-void handle_set_job(uv_handle_t *handle, Job *job)
-{
- init(handle)->job = job;
-}
-
-static HandleData *init(uv_handle_t *handle)
-{
- HandleData *rv;
-
- if (handle->data == NULL) {
- rv = xmalloc(sizeof(HandleData));
- rv->rstream = NULL;
- rv->wstream = NULL;
- rv->job = NULL;
- handle->data = rv;
- } else {
- rv = handle->data;
- }
-
- return rv;
-}
diff --git a/src/os/uv_helpers.h b/src/os/uv_helpers.h
deleted file mode 100644
index 9d4cea30b2..0000000000
--- a/src/os/uv_helpers.h
+++ /dev/null
@@ -1,47 +0,0 @@
-#ifndef NEOVIM_OS_UV_HELPERS_H
-#define NEOVIM_OS_UV_HELPERS_H
-
-#include <uv.h>
-
-#include "os/wstream_defs.h"
-#include "os/rstream_defs.h"
-#include "os/job_defs.h"
-
-/// Gets the RStream instance associated with a libuv handle
-///
-/// @param handle libuv handle
-/// @return the RStream pointer
-RStream *handle_get_rstream(uv_handle_t *handle);
-
-/// Associates a RStream instance with a libuv handle
-///
-/// @param handle libuv handle
-/// @param rstream the RStream pointer
-void handle_set_rstream(uv_handle_t *handle, RStream *rstream);
-
-/// Gets the WStream instance associated with a libuv handle
-///
-/// @param handle libuv handle
-/// @return the WStream pointer
-WStream *handle_get_wstream(uv_handle_t *handle);
-
-/// Associates a WStream instance with a libuv handle
-///
-/// @param handle libuv handle
-/// @param wstream the WStream pointer
-void handle_set_wstream(uv_handle_t *handle, WStream *wstream);
-
-/// Gets the Job instance associated with a libuv handle
-///
-/// @param handle libuv handle
-/// @return the Job pointer
-Job *handle_get_job(uv_handle_t *handle);
-
-/// Associates a Job instance with a libuv handle
-///
-/// @param handle libuv handle
-/// @param job the Job pointer
-void handle_set_job(uv_handle_t *handle, Job *job);
-
-#endif // NEOVIM_OS_UV_HELPERS_H
-
diff --git a/src/os/wstream.c b/src/os/wstream.c
deleted file mode 100644
index 0b289e80f5..0000000000
--- a/src/os/wstream.c
+++ /dev/null
@@ -1,117 +0,0 @@
-#include <stdint.h>
-#include <stdbool.h>
-
-#include <uv.h>
-
-#include "os/uv_helpers.h"
-#include "os/wstream.h"
-#include "os/wstream_defs.h"
-#include "vim.h"
-#include "memory.h"
-
-struct wstream {
- uv_stream_t *stream;
- // Memory currently used by pending buffers
- uint32_t curmem;
- // Maximum memory used by this instance
- uint32_t maxmem;
- // Number of pending requests
- uint32_t pending_reqs;
- bool freed;
-};
-
-typedef struct {
- WStream *wstream;
- // Buffer containing data to be written
- char *buffer;
- // Size of the buffer
- uint32_t length;
- // If it's our responsibility to free the buffer
- bool free;
-} WriteData;
-
-static void write_cb(uv_write_t *req, int status);
-
-WStream * wstream_new(uint32_t maxmem)
-{
- WStream *rv = xmalloc(sizeof(WStream));
- rv->maxmem = maxmem;
- rv->stream = NULL;
- rv->curmem = 0;
- rv->pending_reqs = 0;
- rv->freed = false;
-
- return rv;
-}
-
-void wstream_free(WStream *wstream)
-{
- if (!wstream->pending_reqs) {
- free(wstream);
- } else {
- wstream->freed = true;
- }
-}
-
-void wstream_set_stream(WStream *wstream, uv_stream_t *stream)
-{
- handle_set_wstream((uv_handle_t *)stream, wstream);
- wstream->stream = stream;
-}
-
-bool wstream_write(WStream *wstream, char *buffer, uint32_t length, bool free)
-{
- WriteData *data;
- uv_buf_t uvbuf;
- uv_write_t *req;
-
- if (wstream->freed) {
- // Don't accept write requests after the WStream instance was freed
- return false;
- }
-
- if (wstream->curmem + length > wstream->maxmem) {
- return false;
- }
-
- if (free) {
- // We should only account for buffers that are ours to free
- wstream->curmem += length;
- }
-
- data = xmalloc(sizeof(WriteData));
- data->wstream = wstream;
- data->buffer = buffer;
- data->length = length;
- data->free = free;
- req = xmalloc(sizeof(uv_write_t));
- req->data = data;
- uvbuf.base = buffer;
- uvbuf.len = length;
- wstream->pending_reqs++;
- uv_write(req, wstream->stream, &uvbuf, 1, write_cb);
-
- return true;
-}
-
-static void write_cb(uv_write_t *req, int status)
-{
- WriteData *data = req->data;
-
- free(req);
-
- if (data->free) {
- // Free the data written to the stream
- free(data->buffer);
- data->wstream->curmem -= data->length;
- }
-
- data->wstream->pending_reqs--;
- if (data->wstream->freed && data->wstream->pending_reqs == 0) {
- // Last pending write, free the wstream;
- free(data->wstream);
- }
-
- free(data);
-}
-
diff --git a/src/os/wstream.h b/src/os/wstream.h
deleted file mode 100644
index 4a557ffd9f..0000000000
--- a/src/os/wstream.h
+++ /dev/null
@@ -1,40 +0,0 @@
-#ifndef NEOVIM_OS_WSTREAM_H
-#define NEOVIM_OS_WSTREAM_H
-
-#include <stdint.h>
-#include <stdbool.h>
-#include <uv.h>
-
-#include "os/wstream_defs.h"
-
-/// Creates a new WStream instance. A WStream encapsulates all the boilerplate
-/// necessary for writing to a libuv stream.
-///
-/// @param maxmem Maximum amount memory used by this `WStream` instance.
-/// @return The newly-allocated `WStream` instance
-WStream * wstream_new(uint32_t maxmem);
-
-/// Frees all memory allocated for a WStream instance
-///
-/// @param wstream The `WStream` instance
-void wstream_free(WStream *wstream);
-
-/// Sets the underlying `uv_stream_t` instance
-///
-/// @param wstream The `WStream` instance
-/// @param stream The new `uv_stream_t` instance
-void wstream_set_stream(WStream *wstream, uv_stream_t *stream);
-
-/// Queues data for writing to the backing file descriptor of a `WStream`
-/// instance. This will fail if the write would cause the WStream use more
-/// memory than specified by `maxmem`.
-///
-/// @param wstream The `WStream` instance
-/// @param buffer The buffer which contains data to be written
-/// @param length Number of bytes that should be written from `buffer`
-/// @param free If true, `buffer` will be freed after the write is complete
-/// @return true if the data was successfully queued, false otherwise.
-bool wstream_write(WStream *wstream, char *buffer, uint32_t length, bool free);
-
-#endif // NEOVIM_OS_WSTREAM_H
-
diff --git a/src/os/wstream_defs.h b/src/os/wstream_defs.h
deleted file mode 100644
index 59d57365fa..0000000000
--- a/src/os/wstream_defs.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#ifndef NEOVIM_OS_WSTREAM_DEFS_H
-#define NEOVIM_OS_WSTREAM_DEFS_H
-
-typedef struct wstream WStream;
-
-#endif // NEOVIM_OS_WSTREAM_DEFS_H
-