Commit 8fb3ee88 authored by Peter Pentchev's avatar Peter Pentchev

Handle short read/writes and I/O errors

parent 275537b9
......@@ -8,6 +8,7 @@ Change log for hexer, the multi-view binary editor
- remove some unused functions
- simplify exh_save_buffer(): it's only used on the whole file
- declare some functions as printf-like
- handle short reads/writes and read/write errors
0.1.8 2014/09/11
- fix a crash when inserting or replacing a half-byte
......
......@@ -57,6 +57,7 @@
#include "buffer.h"
#include "defs.h"
#include "util.h"
struct BufferOptions b_default_options = {
BUFFER_BLOCKSIZE,
......@@ -457,6 +458,7 @@ b_read_buffer_from_file(Buffer * const buffer, const char * const filename)
BufferBlock *i = 0;
char *tmp;
int file = open(filename, O_RDONLY);
int err_f = 0;
assert(!buffer->read_only);
BUFFER_CHANGED(buffer);
......@@ -485,12 +487,16 @@ b_read_buffer_from_file(Buffer * const buffer, const char * const filename)
}
buffer->size += bytes_read;
} else {
/* FIXME: handle read errors here */
err_f = bytes_read < 0;
free((char *)tmp);
break;
}
} while (1);
close(file);
if (err_f) {
b_clear(buffer);
return -1;
}
return buffer->size;
}
/* b_read_buffer_from_file */
......@@ -510,14 +516,13 @@ b_write_buffer_to_file(Buffer *buffer, char *filename)
i;
i = i->next_block, blocks++) {
ssize_t bytes;
bytes = write(file,
bytes = write_buf(file,
i->data,
(blocks * bs > buffer->size) ? buffer->size % bs : bs);
if (bytes < 0) {
close(file);
return -1;
}
/* FIXME: handle short writes */
bytes_wrote += bytes;
}
close(file);
......@@ -541,8 +546,7 @@ b_copy_to_file(Buffer *buffer, const char *filename, unsigned long position, uns
bytes_read =
b_read(buffer, tmp, position,
(buffer->blocksize < count) ? buffer->blocksize : count);
if (bytes_read < 0 || write(file, tmp, bytes_read) < 0) {
/* FIXME: handle short writes */
if (bytes_read < 0 || write_buf(file, tmp, bytes_read) < 0) {
free((char *)tmp);
close(file);
return -1;
......@@ -574,8 +578,7 @@ b_paste_from_file(Buffer *buffer, const char *filename, unsigned long position)
BUFFER_CHANGED(buffer);
do {
bytes_read = read(file, tmp, buffer->blocksize);
/* FIXME: handle read errors */
if (b_insert(buffer, position, bytes_read) < 0) {
if (bytes_read < 0 || b_insert(buffer, position, bytes_read) < 0) {
free((char *)tmp);
close(file);
return -1;
......
......@@ -1155,12 +1155,8 @@ exhcmd_help(struct he_s *hedit, const char *args, long begin __unused, long end
close(pipefd[1]);
goto exit_exhcmd_help;
} else if (!pid2) { /* child */
size_t len, n;
ssize_t res;
for (n = 0, len = strlen(helptext); n < len; n += res)
if ((res = write(pipefd[1], helptext + n, len - n)) == -1)
exit(1);
if (write_buf(pipefd[1], helptext, strlen(helptext)) < 0)
exit(1);
close(pipefd[1]);
exit(0);
}
......
......@@ -67,6 +67,7 @@
#include "regex.h"
#include "set.h"
#include "tio.h"
#include "util.h"
#define EXH_DEFAULT_SHELL "/bin/sh"
#define EXH_DEFAULT_PAGER "more"
......@@ -143,8 +144,8 @@ exh_shell_command(const char * const command, int pager_f)
close(pipe2[0]);
close(pipe2[1]);
/* send the command to the shell */
if (write(pipe1[1], command, strlen(command)) != (ssize_t)strlen(command) ||
write(pipe1[1], "\n", 1) != 1) {
if (write_buf(pipe1[1], command, strlen(command)) < 0 ||
write_buf(pipe1[1], "\n", 1) < 0) {
close(pipe1[1]);
he_message(1, "couldn't send the `%s' command to the pager", command);
close(pipe2[0]);
......@@ -197,8 +198,8 @@ exh_shell_command(const char * const command, int pager_f)
exit(EXIT_EXEC_FAILED);
}
} else { /* !pager_f */
if (write(pipe1[1], command, strlen(command)) != (ssize_t)strlen(command) ||
write(pipe1[1], "\n", 1) != 1) {
if (write_buf(pipe1[1], command, strlen(command)) < 0 ||
write_buf(pipe1[1], "\n", 1) < 0) {
close(pipe1[1]);
he_message(1, "couldn't send command `%s' to pager", command);
} else {
......
......@@ -49,6 +49,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "buffer.h"
#include "hexer.h"
......@@ -117,6 +118,20 @@ strerror(int errnum)
}
#endif /* HAVE_STRERROR */
int
write_buf(const int fd, const char * const buf, const size_t len)
{
size_t written = 0;
while (written < len) {
const size_t n = write(fd, buf + written, len - written);
if (n < 1)
return -1;
written += n;
}
return written;
}
/* end of util.c */
......
......@@ -48,5 +48,6 @@ char *strerror(int);
int util_strsort(char **);
int util_trunc(char *);
int write_buf(int, const char *, size_t);
#endif /* _UTIL_H_ */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment