summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Build/source/texk/README15
-rw-r--r--Build/source/texk/xdvik/CHANGES33
-rw-r--r--Build/source/texk/xdvik/ChangeLog4
-rwxr-xr-xBuild/source/texk/xdvik/configure36
-rw-r--r--Build/source/texk/xdvik/configure.ac4
-rw-r--r--Build/source/texk/xdvik/dvi-draw.c16
-rw-r--r--Build/source/texk/xdvik/dvi-init.c4
-rw-r--r--Build/source/texk/xdvik/events.c118
-rw-r--r--Build/source/texk/xdvik/events.h8
-rw-r--r--Build/source/texk/xdvik/exit-handlers.c41
-rw-r--r--Build/source/texk/xdvik/exit-handlers.h4
-rw-r--r--Build/source/texk/xdvik/gui/print-dialog.c25
-rw-r--r--Build/source/texk/xdvik/gui/xm_prefs_helpers.c16
-rw-r--r--Build/source/texk/xdvik/gui/xm_toolbar.c2
-rw-r--r--Build/source/texk/xdvik/hypertex.c10
-rw-r--r--Build/source/texk/xdvik/m4/xdvi-xinput-2-1.m45
-rw-r--r--Build/source/texk/xdvik/main.c8
-rw-r--r--Build/source/texk/xdvik/print-internal.c6
-rw-r--r--Build/source/texk/xdvik/psgs.c4
-rw-r--r--Build/source/texk/xdvik/special.c488
-rw-r--r--Build/source/texk/xdvik/special.h4
-rw-r--r--Build/source/texk/xdvik/texmf/XDvi6
-rw-r--r--Build/source/texk/xdvik/util.c64
-rw-r--r--Build/source/texk/xdvik/util.h4
-rw-r--r--Build/source/texk/xdvik/version.h2
-rw-r--r--Build/source/texk/xdvik/xdvi.1.in27
-rw-r--r--Build/source/texk/xdvik/xdvi.c40
27 files changed, 638 insertions, 356 deletions
diff --git a/Build/source/texk/README b/Build/source/texk/README
index 82994530222..35261d56aac 100644
--- a/Build/source/texk/README
+++ b/Build/source/texk/README
@@ -121,5 +121,18 @@ web2c - maintained here, by us - core web2c, plain tex, etc.
uptex - https://texwiki.texjp.org/?upTeX%2CupLaTeX
xetex - http://tug.org/xetex/
-xdvik 22.87 - checked 14apr14
+xdvik 22.87.03 - checked 6apr16
http://sourceforge.net/projects/xdvi/files/xdvik/
+ Procedure for updating xdvik from sourceforge release:
+tar xf ...
+diff -crN2 \
+ -x .cvsignore -x configure -x autom4te.cache -x Makefile.in -x ChangeLog \
+ xdvik xdvik-22.87.03/texk/xdvik >/tmp/c
+cd xdvik
+patch -p1 </tmp/c
+reautoconf
+add import entry to ChangeLog, update texk/README
+remove unpacked ../xdvik-*
+make sure it builds
+commit.
+
diff --git a/Build/source/texk/xdvik/CHANGES b/Build/source/texk/xdvik/CHANGES
index 2c2310c2561..1886a612078 100644
--- a/Build/source/texk/xdvik/CHANGES
+++ b/Build/source/texk/xdvik/CHANGES
@@ -9,6 +9,39 @@ Versions containing major changes are marked as `beta'; these
may contain undetected bugs. Such versions shouldn't be used
by distributors.
+ * 22.87.03 (2016-04-02):
+ + incorporated changes in xdvik itself from the TeX Live version:
+ m4/xdvi-check-iconv.m4: Somewhat improved logic.
+ many places: avoided compiler warnings and cleaned up including of
+ header files.
+ + events.c: Fixed bug #391 (compilation with xaw3d).
+ + m4/xdvi-xinput-2-1.m4: Added check for -lXi (in addition to headers)
+ + events.h, main.c, dvi-init.c, special.c, xdvi.c: Fixed bug in which
+ papersize specials were ignored if the numbers in them had too many
+ digits. Also fixed rounding of negative numbers.
+ + psgs.c: Fixed bug #395 (strings.h --> string.h in psgs.c)
+ + texmf/XDvi: Fixed bug #397 (error message "Cannot convert string ...
+ to type FontStruct")
+ + events.c, events.h, util.c, util.h, and elsewhere: Fixed killing of
+ subprocesses in fork_process().
+ + exit-handlers.c: Ignore duplicate requests (such as
+ remove_tmp_dvi_file).
+ + events.c, xdvi.1.in: Added (unbound) user-exec() action.
+ + dvi-draw.c: Fixed bug #398 (crashed with message "currinf.set_char_p
+ is not a registered routine!" during scanning (string searches
+ or source specials))
+ + many places: Update from TeX Live, as of 2016-03-18:
+ Disable smooth scrolling by default for native TeX Live builds
+ Change handling of subdirectory squeeze (when cross compiling)
+ Avoid undefined behaviour when char is signed
+ Use link instead of compile check for XInput 2.1
+ Do not include c-auto.h from headers
+ Minor changes to avoid some compiler warnings
+ psheader.txt: Remove psfig macros due to copyright issues
+ Pulled in updated libraries, etc.
+ Removed outdated copies of the freetype2 library
+ + Internal changes in handling of PostScript file inclusion
+
* 22.87 (2014-04-12):
+ ft.c: Avoid a compiler warning.
+ font-open.c: Add support for .runlibfileifexists in gs Fontmap file;
diff --git a/Build/source/texk/xdvik/ChangeLog b/Build/source/texk/xdvik/ChangeLog
index 98a4bbed470..7add28090d1 100644
--- a/Build/source/texk/xdvik/ChangeLog
+++ b/Build/source/texk/xdvik/ChangeLog
@@ -1,3 +1,7 @@
+2016-04-06 Karl Berry <karl@tug.org>
+
+ * Import xdvik-22.87.03.
+
2015-04-17 Karl Berry <karl@tug.org>
* psheader.txt (/psfts, /startTexFig, /doclip, /endTexFig):
diff --git a/Build/source/texk/xdvik/configure b/Build/source/texk/xdvik/configure
index 9d277106c95..f7d4eeaace8 100755
--- a/Build/source/texk/xdvik/configure
+++ b/Build/source/texk/xdvik/configure
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for xdvik (TeX Live) 22.87.
+# Generated by GNU Autoconf 2.69 for xdvik 22.87.03.
#
# Report bugs to <tex-k@tug.org>.
#
@@ -588,10 +588,10 @@ MFLAGS=
MAKEFLAGS=
# Identity of this package.
-PACKAGE_NAME='xdvik (TeX Live)'
-PACKAGE_TARNAME='xdvik--tex-live-'
-PACKAGE_VERSION='22.87'
-PACKAGE_STRING='xdvik (TeX Live) 22.87'
+PACKAGE_NAME='xdvik'
+PACKAGE_TARNAME='xdvik'
+PACKAGE_VERSION='22.87.03'
+PACKAGE_STRING='xdvik 22.87.03'
PACKAGE_BUGREPORT='tex-k@tug.org'
PACKAGE_URL=''
@@ -1377,7 +1377,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
-\`configure' configures xdvik (TeX Live) 22.87 to adapt to many kinds of systems.
+\`configure' configures xdvik 22.87.03 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1425,8 +1425,7 @@ Fine tuning of the installation directories:
--infodir=DIR info documentation [DATAROOTDIR/info]
--localedir=DIR locale-dependent data [DATAROOTDIR/locale]
--mandir=DIR man documentation [DATAROOTDIR/man]
- --docdir=DIR documentation root
- [DATAROOTDIR/doc/xdvik--tex-live-]
+ --docdir=DIR documentation root [DATAROOTDIR/doc/xdvik]
--htmldir=DIR html documentation [DOCDIR]
--dvidir=DIR dvi documentation [DOCDIR]
--pdfdir=DIR pdf documentation [DOCDIR]
@@ -1452,7 +1451,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of xdvik (TeX Live) 22.87:";;
+ short | recursive ) echo "Configuration of xdvik 22.87.03:";;
esac
cat <<\_ACEOF
@@ -1607,7 +1606,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-xdvik (TeX Live) configure 22.87
+xdvik configure 22.87.03
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2446,7 +2445,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by xdvik (TeX Live) $as_me 22.87, which was
+It was created by xdvik $as_me 22.87.03, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@@ -8130,8 +8129,8 @@ fi
# Define the identity of the package.
- PACKAGE='xdvik--tex-live-'
- VERSION='22.87'
+ PACKAGE='xdvik'
+ VERSION='22.87.03'
cat >>confdefs.h <<_ACEOF
@@ -15851,6 +15850,9 @@ main ()
{
Display *DISP; int ndevices;
XIDeviceInfo *info = XIQueryDevice(DISP, XIAllDevices, &ndevices);
+#if (XI_2_Major < 2 || (XI_2_Major == 2 && XI_2_Minor < 1))
+choke me "XInput version is < 2.1"
+#endif
;
return 0;
}
@@ -17734,7 +17736,7 @@ Usage: $0 [OPTIONS]
Report bugs to <bug-libtool@gnu.org>."
lt_cl_version="\
-xdvik (TeX Live) config.lt 22.87
+xdvik config.lt 22.87.03
configured by $0, generated by GNU Autoconf 2.69.
Copyright (C) 2011 Free Software Foundation, Inc.
@@ -19094,7 +19096,7 @@ cat >>confdefs.h <<_ACEOF
_ACEOF
-XDVIK_VERSION=22.87
+XDVIK_VERSION=22.87.03
ac_config_files="$ac_config_files Makefile tests/Makefile"
@@ -19645,7 +19647,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
-This file was extended by xdvik (TeX Live) $as_me 22.87, which was
+This file was extended by xdvik $as_me 22.87.03, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -19711,7 +19713,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
-xdvik (TeX Live) config.status 22.87
+xdvik config.status 22.87.03
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
diff --git a/Build/source/texk/xdvik/configure.ac b/Build/source/texk/xdvik/configure.ac
index 9587d989975..13aa33016b8 100644
--- a/Build/source/texk/xdvik/configure.ac
+++ b/Build/source/texk/xdvik/configure.ac
@@ -6,8 +6,8 @@ dnl This file is free software; the copyright holder
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
dnl
-m4_define([xdvik_version], [22.87])
-AC_INIT([xdvik (TeX Live)], xdvik_version, [tex-k@tug.org])
+m4_define([xdvik_version], [22.87.03])
+AC_INIT([xdvik], xdvik_version, [tex-k@tug.org])
AC_PREREQ([2.65])
AC_CONFIG_SRCDIR([xdvi.c])
AC_CONFIG_AUX_DIR([../../build-aux])
diff --git a/Build/source/texk/xdvik/dvi-draw.c b/Build/source/texk/xdvik/dvi-draw.c
index 4a9bbe88961..e062f5f591b 100644
--- a/Build/source/texk/xdvik/dvi-draw.c
+++ b/Build/source/texk/xdvik/dvi-draw.c
@@ -2943,7 +2943,12 @@ text_do_char(FILE *fp, struct scan_info *info, wide_ubyte ch)
do_load_freetype_font();
#endif
- if (currinf.set_char_p == load_n_set_char) {
+#if FREETYPE
+ while (currinf.set_char_p == load_n_set_char)
+#else
+ if (currinf.set_char_p == load_n_set_char)
+#endif
+ {
if (globals.ev.flags & EV_GE_NEWDOC) /* if abort */
return 0;
if (!load_font(currinf.fontp
@@ -3072,7 +3077,12 @@ geom_do_char(FILE *fp, struct scan_info *info, wide_ubyte ch)
do_load_freetype_font();
#endif
- if (currinf.set_char_p == load_n_set_char) {
+#if FREETYPE
+ while (currinf.set_char_p == load_n_set_char)
+#else
+ if (currinf.set_char_p == load_n_set_char)
+#endif
+ {
if (globals.ev.flags & EV_GE_NEWDOC) /* if abort */
return 0;
if (!load_font(currinf.fontp
@@ -3781,7 +3791,7 @@ src_spawn_editor(const struct src_parsed_special *parsed)
argv = src_format_arguments(get_separated_list(resource.editor, " \t", True),
expanded_filename, parsed->line, parsed->col);
- fork_process(argv[0], False, NULL, NULL, NULL, argv);
+ fork_process(argv[0], False, NULL, NULL, NULL, 0, argv);
free(expanded_filename);
for (i = 0; argv[i] != NULL; i++)
diff --git a/Build/source/texk/xdvik/dvi-init.c b/Build/source/texk/xdvik/dvi-init.c
index 10e425fe303..6126a08fe1b 100644
--- a/Build/source/texk/xdvik/dvi-init.c
+++ b/Build/source/texk/xdvik/dvi-init.c
@@ -894,8 +894,8 @@ set_paper_type(const char *arg)
arg1 = strchr(arg, 'x');
if (arg1 == NULL)
return False;
- m_paper_unshrunk_w = atopix(arg, False);
- m_paper_unshrunk_h = atopix(arg1 + 1, False);
+ m_paper_unshrunk_w = atopix(arg);
+ m_paper_unshrunk_h = atopix(arg1 + 1);
globals.grid_paper_unit = atopixunit(arg);
diff --git a/Build/source/texk/xdvik/events.c b/Build/source/texk/xdvik/events.c
index 2ad55d03686..e0709382484 100644
--- a/Build/source/texk/xdvik/events.c
+++ b/Build/source/texk/xdvik/events.c
@@ -1,6 +1,6 @@
/*======================================================================*\
-Copyright (c) 1990-2014 Paul Vojta and others
+Copyright (c) 1990-2016 Paul Vojta and others
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to
@@ -80,6 +80,7 @@ in xdvi.c.
#include "statusline.h"
#include "hypertex.h"
#include "dvi-init.h"
+#include "exit-handlers.h"
#include "Tip.h"
#include "browser.h"
#include "search-internal.h"
@@ -409,6 +410,7 @@ static void Act_source_special(Widget, XEvent *, String *, Cardinal *);
static void Act_show_source_specials(Widget, XEvent *, String *, Cardinal *);
static void Act_source_what_special(Widget, XEvent *, String *, Cardinal *);
static void Act_unpause_or_next(Widget, XEvent *, String *, Cardinal *);
+static void Act_user_exec(Widget, XEvent *, String *, Cardinal *);
static void Act_ruler_snap_origin(Widget w, XEvent *event, String *params, Cardinal *num_params);
static void Act_load_url(Widget w, XEvent *event, String *params, Cardinal *num_params);
#ifdef MOTIF
@@ -483,6 +485,7 @@ static XtActionsRec m_actions[] = {
{"show-source-specials", Act_show_source_specials},
{"source-what-special", Act_source_what_special},
{"unpause-or-next", Act_unpause_or_next},
+ {"user-exec", Act_user_exec},
#if 0 /* not implemented yet */
{"set-papersize", Act_set_papersize},
{"set-paper-landscape", Act_set_paper_landscape},
@@ -3948,6 +3951,42 @@ Act_source_what_special(Widget w, XEvent *event,
source_reverse_search(my_x, my_y, False);
}
+static const char *user_exec_help =
+"The user-exec() action lets you run a child process. "
+"It takes a single string, which is tokenized on whitespace.";
+
+void
+Act_user_exec(Widget w, XEvent *event,
+ String *params, Cardinal *num_params)
+{
+ char **argv;
+ int i;
+ char *errmsg = NULL;
+
+ if (*num_params == 0)
+ errmsg = "No arguments supplied to the user-exec() action.";
+ else if (*num_params > 1)
+ errmsg = "Too many arguments supplied to the user-exec() action.";
+ else if (setenv("XDVI_FILE", globals.dvi_name, 1) == -1)
+ errmsg = strerror(errno);
+
+ if (errmsg) {
+ popup_message(globals.widgets.top_level,
+ MSG_ERR,
+ /* helptext */
+ user_exec_help,
+ /* popup */
+ errmsg);
+ return;
+ }
+
+ argv = get_separated_list(params[0], " \t", True);
+ fork_process(argv[0], False, NULL, NULL, NULL, 0, argv);
+ for (i = 0; argv[i] != NULL; i++)
+ free(argv[i]);
+ free(argv);
+}
+
static void
select_cb(const char *filename, void *data)
{
@@ -5073,38 +5112,70 @@ do_sigsegv(void)
/*
- * Handle termination signals. Kill child processes, if permitted.
- * Otherwise, leave it up to the caller. This is the only place where
- * the EV_TERM event flag is set, and it can only happen if there's an
- * active non-killable process. This should only happen if read_events()
- * is called from one of a very few select locations.
+ * Handle termination signals. Just call xdvi_exit, which does all the
+ * work, since that is the common exit point.
*/
static void
do_sigterm(void)
{
+ sig_flags &= ~SF_TERM;
+
+ xdvi_exit(EXIT_SUCCESS);
+}
+
+/*
+ * This routine should be used for all exits. (SU: This is different
+ * from non-k xdvi, where it's only used for `non-early' exits; all
+ * routines called here should be aware of their own state and either
+ * perform cleanup or just return, unless xdvi_exit() itself checks for
+ * the status).
+ */
+
+void
+xdvi_exit(int status)
+{
struct xchild *cp;
- sig_flags &= ~SF_TERM;
+ /* do the following only if the window has been opened: */
+ if (globals.widgets.top_level != 0 && XtIsRealized(globals.widgets.top_level)) {
+ char *filehist;
+ file_history_set_page(current_page);
+ filehist = file_history_get_list();
+ store_preference(NULL, "fileHistory", "%s", filehist);
+ free(filehist);
+
+#if MOTIF
+ if (preferences_changed()) {
+ return;
+ }
+ /* else { */
+ /* fprintf(stderr, "Preferences not changed.\n"); */
+ /* } */
+#endif
+ /* try to save user preferences, unless we're exiting with an error */
+ if (status == EXIT_SUCCESS && !save_user_preferences(True))
+ return;
+
+ /* Clean up the "xdvi windows" property in the root window. */
+ update_window_property(XtWindow(globals.widgets.top_level), False);
+ }
+
+#if PS
+ ps_destroy_nofree();
+#endif
/* loop through child processes */
for (cp = child_recs; cp != NULL; cp = cp->next) {
- if (cp->killable)
- kill(cp->pid, SIGKILL);
+ if (cp->killsig > 0)
+ kill(cp->pid, cp->killsig);
+ else if (cp->killsig < 0)
+ kill(-cp->pid, -cp->killsig);
}
- /* SU: Unlike non-k xdvi, we don't care about whether all children have been
- killed, since processes forked via fork_process() (e.g. the web browser)
- may still continue running. So we just exit here.
- */
- xdvi_exit(EXIT_SUCCESS);
+ call_exit_handlers();
- /* BUG ALERT: since xdvi_exit() may return (checks before writing to ~/.xdvirc),
- we mustn't do the following which is in non-k xdvi, else we'll end up in a busy loop.
- I don't know who the `caller' is anyway ...
-
- globals.ev.flags |= EV_TERM; /\* otherwise, let the caller handle it *\/
- */
+ exit(status);
}
@@ -5306,7 +5377,7 @@ xi2_emulate_action(struct xdvi_action *actp, struct xi2_valinfo *valinfo,
}
if (actp->proc == Act_wheel) {
-# if XAW
+# if !MOTIF
if (globals.widgets.y_bar != NULL)
XtCallCallbacks(globals.widgets.y_bar, XtNscrollProc,
cast_int_to_XtPointer(dist));
@@ -5317,7 +5388,7 @@ xi2_emulate_action(struct xdvi_action *actp, struct xi2_valinfo *valinfo,
# endif /* MOTIF */
}
else { /* Act_hwheel */
-# if XAW
+# if !MOTIF
if (globals.widgets.x_bar != NULL)
XtCallCallbacks(globals.widgets.x_bar, XtNscrollProc,
cast_int_to_XtPointer(dist));
@@ -6151,8 +6222,6 @@ do_pages(void)
True,
#endif
&errflag)) {
-#if PS
- ps_clear_cache();
#if PS_GS
if (resource.gs_alpha) {
/* restart gs so that user has a method for fixing GS artifacts with gs_alpha
@@ -6160,7 +6229,6 @@ do_pages(void)
ps_destroy();
}
#endif
-#endif
statusline_info(STATUS_SHORT, "File reloaded.");
}
/* else { */
diff --git a/Build/source/texk/xdvik/events.h b/Build/source/texk/xdvik/events.h
index 5c5cb8b8ea9..cc94f9c4925 100644
--- a/Build/source/texk/xdvik/events.h
+++ b/Build/source/texk/xdvik/events.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1990-2004 Paul Vojta and the xdvik development team
+ * Copyright (c) 1990-2015 Paul Vojta and the xdvik development team
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
@@ -87,10 +87,10 @@ typedef void (*childProcT)(int exitval, struct xchild *this);
struct xchild {
struct xchild *next; /* link to next in list */
pid_t pid; /* pid of process, or 0 */
- Boolean killable; /* if can be killed with SIGKILL */
char *name; /* name of process, for printing error message */
struct xio *io; /* pointer to i/o structure for reading error msg. */
void *data; /* arbitrary data passed to proc */
+ int killsig; /* signal to use when killing it, or 0 */
/* proc is a pointer to a function to call when the child exits; it will be
* called with 2 arguments:
@@ -125,7 +125,8 @@ extern void cancel_timer(struct xtimer *tp);
extern int get_num_actions(void);
extern XtActionsRec *get_actions(void);
-extern int atopix(const char *, Boolean);
+extern int atopix(const char *);
+extern int atopix_signed(const char *);
extern int check_goto_page(int pageno, Boolean insert_into_pagehist);
extern Boolean get_int_arg(String * param, Cardinal *num_params, int *res);
@@ -150,6 +151,7 @@ extern void set_chld(struct xchild *);
extern void clear_chld(struct xchild *);
extern void set_io(struct xio *);
extern void clear_io(struct xio *);
+extern void xdvi_exit(int);
extern unsigned int read_events(unsigned int);
typedef void (*home_proc) (wide_bool);
diff --git a/Build/source/texk/xdvik/exit-handlers.c b/Build/source/texk/xdvik/exit-handlers.c
index 79a0629a973..0b34fdc2f45 100644
--- a/Build/source/texk/xdvik/exit-handlers.c
+++ b/Build/source/texk/xdvik/exit-handlers.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004 Stefan Ulrich
+ * Copyright (c) 2004-2015 Stefan Ulrich and the xdvik development team
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
@@ -34,19 +34,27 @@
static struct exit_list {
exit_procedure proc;
void *arg;
+ struct exit_list *next;
} *exit_procs = NULL;
-static size_t exit_procs_size = 0;
-
void register_exit_handler(exit_procedure proc, void *arg)
{
- size_t idx = exit_procs_size;
- exit_procs_size++;
- exit_procs = xrealloc(exit_procs, sizeof *exit_procs * exit_procs_size);
- exit_procs[idx].proc = proc;
- exit_procs[idx].arg = arg;
+ struct exit_list *ep;
+
+ /* first check for duplicates (needed because of remove_tmp_dvi_file) */
+ for (ep = exit_procs; ep != NULL; ep = ep->next) {
+ if (ep->proc == proc && ep->arg == arg)
+ return;
+ }
+
+ ep = xmalloc(sizeof *ep);
+ ep->proc = proc;
+ ep->arg = arg;
+ ep->next = exit_procs;
+ exit_procs = ep;
}
+#if 0 /* This is currently unused. */
void unregister_exit_handler(exit_procedure proc)
{
size_t i;
@@ -58,14 +66,21 @@ void unregister_exit_handler(exit_procedure proc)
}
}
}
+#endif
void call_exit_handlers(void)
{
- size_t i;
- for (i = 0; i < exit_procs_size; i++) {
- if (exit_procs[i].proc)
- exit_procs[i].proc(exit_procs[i].arg);
+ struct exit_list *ep;
+
+ for (ep = exit_procs; ep != NULL; ep = ep->next) {
+ ep->proc(ep->arg);
/* fprintf(stderr, "calling exit proc %lu\n", (unsigned long)i); */
}
- free(exit_procs);
+
+ /* free them */
+ while (exit_procs != NULL) {
+ ep = exit_procs;
+ exit_procs = exit_procs->next;
+ free(ep);
+ }
}
diff --git a/Build/source/texk/xdvik/exit-handlers.h b/Build/source/texk/xdvik/exit-handlers.h
index 507f528358c..e9fb2de0b52 100644
--- a/Build/source/texk/xdvik/exit-handlers.h
+++ b/Build/source/texk/xdvik/exit-handlers.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004 Stefan Ulrich
+ * Copyright (c) 2004-2015 Stefan Ulrich and the xdvik development team
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
@@ -26,8 +26,8 @@
typedef void (*exit_procedure) (void *);
-extern void unregister_exit_handler(exit_procedure proc);
extern void register_exit_handler(exit_procedure proc, void *arg);
+/* extern void unregister_exit_handler(exit_procedure proc); */
extern void call_exit_handlers(void);
#endif /* EXIT_HANDLERS_H_ */
diff --git a/Build/source/texk/xdvik/gui/print-dialog.c b/Build/source/texk/xdvik/gui/print-dialog.c
index 19b59f18a15..2a21077414e 100644
--- a/Build/source/texk/xdvik/gui/print-dialog.c
+++ b/Build/source/texk/xdvik/gui/print-dialog.c
@@ -618,9 +618,9 @@ motif_create_dialog(struct save_or_print_info *info)
char ofstring[1024];
Widget form, pane, box;
- Widget print_or_save_frame, destination_label, destination_form;
+ Widget print_or_save_frame, destination_form;
Widget dvips_options_label;
- Widget pages_frame, pages_label, pages_form;
+ Widget pages_frame, pages_form;
Widget print_to_file_text, to_file_radio_or_label;
Widget dvips_options_text;
Widget print_to_file_button;
@@ -689,11 +689,11 @@ motif_create_dialog(struct save_or_print_info *info)
NULL);
str = XmStringCreateLocalized("Print to:");
- destination_label = XtVaCreateManagedWidget("title", xmLabelGadgetClass,
- print_or_save_frame,
- XmNchildType, XmFRAME_TITLE_CHILD,
- XmNlabelString, str,
- NULL);
+ XtVaCreateManagedWidget("title", xmLabelGadgetClass,
+ print_or_save_frame,
+ XmNchildType, XmFRAME_TITLE_CHILD,
+ XmNlabelString, str,
+ NULL);
XmStringFree(str);
destination_form = XtVaCreateWidget("destination_form", xmFormWidgetClass, print_or_save_frame,
@@ -796,10 +796,11 @@ motif_create_dialog(struct save_or_print_info *info)
NULL);
str = XmStringCreateLocalized("Save as:");
- destination_label = XtVaCreateManagedWidget("title", xmLabelGadgetClass, print_or_save_frame,
- XmNchildType, XmFRAME_TITLE_CHILD,
- XmNlabelString, str,
- NULL);
+ XtVaCreateManagedWidget("title", xmLabelGadgetClass,
+ print_or_save_frame,
+ XmNchildType, XmFRAME_TITLE_CHILD,
+ XmNlabelString, str,
+ NULL);
XmStringFree(str);
destination_form = XtVaCreateWidget("destination_form", xmFormWidgetClass, print_or_save_frame,
@@ -966,7 +967,7 @@ motif_create_dialog(struct save_or_print_info *info)
NULL);
str = XmStringCreateLocalized("Pages:");
- pages_label = XtVaCreateManagedWidget("title", xmLabelGadgetClass, pages_frame,
+ XtVaCreateManagedWidget("title", xmLabelGadgetClass, pages_frame,
XmNchildType, XmFRAME_TITLE_CHILD,
XmNlabelString, str,
NULL);
diff --git a/Build/source/texk/xdvik/gui/xm_prefs_helpers.c b/Build/source/texk/xdvik/gui/xm_prefs_helpers.c
index 5feb3e387f0..7609e8170cd 100644
--- a/Build/source/texk/xdvik/gui/xm_prefs_helpers.c
+++ b/Build/source/texk/xdvik/gui/xm_prefs_helpers.c
@@ -837,7 +837,7 @@ prefs_helpers(struct topic_info *tinfo)
{
/* struct prefs_choice *prefs = (struct prefs_choice *)info->data; */
Widget form, /* frame, */ form1;
- Widget browser_command, editor_command;
+ Widget browser_command;
form = XmCreateForm(tinfo->right_form, "helpers_form", NULL, 0);
@@ -863,13 +863,13 @@ prefs_helpers(struct topic_info *tinfo)
m_browser_list,
select_browser_cb, tinfo);
- editor_command = h_create_command(Xdvi_EDITOR_COMBO_NAME,
- Xdvi_EDITOR_MENU_NAME,
- "Editor for Source Specials: ",
- resource.editor,
- form1, browser_command,
- m_editor_list,
- select_editor_cb, tinfo);
+ h_create_command(Xdvi_EDITOR_COMBO_NAME,
+ Xdvi_EDITOR_MENU_NAME,
+ "Editor for Source Specials: ",
+ resource.editor,
+ form1, browser_command,
+ m_editor_list,
+ select_editor_cb, tinfo);
/* #if PS_GS */
/* Widget b2 = XmCreateLabelGadget(rowcol, "[x] Use Ghostscript to interpret PS specials", NULL, 0); */
diff --git a/Build/source/texk/xdvik/gui/xm_toolbar.c b/Build/source/texk/xdvik/gui/xm_toolbar.c
index f68e376e966..7b523d344db 100644
--- a/Build/source/texk/xdvik/gui/xm_toolbar.c
+++ b/Build/source/texk/xdvik/gui/xm_toolbar.c
@@ -309,7 +309,6 @@ create_pixmap(Widget parent, int iconidx, Pixmap *sen, Pixmap *insen)
{"topShadowColor", NULL, 0},
{"selectColor", NULL, 0}
};
- static int screenNum;
static Pixmap tools_map;
static Pixmap tools_mask;
static Pixmap shade_map;
@@ -336,7 +335,6 @@ create_pixmap(Widget parent, int iconidx, Pixmap *sen, Pixmap *insen)
NULL);
XtRealizeWidget(dummy); /* note: doesn't pop it up */
rootWindow = XtWindow(dummy);
- screenNum = DefaultScreen(XtDisplay(globals.widgets.top_level));
ASSERT(rootWindow != 0, "");
XtVaGetValues(parent,
XmNbackground, &color[BACKGROUND].pixel,
diff --git a/Build/source/texk/xdvik/hypertex.c b/Build/source/texk/xdvik/hypertex.c
index ac9d35934c1..736ae4b0b3c 100644
--- a/Build/source/texk/xdvik/hypertex.c
+++ b/Build/source/texk/xdvik/hypertex.c
@@ -1954,7 +1954,7 @@ launch_xdvi(const char *filename, const char *anchor_name)
printing to stderr, so we use plain fork/exec (see comments in util.c)
*/
#if 0
- fork_process(argv[0], False, NULL, NULL, NULL, argv);
+ fork_process(argv[0], False, NULL, NULL, NULL, 0, argv);
#else
{
int pid;
@@ -2138,7 +2138,7 @@ launch_program(const char *filename)
strcpy(syscmd + offset + (ptr - viewer) + strlen(fullpath), ptr + strlen(format_string));
/*
- mailcap(4) says that the mailcap command shall be passed to system(),
+ mailcap(5) says that the mailcap command shall be passed to system(),
so we musn't use fork_process() directly here. Instead, we pass the command
to `/bin/sh -c', but via fork_process so that
@@ -2154,9 +2154,11 @@ launch_program(const char *filename)
argv[2] = syscmd;
argv[3] = NULL;
#if COPY_TMP_FILE
- fork_process("/bin/sh", False, globals.dvi_file.dirname, remove_temp_file, fullpath, argv);
+ fork_process("/bin/sh", False, globals.dvi_file.dirname, remove_temp_file,
+ fullpath, 0, argv);
#else
- fork_process("/bin/sh", False, globals.dvi_file.dirname, NULL, NULL, argv);
+ fork_process("/bin/sh", False, globals.dvi_file.dirname, NULL,
+ NULL, 0, argv);
#endif
FREE(viewer);
diff --git a/Build/source/texk/xdvik/m4/xdvi-xinput-2-1.m4 b/Build/source/texk/xdvik/m4/xdvi-xinput-2-1.m4
index d7fbe009a96..7ca32f195a5 100644
--- a/Build/source/texk/xdvik/m4/xdvi-xinput-2-1.m4
+++ b/Build/source/texk/xdvik/m4/xdvi-xinput-2-1.m4
@@ -33,7 +33,10 @@ CPPFLAGS="$X_CFLAGS $CPPFLAGS"
LDFLAGS="$X_LIBS $LDFLAGS"
AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <X11/extensions/XInput2.h>]],
[[Display *DISP; int ndevices;
-XIDeviceInfo *info = XIQueryDevice(DISP, XIAllDevices, &ndevices);]])],
+XIDeviceInfo *info = XIQueryDevice(DISP, XIAllDevices, &ndevices);
+#if (XI_2_Major < 2 || (XI_2_Major == 2 && XI_2_Minor < 1))
+choke me "XInput version is < 2.1"
+#endif]])],
[xdvi_cv_xinput_2_1=yes],
[xdvi_cv_xinput_2_1=no])
LIBS=$xdvi_xi2_save_LIBS
diff --git a/Build/source/texk/xdvik/main.c b/Build/source/texk/xdvik/main.c
index 102efab1dec..644d25e9529 100644
--- a/Build/source/texk/xdvik/main.c
+++ b/Build/source/texk/xdvik/main.c
@@ -641,12 +641,12 @@ init_check_resources(void)
/* margins */
if (resource.sidemargin)
- resource.sidemargin_int = atopix(resource.sidemargin, False);
+ resource.sidemargin_int = atopix(resource.sidemargin);
if (resource.topmargin)
- resource.topmargin_int = atopix(resource.topmargin, False);
- resource.xoffset_int = resource.xoffset ? atopix(resource.xoffset, True)
+ resource.topmargin_int = atopix(resource.topmargin);
+ resource.xoffset_int = resource.xoffset ? atopix_signed(resource.xoffset)
: resource.pixels_per_inch;
- resource.yoffset_int = resource.yoffset ? atopix(resource.yoffset, True)
+ resource.yoffset_int = resource.yoffset ? atopix_signed(resource.yoffset)
: resource.pixels_per_inch;
/* paper type */
diff --git a/Build/source/texk/xdvik/print-internal.c b/Build/source/texk/xdvik/print-internal.c
index cc6206fc56d..dfa6f9a4ff8 100644
--- a/Build/source/texk/xdvik/print-internal.c
+++ b/Build/source/texk/xdvik/print-internal.c
@@ -81,7 +81,8 @@
# define XIO_OUT 2
#endif /* HAVE_POLL */
-static struct xchild print_child = {NULL, 0, True, "dvips", NULL, NULL, NULL };
+static struct xchild print_child = {NULL, 0, "dvips", NULL, NULL, SIGKILL, NULL
+ };
static char *read_from_dvips(int, void *);
@@ -512,7 +513,8 @@ call_ps2pdf(const char *path, const struct save_or_print_info *info)
/* need to run this in globals.xdvi_dir again, since the dvips conversion directory
globals.dvi_file.dirname may not be writable! */
- if (!fork_process("ps2pdf", True, globals.cwd, ps2pdf_exited, (void *)info, (char **)argv)) {
+ if (!fork_process("ps2pdf", True, globals.cwd, ps2pdf_exited, (void *)info,
+ 0, (char **)argv)) {
popup_message(globals.widgets.top_level,
MSG_ERR,
NULL, "Couldn't fork %s process: %s\n", argv[0], strerror(errno));
diff --git a/Build/source/texk/xdvik/psgs.c b/Build/source/texk/xdvik/psgs.c
index 8a5689377a7..98df537173a 100644
--- a/Build/source/texk/xdvik/psgs.c
+++ b/Build/source/texk/xdvik/psgs.c
@@ -37,7 +37,7 @@ OTHER DEALINGS IN THE SOFTWARE.
/* Condition for retrying a write */
#include <errno.h>
-#include <strings.h>
+#include <string.h>
#include "kpathsea/c-pathmx.h"
#include "dvi-init.h"
@@ -174,7 +174,7 @@ static struct xio gs_xio = {NULL, 0, XIO_IN,
NULL /* data */
};
-static struct xchild gs_child = { NULL, 0, True, NULL, NULL, NULL, gs_died };
+static struct xchild gs_child = { NULL, 0, NULL, NULL, NULL, SIGKILL, gs_died };
#define GS_pid (gs_child.pid)
/* It seems that XtTimers don't work reliably with xdvi's event treatment;
diff --git a/Build/source/texk/xdvik/special.c b/Build/source/texk/xdvik/special.c
index 3cf55298ec8..491c583b953 100644
--- a/Build/source/texk/xdvik/special.c
+++ b/Build/source/texk/xdvik/special.c
@@ -1,6 +1,6 @@
/*========================================================================*\
-Copyright (c) 1990-2004 Paul Vojta
+Copyright (c) 1990-2016 Paul Vojta and others
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to
@@ -946,106 +946,120 @@ drawbegin_none(int xul, int yul, const char *cp)
}
-struct tickrec {
- struct tickrec *next;
- int pageno;
- char *command;
+/*
+ * Mechanism to keep track of included PS files.
+ */
+
+struct avl_psinfo {
+ AVL_COMMON;
+ char *fullpath;
char *tempname;
+ dev_t ps_dev;
+ ino_t ps_ino;
+ time_t ps_mtime;
+ Boolean is_new; /* set if previous use failed because of !allow_shell */
};
-static struct tickrec *tickhead = NULL; /* head of linked list of */
-/* cached information */
-static int nticks = 0; /* number of records total */
-
-#ifndef TICKCACHESIZE
-#define TICKCACHESIZE 3
-#endif
+static struct avl_psinfo *psinfo_head = NULL;
-#ifndef TICKTMP
-#define TICKTMP "/tmp"
-#endif
/*
- * cachetick() - returns:
- * NULL error;
- * fp == NULL string was not in cache, fd = file
- * fp != NULL string was in cache, fp = cached file
+ * ps_clear_cache() resets the cache to the empty state.
*/
-static struct tickrec *
-cachetick(const char *filename, kpse_file_format_type pathinfo, FILE **fp, int *fdp)
+static void
+clear_psinfo_node(struct avl_psinfo *psinfp)
{
- struct tickrec **linkp;
- struct tickrec *tikp;
- struct tickrec **freerecp;
-
- linkp = &tickhead;
- freerecp = NULL;
- for (;;) { /* see if we have it already */
- tikp = *linkp;
- if (tikp == NULL) { /* if end of list */
- int fd;
-
- if (nticks >= TICKCACHESIZE && freerecp != NULL) {
- tikp = *freerecp;
- *freerecp = tikp->next;
- free(tikp->command);
- unlink(tikp->tempname);
- /* reuse tikp and tikp->tempname */
- }
- else {
- tikp = xmalloc(sizeof(struct tickrec));
- tikp->tempname = NULL;
- ++nticks;
- }
- fd = xdvi_temp_fd(&tikp->tempname);
- if (fd == -1) {
- perror("Cannot create temporary file");
- free(tikp->tempname);
- free(tikp);
- return NULL;
- }
- tikp->command = xstrdup(filename);
- *fp = NULL;
- *fdp = fd;
- break;
- }
- if (strcmp(filename, tikp->command) == 0) { /* found it */
- *linkp = tikp->next; /* unlink it */
- *fp = XFOPEN(tikp->tempname, OPEN_MODE);
- if (*fp == NULL) {
- perror(tikp->tempname);
- free(tikp->tempname);
- free(tikp->command);
- free(tikp);
- return NULL;
- }
- break;
- }
- if (tikp->pageno != current_page)
- freerecp = linkp;
- linkp = &tikp->next;
+ if (psinfp->fullpath != NULL) {
+ free(psinfp->fullpath);
+ psinfp->fullpath = NULL;
+ }
+ if (psinfp->tempname != NULL) {
+ if (unlink(psinfp->tempname) < 0)
+ perror(psinfp->tempname);
+ free(psinfp->tempname);
+ psinfp->tempname = NULL;
}
- tikp->next = tickhead; /* link it in */
- tickhead = tikp;
- tikp->pageno = pathinfo != kpse_tex_ps_header_format ? current_page : -1;
- return tikp;
}
-void
+static void
+clear_psinfo_tree(struct avl_psinfo *psinfp)
+{
+ if (psinfp == NULL)
+ return;
+
+ clear_psinfo_tree((struct avl_psinfo *) psinfp->left);
+ clear_psinfo_tree((struct avl_psinfo *) psinfp->right);
+ free((char *) psinfp->key);
+ clear_psinfo_node(psinfp);
+ free(psinfp);
+}
+
+static void
ps_clear_cache(void)
{
- struct tickrec *tikp;
+ clear_psinfo_tree(psinfo_head);
+ psinfo_head = NULL;
+}
+
+
+/*
+ * ps_clear_cache_nofree() does the same thing as ps_clear_cache(), but
+ * without ever calling free(). This is because it may be called
+ * following a segmentation fault, in which case the heap may be corrupted.
+ */
+
+static void
+clear_psinfo_node_nofree(struct avl_psinfo *psinfp)
+{
+ if (psinfp->fullpath != NULL) {
+ psinfp->fullpath = NULL;
+ }
+ if (psinfp->tempname != NULL) {
+ if (unlink(psinfp->tempname) < 0)
+ perror(psinfp->tempname);
+ psinfp->tempname = NULL;
+ }
+}
+
+static void
+clear_psinfo_tree_nofree(struct avl_psinfo *psinfp)
+{
+ if (psinfp == NULL)
+ return;
+
+ clear_psinfo_tree_nofree((struct avl_psinfo *) psinfp->left);
+ clear_psinfo_tree_nofree((struct avl_psinfo *) psinfp->right);
+ clear_psinfo_node_nofree(psinfp);
+}
+
+static void
+ps_clear_cache_nofree(void)
+{
+ clear_psinfo_tree_nofree(psinfo_head);
+ psinfo_head = NULL;
+}
+
- while (tickhead != NULL) {
- tikp = tickhead;
- tickhead = tickhead->next;
- free(tikp->command);
- unlink(tikp->tempname);
- free((char *)tikp->tempname);
- free(tikp);
+/*
+ * ps_new_tempfile() - Opens a new temporary file.
+ * Returns the fd, or -1 if an error occurred.
+ */
+
+static int
+ps_new_tempfile(struct avl_psinfo *psinfp)
+{
+ int fd;
+
+ fd = xdvi_temp_fd(&psinfp->tempname);
+ if (fd == -1) {
+ XDVI_ERROR((stderr,
+ "Cannot create temporary file for PostScript figure file: %s",
+ strerror(errno)));
+ free(psinfp->tempname);
+ psinfp->tempname = NULL;
}
- nticks = 0;
+ return fd;
}
#ifndef UNCOMPRESS
@@ -1081,18 +1095,20 @@ try_open_tempname(int status, struct xchild *this)
if (WEXITSTATUS(status) != 0) {
/* default error procedure */
handle_child_exit(status, this);
+ this = NULL; /* prevent freeing it twice */
}
else {
- struct tickrec *tikp = (struct tickrec *)this->data;
- FILE *f = XFOPEN(tikp->tempname, OPEN_MODE);
- fprintf(stderr, "FILE: %s\n", tikp->tempname);
+ struct avl_psinfo *psinfp = (struct avl_psinfo *) this->data;
+ FILE *f = XFOPEN(psinfp->tempname, OPEN_MODE);
+
+ fprintf(stderr, "FILE: %s\n", psinfp->tempname);
if (f == NULL) {
- perror(tikp->tempname);
+ perror(psinfp->tempname);
}
else {
- fprintf(stderr, "sending file: %s, %p\n", tikp->tempname, (void *)f);
+ fprintf(stderr, "sending file: %s, %p\n", psinfp->tempname, (void *)f);
/* There's no point in invoking
- psp.drawfile(tikp->tempname, f);
+ psp.drawfile(psinfp->tempname, f);
here, since usually it will be already too late (draw_part() which
had called us via applicationDoSpecial() will already have terminated).
So instead, we just close the file and force a redraw of the entire page.
@@ -1120,6 +1136,11 @@ try_open_tempname(int status, struct xchild *this)
NULL,
"Process `%s' terminated with unknown status.", this->name);
}
+ if (this != NULL) { /* if it wasn't freed already */
+ free(this->name);
+ free(this->io);
+ free(this);
+ }
}
static void
@@ -1129,8 +1150,8 @@ send_ps_file(const char *filename, kpse_file_format_type pathinfo)
int fd;
static const char *argv[] = { NULL, "-c", NULL, NULL };
char *bufp = NULL;
- struct tickrec *volatile tikp;
size_t len;
+ struct avl_psinfo *volatile psinfp;
char magic1, magic2, magic3;
static Boolean warned_about_shellescape = False;
static size_t ffline_len = 0;
@@ -1141,7 +1162,18 @@ send_ps_file(const char *filename, kpse_file_format_type pathinfo)
return;
}
+ len = strlen(filename);
+ psinfp = (struct avl_psinfo *) avladd(filename, len,
+ (struct avl **) &psinfo_head, sizeof(struct avl_psinfo));
+
+ if (psinfp->key == filename) { /* if new record */
+ psinfp->is_new = True;
+ psinfp->key = xmemdup(filename, len + 1);
+ psinfp->fullpath = psinfp->tempname = NULL;
+ }
+
if (filename[0] == '`') {
+ /* To test this code, use \special{psfile="`cat file.ps"} */
if (!resource.allow_shell) {
if (!warned_about_shellescape) {
choice_dialog_sized(globals.widgets.top_level,
@@ -1185,113 +1217,195 @@ send_ps_file(const char *filename, kpse_file_format_type pathinfo)
return;
}
- tikp = cachetick(filename, pathinfo, &f, &fd);
- if (tikp == NULL) /* if error */
- return;
- if (f == NULL) {
+ if (!psinfp->is_new) { /* if we already have it */
+ if (psinfp->tempname == NULL) { /* if previously known error */
+ draw_bbox();
+ return;
+ }
+ f = XFOPEN(psinfp->tempname, OPEN_MODE);
+ if (f == NULL) {
+ perror(psinfp->tempname);
+ /* WARN1(XmDIALOG_ERROR,
+ "Cannot open temporary PostScript file:\n%s",
+ psinfp->tempname); */
+ clear_psinfo_node(psinfp);
+ draw_bbox();
+ return;
+ }
+ psp.drawfile(psinfp->tempname, f);
+ }
+ else { /* it is new */
char *argv[4];
- /* if not cached, need to create.
- Fork so that we can collect the process' error messages. */
- /* FIXME: Insecure - this is a /tmp race; shouldn't close(fd), just re-use it */
+ psinfp->is_new = False;
+
+ /* Create the file (it wasn't cached).
+ Fork so that we can collect the process's error messages. */
+
+ fd = ps_new_tempfile(psinfp);
+ if (fd == -1) { /* if error */
+ draw_bbox();
+ return;
+ }
+
+ /* FIXME: Insecure - this is a /tmp race;
+ shouldn't close(fd), just re-use it */
close(fd);
- len = strlen(filename) + strlen(tikp->tempname) + (4 - 1);
+ len = strlen(filename) + strlen(psinfp->tempname) + (4 - 1);
if (len > ffline_len) {
ffline_len += FFLINE_STEP;
ffline = xrealloc(ffline, ffline_len);
}
- sprintf(ffline, "%s > %s", filename + 1, tikp->tempname);
+ sprintf(ffline, "%s > %s", filename + 1, psinfp->tempname);
argv[0] = "/bin/sh";
argv[1] = "-c";
argv[2] = ffline;
argv[3] = NULL;
- fork_process("/bin/sh", False, globals.dvi_file.dirname, try_open_tempname, tikp, argv);
- }
- else {
- bufp = tikp->tempname;
- psp.drawfile(bufp, f);
+ fork_process("/bin/sh", False, globals.dvi_file.dirname,
+ try_open_tempname, psinfp, -SIGKILL, argv);
}
}
- else {
+ else { /* not shell escape */
char *expanded_filename = NULL;
struct stat statbuf;
- expanded_filename = find_file(filename, &statbuf, pathinfo);
-
- if (expanded_filename == NULL &&
- (pathinfo == kpse_enc_format || pathinfo == kpse_type1_format)) {
- /* in this case, we also kpathsea-search in the `old' place for
- backwards compatibility: kpse_tex_ps_header_format (see comment
- for load_vector(), dvi-draw.c for details) */
- expanded_filename = kpse_find_file(filename, kpse_tex_ps_header_format, True);
- }
- if (expanded_filename == NULL) {
- expanded_filename = kpse_find_file(filename, kpse_program_text_format, True);
- }
- if (expanded_filename == NULL) { /* still no success, complain */
- /* FIXME: this warning may be overwritten by warning about raw PS specials,
- so additinally dump to stderr. TODO: make statusline printing respect
- more important messages. */
- XDVI_WARNING((stderr, "Could not find graphics file \"%s\"", filename));
- statusline_info(STATUS_MEDIUM, "Warning: Could not find graphics file \"%s\"",
- filename);
- draw_bbox();
- return;
+
+ if (psinfp->fullpath != NULL) { /* if existing rec., no error */
+ /* Check file modification time */
+ if (stat(psinfp->fullpath, &statbuf) != 0) {
+ perror(psinfp->fullpath);
+ if (psinfp->ps_mtime != 0) {
+ clear_psinfo_node(psinfp);
+ psinfp->is_new = True;
+ }
+ }
+ else {
+ if (psinfp->ps_dev != statbuf.st_dev
+ || psinfp->ps_ino != statbuf.st_ino
+ || psinfp->ps_mtime != statbuf.st_mtime) {
+ clear_psinfo_node(psinfp);
+ psinfp->is_new = True;
+ }
+ }
}
- if (globals.debug & DBG_OPEN)
- printf("%s:%d: |%s| expanded to |%s|\n", __FILE__, __LINE__, filename, expanded_filename);
-
- /* may need to adjust ffline_len, ffline */
- while (strlen(expanded_filename) + 1 > ffline_len) {
- ffline_len += FFLINE_STEP;
- ffline = xrealloc(ffline, ffline_len);
- }
- strcpy(ffline, expanded_filename);
- bufp = ffline;
- f = XFOPEN(expanded_filename, OPEN_MODE);
- if (f == NULL) {
- XDVI_WARNING((stderr, "Could not open graphics file \"%s\": %s", expanded_filename, strerror(errno)));
- statusline_info(STATUS_MEDIUM, "Warning: Could not open graphics file \"%s\": %s",
- expanded_filename, strerror(errno));
- free(expanded_filename);
- draw_bbox();
- return;
+
+ if (!psinfp->is_new) {
+ bufp = psinfp->tempname;
+ if (bufp == NULL) {
+ bufp = psinfp->fullpath;
+ if (bufp == NULL) { /* if error already noted */
+ draw_bbox();
+ return;
+ }
+ }
+ f = XFOPEN(bufp, OPEN_MODE);
+ if (f == NULL) {
+ XDVI_WARNING((stderr, "Could not find graphics or temporary file \"%s\"",
+ bufp));
+ statusline_info(STATUS_MEDIUM, "Warning: Could not find graphics or temporary file \"%s\"",
+ bufp);
+ clear_psinfo_node(psinfp);
+ draw_bbox();
+ return;
+ }
}
- free(expanded_filename);
-
- /* check for compressed files */
- len = strlen(filename);
- magic1 = '\037';
- magic3 = '\0';
- if ((len > 2 && strcmp(filename + len - 2, ".Z") == 0
- && (argv[0] = UNCOMPRESS, magic2 = '\235', True))
- || (len > 3 && strcmp(filename + len - 3, ".gz") == 0
- && (argv[0] = GUNZIP, magic2 = '\213', True))
- || (len > 4 && strcmp(filename + len - 4, ".bz2") == 0
- && (argv[0] = BUNZIP2, magic1 = 'B', magic2 = 'Z',
- magic3 = 'h', True))) {
- if (getc(f) != magic1 || (char)getc(f) != magic2
- || (magic3 != '\0' && getc(f) != magic3)) {
- rewind(f);
+ else { /* node is new */
+ psinfp->is_new = False;
+
+ expanded_filename = find_file(filename, &statbuf, pathinfo);
+
+ if (expanded_filename == NULL &&
+ (pathinfo == kpse_enc_format || pathinfo == kpse_type1_format))
+ {
+ /* in this case, we also kpathsea-search in the `old' place for
+ backwards compatibility: kpse_tex_ps_header_format
+ (see comment for load_vector(), dvi-draw.c for details) */
+ expanded_filename = kpse_find_file(filename,
+ kpse_tex_ps_header_format, True);
+ }
+ if (expanded_filename == NULL) {
+ expanded_filename = kpse_find_file(filename,
+ kpse_program_text_format, True);
+ }
+ if (expanded_filename == NULL) { /* still no success, complain */
+ /* FIXME: this warning may be overwritten by warning about raw
+ PS specials, so additinally dump to stderr.
+ TODO: make statusline printing respect more important
+ messages. */
+ XDVI_WARNING((stderr, "Could not find graphics file \"%s\"",
+ filename));
+ statusline_info(STATUS_MEDIUM,
+ "Warning: Could not find graphics file \"%s\"",
+ filename);
+ draw_bbox();
+ return;
+ }
+ if (globals.debug & DBG_OPEN)
+ printf("%s:%d: |%s| expanded to |%s|\n", __FILE__, __LINE__,
+ filename, expanded_filename);
+
+ f = XFOPEN(expanded_filename, OPEN_MODE);
+ if (f == NULL) {
+ XDVI_WARNING((stderr, "Could not open graphics file \"%s\": %s",
+ expanded_filename, strerror(errno)));
+ statusline_info(STATUS_MEDIUM,
+ "Warning: Could not open graphics file \"%s\": %s",
+ expanded_filename, strerror(errno));
+ free(expanded_filename);
+ draw_bbox();
+ return;
+ }
+
+ bufp = psinfp->fullpath = expanded_filename;
+
+ if (fstat(fileno(f), &statbuf) == 0) { /* get mod. time */
+ psinfp->ps_dev = statbuf.st_dev;
+ psinfp->ps_ino = statbuf.st_ino;
+ psinfp->ps_mtime = statbuf.st_mtime;
}
else {
- fclose(f);
+ perror(bufp);
+ psinfp->ps_dev = 0;
+ psinfp->ps_ino = 0;
+ psinfp->ps_mtime = 0;
+ }
- tikp = cachetick(filename, pathinfo, &f, &fd);
- if (tikp == NULL) /* if error */
- return;
- if (f == NULL) { /* if not cached, need to create */
+ /* check for compressed files */
+
+ len = strlen(filename);
+ magic1 = '\037';
+ magic3 = '\0';
+ if ((len > 2 && strcmp(filename + len - 2, ".Z") == 0
+ && (argv[0] = UNCOMPRESS, magic2 = '\235', True))
+ || (len > 3 && strcmp(filename + len - 3, ".gz") == 0
+ && (argv[0] = GUNZIP, magic2 = '\213', True))
+ || (len > 4 && strcmp(filename + len - 4, ".bz2") == 0
+ && (argv[0] = BUNZIP2, magic1 = 'B', magic2 = 'Z',
+ magic3 = 'h', True))) {
+ if (getc(f) != magic1 || (char)getc(f) != magic2
+ || (magic3 != '\0' && getc(f) != magic3)) {
+ rewind(f);
+ }
+ else {
pid_t pid;
int status;
+ fclose(f);
+
+ fd = ps_new_tempfile(psinfp);
+ if (fd == -1) { /* if error */
+ clear_psinfo_node(psinfp);
+ return;
+ }
argv[2] = bufp;
fflush(stderr); /* avoid double flushing */
pid = vfork();
if (pid == 0) { /* if child */
(void)dup2(fd, 1);
(void)execvp(argv[0], (char **)argv);
- XDVI_ERROR((stderr, "Execvp of %s failed: %s", argv[0], strerror(errno)));
+ XDVI_ERROR((stderr, "Execvp of %s failed: %s", argv[0],
+ strerror(errno)));
_exit(EXIT_FAILURE);
}
(void)close(fd);
@@ -1320,13 +1434,14 @@ send_ps_file(const char *filename, kpse_file_format_type pathinfo)
perror("[xdvik] waitpid");
return;
}
- f = XFOPEN(tikp->tempname, OPEN_MODE);
+ f = XFOPEN(psinfp->tempname, OPEN_MODE);
if (f == NULL) {
- perror(tikp->tempname);
+ perror(psinfp->tempname);
+ draw_bbox();
return;
}
+ bufp = psinfp->tempname;
}
- bufp = tikp->tempname;
}
}
/* Success! */
@@ -1338,25 +1453,31 @@ send_ps_file(const char *filename, kpse_file_format_type pathinfo)
void
ps_destroy(void)
{
- struct tickrec *tikp;
-
/* Note: old NeXT systems (at least) lack atexit/on_exit. */
psp.destroy();
- for (tikp = tickhead; tikp != NULL; tikp = tikp->next)
- if (unlink(tikp->tempname) < 0)
- perror(tikp->tempname);
+ ps_clear_cache();
}
+
+/*
+ * Same as above, but refrains from calling free() (may be called
+ * following a seg fault).
+ */
+
+void
+ps_destroy_nofree(void)
+{
+ psp.destroy();
+ ps_clear_cache_nofree();
+}
+
+
#endif /* PS */
void
init_prescan(void)
{
-#if PS
- struct tickrec *tikp;
-#endif
-
scanned_page = scanned_page_reset = resource.prescan ? -1 : total_pages + 1;
#if PS
scanned_page_ps = scanned_page_ps_bak = scanned_page;
@@ -1370,8 +1491,7 @@ init_prescan(void)
if (resource.postscript == 0)
scanned_page_ps = total_pages + 1;
- for (tikp = tickhead; tikp != NULL; tikp = tikp->next)
- tikp->pageno = -1;
+ ps_clear_cache();
psp.newdoc();
#endif
@@ -2268,14 +2388,14 @@ myatopix(const char **pp)
/* if units are present */
if (p1 - p0 <= SCR_LEN - 3) {
sprintf(scr, "%.*s%c%c", (int)(p1 - p0), p0, *cp, cp[1]);
- value = atopix(scr, False);
+ value = atopix(scr);
}
else
value = 0;
cp += 2;
}
else
- value = atopix(p0, False);
+ value = atopix(p0);
*pp = cp;
return value;
diff --git a/Build/source/texk/xdvik/special.h b/Build/source/texk/xdvik/special.h
index efcd3b7deb5..e6994d3f995 100644
--- a/Build/source/texk/xdvik/special.h
+++ b/Build/source/texk/xdvik/special.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2004 the xdvik development team
+ * Copyright (c) 2002-2016 the xdvik development team
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
@@ -44,8 +44,8 @@ struct psprocs {
void (*newdoc) (void);
};
-extern void ps_clear_cache(void);
extern void ps_destroy(void);
+extern void ps_destroy_nofree(void);
extern void drawbegin_none(int, int, const char *);
extern void draw_bbox(void);
extern void display_bboxes(void);
diff --git a/Build/source/texk/xdvik/texmf/XDvi b/Build/source/texk/xdvik/texmf/XDvi
index 3e0f4984e4c..99e0533a3b9 100644
--- a/Build/source/texk/xdvik/texmf/XDvi
+++ b/Build/source/texk/xdvik/texmf/XDvi
@@ -125,7 +125,7 @@ Ctrl<Btn5Down>:set-shrink-factor(-)\n\
!!!------------------------------------------------------------------------------
!!! background color and font:
*tipShell.background: cornsilk
-*tipShell.fontSet: -*-helvetica-medium-r-*-*-12-*-*-*-*-*-*
+*tipShell.fontSet: -*-helvetica-medium-r-*-*-12-*-*-*-*-*-*-*
!!! time the mouse needs to stay on a button until tooltips pop up,
!!! in milliseconds; set to a negative value to disable:
@@ -135,9 +135,9 @@ Ctrl<Btn5Down>:set-shrink-factor(-)\n\
!!!------------------------------------------------------------------------------
!!!------------------------------ Fonts and colors ------------------------------
!!!------------------------------------------------------------------------------
-*font: -*-helvetica-medium-r-*-*-12-*-*-*-*-*-*
+*font: -*-helvetica-medium-r-*-*-12-*-*-*-*-*-*-*
!!! Use a smaller font for the statusline in the Xaw version:
-*statusline.font: -*-helvetica-medium-r-*-*-10-*-*-*-*-*-*
+*statusline.font: -*-helvetica-medium-r-*-*-10-*-*-*-*-*-*-*
!!! Motif fonts. Meaning of the tags is:
!!! NORMAL: Ordinary text, labels etc.
diff --git a/Build/source/texk/xdvik/util.c b/Build/source/texk/xdvik/util.c
index fec0200780c..be5a9c28e0a 100644
--- a/Build/source/texk/xdvik/util.c
+++ b/Build/source/texk/xdvik/util.c
@@ -1,6 +1,6 @@
/*========================================================================*\
-Copyright (c) 1990-2013 Paul Vojta and others
+Copyright (c) 1990-2015 Paul Vojta and others
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to
@@ -49,7 +49,6 @@ in xdvi.c.
#include "search-internal.h"
#include "encodings.h"
#include "filehist.h"
-#include "exit-handlers.h"
#include "xm_prefs.h" /* for preferences_changed() */
#include <errno.h>
@@ -284,50 +283,6 @@ try_open_mode(const char *fname, int flags, mode_t mode)
/*
- * This routine should be used for all exits. (SU: This is different
- * from non-k xdvi, where it's only used for `non-early' exits; all
- * routines called here should be aware of their own state and either
- * perform cleanup or just return, unless xdvi_exit() itself checks for
- * the status).
- */
-
-void
-xdvi_exit(int status)
-{
- /* do the following only if the window has been opened: */
- if (globals.widgets.top_level != 0 && XtIsRealized(globals.widgets.top_level)) {
- char *filehist;
- file_history_set_page(current_page);
- filehist = file_history_get_list();
- store_preference(NULL, "fileHistory", "%s", filehist);
- free(filehist);
-
-#if MOTIF
- if (preferences_changed()) {
- return;
- }
- /* else { */
- /* fprintf(stderr, "Preferences not changed.\n"); */
- /* } */
-#endif
- /* try to save user preferences, unless we're exiting with an error */
- if (status == EXIT_SUCCESS && !save_user_preferences(True))
- return;
-
- /* Clean up the "xdvi windows" property in the root window. */
- update_window_property(XtWindow(globals.widgets.top_level), False);
- }
-
-#if PS
- ps_destroy();
-#endif
-
- call_exit_handlers();
-
- exit(status);
-}
-
-/*
* invoked on SIGSEGV: try to stop gs before aborting, to prevent gs
* running on with 100% CPU consumption - this can be annoying during
* testing. We'd also like to clean up the "xdvi windows" property in
@@ -1008,11 +963,18 @@ read_child_error(int fd, void *data)
*
* If dirname != NULL, the child will chdir into dirname before running the
* command.
+ *
+ * If killsig == 0, the process will not be killed when xdvi terminates.
+ * If killsig > 0, the process will be sent this signal when xdvi terminates.
+ * If killsig < 0, the process will be given its own group, and the whole group
+ * will be sent -killsig when xdvi terminates. This is useful when invoking
+ * /bin/sh. Generally killsig (if nonzero) should be SIGKILL or -SIGKILL.
*/
Boolean
fork_process(const char *proc_name, Boolean redirect_stdout,
const char *dirname,
childProcT exit_proc, void *data,
+ int killsig,
char *const argv[])
{
int i, pid;
@@ -1069,6 +1031,15 @@ fork_process(const char *proc_name, Boolean redirect_stdout,
#endif /* TRY_FIX */
close(err_pipe[0]); /* no reading from stderr */
+ /* (Maybe) set session ID, so that kill will also affect subprocesses */
+ if (killsig < 0) {
+ if (setsid() == -1) {
+ perror("setsid");
+ _exit(EXIT_FAILURE);
+ return False; /* make compiler happy */
+ }
+ }
+
/* redirect writing to stderr */
if (dup2(err_pipe[1], STDERR_FILENO) != STDERR_FILENO) {
perror("dup2 for stderr");
@@ -1116,6 +1087,7 @@ fork_process(const char *proc_name, Boolean redirect_stdout,
my_child->pid = pid;
my_child->name = buf;
my_child->data = data;
+ my_child->killsig = killsig;
if (exit_proc == NULL) { /* use default exit procedure */
my_child->proc = handle_child_exit;
}
diff --git a/Build/source/texk/xdvik/util.h b/Build/source/texk/xdvik/util.h
index 68ce521c1d5..09a14fde460 100644
--- a/Build/source/texk/xdvik/util.h
+++ b/Build/source/texk/xdvik/util.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2013 the xdvik development team
+ * Copyright (c) 2002-2015 the xdvik development team
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
@@ -67,6 +67,7 @@ extern char *read_child_error(int fd, void *data);
extern Boolean fork_process(const char *file, Boolean redirect_stdout,
const char *dirname,
childProcT exit_proc, void *data,
+ int killsig,
char *const argv[]);
extern void prep_fd(int fd, wide_bool noblock);
@@ -110,7 +111,6 @@ extern void close_a_file(void);
extern unsigned long get_bytes(FILE *, int);
extern long get_lbytes(FILE *, int);
-extern void xdvi_exit(int);
extern void do_abort(void);
/* various levels of warning/error messages */
diff --git a/Build/source/texk/xdvik/version.h b/Build/source/texk/xdvik/version.h
index c2f986a0406..068eff89cb2 100644
--- a/Build/source/texk/xdvik/version.h
+++ b/Build/source/texk/xdvik/version.h
@@ -2,7 +2,7 @@
#ifndef VERSION_H_
#define VERSION_H_
-#define XDVI_VERSION "22.87"
+#define XDVI_VERSION "22.87.03"
#ifdef MOTIF
#define XDVI_GUI "(Motif toolkit)"
diff --git a/Build/source/texk/xdvik/xdvi.1.in b/Build/source/texk/xdvik/xdvi.1.in
index c46a8027cb7..aa3f05551cb 100644
--- a/Build/source/texk/xdvik/xdvi.1.in
+++ b/Build/source/texk/xdvik/xdvi.1.in
@@ -2673,6 +2673,33 @@ is
then the corresponding shrink factor is the ratio
.IR p / n ,
rounded to the nearest integer.
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.TP
+.B user-exec()
+This action takes one (required) argument. Runs an external program
+specified by the argument, which is tokenized on whitespace. The
+.B XDVI_FILE
+environment variable is set to the absolute pathname of the DVI file,
+so that the program can find the DVI. As an example, to establish the
+key
+.RB ` m '
+as a keybinding that regenerates the DVI file with `make', put the
+following into your
+.I ~/.Xdefaults
+file:
+.sp
+xdvi.mainTranslations: #override\e
+.br
+<Key>m: user-exec(xdvi-remake)\en
+
+where `xdvi-remake' names a program in your
+.B PATH
+analogous to `cd $(dirname $XDVI_FILE) && make $(basename $XDVI_FILE)'.
+(See also the section
+.B SIGNALS
+for a way to get
+.B xdvi
+to reload the DVI file once it has been regenerated.)
.PP
.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
diff --git a/Build/source/texk/xdvik/xdvi.c b/Build/source/texk/xdvik/xdvi.c
index cd749c54a30..9d14874288a 100644
--- a/Build/source/texk/xdvik/xdvi.c
+++ b/Build/source/texk/xdvik/xdvi.c
@@ -763,22 +763,26 @@ static WidgetClassRec drawingWidgetClass = {
int
-atopix(const char *arg, Boolean allow_minus)
+atopix(const char *arg)
{
int len = strlen(arg);
const char *arg_end = arg;
- char tmp[11];
- double factor;
+ char tmp[16];
+ double factor, val;
- if (allow_minus && *arg_end == '-')
- ++arg_end;
while ((*arg_end >= '0' && *arg_end <= '9') || *arg_end == '.')
- if (arg_end >= arg + XtNumber(tmp) - 1)
- return 0;
- else
- ++arg_end;
- memcpy(tmp, arg, arg_end - arg);
- tmp[arg_end - arg] = '\0';
+ ++arg_end;
+
+ if (arg_end >= arg + XtNumber(tmp) - 1) { /* should be rare */
+ char *tmp_var = xstrndup(arg, arg_end - arg);
+ val = atof(tmp_var);
+ free(tmp_var);
+ }
+ else {
+ memcpy(tmp, arg, arg_end - arg);
+ tmp[arg_end - arg] = '\0';
+ val = atof(tmp);
+ }
#if A4
factor = 1.0 / 2.54; /* cm */
@@ -819,7 +823,13 @@ atopix(const char *arg, Boolean allow_minus)
break;
}
- return factor * atof(tmp) * resource.pixels_per_inch + 0.5;
+ return factor * val * resource.pixels_per_inch + 0.5;
+}
+
+int
+atopix_signed(const char *arg)
+{
+ return *arg == '-' ? -atopix(arg + 1) : atopix(arg);
}
#if CHECK_APP_FILEVERSION
@@ -1893,8 +1903,8 @@ compile_modifiers(const char **pp, struct mouse_acts *mactp)
{
const char *p = *pp;
const char *p1;
- LateBindingsPtr latep = NULL;
- int nlate;
+ LateBindingsPtr latep = NULL;
+ int nlate = 3;
while (*p == ' ' || *p == '\t')
++p;
@@ -1983,7 +1993,7 @@ compile_modifiers(const char **pp, struct mouse_acts *mactp)
LateBindingsPtr lp1;
if (latep == NULL) {
- nlate = 3;
+ /* nlate = 3; (done earlier to avoid compiler warning) */
latep = xmalloc(3 * sizeof(LateBindings));
latep->ref_count = 1;
}