1
0
mirror of https://github.com/rkd77/elinks.git synced 2024-06-24 00:56:14 +00:00

[dos] Very experimental DOS port based on links-2.26 code

WATT-32 and openssl you must compile yourself.
You must tweak configure options, something like:
--disable-utf-8, etc.
Only checked on dosemu with LFN. Networking lags is a bit.
This commit is contained in:
Witold Filipczyk 2022-05-09 18:53:36 +02:00
parent 75d61e5431
commit 2bec2984c4
30 changed files with 1534 additions and 49 deletions

View File

@ -151,6 +151,7 @@ CONFIG_NNTP = @CONFIG_NNTP@
CONFIG_NO_ROOT_EXEC = @CONFIG_NO_ROOT_EXEC@
CONFIG_OPENSSL = @CONFIG_OPENSSL@
CONFIG_OS_BEOS = @CONFIG_OS_BEOS@
CONFIG_OS_DOS = @CONFIG_OS_DOS@
CONFIG_OS_OS2 = @CONFIG_OS_OS2@
CONFIG_OS_RISCOS = @CONFIG_OS_RISCOS@
CONFIG_OS_UNIX = @CONFIG_OS_UNIX@

View File

@ -35,7 +35,7 @@ configure() {
LD=$2 \
LDFLAGS=$4 \
CXX=$CXX_CUST \
CFLAGS="-O2 -I/usr/local/include" \
CFLAGS="-O2 -I/usr/local/include $6" \
LIBS=$5 \
CXXFLAGS=$6 \
PKG_CONFIG="./pkg-config.sh" \
@ -76,7 +76,7 @@ configure() {
if [ $? -eq 0 ]; then
echo "--[ Configuration Sucessfull ]--"
# turn off warnings
sed -i 's/-Wall/-w/g' Makefile.config
#sed -i 's/-Wall/-w/g' Makefile.config
#sed -i 's/-lpthread/-pthread/g' Makefile.config
#build
return 0
@ -185,6 +185,15 @@ set_arch() {
CXXFLAGS="-I/usr/local/include"
LDFLAGS="-L/usr/local/lib"
LIBS="-lws2_32"
elif [ "$1" = "djgpp" ]; then
ARCHIT="$1"
CC="i586-pc-msdosdjgpp-gcc"
LD="i586-pc-msdosdjgpp-ld --allow-multiple-definition"
MAKE_HOST="i586-pc-msdosdjgpp"
BIN_SUFFIX=".exe"
CXXFLAGS="-I/usr/local/include -I/home/elinks/.dosemu/drive_c/LINKS/watt32/inc"
LDFLAGS="-L/usr/local/lib -L/home/elinks/.dosemu/drive_c/LINKS/watt32/lib"
LIBS="-lwatt"
elif [ "$1" = "arm32" ]; then
ARCHIT="$1"
CC="arm-linux-gnueabihf-gcc"
@ -217,7 +226,7 @@ set_arch() {
# ARCH SELECTION MENU
arch_menu() {
MENU_ARCHS="$ARCHS null null null null return"
MENU_ARCHS="$ARCHS null null null return"
echo "[=] Build architecture selection menu"
select SEL in $MENU_ARCHS; do
echo "[=] Build architecture selection menu"
@ -233,6 +242,8 @@ arch_menu() {
set_arch "$SEL"
elif [ "$SEL" = "arm64" ]; then
set_arch "$SEL"
elif [ "$SEL" = "djgpp" ]; then
set_arch "$SEL"
elif [ "$SEL" = "native" ]; then
set_arch native
elif [ "$SEL" = "make" ]; then
@ -251,7 +262,7 @@ arch_menu() {
# MAIN LOOP
ARCHIT=""
BIN_SUFFIX=""
ARCHS="lin32 lin64 win32 win64 arm32 arm64 native"
ARCHS="lin32 lin64 win32 win64 arm32 arm64 djgpp native"
CC_SEL="arch null null build \
config make test \
pub debug \

View File

@ -174,6 +174,9 @@
/* Define if you want: BEOS support */
#mesondefine CONFIG_OS_BEOS
/* Define if you want: DOS support */
#mesondefine CONFIG_OS_DOS
/* Define if you want: EMX support */
#mesondefine CONFIG_OS_OS2

View File

@ -173,6 +173,9 @@ kill me!
EL_CHECK_COMPILER_MACROS(CONFIG_OS_BEOS, [BEOS], [__BEOS__])
AC_SUBST(CONFIG_OS_BEOS)
EL_CHECK_COMPILER_MACROS(CONFIG_OS_DOS, [DOS], [__DJGPP])
AC_SUBST(CONFIG_OS_DOS)
EL_CHECK_COMPILER_MACROS(CONFIG_OS_RISCOS, [RISCOS], [__riscos__])
AC_SUBST(CONFIG_OS_RISCOS)
@ -232,10 +235,14 @@ AC_CHECK_HEADERS(termios.h)
AC_CHECK_HEADERS(poll.h)
AC_CHECK_HEADERS(stdalign.h)
AC_CHECK_HEADERS(sys/un.h,
[CONFIG_INTERLINK=yes
EL_CONFIG([CONFIG_INTERLINK], [interlinking])],
[CONFIG_INTERLINK=no])
if test "$CONFIG_OS_DOS" = no; then
AC_CHECK_HEADERS(sys/un.h,
[CONFIG_INTERLINK=yes
EL_CONFIG([CONFIG_INTERLINK], [interlinking])],
[CONFIG_INTERLINK=no])
else
CONFIG_INTERLINK=no
fi
AC_SUBST(CONFIG_INTERLINK)
# ===================================================================

View File

@ -123,6 +123,7 @@ else
endif
conf_data.set('CONFIG_SSL', true)
conf_data.set('CONFIG_OS_DOS', false)
conf_data.set('CONFIG_OS_OS2', false)
conf_data.set('CONFIG_OS_RISCOS', false)

View File

@ -319,13 +319,13 @@ parse_set_common(struct option *opt_tree, struct conf_parsing_state *state,
* as long as OPT_TOUCHED is set. */
}
if (!option_types[opt->type].read) {
if (!option_types[opt->type].read2) {
show_parse_error(state, ERROR_VALUE);
skip_option_value(&state->pos);
return ERROR_VALUE;
}
val = option_types[opt->type].read(opt, &state->pos.look,
val = option_types[opt->type].read2(opt, &state->pos.look,
&state->pos.line);
if (!val) {
/* The reader function failed. Jump back to
@ -368,11 +368,11 @@ parse_set_common(struct option *opt_tree, struct conf_parsing_state *state,
add_bytes_to_string(mirror, optname_orig,
optname_len);
state->mirrored = state->pos.look;
} else if (option_types[opt->type].write) {
} else if (option_types[opt->type].write2) {
add_bytes_to_string(mirror, state->mirrored,
pos_before_value.look
- state->mirrored);
option_types[opt->type].write(opt, mirror);
option_types[opt->type].write2(opt, mirror);
state->mirrored = state->pos.look;
}
/* Remember that the option need not be
@ -458,14 +458,14 @@ parse_unset(struct option *opt_tree, struct conf_parsing_state *state,
/* The "unset" command is already in the file,
* and unlike with "set", there is no value
* to be updated. */
} else if (option_types[opt->type].write) {
} else if (option_types[opt->type].write2) {
/* Replace the "unset" command with a
* "set" command. */
add_to_string(mirror, "set ");
add_bytes_to_string(mirror, optname_orig,
optname_len);
add_to_string(mirror, " = ");
option_types[opt->type].write(opt, mirror);
option_types[opt->type].write2(opt, mirror);
state->mirrored = state->pos.look;
}
/* Remember that the option need not be
@ -490,7 +490,7 @@ parse_bind(struct option *opt_tree, struct conf_parsing_state *state,
/* Keymap */
before_error = state->pos;
keymap = option_types[OPT_STRING].read(NULL, &state->pos.look,
keymap = option_types[OPT_STRING].read2(NULL, &state->pos.look,
&state->pos.line);
skip_white(&state->pos);
if (!keymap || !*state->pos.look) {
@ -500,7 +500,7 @@ parse_bind(struct option *opt_tree, struct conf_parsing_state *state,
/* Keystroke */
before_error = state->pos;
keystroke = option_types[OPT_STRING].read(NULL, &state->pos.look,
keystroke = option_types[OPT_STRING].read2(NULL, &state->pos.look,
&state->pos.line);
skip_white(&state->pos);
if (!keystroke || !*state->pos.look) {
@ -525,7 +525,7 @@ parse_bind(struct option *opt_tree, struct conf_parsing_state *state,
/* Action */
before_error = state->pos;
action = option_types[OPT_STRING].read(NULL, &state->pos.look,
action = option_types[OPT_STRING].read2(NULL, &state->pos.look,
&state->pos.line);
if (!action) {
mem_free(keymap); mem_free(keystroke);
@ -589,7 +589,7 @@ parse_include(struct option *opt_tree, struct conf_parsing_state *state,
/* File name */
before_error = state->pos;
fname = option_types[OPT_STRING].read(NULL, &state->pos.look,
fname = option_types[OPT_STRING].read2(NULL, &state->pos.look,
&state->pos.line);
if (!fname) {
done_string(&dumbstring);
@ -982,8 +982,8 @@ smart_config_output_fn(struct string *string, struct option *option,
/* OPT_ALIAS won't ever. OPT_TREE won't reach action 2.
* OPT_SPECIAL makes no sense in the configuration
* context. */
assert(option_types[option->type].write);
option_types[option->type].write(option, string);
assert(option_types[option->type].write2);
option_types[option->type].write2(option, string);
}
add_char_to_string(string, '\n');
if (do_print_comment) add_char_to_string(string, '\n');
@ -1042,12 +1042,12 @@ smart_config_output_fn_html(struct string *string, struct option *option,
add_to_string(string, option->name);
add_to_string(string, "\"/><input type=\"text\" name=\"val\" value=\"");
assert(option_types[option->type].write);
assert(option_types[option->type].write2);
{
struct string tmp;
if (init_string(&tmp)) {
option_types[option->type].write(option, &tmp);
option_types[option->type].write2(option, &tmp);
if (tmp.length >= 2 && tmp.source[0] == '"' && tmp.source[tmp.length - 1] == '"') {
add_bytes_to_string(string, tmp.source + 1, tmp.length - 2);

View File

@ -152,7 +152,7 @@ get_option_info(struct listbox_item *item, struct terminal *term)
mem_free(type);
}
if (option_types[option->type].write) {
if (option_types[option->type].write2) {
char *range;
struct string value;
@ -161,7 +161,7 @@ get_option_info(struct listbox_item *item, struct terminal *term)
return NULL;
}
option_types[option->type].write(option, &value);
option_types[option->type].write2(option, &value);
range = get_range_string(option);
if (range) {
@ -273,7 +273,7 @@ check_valid_option(struct dialog_data *dlg_data, struct widget_data *widget_data
int dummy_line = 0;
commandline = 1;
chinon = option_types[option->type].read(option, &value, &dummy_line);
chinon = option_types[option->type].read2(option, &value, &dummy_line);
if (chinon) {
if (option_types[option->type].set &&
option_types[option->type].set(option, chinon)) {
@ -307,7 +307,7 @@ build_edit_dialog(struct terminal *term, struct session *ses,
if (!init_string(&tvalue)) return;
commandline = 1;
option_types[option->type].write(option, &tvalue);
option_types[option->type].write2(option, &tvalue);
commandline = 0;
/* Create the dialog */
@ -383,8 +383,8 @@ push_edit_button(struct dialog_data *dlg_data,
if (!box->sel || !box->sel->udata) return EVENT_PROCESSED;
option = (struct option *)box->sel->udata;
if (!option_types[option->type].write ||
!option_types[option->type].read ||
if (!option_types[option->type].write2 ||
!option_types[option->type].read2 ||
!option_types[option->type].set) {
info_box(term, 0,
N_("Edit"), ALIGN_LEFT,

View File

@ -1163,7 +1163,7 @@ smart_config_string(struct string *str, int print_comment, int i18n,
/* And the option itself */
if (option_types[option->type].write) {
if (option_types[option->type].write2) {
fn(str, option, path, depth,
do_print_comment, 2, i18n);

View File

@ -39,7 +39,7 @@ gen_cmd(struct option *o, char ***argv, int *argc)
/* FIXME!! We will modify argv! (maybe) */
commandline = 1;
str = option_types[o->type].read(o, *argv, &dummy_line);
str = option_types[o->type].read2(o, *argv, &dummy_line);
commandline = 0;
if (str) {
/* We ate parameter */
@ -118,8 +118,8 @@ redir_rd(struct option *opt, char **file, int *line)
assertm(real != NULL, "%s aliased to unknown option %s!", opt->name, opt->value.string);
if_assert_failed { return ret; }
if (option_types[real->type].read) {
ret = option_types[real->type].read(real, file, line);
if (option_types[real->type].read2) {
ret = option_types[real->type].read2(real, file, line);
if (ret && (opt->flags & OPT_ALIAS_NEGATE) && real->type == OPT_BOOL) {
*(long *) ret = !*(long *) ret;
}
@ -136,8 +136,8 @@ redir_wr(struct option *opt, struct string *string)
assertm(real != NULL, "%s aliased to unknown option %s!", opt->name, opt->value.string);
if_assert_failed { return; }
if (option_types[real->type].write)
option_types[real->type].write(real, string);
if (option_types[real->type].write2)
option_types[real->type].write2(real, string);
}
static int

View File

@ -11,8 +11,8 @@ extern "C" {
struct option_type_info {
const char *name;
const char *(*cmdline)(struct option *, char ***, int *);
char *(*read)(struct option *, char **, int *);
void (*write)(struct option *, struct string *);
char *(*read2)(struct option *, char **, int *);
void (*write2)(struct option *, struct string *);
void (*dup)(struct option *, struct option *, int);
int (*set)(struct option *, char *);
int (*equals)(struct option *, const char *);

View File

@ -38,4 +38,12 @@
#define C_(str) (char *)((str))
#ifdef CONFIG_OS_DOS
#define loop_select(a, b, c, d, e) dos_select(a, b, c, d, e, 1)
#define select2(a, b, c, d, e) dos_select(a, b, c, d, e, 0)
#else
#define loop_select select
#define select2 select
#endif
#endif

View File

@ -114,7 +114,7 @@ open_encoded(int fd, stream_encoding_T encoding)
if (!stream) return NULL;
stream->encoding = encoding;
if (decoding_backends[stream->encoding]->open(stream, fd) >= 0)
if (decoding_backends[stream->encoding]->eopen(stream, fd) >= 0)
return stream;
mem_free(stream);
@ -127,7 +127,7 @@ open_encoded(int fd, stream_encoding_T encoding)
int
read_encoded(struct stream_encoded *stream, char *data, int len)
{
return decoding_backends[stream->encoding]->read(stream, data, len);
return decoding_backends[stream->encoding]->eread(stream, data, len);
}
/* Decode an entire file from a buffer. This function is not suitable
@ -145,7 +145,7 @@ decode_encoded_buffer(struct stream_encoded *stream, stream_encoding_T encoding,
void
close_encoded(struct stream_encoded *stream)
{
decoding_backends[stream->encoding]->close(stream);
decoding_backends[stream->encoding]->eclose(stream);
mem_free(stream);
}

View File

@ -30,10 +30,10 @@ struct stream_encoded {
struct decoding_backend {
const char *name;
const char *const *extensions;
int (*open)(struct stream_encoded *stream, int fd);
int (*read)(struct stream_encoded *stream, char *data, int len);
int (*eopen)(struct stream_encoded *stream, int fd);
int (*eread)(struct stream_encoded *stream, char *data, int len);
char *(*decode_buffer)(struct stream_encoded *stream, char *data, int len, int *new_len);
void (*close)(struct stream_encoded *stream);
void (*eclose)(struct stream_encoded *stream);
};
struct stream_encoded *open_encoded(int, stream_encoding_T);

View File

@ -369,7 +369,7 @@ elinks_usleep(unsigned long useconds)
delay.tv_sec = 0;
delay.tv_usec = useconds;
select(0, &dummy1, &dummy2, &dummy3, &delay);
select2(0, &dummy1, &dummy2, &dummy3, &delay);
}
/* Listen on socket for internal ELinks communication.

View File

@ -361,6 +361,10 @@ main(int argc, char *argv[])
ac = argc;
av = (char **) argv;
#ifdef CONFIG_OS_DOS
init_os();
#endif
select_loop(init);
terminate_all_subsystems();

View File

@ -572,7 +572,7 @@ select_loop(void (*init)(void))
timeout = (struct timeval *) &t;
}
n = select(w_max, &x_read, &x_write, &x_error, timeout);
n = loop_select(w_max, &x_read, &x_write, &x_error, timeout);
if (n < 0) {
/* The following calls (especially gettext)
* might change errno. */
@ -663,7 +663,7 @@ can_read_or_write(int fd, int write)
else
rfds = &fds;
return select(fd + 1, rfds, wfds, NULL, &tv);
return select2(fd + 1, rfds, wfds, NULL, &tv);
#endif
}

View File

@ -105,6 +105,15 @@ init_openssl(struct module *module)
}
#endif
#if defined(HAVE_RAND_ADD) && defined(CONFIG_OS_DOS)
{
unsigned char *os_pool;
int os_pool_size;
os_seed_random(&os_pool, &os_pool_size);
if (os_pool_size) RAND_add(os_pool, os_pool_size, os_pool_size);
mem_free(os_pool);
}
#endif
SSLeay_add_ssl_algorithms();
context = SSL_CTX_new(SSLv23_client_method());
SSL_CTX_set_options(context, SSL_OP_ALL);

View File

@ -3,6 +3,7 @@ include $(top_builddir)/Makefile.config
INCLUDES += $(X_CFLAGS)
SUBDIRS-$(CONFIG_OS_BEOS) += beos
SUBDIRS-$(CONFIG_OS_DOS) += dos
SUBDIRS-$(CONFIG_OS_OS2) += os2
SUBDIRS-$(CONFIG_OS_RISCOS) += riscos
SUBDIRS-$(CONFIG_OS_UNIX) += unix

6
src/osdep/dos/Makefile Normal file
View File

@ -0,0 +1,6 @@
top_builddir=../../..
include $(top_builddir)/Makefile.config
OBJS = dos.o
include $(top_srcdir)/Makefile.lib

1157
src/osdep/dos/dos.c Normal file

File diff suppressed because it is too large Load Diff

46
src/osdep/dos/dos.h Normal file
View File

@ -0,0 +1,46 @@
#ifndef EL__OSDEP_DOS_DOS_H
#define EL__OSDEP_DOS_DOS_H
#ifdef CONFIG_OS_DOS
#ifdef __cplusplus
extern "C" {
#endif
#define DOS_EXTRA_KEYBOARD
#ifdef DOS_EXTRA_KEYBOARD
#define OS_SETRAW
#endif
#include <sys/types.h>
struct timeval;
int dos_read(int fd, void *buf, size_t size);
int dos_write(int fd, const void *buf, size_t size);
int dos_pipe(int fd[2]);
int dos_close(int fd);
int dos_select(int n, fd_set *rs, fd_set *ws, fd_set *es, struct timeval *t, int from_main_loop);
void init_os(void);
void save_terminal(void);
void restore_terminal(void);
int dos_setraw(int ctl, int save);
#ifndef DOS_OVERRIDES_SELF
#define read dos_read
#define write dos_write
#define pipe dos_pipe
#define close dos_close
#endif
#ifdef __cplusplus
}
#endif
#endif
#endif

View File

@ -0,0 +1 @@
srcs += files('dos.c')

193
src/osdep/dos/vpipe.inc Normal file
View File

@ -0,0 +1,193 @@
#define VIRTUAL_PIPE_FLAG_WRITE 1
#define VIRTUAL_PIPE_FLAG_NONBLOCK 2
struct virtual_pipe {
unsigned char content[VIRTUAL_PIPE_SIZE];
unsigned used;
unsigned n_rd;
unsigned n_wr;
};
static struct virtual_pipe *pipe_desc[FD_SETSIZE] = { NULL };
static unsigned pipe_flags[FD_SETSIZE] = { 0 };
static struct virtual_pipe *get_virtual_pipe(int fd)
{
struct virtual_pipe *desc;
if (fd >= FD_SETSIZE || !pipe_desc[fd]) return NULL;
pipe_lock();
desc = pipe_desc[fd];
if (!desc) {
pipe_unlock();
return NULL;
}
return desc;
}
static int vpipe_read(int fd, void *buf, size_t size)
{
int should_wake;
struct virtual_pipe *desc;
test_again:
if (!(desc = get_virtual_pipe(fd)))
return -2;
if (pipe_flags[fd] & VIRTUAL_PIPE_FLAG_WRITE) elinks_internal("vpipe_read: reading from write pipe descriptor");
if (!desc->used) {
if (!desc->n_wr) {
#ifdef TRACE_PIPES
fprintf(stderr, "read(%d) -> zero.", fd);
#endif
pipe_unlock();
return 0;
}
if (pipe_flags[fd] & VIRTUAL_PIPE_FLAG_NONBLOCK) {
#ifdef TRACE_PIPES
fprintf(stderr, "read(%d) -> wouldblock.", fd);
#endif
pipe_unlock();
errno = EAGAIN;
return -1;
}
#ifdef TRACE_PIPES
fprintf(stderr, "read(%d) -> sleep.", fd);
#endif
pipe_unlock_wait();
pipe_unlock();
goto test_again;
}
should_wake = desc->used == VIRTUAL_PIPE_SIZE;
if (size > desc->used)
size = desc->used;
memcpy(buf, desc->content, size);
memmove(desc->content, desc->content + size, desc->used -= size);
#ifdef TRACE_PIPES
fprintf(stderr, "read(%d) -> %d. (%d)", fd, size, should_wake);
#endif
pipe_unlock();
if (should_wake) pipe_wake();
return size;
}
static int vpipe_write(int fd, const void *buf, size_t size)
{
int should_wake;
struct virtual_pipe *desc;
test_again:
if (!(desc = get_virtual_pipe(fd)))
return -2;
if (!(pipe_flags[fd] & VIRTUAL_PIPE_FLAG_WRITE)) elinks_internal("vpipe_write: writing to read pipe descriptor");
if (!desc->n_rd) {
#ifdef TRACE_PIPES
fprintf(stderr, "write(%d) -> epipe.", fd);
#endif
pipe_unlock();
errno = EPIPE;
return -1;
}
if (desc->used == VIRTUAL_PIPE_SIZE) {
if (pipe_flags[fd] & VIRTUAL_PIPE_FLAG_NONBLOCK) {
#ifdef TRACE_PIPES
fprintf(stderr, "write(%d) -> wouldblock.", fd);
#endif
pipe_unlock();
errno = EAGAIN;
return -1;
}
#ifdef TRACE_PIPES
fprintf(stderr, "write(%d) -> sleep.", fd);
#endif
pipe_unlock_wait();
pipe_unlock();
goto test_again;
}
should_wake = !desc->used;
if (size > (VIRTUAL_PIPE_SIZE - desc->used))
size = VIRTUAL_PIPE_SIZE - desc->used;
memcpy(desc->content + desc->used, buf, size);
desc->used += size;
#ifdef TRACE_PIPES
fprintf(stderr, "write(%d) -> %d.", fd, size);
#endif
pipe_unlock();
if (should_wake) pipe_wake();
return size;
}
static int vpipe_close(int fd)
{
struct virtual_pipe *desc;
if (!(desc = get_virtual_pipe(fd)))
return -2;
if (!(pipe_flags[fd] & VIRTUAL_PIPE_FLAG_WRITE)) {
if (!desc->n_rd) elinks_internal("vpipe_close: read counter underflow");
desc->n_rd--;
} else {
if (!desc->n_wr) elinks_internal("vpipe_close: write counter underflow");
desc->n_wr--;
}
pipe_desc[fd] = NULL;
pipe_flags[fd] = 0;
pipe_unlock();
if (!desc->n_rd && !desc->n_wr)
free(desc);
return close(fd);
}
static int vpipe_create(int fd[2])
{
int rs;
struct virtual_pipe *desc;
EINTRLOOP(fd[0], open("/dev/null", O_RDONLY));
if (fd[0] == -1)
goto err0;
EINTRLOOP(fd[1], open("/dev/null", O_WRONLY));
if (fd[1] == -1)
goto err1;
if (fd[0] >= FD_SETSIZE || fd[1] >= FD_SETSIZE) {
errno = EMFILE;
goto err2;
}
desc = malloc(sizeof(struct virtual_pipe));
if (!desc) goto err2;
desc->used = 0;
desc->n_rd = 1;
desc->n_wr = 1;
pipe_lock();
if (pipe_desc[fd[0]] || pipe_flags[fd[0]] || pipe_desc[fd[1]] || pipe_flags[fd[0]])
elinks_internal("c_pipe: pipe handles %d, %d already used: %p, %d, %p, %d", fd[0], fd[1], pipe_desc[fd[0]], pipe_flags[fd[0]], pipe_desc[fd[1]], pipe_flags[fd[0]]);
pipe_desc[fd[0]] = desc;
pipe_flags[fd[0]] = 0;
pipe_desc[fd[1]] = desc;
pipe_flags[fd[1]] = VIRTUAL_PIPE_FLAG_WRITE;
#ifdef DOS
pipe_flags[fd[0]] |= VIRTUAL_PIPE_FLAG_NONBLOCK;
pipe_flags[fd[1]] |= VIRTUAL_PIPE_FLAG_NONBLOCK;
#endif
pipe_unlock();
return 0;
err2:
EINTRLOOP(rs, close(fd[1]));
err1:
EINTRLOOP(rs, close(fd[0]));
err0:
return -1;
}
static int vpipe_may_read(int fd)
{
if (pipe_flags[fd] & VIRTUAL_PIPE_FLAG_WRITE) elinks_internal("vpipe_may_read: selecting write descriptor %d for read", fd);
return pipe_desc[fd]->used || !pipe_desc[fd]->n_wr;
}
static int vpipe_may_write(int fd)
{
if (!(pipe_flags[fd] & VIRTUAL_PIPE_FLAG_WRITE)) elinks_internal("vpipe_may_write: selecting read descriptor %d for write", fd);
return pipe_desc[fd]->used != VIRTUAL_PIPE_SIZE || !pipe_desc[fd]->n_rd;
}
static void clear_inactive(fd_set *fs, int i)
{
if (!fs) return;
while (--i >= 0) FD_CLR(i, fs);
}

View File

@ -42,7 +42,7 @@ extern "C" {
#endif
/* Attempt to workaround the EINTR mess. */
#if defined(EINTR) && !defined(CONFIG_OS_WIN32)
#if defined(EINTR) && !defined(CONFIG_OS_WIN32) && !defined(CONFIG_OS_DOS)
#ifdef TEMP_FAILURE_RETRY /* GNU libc */
#define safe_read(fd, buf, count) TEMP_FAILURE_RETRY(read(fd, buf, count))
@ -76,9 +76,17 @@ safe_write(int fd, const void *buf, size_t count) {
#else /* EINTR && !CONFIG_OS_WIN32 */
#ifdef CONFIG_OS_DOS
#define safe_read(fd, buf, count) dos_read(fd, buf, count)
#define safe_write(fd, buf, count) dos_write(fd, buf, count)
#else
#define safe_read(fd, buf, count) read(fd, buf, count)
#define safe_write(fd, buf, count) write(fd, buf, count)
#endif
#endif /* EINTR && !CONFIG_OS_WIN32 */
#ifndef HAVE_FTELLO

View File

@ -3,6 +3,9 @@
if conf_data.get('CONFIG_OS_BEOS')
subdir('beos')
endif
if conf_data.get('CONFIG_OS_DOS')
subdir('dos')
endif
if conf_data.get('CONFIG_OS_OS2')
subdir('os2')
endif

View File

@ -72,6 +72,7 @@
#include "util/string.h"
#ifndef CONFIG_OS_DOS
/* Set a file descriptor to non-blocking mode. It returns a non-zero value
* on error. */
int
@ -102,6 +103,7 @@ set_nonblocking_fd(int fd)
return 0;
#endif
}
#endif
/* Set a file descriptor to blocking mode. It returns a non-zero value on
* error. */
@ -192,7 +194,7 @@ get_shell(void)
/* Terminal size */
#if !defined(CONFIG_OS_OS2) && !defined(CONFIG_OS_WIN32)
#if !defined(CONFIG_OS_OS2) && !defined(CONFIG_OS_WIN32) && !defined(CONFIG_OS_DOS)
static void
sigwinch(void *s)
@ -252,7 +254,7 @@ c_pipe(int *fd)
return pipe(fd);
}
#elif defined(CONFIG_OS_OS2) || defined(CONFIG_OS_WIN32)
#elif defined(CONFIG_OS_OS2) || defined(CONFIG_OS_WIN32) || defined(CONFIG_OS_DOS)
void
set_bin(int fd)
@ -859,7 +861,7 @@ start_thread(void (*fn)(void *, int), void *ptr, int l)
#endif
#ifndef OS2_MOUSE
#if !defined(OS2_MOUSE) && !defined(CONFIG_OS_DOS)
void
want_draw(void)
{

View File

@ -2,6 +2,7 @@
#define EL__OSDEP_OSDEP_H
#include "osdep/beos/beos.h"
#include "osdep/dos/dos.h"
#include "osdep/os2/os2.h"
#include "osdep/riscos/riscos.h"
#include "osdep/unix/unix.h"

View File

@ -12,6 +12,10 @@
#include <unistd.h>
#endif
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#include "elinks.h"
#include "intl/libintl.h"

View File

@ -14,6 +14,7 @@
#include "elinks.h"
#include "osdep/osdep.h"
#include "terminal/hardio.h"
#include "util/error.h"

View File

@ -167,6 +167,10 @@ kbd_ctrl_c(void)
static void
send_init_sequence(int h, int altscreen)
{
#ifdef CONFIG_OS_DOS
save_terminal();
#endif
want_draw();
write_sequence(h, INIT_TERMINAL_SEQ);
/* If alternate screen is supported switch to it. */
@ -178,7 +182,10 @@ send_init_sequence(int h, int altscreen)
send_mouse_init_sequence(h);
}
#endif
#ifndef CONFIG_OS_DOS
write_sequence(h, INIT_BRACKETED_PASTE_SEQ);
#endif
done_draw();
}
#define DONE_CLS_SEQ "\033[2J" /**< Erase in Display, Clear All */
@ -189,7 +196,10 @@ send_init_sequence(int h, int altscreen)
static void
send_done_sequence(int h, int altscreen)
{
want_draw();
#ifndef CONFIG_OS_DOS
write_sequence(h, DONE_BRACKETED_PASTE_SEQ);
#endif
write_sequence(h, DONE_CLS_SEQ);
#ifdef CONFIG_MOUSE
@ -202,6 +212,10 @@ send_done_sequence(int h, int altscreen)
}
write_sequence(h, DONE_TERMINAL_SEQ);
done_draw();
#ifdef CONFIG_OS_DOS
restore_terminal();
#endif
}
@ -309,6 +323,10 @@ handle_trm(int std_in, int std_out, int sock_in, int sock_out, int ctl_in,
memset(&info, 0, sizeof(info));
#ifdef CONFIG_OS_DOS
dos_setraw(ctl_in, 1);
#endif
get_terminal_size(ctl_in, &size->width, &size->height);
info.event.ev = EVENT_INIT;
info.system_env = get_system_env();