mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
Merge #2184: Fix coverity issues. (6)
Reviewed-by: oni-link <knil.ino@gmail.com>
This commit is contained in:
commit
4bc62c76c7
@ -10,6 +10,7 @@
|
||||
* ex_getln.c: Functions for entering and editing an Ex command line.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
@ -3858,8 +3859,10 @@ expand_shellcmd (
|
||||
STRLCPY(buf + l, pat, MAXPATHL - l);
|
||||
|
||||
/* Expand matches in one directory of $PATH. */
|
||||
char_u **prev_file = *file;
|
||||
ret = expand_wildcards(1, &buf, num_file, file, flags);
|
||||
if (ret == OK) {
|
||||
assert(*file != prev_file);
|
||||
ga_grow(&ga, *num_file);
|
||||
{
|
||||
for (i = 0; i < *num_file; ++i) {
|
||||
|
@ -7416,7 +7416,7 @@ long read_eintr(int fd, void *buf, size_t bufsize)
|
||||
long ret;
|
||||
|
||||
for (;; ) {
|
||||
ret = vim_read(fd, buf, bufsize);
|
||||
ret = read(fd, buf, bufsize);
|
||||
if (ret >= 0 || errno != EINTR)
|
||||
break;
|
||||
}
|
||||
@ -7435,7 +7435,7 @@ long write_eintr(int fd, void *buf, size_t bufsize)
|
||||
/* Repeat the write() so long it didn't fail, other than being interrupted
|
||||
* by a signal. */
|
||||
while (ret < (long)bufsize) {
|
||||
wlen = vim_write(fd, (char *)buf + ret, bufsize - ret);
|
||||
wlen = write(fd, (char *)buf + ret, bufsize - ret);
|
||||
if (wlen < 0) {
|
||||
if (errno != EINTR)
|
||||
break;
|
||||
|
@ -54,6 +54,7 @@
|
||||
#include "nvim/cursor.h"
|
||||
#include "nvim/eval.h"
|
||||
#include "nvim/fileio.h"
|
||||
#include "nvim/func_attr.h"
|
||||
#include "nvim/main.h"
|
||||
#include "nvim/mark.h"
|
||||
#include "nvim/mbyte.h"
|
||||
@ -630,6 +631,15 @@ static int ml_check_b0_id(ZERO_BL *b0p)
|
||||
return OK;
|
||||
}
|
||||
|
||||
/// Return true if all strings in b0 are correct (nul-terminated).
|
||||
static bool ml_check_b0_strings(ZERO_BL *b0p) FUNC_ATTR_NONNULL_ALL
|
||||
{
|
||||
return (memchr(b0p->b0_version, NUL, 10)
|
||||
&& memchr(b0p->b0_uname, NUL, B0_UNAME_SIZE)
|
||||
&& memchr(b0p->b0_hname, NUL, B0_HNAME_SIZE)
|
||||
&& memchr(b0p->b0_fname, NUL, B0_FNAME_SIZE_CRYPT));
|
||||
}
|
||||
|
||||
/*
|
||||
* Update the timestamp or the B0_SAME_DIR flag of the .swp file.
|
||||
*/
|
||||
@ -1522,6 +1532,8 @@ static time_t swapfile_info(char_u *fname)
|
||||
MSG_PUTS(_(" [from Vim version 3.0]"));
|
||||
} else if (ml_check_b0_id(&b0) == FAIL) {
|
||||
MSG_PUTS(_(" [does not look like a Vim swap file]"));
|
||||
} else if (!ml_check_b0_strings(&b0)) {
|
||||
MSG_PUTS(_(" [garbled strings (not nul terminated)]"));
|
||||
} else {
|
||||
MSG_PUTS(_(" file name: "));
|
||||
if (b0.b0_fname[0] == NUL)
|
||||
|
@ -20,6 +20,7 @@
|
||||
|
||||
#include <uv.h>
|
||||
|
||||
#include "nvim/func_attr.h"
|
||||
#include "nvim/os/job.h"
|
||||
#include "nvim/os/job_defs.h"
|
||||
#include "nvim/os/job_private.h"
|
||||
@ -37,9 +38,10 @@ typedef struct {
|
||||
int tty_fd;
|
||||
} PtyProcess;
|
||||
|
||||
void pty_process_init(Job *job)
|
||||
void pty_process_init(Job *job) FUNC_ATTR_NONNULL_ALL
|
||||
{
|
||||
PtyProcess *ptyproc = xmalloc(sizeof(PtyProcess));
|
||||
ptyproc->tty_fd = -1;
|
||||
|
||||
if (job->opts.writable) {
|
||||
uv_pipe_init(uv_default_loop(), &ptyproc->proc_stdin, 0);
|
||||
@ -62,14 +64,35 @@ void pty_process_init(Job *job)
|
||||
job->process = ptyproc;
|
||||
}
|
||||
|
||||
void pty_process_destroy(Job *job)
|
||||
void pty_process_destroy(Job *job) FUNC_ATTR_NONNULL_ALL
|
||||
{
|
||||
free(job->opts.term_name);
|
||||
free(job->process);
|
||||
job->process = NULL;
|
||||
}
|
||||
|
||||
bool pty_process_spawn(Job *job)
|
||||
static bool set_pipe_duplicating_descriptor(int fd, uv_pipe_t *pipe)
|
||||
FUNC_ATTR_NONNULL_ALL
|
||||
{
|
||||
int fd_dup = dup(fd);
|
||||
if (fd_dup < 0) {
|
||||
ELOG("Failed to dup descriptor %d: %s", fd, strerror(errno));
|
||||
return false;
|
||||
}
|
||||
int uv_result = uv_pipe_open(pipe, fd_dup);
|
||||
if (uv_result) {
|
||||
ELOG("Failed to set pipe to descriptor %d: %s",
|
||||
fd_dup, uv_strerror(uv_result));
|
||||
close(fd_dup);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static const unsigned int KILL_RETRIES = 5;
|
||||
static const unsigned int KILL_TIMEOUT = 2; // seconds
|
||||
|
||||
bool pty_process_spawn(Job *job) FUNC_ATTR_NONNULL_ALL
|
||||
{
|
||||
int master;
|
||||
PtyProcess *ptyproc = job->process;
|
||||
@ -88,18 +111,29 @@ bool pty_process_spawn(Job *job)
|
||||
}
|
||||
|
||||
// make sure the master file descriptor is non blocking
|
||||
fcntl(master, F_SETFL, fcntl(master, F_GETFL) | O_NONBLOCK);
|
||||
|
||||
if (job->opts.writable) {
|
||||
uv_pipe_open(&ptyproc->proc_stdin, dup(master));
|
||||
int master_status_flags = fcntl(master, F_GETFL);
|
||||
if (master_status_flags == -1) {
|
||||
ELOG("Failed to get master descriptor status flags: %s", strerror(errno));
|
||||
goto error;
|
||||
}
|
||||
if (fcntl(master, F_SETFL, master_status_flags | O_NONBLOCK) == -1) {
|
||||
ELOG("Failed to make master descriptor non-blocking: %s", strerror(errno));
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (job->opts.stdout_cb) {
|
||||
uv_pipe_open(&ptyproc->proc_stdout, dup(master));
|
||||
if (job->opts.writable
|
||||
&& !set_pipe_duplicating_descriptor(master, &ptyproc->proc_stdin)) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (job->opts.stderr_cb) {
|
||||
uv_pipe_open(&ptyproc->proc_stderr, dup(master));
|
||||
if (job->opts.stdout_cb
|
||||
&& !set_pipe_duplicating_descriptor(master, &ptyproc->proc_stdout)) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (job->opts.stderr_cb
|
||||
&& !set_pipe_duplicating_descriptor(master, &ptyproc->proc_stderr)) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
uv_signal_init(uv_default_loop(), &ptyproc->schld);
|
||||
@ -108,25 +142,52 @@ bool pty_process_spawn(Job *job)
|
||||
ptyproc->tty_fd = master;
|
||||
job->pid = pid;
|
||||
return true;
|
||||
|
||||
error:
|
||||
close(master);
|
||||
|
||||
// terminate spawned process
|
||||
kill(pid, SIGTERM);
|
||||
int status, child;
|
||||
unsigned int try = 0;
|
||||
while (try++ < KILL_RETRIES && !(child = waitpid(pid, &status, WNOHANG))) {
|
||||
sleep(KILL_TIMEOUT);
|
||||
}
|
||||
if (child != pid) {
|
||||
kill(pid, SIGKILL);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void pty_process_close(Job *job)
|
||||
void pty_process_close(Job *job) FUNC_ATTR_NONNULL_ALL
|
||||
{
|
||||
PtyProcess *ptyproc = job->process;
|
||||
uv_signal_stop(&ptyproc->schld);
|
||||
uv_close((uv_handle_t *)&ptyproc->schld, NULL);
|
||||
pty_process_close_master(job);
|
||||
job_close_streams(job);
|
||||
job_decref(job);
|
||||
}
|
||||
|
||||
void pty_process_close_master(Job *job) FUNC_ATTR_NONNULL_ALL
|
||||
{
|
||||
PtyProcess *ptyproc = job->process;
|
||||
if (ptyproc->tty_fd >= 0) {
|
||||
close(ptyproc->tty_fd);
|
||||
ptyproc->tty_fd = -1;
|
||||
}
|
||||
}
|
||||
|
||||
void pty_process_resize(Job *job, uint16_t width, uint16_t height)
|
||||
FUNC_ATTR_NONNULL_ALL
|
||||
{
|
||||
PtyProcess *ptyproc = job->process;
|
||||
ptyproc->winsize = (struct winsize){height, width, 0, 0};
|
||||
ioctl(ptyproc->tty_fd, TIOCSWINSZ, &ptyproc->winsize);
|
||||
}
|
||||
|
||||
static void init_child(Job *job)
|
||||
static void init_child(Job *job) FUNC_ATTR_NONNULL_ALL
|
||||
{
|
||||
unsetenv("COLUMNS");
|
||||
unsetenv("LINES");
|
||||
@ -146,7 +207,7 @@ static void init_child(Job *job)
|
||||
fprintf(stderr, "execvp failed: %s\n", strerror(errno));
|
||||
}
|
||||
|
||||
static void chld_handler(uv_signal_t *handle, int signum)
|
||||
static void chld_handler(uv_signal_t *handle, int signum) FUNC_ATTR_NONNULL_ALL
|
||||
{
|
||||
Job *job = handle->data;
|
||||
int stat = 0;
|
||||
@ -171,7 +232,7 @@ static void chld_handler(uv_signal_t *handle, int signum)
|
||||
pty_process_close(job);
|
||||
}
|
||||
|
||||
static void init_termios(struct termios *termios)
|
||||
static void init_termios(struct termios *termios) FUNC_ATTR_NONNULL_ALL
|
||||
{
|
||||
memset(termios, 0, sizeof(struct termios));
|
||||
// Taken from pangoterm
|
||||
|
@ -322,13 +322,10 @@ enum {
|
||||
(size_t)(n))
|
||||
|
||||
#ifndef EINTR
|
||||
# define read_eintr(fd, buf, count) vim_read((fd), (buf), (count))
|
||||
# define write_eintr(fd, buf, count) vim_write((fd), (buf), (count))
|
||||
# define read_eintr(fd, buf, count) read((fd), (buf), (count))
|
||||
# define write_eintr(fd, buf, count) write((fd), (buf), (count))
|
||||
#endif
|
||||
|
||||
# define vim_read(fd, buf, count) read((fd), (char *)(buf), (size_t) (count))
|
||||
# define vim_write(fd, buf, count) write((fd), (char *)(buf), (size_t) (count))
|
||||
|
||||
/*
|
||||
* Enums need a typecast to be used as array index (for Ultrix).
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user