2007-07-27 09:50:37 -04:00
|
|
|
/** Low-level terminal-suitable I/O routines
|
|
|
|
* @file */
|
2005-09-15 09:58:31 -04:00
|
|
|
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
#include "config.h"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include <errno.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <sys/types.h>
|
|
|
|
#ifdef HAVE_UNISTD_H
|
|
|
|
#include <unistd.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include "elinks.h"
|
|
|
|
|
2022-05-09 12:53:36 -04:00
|
|
|
#include "osdep/osdep.h"
|
2005-09-15 09:58:31 -04:00
|
|
|
#include "terminal/hardio.h"
|
|
|
|
#include "util/error.h"
|
|
|
|
|
|
|
|
/* Define it to have data written to stderr */
|
2005-09-17 14:06:01 -04:00
|
|
|
#if 0
|
|
|
|
#define DEBUG_HARDIO
|
|
|
|
#endif
|
2005-09-15 09:58:31 -04:00
|
|
|
|
|
|
|
#undef debug_open
|
|
|
|
#undef debug_flush
|
|
|
|
#undef debug_write
|
|
|
|
|
|
|
|
#ifdef DEBUG_HARDIO
|
|
|
|
static void
|
2021-01-02 10:20:27 -05:00
|
|
|
hw_debug_open(char *name, int fd, char *data, int datalen)
|
2005-09-15 09:58:31 -04:00
|
|
|
{
|
|
|
|
fprintf(stderr, "[%s (fd=%d, data=%p, datalen=%d)]\n",
|
|
|
|
name, fd, data, datalen);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
hw_debug_flush()
|
|
|
|
{
|
|
|
|
fputs("\n\n", stderr);
|
|
|
|
fflush(stderr);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2021-01-02 10:20:27 -05:00
|
|
|
hw_debug_write(char *data, int w)
|
2005-09-15 09:58:31 -04:00
|
|
|
{
|
|
|
|
int hex = 0;
|
|
|
|
int i = 0;
|
|
|
|
|
|
|
|
if (!w) return;
|
|
|
|
|
|
|
|
for (; i < w; i++) {
|
|
|
|
if (data[i] == ' ') {
|
|
|
|
int c = i;
|
|
|
|
|
|
|
|
while (i < w && data[++i] == ' ');
|
|
|
|
|
|
|
|
if (i - c - 1 > 1) {
|
|
|
|
fprintf(stderr, "[+ %d spaces]\n", i - c - 1);
|
|
|
|
if (i == w) break;
|
|
|
|
c = 0;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
c = 0;
|
|
|
|
i--;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (data[i] >= ' ' && data[i] < 127 && data[i] != '|') {
|
|
|
|
if (hex) {
|
|
|
|
fputc('|', stderr);
|
|
|
|
hex = 0;
|
|
|
|
}
|
|
|
|
fputc(data[i], stderr);
|
|
|
|
} else {
|
|
|
|
if (!hex) {
|
|
|
|
fputc('|', stderr);
|
|
|
|
hex = 1;
|
|
|
|
}
|
|
|
|
fprintf(stderr,"%02x", data[i]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#define debug_open(n, fd, data, datalen) hw_debug_open(n, fd, data, datalen)
|
|
|
|
#define debug_flush() hw_debug_flush()
|
|
|
|
#define debug_write(data, datalen) hw_debug_write(data, datalen)
|
2005-09-17 14:06:01 -04:00
|
|
|
|
|
|
|
#else /* DEBUG_HARDIO */
|
|
|
|
|
2005-09-15 09:58:31 -04:00
|
|
|
#define debug_open(n, fd, data, datalen)
|
|
|
|
#define debug_flush()
|
|
|
|
#define debug_write(data, datalen)
|
2005-09-17 14:06:01 -04:00
|
|
|
|
|
|
|
#endif /* DEBUG_HARDIO */
|
2005-09-15 09:58:31 -04:00
|
|
|
|
|
|
|
|
|
|
|
ssize_t
|
2022-02-16 14:49:21 -05:00
|
|
|
hard_write(int fd, const char *data, size_t datalen)
|
2005-09-15 09:58:31 -04:00
|
|
|
{
|
|
|
|
ssize_t total = datalen;
|
|
|
|
|
|
|
|
assert(data && datalen >= 0);
|
|
|
|
if_assert_failed return -1;
|
|
|
|
|
|
|
|
debug_open("hard_write", fd, data, datalen);
|
|
|
|
|
|
|
|
while (datalen > 0) {
|
|
|
|
ssize_t written = safe_write(fd, data, datalen);
|
|
|
|
|
|
|
|
if (written <= 0) {
|
|
|
|
if (written) return -1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
debug_write(data, written);
|
|
|
|
|
|
|
|
data += written;
|
|
|
|
datalen -= written;
|
|
|
|
}
|
|
|
|
|
|
|
|
debug_flush();
|
|
|
|
|
|
|
|
/* Return number of bytes written. */
|
|
|
|
return (total - datalen);
|
|
|
|
}
|
|
|
|
|
|
|
|
ssize_t
|
2021-01-02 10:20:27 -05:00
|
|
|
hard_read(int fd, char *data, size_t datalen)
|
2005-09-15 09:58:31 -04:00
|
|
|
{
|
|
|
|
ssize_t total = datalen;
|
|
|
|
|
|
|
|
assert(data && datalen >= 0);
|
|
|
|
if_assert_failed return -1;
|
|
|
|
|
|
|
|
debug_open("hard_read", fd, data, datalen);
|
|
|
|
|
|
|
|
while (datalen > 0) {
|
|
|
|
ssize_t readlen = safe_read(fd, data, datalen);
|
|
|
|
|
|
|
|
if (readlen <= 0) {
|
|
|
|
if (readlen) return -1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
debug_write(data, readlen);
|
|
|
|
|
|
|
|
data += readlen;
|
|
|
|
datalen -= readlen;
|
|
|
|
}
|
|
|
|
|
|
|
|
debug_flush();
|
|
|
|
|
|
|
|
/* Return number of bytes read. */
|
|
|
|
return (total - datalen);
|
|
|
|
}
|