mirror of
https://github.com/rkd77/elinks.git
synced 2025-02-02 15:09:23 -05: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:
parent
75d61e5431
commit
2bec2984c4
@ -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@
|
||||
|
19
build.sh
19
build.sh
@ -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 \
|
||||
|
@ -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
|
||||
|
||||
|
15
configure.ac
15
configure.ac
@ -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)
|
||||
|
||||
# ===================================================================
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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
|
||||
|
@ -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 *);
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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.
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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
6
src/osdep/dos/Makefile
Normal 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
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
46
src/osdep/dos/dos.h
Normal 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
|
1
src/osdep/dos/meson.build
Normal file
1
src/osdep/dos/meson.build
Normal file
@ -0,0 +1 @@
|
||||
srcs += files('dos.c')
|
193
src/osdep/dos/vpipe.inc
Normal file
193
src/osdep/dos/vpipe.inc
Normal 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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -14,6 +14,7 @@
|
||||
|
||||
#include "elinks.h"
|
||||
|
||||
#include "osdep/osdep.h"
|
||||
#include "terminal/hardio.h"
|
||||
#include "util/error.h"
|
||||
|
||||
|
@ -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();
|
||||
|
Loading…
x
Reference in New Issue
Block a user