summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJim Blandy <jimb@redhat.com>1992-01-13 21:48:03 +0000
committerJim Blandy <jimb@redhat.com>1992-01-13 21:48:03 +0000
commit254f294c2e37a22e04bff74fedfdc9b1fcc93b93 (patch)
tree060dbe9a444bcf1c2e1bc7802fc4dfc1717520aa /src
parenta48a36d045feed054f3532c5596449466a60a3cd (diff)
downloademacs-254f294c2e37a22e04bff74fedfdc9b1fcc93b93.tar.gz
entered into RCS
Diffstat (limited to 'src')
-rw-r--r--src/=XTests.c48
-rw-r--r--src/=XTests.h7
-rw-r--r--src/=xscrollbar.h123
-rw-r--r--src/abbrev.c45
-rw-r--r--src/acldef.h40
-rw-r--r--src/casefiddle.c3
-rw-r--r--src/casetab.c10
-rw-r--r--src/chpdef.h38
-rw-r--r--src/cm.c414
-rw-r--r--src/disptab.h82
-rw-r--r--src/doprnt.c4
-rw-r--r--src/indent.h34
-rw-r--r--src/insdel.c20
-rw-r--r--src/ioctl.h1
-rw-r--r--src/lastfile.c38
-rw-r--r--src/line.h7
-rw-r--r--src/macros.h31
-rw-r--r--src/marker.c12
-rw-r--r--src/mocklisp.c8
-rw-r--r--src/mocklisp.h2
-rw-r--r--src/ndir.h51
-rw-r--r--src/param.h2
-rw-r--r--src/point.h5
-rw-r--r--src/pre-crt0.c9
-rw-r--r--src/puresize.h12
-rw-r--r--src/sink.h91
-rw-r--r--src/sink11.h51
-rw-r--r--src/sink11mask.h51
-rw-r--r--src/terminfo.c50
-rw-r--r--src/uaf.h23
-rw-r--r--src/unexconvex.c601
-rw-r--r--src/unexelf.c703
-rw-r--r--src/unexenix.c262
-rw-r--r--src/unexhp9k800.c6
-rw-r--r--src/vlimit.h2
-rw-r--r--src/vms-pp.c2
-rw-r--r--src/vms-pwd.h34
-rw-r--r--src/vmsdir.h97
-rw-r--r--src/vmsfns.c14
-rw-r--r--src/vmsmap.c224
-rw-r--r--src/vmspaths.h15
-rw-r--r--src/vmsproc.c6
-rw-r--r--src/vmsproc.h21
43 files changed, 3194 insertions, 105 deletions
diff --git a/src/=XTests.c b/src/=XTests.c
index 9c1d3666bdb..4147ecd35d6 100644
--- a/src/=XTests.c
+++ b/src/=XTests.c
@@ -67,8 +67,8 @@ main (argc,argv)
int depth;
Pixmap pix;
char *string = "Kill the head and the body will die.";
- char dash_list[] = {6, 4, 6, 4};
- int dashes = 4;
+ char dash_list[] = {4, 4};
+ int dashes = 2;
if (argc < 2)
dpy_string = "localhost:0.0";
@@ -105,24 +105,19 @@ main (argc,argv)
&gc_values);
gc_values.foreground = obtain_color ("red");
- gc_values.function = GXor;
gc_values.line_width = 3;
gc_values.line_style = LineOnOffDash;
gc_values.cap_style = CapRound;
gc_values.join_style = JoinRound;
line_xor_gc = XCreateGC (dpy, window,
GCForeground | GCBackground | GCLineStyle
- | GCJoinStyle | GCCapStyle | GCLineWidth
- | GCFunction,
+ | GCJoinStyle | GCCapStyle | GCLineWidth,
&gc_values);
XSetDashes (dpy, line_xor_gc, 0, dash_list, dashes);
- gc_values.background = WhitePixel (dpy, DefaultScreen (dpy));
- gc_values.foreground = obtain_color ("blue");
line_xor_inv_gc = XCreateGC (dpy, window,
- GCForeground | GCBackground
- | GCLineWidth | GCFunction,
- &gc_values);
+ GCForeground | GCBackground | GCLineWidth,
+ &gc_values);
depth = DefaultDepthOfScreen (ScreenOfDisplay (dpy, DefaultScreen (dpy)));
pix = XCreateBitmapFromData (dpy, window, page_glyf_bits,
@@ -137,25 +132,20 @@ main (argc,argv)
switch (event.type)
{
case ButtonPress:
-#if 0
- if (event.xbutton.state && ShiftMask)
-#endif
- switch (event.xbutton.button)
- {
- case Button1:
- XDrawLine (dpy, window, line_xor_gc, 25, 75, 125, 75);
- XFlush (dpy);
- XDrawLine (dpy, window, line_xor_gc, 25, 75, 125, 75);
- break;
-
- case Button2:
- XDrawLine (dpy, window, line_xor_gc, 25, 75, 125, 75);
- break;
-
- case Button3:
- XDrawLine (dpy, window, line_xor_gc, 25, 75, 125, 75);
- break;
- }
+ switch (event.xbutton.button)
+ {
+ case Button1:
+ XDrawLine (dpy, window, line_xor_gc, 25, 75, 300, 75);
+ break;
+
+ case Button2:
+ XDrawLine (dpy, window, line_xor_inv_gc, 25, 25, 300, 25);
+ break;
+
+ case Button3:
+ XDrawLine (dpy, window, line_xor_gc, 25, 25, 25, 125);
+ break;
+ }
break;
case KeyPress:
diff --git a/src/=XTests.h b/src/=XTests.h
new file mode 100644
index 00000000000..e91445af7ef
--- /dev/null
+++ b/src/=XTests.h
@@ -0,0 +1,7 @@
+#define page_glyf_width 30
+#define page_glyf_height 10
+static char page_glyf_bits[] = {
+ 0xf0, 0xff, 0xff, 0x03, 0x08, 0x00, 0x00, 0x04, 0xc4, 0x19, 0xf3, 0x08,
+ 0x42, 0xa5, 0x14, 0x10, 0xc1, 0xa5, 0x70, 0x20, 0x41, 0xbc, 0x16, 0x20,
+ 0x42, 0xa4, 0x14, 0x10, 0x44, 0x24, 0xf3, 0x08, 0x08, 0x00, 0x00, 0x04,
+ 0xf0, 0xff, 0xff, 0x03};
diff --git a/src/=xscrollbar.h b/src/=xscrollbar.h
new file mode 100644
index 00000000000..e1a3f45d247
--- /dev/null
+++ b/src/=xscrollbar.h
@@ -0,0 +1,123 @@
+/* Bitmaps and things for scrollbars.
+ Copyright (C) 1989 Free Software Foundation.
+
+This file is part of GNU Emacs.
+
+GNU Emacs is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GNU Emacs is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Emacs; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+
+static void install_vertical_scrollbar ();
+static void install_horizontal_scrollbar ();
+static void x_set_horizontal_scrollbar ();
+static void x_set_vertical_scrollbar ();
+
+/* Prefix-characters for scroll bar commands in Vglobal_mouse_map.
+ Choice of prefix depends on which region of the scroll bar. */
+
+enum scroll_bar_prefix
+ { VSCROLL_BAR_PREFIX = 050, VSCROLL_SLIDER_PREFIX /* unused */,
+ VSCROLL_THUMBUP_PREFIX, VSCROLL_THUMBDOWN_PREFIX,
+ HSCROLL_BAR_PREFIX, HSCROLL_SLIDER_PREFIX /* unused */,
+ HSCROLL_THUMBLEFT_PREFIX, HSCROLL_THUMBRIGHT_PREFIX };
+
+#define CROSS_WIDTH 16
+#define CROSS_HEIGHT 16
+
+#define CROSS_MASK_WIDTH 16
+#define CROSS_MASK_HEIGHT 16
+
+/* Vertical and Horizontal scroll bar widths. */
+#define VSCROLL_WIDTH 18
+#define HSCROLL_HEIGHT 18
+
+#ifdef HAVE_X11
+
+/* Arrow cursors for scroll bars. */
+
+Cursor up_arrow_cursor, down_arrow_cursor, v_double_arrow_cursor;
+Cursor left_arrow_cursor, right_arrow_cursor, h_double_arrow_cursor;
+
+static char cross_bits[] =
+ {
+ 0x00, 0x00, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01,
+ 0x80, 0x01, 0xfe, 0x7f, 0xfe, 0x7f, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01,
+ 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x00, 0x00
+ };
+
+static char gray_bits[] =
+ {
+ 0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa,
+ 0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa,
+ 0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa,
+ 0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa
+ };
+
+static char up_arrow_bits[] =
+ {
+ 0x00, 0x00, 0x80, 0x01, 0xc0, 0x03, 0xe0, 0x07, 0xf0, 0x0f, 0xf8, 0x1f,
+ 0xfc, 0x3f, 0xfe, 0x7f, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01,
+ 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0xff, 0xff
+ };
+
+static char down_arrow_bits[] =
+ {
+ 0xff, 0xff, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01,
+ 0x80, 0x01, 0x80, 0x01, 0xfe, 0x7f, 0xfc, 0x3f, 0xf8, 0x1f, 0xf0, 0x0f,
+ 0xe0, 0x07, 0xc0, 0x03, 0x80, 0x01, 0x00, 0x00
+ };
+
+static char left_arrow_bits[] =
+ {
+ 0x00, 0x80, 0x80, 0x80, 0xc0, 0x80, 0xe0, 0x80, 0xf0, 0x80, 0xf8, 0x80,
+ 0xfc, 0x80, 0xfe, 0xff, 0xfe, 0xff, 0xfc, 0x80, 0xf8, 0x80, 0xf0, 0x80,
+ 0xe0, 0x80, 0xc0, 0x80, 0x80, 0x80, 0x00, 0x80
+ };
+
+static char right_arrow_bits[] =
+ {
+ 0x01, 0x00, 0x01, 0x01, 0x01, 0x03, 0x01, 0x07, 0x01, 0x0f, 0x01, 0x1f,
+ 0x01, 0x3f, 0xff, 0x7f, 0xff, 0x7f, 0x01, 0x3f, 0x01, 0x1f, 0x01, 0x0f,
+ 0x01, 0x07, 0x01, 0x03, 0x01, 0x01, 0x01, 0x00
+ };
+
+static char cross_mask_bits[] =
+ {
+ 0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x03, 0xc0, 0x03,
+ 0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03
+ };
+#else /* not HAVE_X11 */
+static short cross_bits[] =
+ {
+ 0x0000, 0x0180, 0x0180, 0x0180,
+ 0x0180, 0x0180, 0x0180, 0x7ffe,
+ 0x7ffe, 0x0180, 0x0180, 0x0180,
+ 0x0180, 0x0180, 0x0180, 0x0000,
+ };
+
+static short gray_bits[] = {
+ 0xaaaa, 0x5555, 0xaaaa, 0x5555,
+ 0xaaaa, 0x5555, 0xaaaa, 0x5555,
+ 0xaaaa, 0x5555, 0xaaaa, 0x5555,
+ 0xaaaa, 0x5555, 0xaaaa, 0x5555};
+
+static short cross_mask_bits[] =
+ {
+ 0x03c0, 0x03c0, 0x03c0, 0x03c0,
+ 0x03c0, 0x03c0, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0x03c0, 0x03c0,
+ 0x03c0, 0x03c0, 0x03c0, 0x03c0,
+ };
+#endif /* X10 */
diff --git a/src/abbrev.c b/src/abbrev.c
index 74c0e80010a..9a7640b872c 100644
--- a/src/abbrev.c
+++ b/src/abbrev.c
@@ -20,7 +20,6 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "config.h"
#include <stdio.h>
-#undef NULL
#include "lisp.h"
#include "commands.h"
#include "buffer.h"
@@ -113,9 +112,9 @@ it is called after EXPANSION is inserted.")
Lisp_Object sym, oexp, ohook, tem;
CHECK_VECTOR (table, 0);
CHECK_STRING (name, 1);
- if (!NULL (expansion))
+ if (!NILP (expansion))
CHECK_STRING (expansion, 2);
- if (NULL (count))
+ if (NILP (count))
count = make_number (0);
else
CHECK_NUMBER (count, 0);
@@ -126,10 +125,10 @@ it is called after EXPANSION is inserted.")
ohook = XSYMBOL (sym)->function;
if (!((EQ (oexp, expansion)
|| (XTYPE (oexp) == Lisp_String && XTYPE (expansion) == Lisp_String
- && (tem = Fstring_equal (oexp, expansion), !NULL (tem))))
+ && (tem = Fstring_equal (oexp, expansion), !NILP (tem))))
&&
(EQ (ohook, hook)
- || (tem = Fequal (ohook, hook), !NULL (tem)))))
+ || (tem = Fequal (ohook, hook), !NILP (tem)))))
abbrevs_changed = 1;
Fset (sym, expansion);
@@ -156,7 +155,7 @@ DEFUN ("define-mode-abbrev", Fdefine_mode_abbrev, Sdefine_mode_abbrev, 2, 2,
(name, expansion)
Lisp_Object name, expansion;
{
- if (NULL (current_buffer->abbrev_table))
+ if (NILP (current_buffer->abbrev_table))
error ("Major mode has no abbrev table");
Fdefine_abbrev (current_buffer->abbrev_table, Fdowncase (name),
@@ -176,19 +175,19 @@ The default is to try buffer's mode-specific abbrev table, then global table.")
{
Lisp_Object sym;
CHECK_STRING (abbrev, 0);
- if (!NULL (table))
+ if (!NILP (table))
sym = Fintern_soft (abbrev, table);
else
{
sym = Qnil;
- if (!NULL (current_buffer->abbrev_table))
+ if (!NILP (current_buffer->abbrev_table))
sym = Fintern_soft (abbrev, current_buffer->abbrev_table);
- if (NULL (XSYMBOL (sym)->value))
+ if (NILP (XSYMBOL (sym)->value))
sym = Qnil;
- if (NULL (sym))
+ if (NILP (sym))
sym = Fintern_soft (abbrev, Vglobal_abbrev_table);
}
- if (NULL (XSYMBOL (sym)->value)) return Qnil;
+ if (NILP (XSYMBOL (sym)->value)) return Qnil;
return sym;
}
@@ -201,7 +200,7 @@ then ABBREV is looked up in that table only.")
{
Lisp_Object sym;
sym = Fabbrev_symbol (abbrev, table);
- if (NULL (sym)) return sym;
+ if (NILP (sym)) return sym;
return Fsymbol_value (sym);
}
@@ -221,12 +220,12 @@ Returns t if expansion took place.")
register Lisp_Object sym;
Lisp_Object expansion, hook, tem;
- if (!NULL (Vrun_hooks))
+ if (!NILP (Vrun_hooks))
call1 (Vrun_hooks, Qpre_abbrev_expand_hook);
if (XBUFFER (Vabbrev_start_location_buffer) != current_buffer)
Vabbrev_start_location = Qnil;
- if (!NULL (Vabbrev_start_location))
+ if (!NILP (Vabbrev_start_location))
{
tem = Vabbrev_start_location;
CHECK_NUMBER_COERCE_MARKER (tem, 0);
@@ -267,9 +266,9 @@ Returns t if expansion took place.")
sym = oblookup (current_buffer->abbrev_table, buffer, p - buffer);
else
XFASTINT (sym) = 0;
- if (XTYPE (sym) == Lisp_Int || NULL (XSYMBOL (sym)->value))
+ if (XTYPE (sym) == Lisp_Int || NILP (XSYMBOL (sym)->value))
sym = oblookup (Vglobal_abbrev_table, buffer, p - buffer);
- if (XTYPE (sym) == Lisp_Int || NULL (XSYMBOL (sym)->value))
+ if (XTYPE (sym) == Lisp_Int || NILP (XSYMBOL (sym)->value))
return Qnil;
if (INTERACTIVE && !EQ (minibuf_window, selected_window))
@@ -327,7 +326,7 @@ Returns t if expansion took place.")
}
hook = XSYMBOL (sym)->function;
- if (!NULL (hook))
+ if (!NILP (hook))
call0 (hook);
return Qt;
@@ -367,7 +366,7 @@ write_abbrev (sym, stream)
Lisp_Object sym, stream;
{
Lisp_Object name;
- if (NULL (XSYMBOL (sym)->value))
+ if (NILP (XSYMBOL (sym)->value))
return;
insert (" (", 5);
XSET (name, Lisp_String, XSYMBOL (sym)->name);
@@ -387,7 +386,7 @@ describe_abbrev (sym, stream)
{
Lisp_Object one;
- if (NULL (XSYMBOL (sym)->value))
+ if (NILP (XSYMBOL (sym)->value))
return;
one = make_number (1);
Fprin1 (Fsymbol_name (sym), stream);
@@ -395,7 +394,7 @@ describe_abbrev (sym, stream)
Fprin1 (XSYMBOL (sym)->plist, stream);
Findent_to (make_number (20), one);
Fprin1 (XSYMBOL (sym)->value, stream);
- if (!NULL (XSYMBOL (sym)->function))
+ if (!NILP (XSYMBOL (sym)->function))
{
Findent_to (make_number (45), one);
Fprin1 (XSYMBOL (sym)->function, stream);
@@ -424,7 +423,7 @@ define the abbrev table NAME exactly as it is currently defined.")
XSET (stream, Lisp_Buffer, current_buffer);
- if (!NULL (readable))
+ if (!NILP (readable))
{
insert_string ("(");
Fprin1 (name, stream);
@@ -457,7 +456,7 @@ of the form (ABBREVNAME EXPANSION HOOK USECOUNT).")
CHECK_SYMBOL (tabname, 0);
table = Fboundp (tabname);
- if (NULL (table) || (table = Fsymbol_value (tabname), NULL (table)))
+ if (NILP (table) || (table = Fsymbol_value (tabname), NILP (table)))
{
table = Fmake_abbrev_table ();
Fset (tabname, table);
@@ -466,7 +465,7 @@ of the form (ABBREVNAME EXPANSION HOOK USECOUNT).")
}
CHECK_VECTOR (table, 0);
- for (;!NULL (defns); defns = Fcdr (defns))
+ for (;!NILP (defns); defns = Fcdr (defns))
{
elt = Fcar (defns);
name = Fcar (elt);
diff --git a/src/acldef.h b/src/acldef.h
new file mode 100644
index 00000000000..cc4085c6aab
--- /dev/null
+++ b/src/acldef.h
@@ -0,0 +1,40 @@
+#define ACL$K_LENGTH 12
+#define ACL$C_LENGTH 12
+#define ACL$C_FILE 1
+#define ACL$C_DEVICE 2
+#define ACL$C_JOBCTL_QUEUE 3
+#define ACL$C_COMMON_EF_CLUSTER 4
+#define ACL$C_LOGICAL_NAME_TABLE 5
+#define ACL$C_PROCESS 6
+#define ACL$C_GROUP_GLOBAL_SECTION 7
+#define ACL$C_SYSTEM_GLOBAL_SECTION 8
+#define ACL$C_ADDACLENT 1
+#define ACL$C_DELACLENT 2
+#define ACL$C_MODACLENT 3
+#define ACL$C_FNDACLENT 4
+#define ACL$C_FNDACETYP 5
+#define ACL$C_DELETEACL 6
+#define ACL$C_READACL 7
+#define ACL$C_ACLLENGTH 8
+#define ACL$C_READACE 9
+#define ACL$C_RLOCK_ACL 10
+#define ACL$C_WLOCK_ACL 11
+#define ACL$C_UNLOCK_ACL 12
+#define ACL$S_ADDACLENT 255
+#define ACL$S_DELACLENT 255
+#define ACL$S_MODACLENT 255
+#define ACL$S_FNDACLENT 255
+#define ACL$S_FNDACETYP 255
+#define ACL$S_DELETEACL 255
+#define ACL$S_READACL 512
+#define ACL$S_ACLLENGTH 4
+#define ACL$S_READACE 255
+#define ACL$S_RLOCK_ACL 4
+#define ACL$S_WLOCK_ACL 4
+#define ACL$S_UNLOCK_ACL 4
+#define ACL$S_ACLDEF 16
+#define ACL$L_FLINK 0
+#define ACL$L_BLINK 4
+#define ACL$W_SIZE 8
+#define ACL$B_TYPE 10
+#define ACL$L_LIST 12
diff --git a/src/casefiddle.c b/src/casefiddle.c
index d508deb5d60..87dd1c79825 100644
--- a/src/casefiddle.c
+++ b/src/casefiddle.c
@@ -261,7 +261,10 @@ syms_of_casefiddle ()
keys_of_casefiddle ()
{
initial_define_key (control_x_map, Ctl('U'), "upcase-region");
+ Fput (intern ("upcase-region"), Qdisabled, Qt);
initial_define_key (control_x_map, Ctl('L'), "downcase-region");
+ Fput (intern ("downcase-region"), Qdisabled, Qt);
+
initial_define_key (meta_map, 'u', "upcase-word");
initial_define_key (meta_map, 'l', "downcase-word");
initial_define_key (meta_map, 'c', "capitalize-word");
diff --git a/src/casetab.c b/src/casetab.c
index 6d419bfe30f..fa8375ccc69 100644
--- a/src/casetab.c
+++ b/src/casetab.c
@@ -45,8 +45,8 @@ See `set-case-table' for more information on these data structures.")
(XTYPE (obj) == Lisp_String && XSTRING (obj)->size == 256)
return (STRING256_P (down)
- && (NULL (up) || STRING256_P (up))
- && ((NULL (canon) && NULL (eqv))
+ && (NILP (up) || STRING256_P (up))
+ && ((NILP (canon) && NILP (eqv))
|| (STRING256_P (canon) && STRING256_P (eqv)))
? Qt : Qnil);
}
@@ -57,7 +57,7 @@ check_case_table (obj)
{
register Lisp_Object tem;
- while (tem = Fcase_table_p (obj), NULL (tem))
+ while (tem = Fcase_table_p (obj), NILP (tem))
obj = wrong_type_argument (Qcase_table_p, obj, 0);
return (obj);
}
@@ -132,13 +132,13 @@ set_case_table (table, standard)
canon = Fcar_safe (Fcdr_safe (Fcdr_safe (table)));
eqv = Fcar_safe (Fcdr_safe (Fcdr_safe (Fcdr_safe (table))));
- if (NULL (up))
+ if (NILP (up))
{
up = Fmake_string (make_number (256), make_number (0));
compute_trt_inverse (XSTRING (down)->data, XSTRING (up)->data);
}
- if (NULL (canon))
+ if (NILP (canon))
{
register int i;
unsigned char *upvec = XSTRING (up)->data;
diff --git a/src/chpdef.h b/src/chpdef.h
new file mode 100644
index 00000000000..43f7bbf4345
--- /dev/null
+++ b/src/chpdef.h
@@ -0,0 +1,38 @@
+#define CHP$_END 0
+#define CHP$_ACCESS 1
+#define CHP$_FLAGS 2
+#define CHP$_PRIV 3
+#define CHP$_ACMODE 4
+#define CHP$_ACCLASS 5
+#define CHP$_RIGHTS 6
+#define CHP$_ADDRIGHTS 7
+#define CHP$_MODE 8
+#define CHP$_MODES 9
+#define CHP$_MINCLASS 10
+#define CHP$_MAXCLASS 11
+#define CHP$_OWNER 12
+#define CHP$_PROT 13
+#define CHP$_ACL 14
+#define CHP$_AUDITNAME 15
+#define CHP$_ALARMNAME 16
+#define CHP$_MATCHEDACE 17
+#define CHP$_PRIVUSED 18
+#define CHP$_MAX_CODE 19
+#define CHP$M_SYSPRV 1
+#define CHP$M_BYPASS 2
+#define CHP$M_UPGRADE 4
+#define CHP$M_DOWNGRADE 8
+#define CHP$M_GRPPRV 16
+#define CHP$M_READALL 32
+#define CHP$V_SYSPRV 0
+#define CHP$V_BYPASS 1
+#define CHP$V_UPGRADE 2
+#define CHP$V_DOWNGRADE 3
+#define CHP$V_GRPPRV 4
+#define CHP$V_READALL 5
+#define CHP$M_READ 1
+#define CHP$M_WRITE 2
+#define CHP$M_USEREADALL 4
+#define CHP$V_READ 0
+#define CHP$V_WRITE 1
+#define CHP$V_USEREADALL 2
diff --git a/src/cm.c b/src/cm.c
new file mode 100644
index 00000000000..f88acff48f1
--- /dev/null
+++ b/src/cm.c
@@ -0,0 +1,414 @@
+/* Cursor motion subroutines for GNU Emacs.
+ Copyright (C) 1985 Free Software Foundation, Inc.
+ based primarily on public domain code written by Chris Torek
+
+This file is part of GNU Emacs.
+
+GNU Emacs is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GNU Emacs is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Emacs; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+
+#include "config.h"
+#include <stdio.h>
+#include "cm.h"
+#include "termhooks.h"
+
+#define BIG 9999 /* 9999 good on VAXen. For 16 bit machines
+ use about 2000.... */
+
+char *tgoto ();
+
+extern char *BC, *UP;
+
+int cost; /* sums up costs */
+
+/* ARGSUSED */
+evalcost (c)
+ char c;
+{
+ cost++;
+}
+
+void
+cmputc (c)
+ char c;
+{
+ if (termscript)
+ fputc (c & 0177, termscript);
+ putchar (c & 0177);
+}
+
+/* NEXT TWO ARE DONE WITH MACROS */
+#if 0
+/*
+ * Assume the cursor is at row row, column col. Normally used only after
+ * clearing the screen, when the cursor is at (0, 0), but what the heck,
+ * let's let the guy put it anywhere.
+ */
+
+static
+at (row, col) {
+ curY = row;
+ curX = col;
+}
+
+/*
+ * Add n columns to the current cursor position.
+ */
+
+static
+addcol (n) {
+ curX += n;
+
+ /*
+ * If cursor hit edge of screen, what happened?
+ * N.B.: DO NOT!! write past edge of screen. If you do, you
+ * deserve what you get. Furthermore, on terminals with
+ * autowrap (but not magicwrap), don't write in the last column
+ * of the last line.
+ */
+
+ if (curX == Wcm.cm_cols) {
+ /*
+ * Well, if magicwrap, still there, past the edge of the
+ * screen (!). If autowrap, on the col 0 of the next line.
+ * Otherwise on last column.
+ */
+
+ if (Wcm.cm_magicwrap)
+ ; /* "limbo" */
+ else if (Wcm.cm_autowrap) {
+ curX = 0;
+ curY++; /* Beware end of screen! */
+ }
+ else
+ curX--;
+ }
+}
+#endif
+
+/*
+ * (Re)Initialize the cost factors, given the output speed of the terminal
+ * in the variable ospeed. (Note: this holds B300, B9600, etc -- ie stuff
+ * out of <sgtty.h>.)
+ */
+
+cmcostinit ()
+{
+ char *p;
+
+#define COST(x,e) (x ? (cost = 0, tputs (x, 1, e), cost) : BIG)
+#define CMCOST(x,e) ((x == 0) ? BIG : (p = tgoto(x, 0, 0), COST(p ,e)))
+
+ Wcm.cc_up = COST (Wcm.cm_up, evalcost);
+ Wcm.cc_down = COST (Wcm.cm_down, evalcost);
+ Wcm.cc_left = COST (Wcm.cm_left, evalcost);
+ Wcm.cc_right = COST (Wcm.cm_right, evalcost);
+ Wcm.cc_home = COST (Wcm.cm_home, evalcost);
+ Wcm.cc_cr = COST (Wcm.cm_cr, evalcost);
+ Wcm.cc_ll = COST (Wcm.cm_ll, evalcost);
+ Wcm.cc_tab = Wcm.cm_tabwidth ? COST (Wcm.cm_tab, evalcost) : BIG;
+
+ /*
+ * These last three are actually minimum costs. When (if) they are
+ * candidates for the least-cost motion, the real cost is computed.
+ * (Note that "0" is the assumed to generate the minimum cost.
+ * While this is not necessarily true, I have yet to see a terminal
+ * for which is not; all the terminals that have variable-cost
+ * cursor motion seem to take straight numeric values. --ACT)
+ */
+
+ Wcm.cc_abs = CMCOST (Wcm.cm_abs, evalcost);
+ Wcm.cc_habs = CMCOST (Wcm.cm_habs, evalcost);
+ Wcm.cc_vabs = CMCOST (Wcm.cm_vabs, evalcost);
+
+#undef CMCOST
+#undef COST
+}
+
+/*
+ * Calculate the cost to move from (srcy, srcx) to (dsty, dstx) using
+ * up and down, and left and right, motions, and tabs. If doit is set
+ * actually perform the motion.
+ */
+
+static
+calccost (srcy, srcx, dsty, dstx, doit)
+{
+ register int deltay,
+ deltax,
+ c,
+ totalcost;
+ int ntabs,
+ n2tabs,
+ tabx,
+ tab2x,
+ tabcost;
+ register char *p;
+
+ /* If have just wrapped on a terminal with xn,
+ don't believe the cursor position: give up here
+ and force use of absolute positioning. */
+
+ if (curX == Wcm.cm_cols)
+ goto fail;
+
+ totalcost = 0;
+ if ((deltay = dsty - srcy) == 0)
+ goto x;
+ if (deltay < 0)
+ p = Wcm.cm_up, c = Wcm.cc_up, deltay = -deltay;
+ else
+ p = Wcm.cm_down, c = Wcm.cc_down;
+ if (c == BIG) { /* caint get thar from here */
+ if (doit)
+ printf ("OOPS");
+ return c;
+ }
+ totalcost = c * deltay;
+ if (doit)
+ while (--deltay >= 0)
+ tputs (p, 1, cmputc);
+x:
+ if ((deltax = dstx - srcx) == 0)
+ goto done;
+ if (deltax < 0) {
+ p = Wcm.cm_left, c = Wcm.cc_left, deltax = -deltax;
+ goto dodelta; /* skip all the tab junk */
+ }
+ /* Tabs (the toughie) */
+ if (Wcm.cc_tab >= BIG || !Wcm.cm_usetabs)
+ goto olddelta; /* forget it! */
+
+ /*
+ * ntabs is # tabs towards but not past dstx; n2tabs is one more
+ * (ie past dstx), but this is only valid if that is not past the
+ * right edge of the screen. We can check that at the same time
+ * as we figure out where we would be if we use the tabs (which
+ * we will put into tabx (for ntabs) and tab2x (for n2tabs)).
+ */
+
+ ntabs = (deltax + srcx % Wcm.cm_tabwidth) / Wcm.cm_tabwidth;
+ n2tabs = ntabs + 1;
+ tabx = (srcx / Wcm.cm_tabwidth + ntabs) * Wcm.cm_tabwidth;
+ tab2x = tabx + Wcm.cm_tabwidth;
+
+ if (tab2x >= Wcm.cm_cols) /* too far (past edge) */
+ n2tabs = 0;
+
+ /*
+ * Now set tabcost to the cost for using ntabs, and c to the cost
+ * for using n2tabs, then pick the minimum.
+ */
+
+ /* cost for ntabs + cost for right motion */
+ tabcost = ntabs ? ntabs * Wcm.cc_tab + (dstx - tabx) * Wcm.cc_right
+ : BIG;
+
+ /* cost for n2tabs + cost for left motion */
+ c = n2tabs ? n2tabs * Wcm.cc_tab + (tab2x - dstx) * Wcm.cc_left
+ : BIG;
+
+ if (c < tabcost) /* then cheaper to overshoot & back up */
+ ntabs = n2tabs, tabcost = c, tabx = tab2x;
+
+ if (tabcost >= BIG) /* caint use tabs */
+ goto newdelta;
+
+ /*
+ * See if tabcost is less than just moving right
+ */
+
+ if (tabcost < (deltax * Wcm.cc_right)) {
+ totalcost += tabcost; /* use the tabs */
+ if (doit)
+ while (--ntabs >= 0)
+ tputs (Wcm.cm_tab, 1, cmputc);
+ srcx = tabx;
+ }
+
+ /*
+ * Now might as well just recompute the delta.
+ */
+
+newdelta:
+ if ((deltax = dstx - srcx) == 0)
+ goto done;
+olddelta:
+ if (deltax > 0)
+ p = Wcm.cm_right, c = Wcm.cc_right;
+ else
+ p = Wcm.cm_left, c = Wcm.cc_left, deltax = -deltax;
+
+dodelta:
+ if (c == BIG) { /* caint get thar from here */
+fail:
+ if (doit)
+ printf ("OOPS");
+ return BIG;
+ }
+ totalcost += c * deltax;
+ if (doit)
+ while (--deltax >= 0)
+ tputs (p, 1, cmputc);
+done:
+ return totalcost;
+}
+
+#if 0
+losecursor ()
+{
+ curY = -1;
+}
+#endif
+
+#define USEREL 0
+#define USEHOME 1
+#define USELL 2
+#define USECR 3
+
+cmgoto (row, col)
+{
+ int homecost,
+ crcost,
+ llcost,
+ relcost,
+ directcost;
+ int use;
+ char *p,
+ *dcm;
+
+ /* First the degenerate case */
+ if (row == curY && col == curX) /* already there */
+ return;
+
+ if (curY >= 0 && curX >= 0)
+ {
+ /* We may have quick ways to go to the upper-left, bottom-left,
+ * start-of-line, or start-of-next-line. Or it might be best to
+ * start where we are. Examine the options, and pick the cheapest.
+ */
+
+ relcost = calccost (curY, curX, row, col, 0);
+ use = USEREL;
+ if ((homecost = Wcm.cc_home) < BIG)
+ homecost += calccost (0, 0, row, col, 0);
+ if (homecost < relcost)
+ relcost = homecost, use = USEHOME;
+ if ((llcost = Wcm.cc_ll) < BIG)
+ llcost += calccost (Wcm.cm_rows - 1, 0, row, col, 0);
+ if (llcost < relcost)
+ relcost = llcost, use = USELL;
+ if ((crcost = Wcm.cc_cr) < BIG) {
+ if (Wcm.cm_autolf)
+ if (curY + 1 >= Wcm.cm_rows)
+ crcost = BIG;
+ else
+ crcost += calccost (curY + 1, 0, row, col, 0);
+ else
+ crcost += calccost (curY, 0, row, col, 0);
+ }
+ if (crcost < relcost)
+ relcost = crcost, use = USECR;
+ directcost = Wcm.cc_abs, dcm = Wcm.cm_abs;
+ if (row == curY && Wcm.cc_habs < BIG)
+ directcost = Wcm.cc_habs, dcm = Wcm.cm_habs;
+ else if (col == curX && Wcm.cc_vabs < BIG)
+ directcost = Wcm.cc_vabs, dcm = Wcm.cm_vabs;
+ }
+ else
+ {
+ directcost = 0, relcost = 100000;
+ dcm = Wcm.cm_abs;
+ }
+
+ /*
+ * In the following comparison, the = in <= is because when the costs
+ * are the same, it looks nicer (I think) to move directly there.
+ */
+ if (directcost <= relcost)
+ {
+ /* compute REAL direct cost */
+ cost = 0;
+ p = dcm == Wcm.cm_habs ? tgoto (dcm, row, col) :
+ tgoto (dcm, col, row);
+ tputs (p, 1, evalcost);
+ if (cost <= relcost)
+ { /* really is cheaper */
+ tputs (p, 1, cmputc);
+ curY = row, curX = col;
+ return;
+ }
+ }
+
+ switch (use)
+ {
+ case USEHOME:
+ tputs (Wcm.cm_home, 1, cmputc);
+ curY = 0, curX = 0;
+ break;
+
+ case USELL:
+ tputs (Wcm.cm_ll, 1, cmputc);
+ curY = Wcm.cm_rows - 1, curX = 0;
+ break;
+
+ case USECR:
+ tputs (Wcm.cm_cr, 1, cmputc);
+ if (Wcm.cm_autolf)
+ curY++;
+ curX = 0;
+ break;
+ }
+
+ (void) calccost (curY, curX, row, col, 1);
+ curY = row, curX = col;
+}
+
+/* Clear out all terminal info.
+ Used before copying into it the info on the actual terminal.
+ */
+
+Wcm_clear ()
+{
+ bzero (&Wcm, sizeof Wcm);
+ UP = 0;
+ BC = 0;
+}
+
+/*
+ * Initialized stuff
+ * Return 0 if can do CM.
+ * Return -1 if cannot.
+ * Return -2 if size not specified.
+ */
+
+Wcm_init ()
+{
+#if 0
+ if (Wcm.cm_abs && !Wcm.cm_ds)
+ return 0;
+#endif
+ if (Wcm.cm_abs)
+ return 0;
+ /* Require up and left, and, if no absolute, down and right */
+ if (!Wcm.cm_up || !Wcm.cm_left)
+ return - 1;
+ if (!Wcm.cm_abs && (!Wcm.cm_down || !Wcm.cm_right))
+ return - 1;
+ /* Check that we know the size of the screen.... */
+ if (Wcm.cm_rows <= 0 || Wcm.cm_cols <= 0)
+ return - 2;
+ return 0;
+}
diff --git a/src/disptab.h b/src/disptab.h
new file mode 100644
index 00000000000..67d36195555
--- /dev/null
+++ b/src/disptab.h
@@ -0,0 +1,82 @@
+/* Things for GLYPHS and glyph tables.
+ Copyright (C) 1990 Free Software Foundation, Inc.
+
+This file is part of GNU Emacs.
+
+GNU Emacs is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GNU Emacs is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Emacs; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+/* Access the slots of a display-table, according to their purpose. */
+
+#define DISP_TABLE_SIZE 261
+#define DISP_TRUNC_GLYPH(dp) ((dp)->contents[256])
+#define DISP_CONTINUE_GLYPH(dp) ((dp)->contents[257])
+#define DISP_ESCAPE_GLYPH(dp) ((dp)->contents[258])
+#define DISP_CTRL_GLYPH(dp) ((dp)->contents[259])
+#define DISP_INVIS_ROPE(dp) ((dp)->contents[260])
+#define DISP_CHAR_ROPE(dp, c) ((dp)->contents[c])
+
+extern struct Lisp_Vector *window_display_table ();
+
+/* Display table to use for vectors that don't specify their own. */
+extern Lisp_Object Vstandard_display_table;
+
+/* Vector of GLYPH definitions. Indexed by GLYPH number,
+ the contents are a string which is how to output the GLYPH. */
+extern Lisp_Object Vglyph_table;
+
+/* Return the current length of the GLYPH table,
+ or 0 if the table isn't currently valid. */
+#define GLYPH_TABLE_LENGTH \
+ ((XTYPE (Vglyph_table) == Lisp_Vector) \
+ ? XVECTOR (Vglyph_table)->size : 0)
+
+/* Return the current base (for indexing) of the GLYPH table,
+ or 0 if the table isn't currently valid. */
+#define GLYPH_TABLE_BASE \
+ ((XTYPE (Vglyph_table) == Lisp_Vector) \
+ ? XVECTOR (Vglyph_table)->contents : 0)
+
+/* Given BASE and LEN returned by the two previous macros,
+ return nonzero if the GLYPH code G should be output as a single
+ character with code G. Return zero if G has a string in the table. */
+#define GLYPH_SIMPLE_P(base,len,g) \
+ ((g) >= (len) || XTYPE (base[g]) != Lisp_String)
+
+/* Given BASE and LEN returned by the two previous macros,
+ return nonzero if GLYPH code G is aliased to a different code. */
+#define GLYPH_ALIAS_P(base,len,g) \
+ ((g) < (len) && XTYPE (base[g]) == Lisp_Int)
+
+/* Assuming that GLYPH_SIMPLE_P (BASE, LEN, G) is 1,
+ return the alias for G. */
+#define GLYPH_ALIAS(base, g) XINT (base[g])
+
+/* Assuming that GLYPH_SIMPLE_P (BASE, LEN, G) is 0,
+ return the length and the address of the character-sequence
+ used for outputting GLYPH G. */
+#define GLYPH_LENGTH(base,g) XSTRING (base[g])->size
+#define GLYPH_STRING(base,g) XSTRING (base[g])->data
+
+/* GLYPH for a space character. */
+
+#define SPACEGLYPH 040
+#define NULL_GLYPH 00
+
+#define GLYPH_FROM_CHAR(c) (c)
+
+extern int glyphlen ();
+extern void str_to_glyph_cpy ();
+extern void str_to_glyph_ncpy ();
+extern void glyph_to_str_cpy ();
diff --git a/src/doprnt.c b/src/doprnt.c
index 731afe400cc..02584554577 100644
--- a/src/doprnt.c
+++ b/src/doprnt.c
@@ -68,10 +68,10 @@ doprnt (buffer, bufsize, format, format_end, nargs, args)
int size_bound;
fmt++;
- /* Copy this one %-spec into fmtcopy. */
+ /* Copy this one %-spec into fmtcpy. */
string = fmtcpy;
*string++ = '%';
- while (1)
+ while (string < fmtcpy + sizeof fmtcpy - 1)
{
*string++ = *fmt;
if (! (*fmt >= '0' && *fmt <= '9') && *fmt != '-' && *fmt != ' ')
diff --git a/src/indent.h b/src/indent.h
new file mode 100644
index 00000000000..ec6dcaeadf0
--- /dev/null
+++ b/src/indent.h
@@ -0,0 +1,34 @@
+/* Definitions for interface to indent.c
+ Copyright (C) 1985, 1986 Free Software Foundation, Inc.
+
+This file is part of GNU Emacs.
+
+GNU Emacs is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GNU Emacs is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Emacs; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+
+struct position
+ {
+ int bufpos;
+ int hpos;
+ int vpos;
+ int prevhpos;
+ int contin;
+ };
+
+struct position *compute_motion ();
+struct position *vmotion ();
+
+/* Value of point when current_column was called */
+extern int last_known_column_point;
diff --git a/src/insdel.c b/src/insdel.c
index 80f1d67369b..1deda9d7ac8 100644
--- a/src/insdel.c
+++ b/src/insdel.c
@@ -214,7 +214,7 @@ adjust_markers (from, to, amount)
marker = current_buffer->markers;
- while (!NULL (marker))
+ while (!NILP (marker))
{
m = XMARKER (marker);
mpos = m->bufpos;
@@ -352,7 +352,7 @@ insert_from_string (string, pos, length)
GPT += length;
ZV += length;
Z += length;
- point += length;
+ SET_PT (point + length);
signal_after_change (point-length, 0, length);
}
@@ -473,22 +473,22 @@ modify_region (start, end)
prepare_to_modify_buffer (start, end)
Lisp_Object start, end;
{
- if (!NULL (current_buffer->read_only))
+ if (!NILP (current_buffer->read_only))
Fbarf_if_buffer_read_only ();
if (check_protected_fields)
Fregion_fields (start, end, Qnil, Qt);
#ifdef CLASH_DETECTION
- if (!NULL (current_buffer->filename)
+ if (!NILP (current_buffer->filename)
&& current_buffer->save_modified >= MODIFF)
lock_file (current_buffer->filename);
#else
/* At least warn if this file has changed on disk since it was visited. */
- if (!NULL (current_buffer->filename)
+ if (!NILP (current_buffer->filename)
&& current_buffer->save_modified >= MODIFF
- && NULL (Fverify_visited_file_modtime (Fcurrent_buffer ()))
- && !NULL (Ffile_exists_p (current_buffer->filename)))
+ && NILP (Fverify_visited_file_modtime (Fcurrent_buffer ()))
+ && !NILP (Ffile_exists_p (current_buffer->filename)))
call1 (intern ("ask-user-about-supersession-threat"),
current_buffer->filename);
#endif /* not CLASH_DETECTION */
@@ -519,12 +519,12 @@ signal_before_change (start, end)
{
/* If buffer is unmodified, run a special hook for that case. */
if (current_buffer->save_modified >= MODIFF
- && !NULL (Vfirst_change_function))
+ && !NILP (Vfirst_change_function))
{
call0 (Vfirst_change_function);
}
/* Now in any case run the before-change-function if any. */
- if (!NULL (Vbefore_change_function))
+ if (!NILP (Vbefore_change_function))
{
int count = specpdl_ptr - specpdl;
Lisp_Object function;
@@ -551,7 +551,7 @@ signal_before_change (start, end)
signal_after_change (pos, lendel, lenins)
int pos, lendel, lenins;
{
- if (!NULL (Vafter_change_function))
+ if (!NILP (Vafter_change_function))
{
int count = specpdl_ptr - specpdl;
Lisp_Object function;
diff --git a/src/ioctl.h b/src/ioctl.h
new file mode 100644
index 00000000000..0366f6d6bd5
--- /dev/null
+++ b/src/ioctl.h
@@ -0,0 +1 @@
+/* Emacs ioctl emulation for VMS */
diff --git a/src/lastfile.c b/src/lastfile.c
new file mode 100644
index 00000000000..6588a593c92
--- /dev/null
+++ b/src/lastfile.c
@@ -0,0 +1,38 @@
+/* Mark end of data space to dump as pure, for GNU Emacs.
+ Copyright (C) 1985 Free Software Foundation, Inc.
+
+This file is part of GNU Emacs.
+
+GNU Emacs is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GNU Emacs is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Emacs; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+
+/* How this works:
+
+ Fdump_emacs dumps everything up to my_edata as text space (pure).
+
+ The files of Emacs are written so as to have no initialized
+ data that can ever need to be altered except at the first startup.
+ This is so that those words can be dumped as sharable text.
+
+ It is not possible to exercise such control over library files.
+ So it is necessary to refrain from making their data areas shared.
+ Therefore, this file is loaded following all the files of Emacs
+ but before library files.
+ As a result, the symbol my_edata indicates the point
+ in data space between data coming from Emacs and data
+ coming from libraries.
+*/
+
+char my_edata = 0;
diff --git a/src/line.h b/src/line.h
new file mode 100644
index 00000000000..e3441aaaa93
--- /dev/null
+++ b/src/line.h
@@ -0,0 +1,7 @@
+#define line_width 30
+#define line_height 10
+static char line_bits[] = {
+ 0xf0, 0xff, 0xff, 0x03, 0x08, 0x00, 0x00, 0x04, 0x44, 0x48, 0xf4, 0x08,
+ 0x42, 0xc8, 0x14, 0x10, 0x41, 0x48, 0x75, 0x20, 0x41, 0x48, 0x15, 0x20,
+ 0x42, 0x48, 0x16, 0x10, 0xc4, 0x4b, 0xf4, 0x08, 0x08, 0x00, 0x00, 0x04,
+ 0xf0, 0xff, 0xff, 0x03};
diff --git a/src/macros.h b/src/macros.h
new file mode 100644
index 00000000000..36d66898c46
--- /dev/null
+++ b/src/macros.h
@@ -0,0 +1,31 @@
+/* Definitions for keyboard macro interpretation in GNU Emacs.
+ Copyright (C) 1985 Free Software Foundation, Inc.
+
+This file is part of GNU Emacs.
+
+GNU Emacs is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GNU Emacs is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Emacs; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+
+/* Kbd macro currently being executed (a string) */
+
+extern Lisp_Object Vexecuting_macro;
+
+/* Index of next character to fetch from that macro */
+
+extern int executing_macro_index;
+
+/* Nonzero while defining a kbd macro */
+
+extern int defining_kbd_macro;
diff --git a/src/marker.c b/src/marker.c
index d8c0a89819a..6c26e72fae4 100644
--- a/src/marker.c
+++ b/src/marker.c
@@ -36,7 +36,7 @@ Returns nil if MARKER points into a dead buffer.")
{
XSET (buf, Lisp_Buffer, XMARKER (marker)->buffer);
/* Return marker's buffer only if it is not dead. */
- if (!NULL (XBUFFER (buf)->name))
+ if (!NILP (XBUFFER (buf)->name))
return buf;
}
return Qnil;
@@ -87,7 +87,7 @@ Returns MARKER.")
CHECK_MARKER (marker, 0);
/* If position is nil or a marker that points nowhere,
make this marker point nowhere. */
- if (NULL (pos)
+ if (NILP (pos)
|| (XTYPE (pos) == Lisp_Marker && !XMARKER (pos)->buffer))
{
unchain_marker (marker);
@@ -95,7 +95,7 @@ Returns MARKER.")
}
CHECK_NUMBER_COERCE_MARKER (pos, 1);
- if (NULL (buffer))
+ if (NILP (buffer))
b = current_buffer;
else
{
@@ -144,7 +144,7 @@ set_marker_restricted (marker, pos, buffer)
CHECK_MARKER (marker, 0);
/* If position is nil or a marker that points nowhere,
make this marker point nowhere. */
- if (NULL (pos) ||
+ if (NILP (pos) ||
(XTYPE (pos) == Lisp_Marker && !XMARKER (pos)->buffer))
{
unchain_marker (marker);
@@ -152,7 +152,7 @@ set_marker_restricted (marker, pos, buffer)
}
CHECK_NUMBER_COERCE_MARKER (pos, 1);
- if (NULL (buffer))
+ if (NILP (buffer))
b = current_buffer;
else
{
@@ -215,7 +215,7 @@ unchain_marker (marker)
if (XMARKER (marker) == XMARKER (tail))
{
- if (NULL (prev))
+ if (NILP (prev))
{
b->markers = next;
/* Deleting first marker from the buffer's chain.
diff --git a/src/mocklisp.c b/src/mocklisp.c
index 5f0800f94c1..353d4da0e43 100644
--- a/src/mocklisp.c
+++ b/src/mocklisp.c
@@ -32,7 +32,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
* {
* Lisp_Object elt;
*
-* while (!NULL (args))
+* while (!NILP (args))
* {
* elt = Fcar (args);
* Ffset (Fcar (elt), Fcons (Qmocklisp, Fcdr (elt)));
@@ -50,11 +50,11 @@ DEFUN ("ml-if", Fml_if, Sml_if, 0, UNEVALLED, 0, "Mocklisp version of `if'.")
struct gcpro gcpro1;
GCPRO1 (args);
- while (!NULL (args))
+ while (!NILP (args))
{
val = Feval (Fcar (args));
args = Fcdr (args);
- if (NULL (args)) break;
+ if (NILP (args)) break;
if (XINT (val))
{
val = Feval (Fcar (args));
@@ -156,7 +156,7 @@ DEFUN ("ml-prefix-argument-loop", Fml_prefix_argument_loop, Sml_prefix_argument_
struct gcpro gcpro1;
/* Set `arg' in case we call a built-in function that looks at it. Still are a few. */
- if (NULL (Vcurrent_prefix_arg))
+ if (NILP (Vcurrent_prefix_arg))
i = 1;
else
{
diff --git a/src/mocklisp.h b/src/mocklisp.h
index e381bb23f8b..56ff3f7a1de 100644
--- a/src/mocklisp.h
+++ b/src/mocklisp.h
@@ -28,4 +28,4 @@ extern Lisp_Object Fml_arg ();
extern Lisp_Object Fml_interactive ();
extern Lisp_Object Fml_provide_prefix_argument ();
extern Lisp_Object Fml_prefix_argument_loop ();
-extern Lisp_Object FInsStr ();
+extern Lisp_Object Finsert_string ();
diff --git a/src/ndir.h b/src/ndir.h
new file mode 100644
index 00000000000..438d5c20a12
--- /dev/null
+++ b/src/ndir.h
@@ -0,0 +1,51 @@
+/*
+ <dir.h> -- definitions for 4.2BSD-compatible directory access
+
+ last edit: 09-Jul-1983 D A Gwyn
+*/
+
+#ifdef VMS
+#ifndef FAB$C_BID
+#include <fab.h>
+#endif
+#ifndef NAM$C_BID
+#include <nam.h>
+#endif
+#ifndef RMS$_SUC
+#include <rmsdef.h>
+#endif
+#include "dir.h"
+#endif /* VMS */
+
+#define DIRBLKSIZ 512 /* size of directory block */
+#ifdef VMS
+#define MAXNAMLEN (DIR$S_NAME + 7) /* 80 plus room for version #. */
+#define MAXFULLSPEC NAM$C_MAXRSS /* Maximum full spec */
+#else
+#define MAXNAMLEN 15 /* maximum filename length */
+#endif /* VMS */
+ /* NOTE: MAXNAMLEN must be one less than a multiple of 4 */
+
+struct direct /* data from readdir() */
+ {
+ long d_ino; /* inode number of entry */
+ unsigned short d_reclen; /* length of this record */
+ unsigned short d_namlen; /* length of string in d_name */
+ char d_name[MAXNAMLEN+1]; /* name of file */
+ };
+
+typedef struct
+ {
+ int dd_fd; /* file descriptor */
+ int dd_loc; /* offset in block */
+ int dd_size; /* amount of valid data */
+ char dd_buf[DIRBLKSIZ]; /* directory block */
+ } DIR; /* stream data from opendir() */
+
+extern DIR *opendir();
+extern struct direct *readdir();
+extern long telldir();
+extern void seekdir();
+extern void closedir();
+
+#define rewinddir( dirp ) seekdir( dirp, 0L )
diff --git a/src/param.h b/src/param.h
new file mode 100644
index 00000000000..1b27b50a276
--- /dev/null
+++ b/src/param.h
@@ -0,0 +1,2 @@
+/* This is so that Emacs can run on VMS... */
+#define EXEC_PAGESIZE 512
diff --git a/src/point.h b/src/point.h
new file mode 100644
index 00000000000..7bae693f2d4
--- /dev/null
+++ b/src/point.h
@@ -0,0 +1,5 @@
+#define point_width 5
+#define point_height 19
+static char point_bits[] = {
+ 0x1f, 0x0e, 0x0e, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x04, 0x04, 0x0e, 0x0e, 0x1f};
diff --git a/src/pre-crt0.c b/src/pre-crt0.c
new file mode 100644
index 00000000000..67fd31cd6ac
--- /dev/null
+++ b/src/pre-crt0.c
@@ -0,0 +1,9 @@
+/* This file is loaded before crt0.o on machines where we do not
+ remap part of the data space into text space in unexec.
+ On these machines, there is no problem with standard crt0.o's
+ that make environ an initialized variable. However, we do
+ need to make sure the label data_start exists anyway. */
+
+/* Create a label to appear at the beginning of data space. */
+
+int data_start = 0;
diff --git a/src/puresize.h b/src/puresize.h
index 4934ba5f5bc..9473d3df5e7 100644
--- a/src/puresize.h
+++ b/src/puresize.h
@@ -21,9 +21,19 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
At one point, this was defined in config.h, meaning that changing
PURESIZE would make Make recompile all of Emacs. But only a few
- files actually use PURESIZE, so we split it out to its own .h file. */
+ files actually use PURESIZE, so we split it out to its own .h file.
+ Make sure to include this file after config.h, since that tells us
+ whether we are running X windows, which tells us how much pure
+ storage to allocate. */
+
+#ifndef PURESIZE
+#ifdef HAVE_X_WINDOWS
#define PURESIZE 200000
+#else
+#define PURESIZE 196000
+#endif
+#endif
#ifdef VIRT_ADDR_VARIES
diff --git a/src/sink.h b/src/sink.h
new file mode 100644
index 00000000000..1eb6770c83f
--- /dev/null
+++ b/src/sink.h
@@ -0,0 +1,91 @@
+#define sink_width 48
+#define sink_height 48
+#ifdef HAVE_X11
+static char sink_bits[] = {
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0x80, 0x9f,
+ 0xff, 0xff, 0xff, 0xff, 0x9f, 0x9f,
+ 0xff, 0xff, 0xff, 0xff, 0x00, 0x80,
+ 0xff, 0xff, 0xff, 0x7f, 0xfe, 0xbf,
+ 0xff, 0xff, 0xff, 0x7f, 0x03, 0xa0,
+ 0xff, 0xff, 0xff, 0x7f, 0xfd, 0xaf,
+ 0xff, 0xff, 0xff, 0x3f, 0xf9, 0xaf,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xaf,
+ 0xff, 0xff, 0xff, 0xff, 0xfc, 0xaf,
+ 0xff, 0xff, 0xff, 0x7f, 0xf8, 0xaf,
+ 0xff, 0xff, 0xff, 0xff, 0xfc, 0xaf,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xaf,
+ 0xff, 0xff, 0xff, 0xbf, 0xf7, 0xaf,
+ 0xff, 0xff, 0xff, 0x3f, 0xf3, 0xaf,
+ 0xff, 0xff, 0xff, 0xff, 0xfc, 0xaf,
+ 0x3f, 0x00, 0x00, 0x00, 0x00, 0x20,
+ 0x7f, 0x00, 0x00, 0x00, 0x00, 0xe0,
+ 0xdf, 0xf8, 0xff, 0xff, 0xff, 0x07,
+ 0xcf, 0xf9, 0x0f, 0xff, 0xff, 0xe7,
+ 0xcf, 0xf9, 0xf7, 0xff, 0xff, 0xe7,
+ 0xff, 0xf9, 0xf7, 0x63, 0xfb, 0xe7,
+ 0xff, 0xf9, 0x37, 0x5a, 0xfb, 0xe7,
+ 0xcf, 0xf9, 0xf7, 0x5a, 0xfb, 0xe7,
+ 0xcf, 0xf9, 0xf7, 0x5a, 0xf9, 0xe7,
+ 0xef, 0xf9, 0x0f, 0xdb, 0xfa, 0xe7,
+ 0xff, 0xf9, 0xff, 0xff, 0xff, 0xe7,
+ 0xdf, 0xf9, 0xff, 0xff, 0xff, 0xe7,
+ 0xcf, 0x19, 0xfc, 0xff, 0xff, 0xe7,
+ 0xcf, 0xd9, 0xff, 0xff, 0xff, 0xe7,
+ 0xff, 0xd9, 0x47, 0xce, 0x73, 0xe6,
+ 0xff, 0x19, 0xb6, 0xb5, 0xad, 0xe7,
+ 0xcf, 0xd9, 0xb7, 0xb5, 0x7d, 0xe6,
+ 0xc7, 0xd9, 0xb7, 0xb5, 0xed, 0xe5,
+ 0xef, 0x19, 0xb4, 0x4d, 0x73, 0xe6,
+ 0xff, 0xf1, 0xff, 0xff, 0xff, 0xe3,
+ 0xff, 0x03, 0x80, 0x03, 0x00, 0xf0,
+ 0xef, 0x07, 0x00, 0x01, 0x00, 0xf8,
+ 0xc7, 0xff, 0x3f, 0xf9, 0xff, 0xff,
+ 0xe7, 0xff, 0x7f, 0xfd, 0xe0, 0xff,
+ 0xff, 0xff, 0x7f, 0x7d, 0xdf, 0xff,
+ 0xff, 0xff, 0x7f, 0xbd, 0xb1, 0xff,
+ 0xff, 0xff, 0x7f, 0xbb, 0xae, 0xff,
+ 0xef, 0xff, 0xff, 0xda, 0xae, 0xff,
+ 0xc7, 0xff, 0xff, 0x66, 0xaf, 0xff,
+ 0xe7, 0xff, 0xff, 0xbd, 0xaf, 0xff,
+ 0xff, 0xff, 0xff, 0xc3, 0xaf, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xaf, 0xff};
+#else
+short sink_bits[] = {
+ 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0x9f80, 0xffff, 0xffff,
+ 0x9f9f, 0xffff, 0xffff, 0x8000,
+ 0xffff, 0x7fff, 0xbffe, 0xffff,
+ 0x7fff, 0xa003, 0xffff, 0x7fff,
+ 0xaffd, 0xffff, 0x3fff, 0xaff9,
+ 0xffff, 0xffff, 0xafff, 0xffff,
+ 0xffff, 0xaffc, 0xffff, 0x7fff,
+ 0xaff8, 0xffff, 0xffff, 0xaffc,
+ 0xffff, 0xffff, 0xafff, 0xffff,
+ 0xbfff, 0xaff7, 0xffff, 0x3fff,
+ 0xaff3, 0xffff, 0xffff, 0xaffc,
+ 0x003f, 0x0000, 0x2000, 0x007f,
+ 0x0000, 0xe000, 0xf8df, 0xffff,
+ 0x07ff, 0xf9cf, 0xff0f, 0xe7ff,
+ 0xf9cf, 0xfff7, 0xe7ff, 0xf9ff,
+ 0x63f7, 0xe7fb, 0xf9ff, 0x5a37,
+ 0xe7fb, 0xf9cf, 0x5af7, 0xe7fb,
+ 0xf9cf, 0x5af7, 0xe7f9, 0xf9ef,
+ 0xdb0f, 0xe7fa, 0xf9ff, 0xffff,
+ 0xe7ff, 0xf9df, 0xffff, 0xe7ff,
+ 0x19cf, 0xfffc, 0xe7ff, 0xd9cf,
+ 0xffff, 0xe7ff, 0xd9ff, 0xce47,
+ 0xe673, 0x19ff, 0xb5b6, 0xe7ad,
+ 0xd9cf, 0xb5b7, 0xe67d, 0xd9c7,
+ 0xb5b7, 0xe5ed, 0x19ef, 0x4db4,
+ 0xe673, 0xf1ff, 0xffff, 0xe3ff,
+ 0x03ff, 0x0380, 0xf000, 0x07ef,
+ 0x0100, 0xf800, 0xffc7, 0xf93f,
+ 0xffff, 0xffe7, 0xfd7f, 0xffe0,
+ 0xffff, 0x7d7f, 0xffdf, 0xffff,
+ 0xbd7f, 0xffb1, 0xffff, 0xbb7f,
+ 0xffae, 0xffef, 0xdaff, 0xffae,
+ 0xffc7, 0x66ff, 0xffaf, 0xffe7,
+ 0xbdff, 0xffaf, 0xffff, 0xc3ff,
+ 0xffaf, 0xffff, 0xffff, 0xffaf};
+#endif /* HAVE_X11 */
diff --git a/src/sink11.h b/src/sink11.h
new file mode 100644
index 00000000000..dec0280a72b
--- /dev/null
+++ b/src/sink11.h
@@ -0,0 +1,51 @@
+#define sink_width 48
+#define sink_height 48
+static char sink_bits[] = {
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0x80, 0x9f,
+ 0xff, 0xff, 0xff, 0xff, 0x9f, 0x9f,
+ 0xff, 0xff, 0xff, 0xff, 0x00, 0x80,
+ 0xff, 0xff, 0xff, 0x7f, 0xfe, 0xbf,
+ 0xff, 0xff, 0xff, 0x7f, 0x03, 0xa0,
+ 0xff, 0xff, 0xff, 0x7f, 0xfd, 0xaf,
+ 0xff, 0xff, 0xff, 0x3f, 0xf9, 0xaf,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xaf,
+ 0xff, 0xff, 0xff, 0xff, 0xfc, 0xaf,
+ 0xff, 0xff, 0xff, 0x7f, 0xf8, 0xaf,
+ 0xff, 0xff, 0xff, 0xff, 0xfc, 0xaf,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xaf,
+ 0xff, 0xff, 0xff, 0xbf, 0xf7, 0xaf,
+ 0xff, 0xff, 0xff, 0x3f, 0xf3, 0xaf,
+ 0xff, 0xff, 0xff, 0xff, 0xfc, 0xaf,
+ 0x3f, 0x00, 0x00, 0x00, 0x00, 0x20,
+ 0x7f, 0x00, 0x00, 0x00, 0x00, 0xe0,
+ 0xdf, 0xf8, 0xff, 0xff, 0xff, 0x07,
+ 0xcf, 0xf9, 0x0f, 0xff, 0xff, 0xe7,
+ 0xcf, 0xf9, 0xf7, 0xff, 0xff, 0xe7,
+ 0xff, 0xf9, 0xf7, 0x63, 0xfb, 0xe7,
+ 0xff, 0xf9, 0x37, 0x5a, 0xfb, 0xe7,
+ 0xcf, 0xf9, 0xf7, 0x5a, 0xfb, 0xe7,
+ 0xcf, 0xf9, 0xf7, 0x5a, 0xf9, 0xe7,
+ 0xef, 0xf9, 0x0f, 0xdb, 0xfa, 0xe7,
+ 0xff, 0xf9, 0xff, 0xff, 0xff, 0xe7,
+ 0xdf, 0xf9, 0xff, 0xff, 0xff, 0xe7,
+ 0xcf, 0x19, 0xfc, 0xff, 0xff, 0xe7,
+ 0xcf, 0xd9, 0xff, 0xff, 0xff, 0xe7,
+ 0xff, 0xd9, 0x47, 0xce, 0x73, 0xe6,
+ 0xff, 0x19, 0xb6, 0xb5, 0xad, 0xe7,
+ 0xcf, 0xd9, 0xb7, 0xb5, 0x7d, 0xe6,
+ 0xc7, 0xd9, 0xb7, 0xb5, 0xed, 0xe5,
+ 0xef, 0x19, 0xb4, 0x4d, 0x73, 0xe6,
+ 0xff, 0xf1, 0xff, 0xff, 0xff, 0xe3,
+ 0xff, 0x03, 0x80, 0x03, 0x00, 0xf0,
+ 0xef, 0x07, 0x00, 0x01, 0x00, 0xf8,
+ 0xc7, 0xff, 0x3f, 0xf9, 0xff, 0xff,
+ 0xe7, 0xff, 0x7f, 0xfd, 0xe0, 0xff,
+ 0xff, 0xff, 0x7f, 0x7d, 0xdf, 0xff,
+ 0xff, 0xff, 0x7f, 0xbd, 0xb1, 0xff,
+ 0xff, 0xff, 0x7f, 0xbb, 0xae, 0xff,
+ 0xef, 0xff, 0xff, 0xda, 0xae, 0xff,
+ 0xc7, 0xff, 0xff, 0x66, 0xaf, 0xff,
+ 0xe7, 0xff, 0xff, 0xbd, 0xaf, 0xff,
+ 0xff, 0xff, 0xff, 0xc3, 0xaf, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xaf, 0xff};
diff --git a/src/sink11mask.h b/src/sink11mask.h
new file mode 100644
index 00000000000..b0a6e0c6f35
--- /dev/null
+++ b/src/sink11mask.h
@@ -0,0 +1,51 @@
+#define sink_mask_width 48
+#define sink_mask_height 48
+static char sink_mask_bits[] = {
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
diff --git a/src/terminfo.c b/src/terminfo.c
new file mode 100644
index 00000000000..af057133e50
--- /dev/null
+++ b/src/terminfo.c
@@ -0,0 +1,50 @@
+/* Interface from Emacs to terminfo.
+ Copyright (C) 1985, 1986 Free Software Foundation, Inc.
+
+This file is part of GNU Emacs.
+
+GNU Emacs is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GNU Emacs is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Emacs; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+/* Define these variables that serve as global parameters to termcap,
+ so that we do not need to conditionalize the places in Emacs
+ that set them. */
+
+char *UP, *BC, PC;
+short ospeed;
+
+static buffer[512];
+
+/* Interface to curses/terminfo library.
+ Turns out that all of the terminfo-level routines look
+ like their termcap counterparts except for tparm, which replaces
+ tgoto. Not only is the calling sequence different, but the string
+ format is different too.
+*/
+
+char *
+tparam (string, outstring, len, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)
+ char *string;
+ char *outstring;
+ int arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9;
+{
+ char *temp;
+ extern char *tparm();
+
+ temp = tparm (string, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9);
+ if (outstring == 0)
+ outstring = ((char *) (malloc ((strlen (temp)) + 1)));
+ strcpy (outstring, temp);
+ return outstring;
+}
diff --git a/src/uaf.h b/src/uaf.h
index 2b351a2738b..2c9387e8942 100644
--- a/src/uaf.h
+++ b/src/uaf.h
@@ -3,20 +3,19 @@
This file is part of GNU Emacs.
+GNU Emacs is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
GNU Emacs is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY. No author or distributor
-accepts responsibility to anyone for the consequences of using it
-or for whether it serves any particular purpose or works at all,
-unless he says so in writing. Refer to the GNU Emacs General Public
-License for full details.
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
-Everyone is granted permission to copy, modify and redistribute
-GNU Emacs, but only under the conditions described in the
-GNU Emacs General Public License. A copy of this license is
-supposed to have been given to you along with GNU Emacs so you
-can know your rights and responsibilities. It should be in a
-file named COPYING. Among other things, the copyright notice
-and this notice must be preserved on all copies. */
+You should have received a copy of the GNU General Public License
+along with GNU Emacs; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
/*
* User Authorization File record formats
diff --git a/src/unexconvex.c b/src/unexconvex.c
new file mode 100644
index 00000000000..09a7dfff400
--- /dev/null
+++ b/src/unexconvex.c
@@ -0,0 +1,601 @@
+/* Modified version of unexec for convex machines.
+ Note that the GNU project considers support for the peculiarities
+ of the Convex operating system a peripheral activity which should
+ not be allowed to divert effort from development of the GNU system.
+ Changes in this code will be installed when Convex system
+ maintainers send them in, but aside from that we don't plan to
+ think about it, or about whether other Emacs maintenance might
+ break it.
+
+ Copyright (C) 1985, 1986, 1988 Free Software Foundation, Inc.
+
+This file is part of GNU Emacs.
+
+GNU Emacs is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GNU Emacs is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Emacs; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+
+/* modified for C-1 arch by jthomp@convex 871103 */
+/* Corrected to support convex SOFF object file formats and thread specific
+ * regions. streepy@convex 890302
+*/
+
+/*
+ * unexec.c - Convert a running program into an a.out file.
+ *
+ * Author: Spencer W. Thomas
+ * Computer Science Dept.
+ * University of Utah
+ * Date: Tue Mar 2 1982
+ * Modified heavily since then.
+ *
+ * Synopsis:
+ * unexec (new_name, a_name, data_start, bss_start, entry_address)
+ * char *new_name, *a_name;
+ * unsigned data_start, bss_start, entry_address;
+ *
+ * Takes a snapshot of the program and makes an a.out format file in the
+ * file named by the string argument new_name.
+ * If a_name is non-NULL, the symbol table will be taken from the given file.
+ * On some machines, an existing a_name file is required.
+ *
+ * The boundaries within the a.out file may be adjusted with the data_start
+ * and bss_start arguments. Either or both may be given as 0 for defaults.
+ *
+ * Data_start gives the boundary between the text segment and the data
+ * segment of the program. The text segment can contain shared, read-only
+ * program code and literal data, while the data segment is always unshared
+ * and unprotected. Data_start gives the lowest unprotected address.
+ * The value you specify may be rounded down to a suitable boundary
+ * as required by the machine you are using.
+ *
+ * Specifying zero for data_start means the boundary between text and data
+ * should not be the same as when the program was loaded.
+ * If NO_REMAP is defined, the argument data_start is ignored and the
+ * segment boundaries are never changed.
+ *
+ * Bss_start indicates how much of the data segment is to be saved in the
+ * a.out file and restored when the program is executed. It gives the lowest
+ * unsaved address, and is rounded up to a page boundary. The default when 0
+ * is given assumes that the entire data segment is to be stored, including
+ * the previous data and bss as well as any additional storage allocated with
+ * break (2).
+ *
+ * The new file is set up to start at entry_address.
+ *
+ * If you make improvements I'd like to get them too.
+ * harpo!utah-cs!thomas, thomas@Utah-20
+ *
+ */
+
+/* There are several compilation parameters affecting unexec:
+
+* COFF
+
+Define this if your system uses COFF for executables.
+Otherwise we assume you use Berkeley format.
+
+* NO_REMAP
+
+Define this if you do not want to try to save Emacs's pure data areas
+as part of the text segment.
+
+Saving them as text is good because it allows users to share more.
+
+However, on machines that locate the text area far from the data area,
+the boundary cannot feasibly be moved. Such machines require
+NO_REMAP.
+
+Also, remapping can cause trouble with the built-in startup routine
+/lib/crt0.o, which defines `environ' as an initialized variable.
+Dumping `environ' as pure does not work! So, to use remapping,
+you must write a startup routine for your machine in Emacs's crt0.c.
+If NO_REMAP is defined, Emacs uses the system's crt0.o.
+
+* SECTION_ALIGNMENT
+
+Some machines that use COFF executables require that each section
+start on a certain boundary *in the COFF file*. Such machines should
+define SECTION_ALIGNMENT to a mask of the low-order bits that must be
+zero on such a boundary. This mask is used to control padding between
+segments in the COFF file.
+
+If SECTION_ALIGNMENT is not defined, the segments are written
+consecutively with no attempt at alignment. This is right for
+unmodified system V.
+
+* SEGMENT_MASK
+
+Some machines require that the beginnings and ends of segments
+*in core* be on certain boundaries. For most machines, a page
+boundary is sufficient. That is the default. When a larger
+boundary is needed, define SEGMENT_MASK to a mask of
+the bits that must be zero on such a boundary.
+
+* A_TEXT_OFFSET(HDR)
+
+Some machines count the a.out header as part of the size of the text
+segment (a_text); they may actually load the header into core as the
+first data in the text segment. Some have additional padding between
+the header and the real text of the program that is counted in a_text.
+
+For these machines, define A_TEXT_OFFSET(HDR) to examine the header
+structure HDR and return the number of bytes to add to `a_text'
+before writing it (above and beyond the number of bytes of actual
+program text). HDR's standard fields are already correct, except that
+this adjustment to the `a_text' field has not yet been made;
+thus, the amount of offset can depend on the data in the file.
+
+* A_TEXT_SEEK(HDR)
+
+If defined, this macro specifies the number of bytes to seek into the
+a.out file before starting to write the text segment.a
+
+* EXEC_MAGIC
+
+For machines using COFF, this macro, if defined, is a value stored
+into the magic number field of the output file.
+
+* ADJUST_EXEC_HEADER
+
+This macro can be used to generate statements to adjust or
+initialize nonstandard fields in the file header
+
+* ADDR_CORRECT(ADDR)
+
+Macro to correct an int which is the bit pattern of a pointer to a byte
+into an int which is the number of a byte.
+
+This macro has a default definition which is usually right.
+This default definition is a no-op on most machines (where a
+pointer looks like an int) but not on all machines.
+
+*/
+
+#include "config.h"
+#define PERROR(file) report_error (file, new)
+
+#include <a.out.h>
+/* Define getpagesize () if the system does not.
+ Note that this may depend on symbols defined in a.out.h
+ */
+#include "getpagesize.h"
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <sys/stat.h>
+#include <errno.h>
+
+extern char *start_of_text (); /* Start of text */
+extern char *start_of_data (); /* Start of initialized data */
+
+#include <machine/filehdr.h>
+#include <machine/opthdr.h>
+#include <machine/scnhdr.h>
+#include <machine/pte.h>
+
+static long block_copy_start; /* Old executable start point */
+static struct filehdr f_hdr; /* File header */
+static struct opthdr f_ohdr; /* Optional file header (a.out) */
+long bias; /* Bias to add for growth */
+#define SYMS_START block_copy_start
+
+static long text_scnptr;
+static long data_scnptr;
+
+static int pagemask;
+static int pagesz;
+
+static
+report_error (file, fd)
+ char *file;
+ int fd;
+{
+ if (fd)
+ close (fd);
+ error ("Failure operating on %s", file);
+}
+
+#define ERROR0(msg) report_error_1 (new, msg, 0, 0); return -1
+#define ERROR1(msg,x) report_error_1 (new, msg, x, 0); return -1
+#define ERROR2(msg,x,y) report_error_1 (new, msg, x, y); return -1
+
+static
+report_error_1 (fd, msg, a1, a2)
+int fd;
+char *msg;
+int a1, a2;
+{
+ close (fd);
+ error (msg, a1, a2);
+}
+
+/* ****************************************************************
+ * unexec
+ *
+ * driving logic.
+ */
+unexec (new_name, a_name, data_start, bss_start, entry_address)
+char *new_name, *a_name;
+unsigned data_start, bss_start, entry_address;
+{
+ int new, a_out = -1;
+
+ if (a_name && (a_out = open (a_name, 0)) < 0) {
+ PERROR (a_name);
+ }
+ if ((new = creat (new_name, 0666)) < 0) {
+ PERROR (new_name);
+ }
+
+ if (make_hdr (new, a_out, data_start, bss_start, entry_address, a_name, new_name) < 0
+ || copy_text_and_data (new) < 0
+ || copy_sym (new, a_out, a_name, new_name) < 0 ) {
+ close (new);
+ return -1;
+ }
+
+ close (new);
+ if (a_out >= 0)
+ close (a_out);
+ mark_x (new_name);
+ return 0;
+}
+
+/* ****************************************************************
+ * make_hdr
+ *
+ * Make the header in the new a.out from the header in core.
+ * Modify the text and data sizes.
+ */
+
+ struct scnhdr *stbl; /* Table of all scnhdr's */
+ struct scnhdr *f_thdr; /* Text section header */
+ struct scnhdr *f_dhdr; /* Data section header */
+ struct scnhdr *f_tdhdr; /* Thread Data section header */
+ struct scnhdr *f_bhdr; /* Bss section header */
+ struct scnhdr *f_tbhdr; /* Thread Bss section header */
+
+static int
+make_hdr (new, a_out, data_start, bss_start, entry_address, a_name, new_name)
+ int new, a_out;
+ unsigned data_start, bss_start, entry_address;
+ char *a_name;
+ char *new_name;
+{
+ register int scns;
+ unsigned int bss_end;
+ unsigned int eo_data; /* End of initialized data in new exec file */
+ int scntype; /* Section type */
+ int i; /* Var for sorting by vaddr */
+ struct scnhdr scntemp; /* For swapping entries in sort */
+ extern char *start_of_data();
+
+ pagemask = (pagesz = getpagesize()) - 1;
+
+ /* Adjust text/data boundary. */
+ if (!data_start)
+ data_start = (unsigned) start_of_data ();
+
+ data_start = data_start & ~pagemask; /* (Down) to page boundary. */
+
+ bss_end = (sbrk(0) + pagemask) & ~pagemask;
+
+ /* Adjust data/bss boundary. */
+ if (bss_start != 0) {
+ bss_start = (bss_start + pagemask) & ~pagemask;/* (Up) to page bdry. */
+ if (bss_start > bss_end) {
+ ERROR1 ("unexec: Specified bss_start (%x) is past end of program",
+ bss_start);
+ }
+ } else
+ bss_start = bss_end;
+
+ if (data_start > bss_start) { /* Can't have negative data size. */
+ ERROR2 ("unexec: data_start (%x) can't be greater than bss_start (%x)",
+ data_start, bss_start);
+ }
+
+ /* Salvage as much info from the existing file as possible */
+ if (a_out < 0) {
+ ERROR0 ("can't build a COFF file from scratch yet");
+ /*NOTREACHED*/
+ }
+
+ if (read (a_out, &f_hdr, sizeof (f_hdr)) != sizeof (f_hdr)) {
+ PERROR (a_name);
+ }
+ block_copy_start += sizeof (f_hdr);
+ if (f_hdr.h_opthdr > 0) {
+ if (read (a_out, &f_ohdr, sizeof (f_ohdr)) != sizeof (f_ohdr)) {
+ PERROR (a_name);
+ }
+ block_copy_start += sizeof (f_ohdr);
+ }
+
+ /* Allocate room for scn headers */
+ stbl = (struct scnhdr *)malloc( sizeof(struct scnhdr) * f_hdr.h_nscns );
+ if( stbl == NULL ) {
+ ERROR0( "unexec: malloc of stbl failed" );
+ }
+
+ f_tdhdr = f_tbhdr = NULL;
+
+ /* Loop through section headers, copying them in */
+ for (scns = 0; scns < f_hdr.h_nscns; scns++) {
+
+ if( read( a_out, &stbl[scns], sizeof(*stbl)) != sizeof(*stbl)) {
+ PERROR (a_name);
+ }
+
+ scntype = stbl[scns].s_flags & S_TYPMASK; /* What type of section */
+
+ if( stbl[scns].s_scnptr > 0L) {
+ if( block_copy_start < stbl[scns].s_scnptr + stbl[scns].s_size )
+ block_copy_start = stbl[scns].s_scnptr + stbl[scns].s_size;
+ }
+
+ if( scntype == S_TEXT) {
+ f_thdr = &stbl[scns];
+ } else if( scntype == S_DATA) {
+ f_dhdr = &stbl[scns];
+#ifdef S_TDATA
+ } else if( scntype == S_TDATA ) {
+ f_tdhdr = &stbl[scns];
+ } else if( scntype == S_TBSS ) {
+ f_tbhdr = &stbl[scns];
+#endif /* S_TDATA (thread stuff) */
+
+ } else if( scntype == S_BSS) {
+ f_bhdr = &stbl[scns];
+ }
+
+ }
+
+ /* We will now convert TEXT and DATA into TEXT, BSS into DATA, and leave
+ * all thread stuff alone.
+ */
+
+ /* Now we alter the contents of all the f_*hdr variables
+ to correspond to what we want to dump. */
+
+ f_thdr->s_vaddr = (long) start_of_text ();
+ f_thdr->s_size = data_start - f_thdr->s_vaddr;
+ f_thdr->s_scnptr = pagesz;
+ f_thdr->s_relptr = 0;
+ f_thdr->s_nrel = 0;
+
+ eo_data = f_thdr->s_scnptr + f_thdr->s_size;
+
+ if( f_tdhdr ) { /* Process thread data */
+
+ f_tdhdr->s_vaddr = data_start;
+ f_tdhdr->s_size += f_dhdr->s_size - (data_start - f_dhdr->s_vaddr);
+ f_tdhdr->s_scnptr = eo_data;
+ f_tdhdr->s_relptr = 0;
+ f_tdhdr->s_nrel = 0;
+
+ eo_data += f_tdhdr->s_size;
+
+ /* And now for DATA */
+
+ f_dhdr->s_vaddr = f_bhdr->s_vaddr; /* Take BSS start address */
+ f_dhdr->s_size = bss_end - f_bhdr->s_vaddr;
+ f_dhdr->s_scnptr = eo_data;
+ f_dhdr->s_relptr = 0;
+ f_dhdr->s_nrel = 0;
+
+ eo_data += f_dhdr->s_size;
+
+ } else {
+
+ f_dhdr->s_vaddr = data_start;
+ f_dhdr->s_size = bss_start - data_start;
+ f_dhdr->s_scnptr = eo_data;
+ f_dhdr->s_relptr = 0;
+ f_dhdr->s_nrel = 0;
+
+ eo_data += f_dhdr->s_size;
+
+ }
+
+ f_bhdr->s_vaddr = bss_start;
+ f_bhdr->s_size = bss_end - bss_start + pagesz /* fudge */;
+ f_bhdr->s_scnptr = 0;
+ f_bhdr->s_relptr = 0;
+ f_bhdr->s_nrel = 0;
+
+ text_scnptr = f_thdr->s_scnptr;
+ data_scnptr = f_dhdr->s_scnptr;
+ bias = eo_data - block_copy_start;
+
+ if (f_ohdr.o_symptr > 0L) {
+ f_ohdr.o_symptr += bias;
+ }
+
+ if (f_hdr.h_strptr > 0) {
+ f_hdr.h_strptr += bias;
+ }
+
+ if (write (new, &f_hdr, sizeof (f_hdr)) != sizeof (f_hdr)) {
+ PERROR (new_name);
+ }
+
+ if (write (new, &f_ohdr, sizeof (f_ohdr)) != sizeof (f_ohdr)) {
+ PERROR (new_name);
+ }
+
+ for( scns = 0; scns < f_hdr.h_nscns; scns++ ) {
+
+ /* This is a cheesey little loop to write out the section headers
+ * in order of increasing virtual address. Dull but effective.
+ */
+
+ for( i = scns+1; i < f_hdr.h_nscns; i++ ) {
+ if( stbl[i].s_vaddr < stbl[scns].s_vaddr ) { /* Swap */
+ scntemp = stbl[i];
+ stbl[i] = stbl[scns];
+ stbl[scns] = scntemp;
+ }
+ }
+
+ }
+
+ for( scns = 0; scns < f_hdr.h_nscns; scns++ ) {
+
+ if( write( new, &stbl[scns], sizeof(*stbl)) != sizeof(*stbl)) {
+ PERROR (new_name);
+ }
+
+ }
+
+ return (0);
+
+}
+
+/* ****************************************************************
+ * copy_text_and_data
+ *
+ * Copy the text and data segments from memory to the new a.out
+ */
+static int
+copy_text_and_data (new)
+int new;
+{
+ register int scns;
+
+ for( scns = 0; scns < f_hdr.h_nscns; scns++ )
+ write_segment( new, &stbl[scns] );
+
+ return 0;
+}
+
+write_segment( new, sptr )
+int new;
+struct scnhdr *sptr;
+{
+ register char *ptr, *end;
+ register int nwrite, ret;
+ char buf[80];
+ extern int errno;
+ char zeros[128];
+
+ if( sptr->s_scnptr == 0 )
+ return; /* Nothing to do */
+
+ if( lseek( new, (long) sptr->s_scnptr, 0 ) == -1 )
+ PERROR( "unexecing" );
+
+ bzero (zeros, sizeof zeros);
+
+ ptr = (char *) sptr->s_vaddr;
+ end = ptr + sptr->s_size;
+
+ while( ptr < end ) {
+
+ /* distance to next multiple of 128. */
+ nwrite = (((int) ptr + 128) & -128) - (int) ptr;
+ /* But not beyond specified end. */
+ if (nwrite > end - ptr) nwrite = end - ptr;
+ ret = write (new, ptr, nwrite);
+ /* If write gets a page fault, it means we reached
+ a gap between the old text segment and the old data segment.
+ This gap has probably been remapped into part of the text segment.
+ So write zeros for it. */
+ if (ret == -1 && errno == EFAULT)
+ write (new, zeros, nwrite);
+ else if (nwrite != ret) {
+ sprintf (buf,
+ "unexec write failure: addr 0x%x, fileno %d, size 0x%x, wrote 0x%x, errno %d",
+ ptr, new, nwrite, ret, errno);
+ PERROR (buf);
+ }
+ ptr += nwrite;
+ }
+}
+
+/* ****************************************************************
+ * copy_sym
+ *
+ * Copy the relocation information and symbol table from the a.out to the new
+ */
+static int
+copy_sym (new, a_out, a_name, new_name)
+ int new, a_out;
+ char *a_name, *new_name;
+{
+ char page[1024];
+ int n;
+
+ if (a_out < 0)
+ return 0;
+
+ if (SYMS_START == 0L)
+ return 0;
+
+ lseek (a_out, SYMS_START, 0); /* Position a.out to symtab. */
+ lseek( new, (long)f_ohdr.o_symptr, 0 );
+
+ while ((n = read (a_out, page, sizeof page)) > 0) {
+ if (write (new, page, n) != n) {
+ PERROR (new_name);
+ }
+ }
+ if (n < 0) {
+ PERROR (a_name);
+ }
+ return 0;
+}
+
+/* ****************************************************************
+ * mark_x
+ *
+ * After succesfully building the new a.out, mark it executable
+ */
+static
+mark_x (name)
+char *name;
+{
+ struct stat sbuf;
+ int um;
+ int new = 0; /* for PERROR */
+
+ um = umask (777);
+ umask (um);
+ if (stat (name, &sbuf) == -1) {
+ PERROR (name);
+ }
+ sbuf.st_mode |= 0111 & ~um;
+ if (chmod (name, sbuf.st_mode) == -1)
+ PERROR (name);
+}
+
+/* Find the first pty letter. This is usually 'p', as in ptyp0, but
+ is sometimes configured down to 'm', 'n', or 'o' for some reason. */
+
+first_pty_letter ()
+{
+ struct stat buf;
+ char pty_name[16];
+ char c;
+
+ for (c = 'o'; c >= 'a'; c--)
+ {
+ sprintf (pty_name, "/dev/pty%c0", c);
+ if (stat (pty_name, &buf) < 0)
+ return c + 1;
+ }
+ return 'a';
+}
+
diff --git a/src/unexelf.c b/src/unexelf.c
new file mode 100644
index 00000000000..784fab1e7ff
--- /dev/null
+++ b/src/unexelf.c
@@ -0,0 +1,703 @@
+/* Copyright (C) 1985, 1986, 1987, 1988 Free Software Foundation, Inc.
+
+ NO WARRANTY
+
+ BECAUSE THIS PROGRAM IS LICENSED FREE OF CHARGE, WE PROVIDE ABSOLUTELY
+NO WARRANTY, TO THE EXTENT PERMITTED BY APPLICABLE STATE LAW. EXCEPT
+WHEN OTHERWISE STATED IN WRITING, FREE SOFTWARE FOUNDATION, INC,
+RICHARD M. STALLMAN AND/OR OTHER PARTIES PROVIDE THIS PROGRAM "AS IS"
+WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY
+AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE
+DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR
+CORRECTION.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW WILL RICHARD M.
+STALLMAN, THE FREE SOFTWARE FOUNDATION, INC., AND/OR ANY OTHER PARTY
+WHO MAY MODIFY AND REDISTRIBUTE THIS PROGRAM AS PERMITTED BELOW, BE
+LIABLE TO YOU FOR DAMAGES, INCLUDING ANY LOST PROFITS, LOST MONIES, OR
+OTHER SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR
+DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY THIRD PARTIES OR
+A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS) THIS
+PROGRAM, EVEN IF YOU HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY.
+
+ GENERAL PUBLIC LICENSE TO COPY
+
+ 1. You may copy and distribute verbatim copies of this source file
+as you receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy a valid copyright notice "Copyright
+(C) 1987 Free Software Foundation, Inc."; and include following the
+copyright notice a verbatim copy of the above disclaimer of warranty
+and of this License. You may charge a distribution fee for the
+physical act of transferring a copy.
+
+ 2. You may modify your copy or copies of this source file or
+any portion of it, and copy and distribute such modifications under
+the terms of Paragraph 1 above, provided that you also do the following:
+
+ a) cause the modified files to carry prominent notices stating
+ that you changed the files and the date of any change; and
+
+ b) cause the whole of any work that you distribute or publish,
+ that in whole or in part contains or is a derivative of this
+ program or any part thereof, to be licensed at no charge to all
+ third parties on terms identical to those contained in this
+ License Agreement (except that you may choose to grant more extensive
+ warranty protection to some or all third parties, at your option).
+
+ c) You may charge a distribution fee for the physical act of
+ transferring a copy, and you may at your option offer warranty
+ protection in exchange for a fee.
+
+Mere aggregation of another unrelated program with this program (or its
+derivative) on a volume of a storage or distribution medium does not bring
+the other program under the scope of these terms.
+
+ 3. You may copy and distribute this program (or a portion or derivative
+of it, under Paragraph 2) in object code or executable form under the terms
+of Paragraphs 1 and 2 above provided that you also do one of the following:
+
+ a) accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of
+ Paragraphs 1 and 2 above; or,
+
+ b) accompany it with a written offer, valid for at least three
+ years, to give any third party free (except for a nominal
+ shipping charge) a complete machine-readable copy of the
+ corresponding source code, to be distributed under the terms of
+ Paragraphs 1 and 2 above; or,
+
+ c) accompany it with the information you received as to where the
+ corresponding source code may be obtained. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form alone.)
+
+For an executable file, complete source code means all the source code for
+all modules it contains; but, as a special exception, it need not include
+source code for modules which are standard libraries that accompany the
+operating system on which the executable file runs.
+
+ 4. You may not copy, sublicense, distribute or transfer this program
+except as expressly provided under this License Agreement. Any attempt
+otherwise to copy, sublicense, distribute or transfer this program is void and
+your rights to use the program under this License agreement shall be
+automatically terminated. However, parties who have received computer
+software programs from you with this License Agreement will not have
+their licenses terminated so long as such parties remain in full compliance.
+
+ 5. If you wish to incorporate parts of this program into other free
+programs whose distribution conditions are different, write to the Free
+Software Foundation at 675 Mass Ave, Cambridge, MA 02139. We have not yet
+worked out a simple rule that can be stated here, but we will often permit
+this. We will be guided by the two goals of preserving the free status of
+all derivatives of our free software and of promoting the sharing and reuse of
+software.
+
+
+In other words, you are welcome to use, share and improve this program.
+You are forbidden to forbid anyone else to use, share and improve
+what you give them. Help stamp out software-hoarding! */
+
+
+/*
+ * unexec.c - Convert a running program into an a.out file.
+ *
+ * Author: Spencer W. Thomas
+ * Computer Science Dept.
+ * University of Utah
+ * Date: Tue Mar 2 1982
+ * Modified heavily since then.
+ *
+ * Synopsis:
+ * unexec (new_name, a_name, data_start, bss_start, entry_address)
+ * char *new_name, *a_name;
+ * unsigned data_start, bss_start, entry_address;
+ *
+ * Takes a snapshot of the program and makes an a.out format file in the
+ * file named by the string argument new_name.
+ * If a_name is non-NULL, the symbol table will be taken from the given file.
+ * On some machines, an existing a_name file is required.
+ *
+ * The boundaries within the a.out file may be adjusted with the data_start
+ * and bss_start arguments. Either or both may be given as 0 for defaults.
+ *
+ * Data_start gives the boundary between the text segment and the data
+ * segment of the program. The text segment can contain shared, read-only
+ * program code and literal data, while the data segment is always unshared
+ * and unprotected. Data_start gives the lowest unprotected address.
+ * The value you specify may be rounded down to a suitable boundary
+ * as required by the machine you are using.
+ *
+ * Specifying zero for data_start means the boundary between text and data
+ * should not be the same as when the program was loaded.
+ * If NO_REMAP is defined, the argument data_start is ignored and the
+ * segment boundaries are never changed.
+ *
+ * Bss_start indicates how much of the data segment is to be saved in the
+ * a.out file and restored when the program is executed. It gives the lowest
+ * unsaved address, and is rounded up to a page boundary. The default when 0
+ * is given assumes that the entire data segment is to be stored, including
+ * the previous data and bss as well as any additional storage allocated with
+ * break (2).
+ *
+ * The new file is set up to start at entry_address.
+ *
+ * If you make improvements I'd like to get them too.
+ * harpo!utah-cs!thomas, thomas@Utah-20
+ *
+ */
+
+/* Even more heavily modified by james@bigtex.cactus.org of Dell Computer Co.
+ * ELF support added.
+ *
+ * Basic theory: the data space of the running process needs to be
+ * dumped to the output file. Normally we would just enlarge the size
+ * of .data, scooting everything down. But we can't do that in ELF,
+ * because there is often something between the .data space and the
+ * .bss space.
+ *
+ * In the temacs dump below, notice that the Global Offset Table
+ * (.got) and the Dynamic link data (.dynamic) come between .data1 and
+ * .bss. It does not work to overlap .data with these fields.
+ *
+ * The solution is to create a new .data segment. This segment is
+ * filled with data from the current process. Since the contents of
+ * various sections refer to sections by index, the new .data segment
+ * is made the last in the table to avoid changing any existing index.
+
+ * This is an example of how the section headers are changed. "Addr"
+ * is a process virtual address. "Offset" is a file offset.
+
+raid:/nfs/raid/src/dist-18.56/src> dump -h temacs
+
+temacs:
+
+ **** SECTION HEADER TABLE ****
+[No] Type Flags Addr Offset Size Name
+ Link Info Adralgn Entsize
+
+[1] 1 2 0x80480d4 0xd4 0x13 .interp
+ 0 0 0x1 0
+
+[2] 5 2 0x80480e8 0xe8 0x388 .hash
+ 3 0 0x4 0x4
+
+[3] 11 2 0x8048470 0x470 0x7f0 .dynsym
+ 4 1 0x4 0x10
+
+[4] 3 2 0x8048c60 0xc60 0x3ad .dynstr
+ 0 0 0x1 0
+
+[5] 9 2 0x8049010 0x1010 0x338 .rel.plt
+ 3 7 0x4 0x8
+
+[6] 1 6 0x8049348 0x1348 0x3 .init
+ 0 0 0x4 0
+
+[7] 1 6 0x804934c 0x134c 0x680 .plt
+ 0 0 0x4 0x4
+
+[8] 1 6 0x80499cc 0x19cc 0x3c56f .text
+ 0 0 0x4 0
+
+[9] 1 6 0x8085f3c 0x3df3c 0x3 .fini
+ 0 0 0x4 0
+
+[10] 1 2 0x8085f40 0x3df40 0x69c .rodata
+ 0 0 0x4 0
+
+[11] 1 2 0x80865dc 0x3e5dc 0xd51 .rodata1
+ 0 0 0x4 0
+
+[12] 1 3 0x8088330 0x3f330 0x20afc .data
+ 0 0 0x4 0
+
+[13] 1 3 0x80a8e2c 0x5fe2c 0x89d .data1
+ 0 0 0x4 0
+
+[14] 1 3 0x80a96cc 0x606cc 0x1a8 .got
+ 0 0 0x4 0x4
+
+[15] 6 3 0x80a9874 0x60874 0x80 .dynamic
+ 4 0 0x4 0x8
+
+[16] 8 3 0x80a98f4 0x608f4 0x449c .bss
+ 0 0 0x4 0
+
+[17] 2 0 0 0x608f4 0x9b90 .symtab
+ 18 371 0x4 0x10
+
+[18] 3 0 0 0x6a484 0x8526 .strtab
+ 0 0 0x1 0
+
+[19] 3 0 0 0x729aa 0x93 .shstrtab
+ 0 0 0x1 0
+
+[20] 1 0 0 0x72a3d 0x68b7 .comment
+ 0 0 0x1 0
+
+raid:/nfs/raid/src/dist-18.56/src> dump -h xemacs
+
+xemacs:
+
+ **** SECTION HEADER TABLE ****
+[No] Type Flags Addr Offset Size Name
+ Link Info Adralgn Entsize
+
+[1] 1 2 0x80480d4 0xd4 0x13 .interp
+ 0 0 0x1 0
+
+[2] 5 2 0x80480e8 0xe8 0x388 .hash
+ 3 0 0x4 0x4
+
+[3] 11 2 0x8048470 0x470 0x7f0 .dynsym
+ 4 1 0x4 0x10
+
+[4] 3 2 0x8048c60 0xc60 0x3ad .dynstr
+ 0 0 0x1 0
+
+[5] 9 2 0x8049010 0x1010 0x338 .rel.plt
+ 3 7 0x4 0x8
+
+[6] 1 6 0x8049348 0x1348 0x3 .init
+ 0 0 0x4 0
+
+[7] 1 6 0x804934c 0x134c 0x680 .plt
+ 0 0 0x4 0x4
+
+[8] 1 6 0x80499cc 0x19cc 0x3c56f .text
+ 0 0 0x4 0
+
+[9] 1 6 0x8085f3c 0x3df3c 0x3 .fini
+ 0 0 0x4 0
+
+[10] 1 2 0x8085f40 0x3df40 0x69c .rodata
+ 0 0 0x4 0
+
+[11] 1 2 0x80865dc 0x3e5dc 0xd51 .rodata1
+ 0 0 0x4 0
+
+[12] 1 3 0x8088330 0x3f330 0x20afc .data
+ 0 0 0x4 0
+
+[13] 1 3 0x80a8e2c 0x5fe2c 0x89d .data1
+ 0 0 0x4 0
+
+[14] 1 3 0x80a96cc 0x606cc 0x1a8 .got
+ 0 0 0x4 0x4
+
+[15] 6 3 0x80a9874 0x60874 0x80 .dynamic
+ 4 0 0x4 0x8
+
+[16] 8 3 0x80c6800 0x7d800 0 .bss
+ 0 0 0x4 0
+
+[17] 2 0 0 0x7d800 0x9b90 .symtab
+ 18 371 0x4 0x10
+
+[18] 3 0 0 0x87390 0x8526 .strtab
+ 0 0 0x1 0
+
+[19] 3 0 0 0x8f8b6 0x93 .shstrtab
+ 0 0 0x1 0
+
+[20] 1 0 0 0x8f949 0x68b7 .comment
+ 0 0 0x1 0
+
+[21] 1 3 0x80a98f4 0x608f4 0x1cf0c .data
+ 0 0 0x4 0
+
+ * This is an example of how the file header is changed. "Shoff" is
+ * the section header offset within the file. Since that table is
+ * after the new .data section, it is moved. "Shnum" is the number of
+ * sections, which we increment.
+ *
+ * "Phoff" is the file offset to the program header. "Phentsize" and
+ * "Shentsz" are the program and section header entries sizes respectively.
+ * These can be larger than the apparent struct sizes.
+
+raid:/nfs/raid/src/dist-18.56/src> dump -f temacs
+
+temacs:
+
+ **** ELF HEADER ****
+Class Data Type Machine Version
+Entry Phoff Shoff Flags Ehsize
+Phentsize Phnum Shentsz Shnum Shstrndx
+
+1 1 2 3 1
+0x80499cc 0x34 0x792f4 0 0x34
+0x20 5 0x28 21 19
+
+raid:/nfs/raid/src/dist-18.56/src> dump -f xemacs
+
+xemacs:
+
+ **** ELF HEADER ****
+Class Data Type Machine Version
+Entry Phoff Shoff Flags Ehsize
+Phentsize Phnum Shentsz Shnum Shstrndx
+
+1 1 2 3 1
+0x80499cc 0x34 0x96200 0 0x34
+0x20 5 0x28 22 19
+
+ * These are the program headers. "Offset" is the file offset to the
+ * segment. "Vaddr" is the memory load address. "Filesz" is the
+ * segment size as it appears in the file, and "Memsz" is the size in
+ * memory. Below, the third segment is the code and the fourth is the
+ * data: the difference between Filesz and Memsz is .bss
+
+raid:/nfs/raid/src/dist-18.56/src> dump -o temacs
+
+temacs:
+ ***** PROGRAM EXECUTION HEADER *****
+Type Offset Vaddr Paddr
+Filesz Memsz Flags Align
+
+6 0x34 0x8048034 0
+0xa0 0xa0 5 0
+
+3 0xd4 0 0
+0x13 0 4 0
+
+1 0x34 0x8048034 0
+0x3f2f9 0x3f2f9 5 0x1000
+
+1 0x3f330 0x8088330 0
+0x215c4 0x25a60 7 0x1000
+
+2 0x60874 0x80a9874 0
+0x80 0 7 0
+
+raid:/nfs/raid/src/dist-18.56/src> dump -o xemacs
+
+xemacs:
+ ***** PROGRAM EXECUTION HEADER *****
+Type Offset Vaddr Paddr
+Filesz Memsz Flags Align
+
+6 0x34 0x8048034 0
+0xa0 0xa0 5 0
+
+3 0xd4 0 0
+0x13 0 4 0
+
+1 0x34 0x8048034 0
+0x3f2f9 0x3f2f9 5 0x1000
+
+1 0x3f330 0x8088330 0
+0x3e4d0 0x3e4d0 7 0x1000
+
+2 0x60874 0x80a9874 0
+0x80 0 7 0
+
+
+ */
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <sys/stat.h>
+#include <memory.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <elf.h>
+#include <sys/mman.h>
+
+#ifndef emacs
+#define fatal(a, b, c) fprintf(stderr, a, b, c), exit(1)
+#else
+extern void fatal(char *, ...);
+#endif
+
+/* Get the address of a particular section or program header entry,
+ * accounting for the size of the entries.
+ */
+
+#define OLD_SECTION_H(n) \
+ (*(Elf32_Shdr *) ((byte *) old_section_h + old_file_h->e_shentsize * (n)))
+#define NEW_SECTION_H(n) \
+ (*(Elf32_Shdr *) ((byte *) new_section_h + new_file_h->e_shentsize * (n)))
+#define OLD_PROGRAM_H(n) \
+ (*(Elf32_Phdr *) ((byte *) old_program_h + old_file_h->e_phentsize * (n)))
+#define NEW_PROGRAM_H(n) \
+ (*(Elf32_Phdr *) ((byte *) new_program_h + new_file_h->e_phentsize * (n)))
+
+typedef unsigned char byte;
+
+/* ****************************************************************
+ * unexec
+ *
+ * driving logic.
+ *
+ * In ELF, this works by replacing the old .bss section with a new
+ * .data section, and inserting an empty .bss immediately afterwards.
+ *
+ */
+void
+unexec (new_name, old_name, data_start, bss_start, entry_address)
+ char *new_name, *old_name;
+ unsigned data_start, bss_start, entry_address;
+{
+ extern unsigned int bss_end;
+ int new_file, old_file, new_file_size;
+
+ /* Pointers to the base of the image of the two files. */
+ caddr_t old_base, new_base;
+
+ /* Pointers to the file, program and section headers for the old and new
+ * files.
+ */
+ Elf32_Ehdr *old_file_h, *new_file_h;
+ Elf32_Phdr *old_program_h, *new_program_h;
+ Elf32_Shdr *old_section_h, *new_section_h;
+
+ /* Point to the section name table in the old file */
+ char *old_section_names;
+
+ Elf32_Addr old_bss_addr, new_bss_addr;
+ Elf32_Word old_bss_size, new_data2_size;
+ Elf32_Off new_data2_offset;
+ Elf32_Addr new_data2_addr;
+
+ int n, old_bss_index, old_data_index, new_data2_index;
+ struct stat stat_buf;
+
+ /* Open the old file & map it into the address space. */
+
+ old_file = open (old_name, O_RDONLY);
+
+ if (old_file < 0)
+ fatal ("Can't open %s for reading: errno %d\n", old_name, errno);
+
+ if (fstat (old_file, &stat_buf) == -1)
+ fatal ("Can't fstat(%s): errno %d\n", old_name, errno);
+
+ old_base = mmap (0, stat_buf.st_size, PROT_READ, MAP_SHARED, old_file, 0);
+
+ if (old_base == (caddr_t) -1)
+ fatal ("Can't mmap(%s): errno %d\n", old_name, errno);
+
+#ifdef DEBUG
+ fprintf (stderr, "mmap(%s, %x) -> %x\n", old_name, stat_buf.st_size,
+ old_base);
+#endif
+
+ /* Get pointers to headers & section names */
+
+ old_file_h = (Elf32_Ehdr *) old_base;
+ old_program_h = (Elf32_Phdr *) ((byte *) old_base + old_file_h->e_phoff);
+ old_section_h = (Elf32_Shdr *) ((byte *) old_base + old_file_h->e_shoff);
+ old_section_names = (char *) old_base
+ + OLD_SECTION_H(old_file_h->e_shstrndx).sh_offset;
+
+ /* Find the old .bss section. Figure out parameters of the new
+ * data2 and bss sections.
+ */
+
+ for (old_bss_index = 1; old_bss_index < old_file_h->e_shnum; old_bss_index++)
+ {
+#ifdef DEBUG
+ fprintf (stderr, "Looking for .bss - found %s\n",
+ old_section_names + OLD_SECTION_H(old_bss_index).sh_name);
+#endif
+ if (!strcmp (old_section_names + OLD_SECTION_H(old_bss_index).sh_name,
+ ".bss"))
+ break;
+ }
+ if (old_bss_index == old_file_h->e_shnum)
+ fatal ("Can't find .bss in %s.\n", old_name, 0);
+
+ old_bss_addr = OLD_SECTION_H(old_bss_index).sh_addr;
+ old_bss_size = OLD_SECTION_H(old_bss_index).sh_size;
+#if defined(emacs) || !defined(DEBUG)
+ bss_end = (unsigned int) sbrk (0);
+ new_bss_addr = (Elf32_Addr) bss_end;
+#else
+ new_bss_addr = old_bss_addr + old_bss_size + 0x1234;
+#endif
+ new_data2_addr = old_bss_addr;
+ new_data2_size = new_bss_addr - old_bss_addr;
+ new_data2_offset = OLD_SECTION_H(old_bss_index).sh_offset;
+
+#ifdef DEBUG
+ fprintf (stderr, "old_bss_index %d\n", old_bss_index);
+ fprintf (stderr, "old_bss_addr %x\n", old_bss_addr);
+ fprintf (stderr, "old_bss_size %x\n", old_bss_size);
+ fprintf (stderr, "new_bss_addr %x\n", new_bss_addr);
+ fprintf (stderr, "new_data2_addr %x\n", new_data2_addr);
+ fprintf (stderr, "new_data2_size %x\n", new_data2_size);
+ fprintf (stderr, "new_data2_offset %x\n", new_data2_offset);
+#endif
+
+ if ((unsigned) new_bss_addr < (unsigned) old_bss_addr + old_bss_size)
+ fatal (".bss shrank when undumping???\n", 0, 0);
+
+ /* Set the output file to the right size and mmap(2) it. Set
+ * pointers to various interesting objects. stat_buf still has
+ * old_file data.
+ */
+
+ new_file = open (new_name, O_RDWR | O_CREAT, 0666);
+ if (new_file < 0)
+ fatal ("Can't creat(%s): errno %d\n", new_name, errno);
+
+ new_file_size = stat_buf.st_size + old_file_h->e_shentsize + new_data2_size;
+
+ if (ftruncate (new_file, new_file_size))
+ fatal ("Can't ftruncate(%s): errno %d\n", new_name, errno);
+
+ new_base = mmap (0, new_file_size, PROT_READ | PROT_WRITE, MAP_SHARED,
+ new_file, 0);
+
+ if (new_base == (caddr_t) -1)
+ fatal ("Can't mmap(%s): errno %d\n", new_name, errno);
+
+ new_file_h = (Elf32_Ehdr *) new_base;
+ new_program_h = (Elf32_Phdr *) ((byte *) new_base + old_file_h->e_phoff);
+ new_section_h = (Elf32_Shdr *)
+ ((byte *) new_base + old_file_h->e_shoff + new_data2_size);
+
+ /* Make our new file, program and section headers as copies of the
+ * originals.
+ */
+
+ memcpy (new_file_h, old_file_h, old_file_h->e_ehsize);
+ memcpy (new_program_h, old_program_h,
+ old_file_h->e_phnum * old_file_h->e_phentsize);
+ memcpy (new_section_h, old_section_h,
+ old_file_h->e_shnum * old_file_h->e_shentsize);
+
+ /* Fix up file header. We'll add one section. Section header is
+ * further away now.
+ */
+
+ new_file_h->e_shoff += new_data2_size;
+ new_file_h->e_shnum += 1;
+
+#ifdef DEBUG
+ fprintf (stderr, "Old section offset %x\n", old_file_h->e_shoff);
+ fprintf (stderr, "Old section count %d\n", old_file_h->e_shnum);
+ fprintf (stderr, "New section offset %x\n", new_file_h->e_shoff);
+ fprintf (stderr, "New section count %d\n", new_file_h->e_shnum);
+#endif
+
+ /* Fix up a new program header. Extend the writable data segment so
+ * that the bss area is covered too. Find that segment by looking
+ * for a segment that ends just before the .bss area. Make sure
+ * that no segments are above the new .data2. Put a loop at the end
+ * to adjust the offset and address of any segment that is above
+ * data2, just in case we decide to allow this later.
+ */
+
+ for (n = new_file_h->e_phnum - 1; n >= 0; n--)
+ {
+ if (NEW_PROGRAM_H(n).p_vaddr + NEW_PROGRAM_H(n).p_filesz > old_bss_addr)
+ fatal ("Program segment above .bss in %s\n", old_name, 0);
+
+ if (NEW_PROGRAM_H(n).p_type == PT_LOAD
+ && (NEW_PROGRAM_H(n).p_vaddr + NEW_PROGRAM_H(n).p_filesz
+ == old_bss_addr))
+ break;
+ }
+ if (n < 0)
+ fatal ("Couldn't find segment next to .bss in %s\n", old_name, 0);
+
+ NEW_PROGRAM_H(n).p_filesz += new_data2_size;
+ NEW_PROGRAM_H(n).p_memsz = NEW_PROGRAM_H(n).p_filesz;
+
+#if 0 /* Maybe allow section after data2 - does this ever happen? */
+ for (n = new_file_h->e_phnum - 1; n >= 0; n--)
+ {
+ if (NEW_PROGRAM_H(n).p_vaddr
+ && NEW_PROGRAM_H(n).p_vaddr >= new_data2_addr)
+ NEW_PROGRAM_H(n).p_vaddr += new_data2_size - old_bss_size;
+
+ if (NEW_PROGRAM_H(n).p_offset >= new_data2_offset)
+ NEW_PROGRAM_H(n).p_offset += new_data2_size;
+ }
+#endif
+
+ /* Fix up section headers based on new .data2 section. Any section
+ * whose offset or virtual address is after the new .data2 section
+ * gets its value adjusted. .bss size becomes zero and new address
+ * is set. data2 section header gets added by copying the existing
+ * .data header and modifying the offset, address and size.
+ */
+
+ for (n = 1; n < new_file_h->e_shnum; n++)
+ {
+ if (NEW_SECTION_H(n).sh_offset >= new_data2_offset)
+ NEW_SECTION_H(n).sh_offset += new_data2_size;
+
+ if (NEW_SECTION_H(n).sh_addr
+ && NEW_SECTION_H(n).sh_addr >= new_data2_addr)
+ NEW_SECTION_H(n).sh_addr += new_data2_size - old_bss_size;
+ }
+
+ new_data2_index = old_file_h->e_shnum;
+
+ for (old_data_index = 1; old_data_index < old_file_h->e_shnum;
+ old_data_index++)
+ if (!strcmp (old_section_names + OLD_SECTION_H(old_data_index).sh_name,
+ ".data"))
+ break;
+ if (old_data_index == old_file_h->e_shnum)
+ fatal ("Can't find .data in %s.\n", old_name, 0);
+
+ memcpy (&NEW_SECTION_H(new_data2_index), &OLD_SECTION_H(old_data_index),
+ new_file_h->e_shentsize);
+
+ NEW_SECTION_H(new_data2_index).sh_addr = new_data2_addr;
+ NEW_SECTION_H(new_data2_index).sh_offset = new_data2_offset;
+ NEW_SECTION_H(new_data2_index).sh_size = new_data2_size;
+
+ NEW_SECTION_H(old_bss_index).sh_size = 0;
+ NEW_SECTION_H(old_bss_index).sh_addr = new_data2_addr + new_data2_size;
+
+ /* Write out the sections. .data and .data1 (and data2, called
+ * ".data" in the strings table) get copied from the current process
+ * instead of the old file.
+ */
+
+ for (n = new_file_h->e_shnum - 1; n; n--)
+ {
+ caddr_t src;
+
+ if (NEW_SECTION_H(n).sh_type == SHT_NULL
+ || NEW_SECTION_H(n).sh_type == SHT_NOBITS)
+ continue;
+
+ if (!strcmp (old_section_names + NEW_SECTION_H(n).sh_name, ".data")
+ || !strcmp ((old_section_names + NEW_SECTION_H(n).sh_name),
+ ".data1"))
+ src = (caddr_t) NEW_SECTION_H(n).sh_addr;
+ else
+ src = old_base + OLD_SECTION_H(n).sh_offset;
+
+ memcpy (NEW_SECTION_H(n).sh_offset + new_base, src,
+ NEW_SECTION_H(n).sh_size);
+ }
+
+ /* Close the files and make the new file executable */
+
+ if (close (old_file))
+ fatal ("Can't close(%s): errno %d\n", old_name, errno);
+
+ if (close (new_file))
+ fatal ("Can't close(%s): errno %d\n", new_name, errno);
+
+ if (stat (new_name, &stat_buf) == -1)
+ fatal ("Can't stat(%s): errno %d\n", new_name, errno);
+
+ n = umask (777);
+ umask (n);
+ stat_buf.st_mode |= 0111 & ~n;
+ if (chmod (new_name, stat_buf.st_mode) == -1)
+ fatal ("Can't chmod(%s): errno %d\n", new_name, errno);
+}
diff --git a/src/unexenix.c b/src/unexenix.c
new file mode 100644
index 00000000000..ea6cd7d5c20
--- /dev/null
+++ b/src/unexenix.c
@@ -0,0 +1,262 @@
+/* Unexec for Xenix.
+ Note that the GNU project considers support for Xenix operation
+ a peripheral activity which should not be allowed to divert effort
+ from development of the GNU system. Changes in this code will be
+ installed when Xenix users send them in, but aside from that
+ we don't plan to think about it, or about whether other Emacs
+ maintenance might break it.
+
+ Copyright (C) 1988 Free Software Foundation, Inc.
+
+This file is part of GNU Emacs.
+
+GNU Emacs is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GNU Emacs is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Emacs; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+
+
+/*
+ On 80386 Xenix, segmentation screws prevent us from modifying the text
+ segment at all. We basically just plug a new value for "data segment
+ size" into the countless headers and copy the other records straight
+ through. The data segment is ORG'ed at the xs_rbase value of the data
+ segment's xseg record (always @ 0x1880000, thanks to the "sophisticated
+ memory management hardware" of the chip) and extends to sbrk(0), exactly.
+ This code is afraid to malloc (should it be?), and alloca has to be the
+ wimpy, malloc-based version; consequently, data is usually copied in
+ smallish chunks.
+
+ gb@entity.com
+*/
+
+#include "config.h"
+#include <sys/types.h>
+#include <fcntl.h>
+#include <sys/file.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#include <varargs.h>
+#include <a.out.h>
+
+static void fatal_unexec ();
+
+#define READ(_fd, _buffer, _size, _error_message, _error_arg) \
+ errno = EEOF; \
+ if (read(_fd, _buffer, _size) != _size) \
+ fatal_unexec(_error_message, _error_arg);
+
+#define WRITE(_fd, _buffer, _size, _error_message, _error_arg) \
+ if (write(_fd, _buffer, _size) != _size) \
+ fatal_unexec(_error_message, _error_arg);
+
+#define SEEK(_fd, _position, _error_message, _error_arg) \
+ errno = EEOF; \
+ if (lseek(_fd, _position, L_SET) != _position) \
+ fatal_unexec(_error_message, _error_arg);
+
+extern int errno;
+extern int sys_nerr;
+extern char *sys_errlist[];
+#define EEOF -1
+
+#ifndef L_SET
+#define L_SET 0
+#endif
+
+/* Should check the magic number of the old executable;
+ not yet written. */
+check_exec (x)
+ struct xexec *x;
+{
+}
+
+
+unexec (new_name, a_name, data_start, bss_start, entry_address)
+ char *new_name, *a_name;
+ unsigned data_start, bss_start, entry_address;
+{
+ char *sbrk (), *datalim = sbrk (0), *data_org;
+ long segpos, textseen, textpos, textlen, datapos, datadiff, datalen;
+
+ struct xexec u_xexec, /* a.out header */
+ *u_xexecp = &u_xexec;
+ struct xext u_xext, /* extended header */
+ *u_xextp = &u_xext;
+ struct xseg u_xseg, /* segment table entry */
+ *u_xsegp = &u_xseg;
+ int i, nsegs, isdata = 0, infd, outfd;
+
+ infd = open (a_name, O_RDONLY, 0);
+ if (infd < 0) fatal_unexec ("opening %s", a_name);
+
+ outfd = creat (new_name, 0666);
+ if (outfd < 0) fatal_unexec ("creating %s", new_name);
+
+ READ (infd, u_xexecp, sizeof (struct xexec),
+ "error reading %s", a_name);
+ check_exec (u_xexecp);
+ READ (infd, u_xextp, sizeof (struct xext),
+ "error reading %s", a_name);
+ segpos = u_xextp->xe_segpos;
+ nsegs = u_xextp->xe_segsize / sizeof (struct xseg);
+ SEEK (infd, segpos, "seek error on %s", a_name);
+ for (i = 0; i < nsegs; i ++)
+ {
+ READ (infd, u_xsegp, sizeof (struct xseg),
+ "error reading %s", a_name);
+ switch (u_xsegp->xs_type)
+ {
+ case XS_TTEXT:
+ {
+ if (i == 0)
+ {
+ textpos = u_xsegp->xs_filpos;
+ textlen = u_xsegp->xs_psize;
+ break;
+ }
+ fatal_unexec ("invalid text segment in %s", a_name);
+ }
+ case XS_TDATA:
+ {
+ if (i == 1)
+ {
+ datapos = u_xsegp->xs_filpos;
+ datalen = datalim - (data_org = (char *)(u_xsegp->xs_rbase));
+ datadiff = datalen - u_xsegp->xs_psize;
+ break;
+ }
+ fatal_unexec ("invalid data segment in %s", a_name);
+ }
+ default:
+ {
+ if (i > 1) break;
+ fatal_unexec ("invalid segment record in %s", a_name);
+ }
+ }
+ }
+ u_xexecp->x_data = datalen;
+ u_xexecp->x_bss = 0;
+ WRITE (outfd, u_xexecp, sizeof (struct xexec),
+ "error writing %s", new_name);
+ WRITE (outfd, u_xextp, sizeof (struct xext),
+ "error writing %s", new_name);
+ SEEK (infd, segpos, "seek error on %s", a_name);
+ SEEK (outfd, segpos, "seek error on %s", new_name);
+
+ /* Copy the text segment record verbatim. */
+
+ copyrec (infd, outfd, sizeof (struct xseg), a_name, new_name);
+
+ /* Read, modify, write the data segment record. */
+
+ READ (infd, u_xsegp, sizeof (struct xseg),
+ "error reading %s", a_name);
+ u_xsegp->xs_psize = u_xsegp->xs_vsize = datalen;
+ u_xsegp->xs_attr &= (~XS_AITER & ~XS_ABSS);
+ WRITE (outfd, u_xsegp, sizeof (struct xseg),
+ "error writing %s", new_name);
+
+ /* Now copy any additional segment records, adjusting their
+ file position field */
+
+ for (i = 2; i < nsegs; i++)
+ {
+ READ (infd, u_xsegp, sizeof (struct xseg),
+ "error reading %s", a_name);
+ u_xsegp->xs_filpos += datadiff;
+ WRITE (outfd, u_xsegp, sizeof (struct xseg),
+ "error writing %s", new_name);
+ }
+
+ SEEK (infd, textpos, "seek error on %s", a_name);
+ SEEK (outfd, textpos, "seek error on %s", new_name);
+ copyrec (infd, outfd, textlen, a_name, new_name);
+
+ SEEK (outfd, datapos, "seek error on %s", new_name);
+ WRITE (outfd, data_org, datalen,
+ "write error on %s", new_name);
+
+ for (i = 2, segpos += (2 * sizeof (struct xseg));
+ i < nsegs;
+ i++, segpos += sizeof (struct xseg))
+ {
+ SEEK (infd, segpos, "seek error on %s", a_name);
+ READ (infd, u_xsegp, sizeof (struct xseg),
+ "read error on %s", a_name);
+ SEEK (infd, u_xsegp->xs_filpos, "seek error on %s", a_name);
+ /* We should be at eof in the output file here, but we must seek
+ because the xs_filpos and xs_psize fields in symbol table
+ segments are inconsistent. */
+ SEEK (outfd, u_xsegp->xs_filpos + datadiff, "seek error on %s", new_name);
+ copyrec (infd, outfd, u_xsegp->xs_psize, a_name, new_name);
+ }
+ close (infd);
+ close (outfd);
+ mark_x (new_name);
+ return 0;
+}
+
+copyrec (infd, outfd, len, in_name, out_name)
+ int infd, outfd, len;
+ char *in_name, *out_name;
+{
+ char buf[BUFSIZ];
+ int chunk;
+
+ while (len)
+ {
+ chunk = BUFSIZ;
+ if (chunk > len)
+ chunk = len;
+ READ (infd, buf, chunk, "error reading %s", in_name);
+ WRITE (outfd, buf, chunk, "error writing %s", out_name);
+ len -= chunk;
+ }
+}
+
+/*
+ * mark_x
+ *
+ * After succesfully building the new a.out, mark it executable
+ */
+static
+mark_x (name)
+ char *name;
+{
+ struct stat sbuf;
+ int um = umask (777);
+ umask (um);
+ if (stat (name, &sbuf) < 0)
+ fatal_unexec ("getting protection on %s", name);
+ sbuf.st_mode |= 0111 & ~um;
+ if (chmod (name, sbuf.st_mode) < 0)
+ fatal_unexec ("setting protection on %s", name);
+}
+
+static void
+fatal_unexec (s, va_alist)
+ va_dcl
+{
+ va_list ap;
+ if (errno == EEOF)
+ fputs ("unexec: unexpected end of file, ", stderr);
+ else if (errno < sys_nerr)
+ fprintf (stderr, "unexec: %s, ", sys_errlist[errno]);
+ else
+ fprintf (stderr, "unexec: error code %d, ", errno);
+ va_start (ap);
+ _doprnt (s, ap, stderr);
+ fputs (".\n", stderr);
+ exit (1);
+}
diff --git a/src/unexhp9k800.c b/src/unexhp9k800.c
index 259b9318514..8d34a3a3d7a 100644
--- a/src/unexhp9k800.c
+++ b/src/unexhp9k800.c
@@ -60,6 +60,7 @@ unexec(new_name, old_name, new_end_of_text, dummy1, dummy2)
int old_size, new_size;
struct header hdr;
struct som_exec_auxhdr auxhdr;
+ long i;
/* For the greatest flexibility, should create a temporary file in
the same directory as the new file. When everything is complete,
@@ -81,7 +82,10 @@ unexec(new_name, old_name, new_end_of_text, dummy1, dummy2)
/* Decide how large the new and old data areas are */
old_size = auxhdr.exec_dsize;
- new_size = sbrk(0) - auxhdr.exec_dmem;
+ /* I suspect these two statements are separate
+ to avoid a compiler bug in hpux version 8. */
+ i = sbrk (0);
+ new_size = i - auxhdr.exec_dmem;
/* Copy the old file to the new, up to the data space */
lseek(old, 0, 0);
diff --git a/src/vlimit.h b/src/vlimit.h
new file mode 100644
index 00000000000..c347dc74df6
--- /dev/null
+++ b/src/vlimit.h
@@ -0,0 +1,2 @@
+/* Dummy for Emacs so that we can run on VMS... */
+#define LIM_DATA 0
diff --git a/src/vms-pp.c b/src/vms-pp.c
index fdfcd9c46a1..2ff47d10daf 100644
--- a/src/vms-pp.c
+++ b/src/vms-pp.c
@@ -16,7 +16,7 @@ GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Emacs; see the file COPYING. If not, write to
-the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
* Usage:
diff --git a/src/vms-pwd.h b/src/vms-pwd.h
new file mode 100644
index 00000000000..6c29197a47a
--- /dev/null
+++ b/src/vms-pwd.h
@@ -0,0 +1,34 @@
+/* GNU Emacs password definition file.
+ Copyright (C) 1986 Free Software Foundation.
+
+This file is part of GNU Emacs.
+
+GNU Emacs is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GNU Emacs is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Emacs; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#ifdef VMS
+/* On VMS, we read the UAF file and emulate some of the necessary
+ fields for Emacs. */
+#include "uaf.h"
+
+struct passwd {
+ char pw_name[UAF$S_USERNAME+1];
+ char pw_passwd[UAF$S_PWD];
+ short pw_uid;
+ short pw_gid;
+ char pw_gecos[UAF$S_OWNER+1];
+ char pw_dir[UAF$S_DEFDEV+UAF$S_DEFDIR+1];
+ char pw_shell[UAF$S_DEFCLI+1];
+};
+#endif /* VMS */
diff --git a/src/vmsdir.h b/src/vmsdir.h
new file mode 100644
index 00000000000..7ea632db625
--- /dev/null
+++ b/src/vmsdir.h
@@ -0,0 +1,97 @@
+/* GNU Emacs VMS directory definition file.
+ Copyright (C) 1986 Free Software Foundation, Inc.
+
+This file is part of GNU Emacs.
+
+GNU Emacs is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GNU Emacs is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Emacs; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+/*
+ * Files-11 Ver. 2 directory structure (VMS V4.x - long names)
+ */
+#ifndef DIR$K_LENGTH
+
+#define DIR$C_FID 0
+#define DIR$C_LINKNAME 1
+#define DIR$K_LENGTH 6
+#define DIR$C_LENGTH 6
+#define DIR$S_DIRDEF 6
+#define DIR$W_SIZE 0
+#define DIR$W_VERLIMIT 2
+#define DIR$B_FLAGS 4
+#define DIR$S_TYPE 3
+#define DIR$V_TYPE 0
+#define DIR$V_NEXTREC 6
+#define DIR$V_PREVREC 7
+#define DIR$B_NAMECOUNT 5
+#define DIR$S_NAME 80
+#define DIR$T_NAME 6
+
+#define DIR$K_VERSION 8
+#define DIR$C_VERSION 8
+#define DIR$S_DIRDEF1 8
+#define DIR$W_VERSION 0
+#define DIR$S_FID 6
+#define DIR$W_FID 2
+#define DIR$W_FID_NUM 2
+#define DIR$W_FID_SEQ 4
+#define DIR$W_FID_RVN 6
+#define DIR$B_FID_RVN 6
+#define DIR$B_FID_NMX 7
+
+#define DIR$S_DIRDEF2 1
+#define DIR$T_LINKNAME 0
+
+typedef struct dir$_name {
+/* short dir$w_size; /* if you read with RMS, it eats this... */
+ short dir$w_verlimit; /* maximum number of versions */
+ union {
+ unsigned char dir_b_flags;
+#define dir$b_flags dir__b_flags.dir_b_flags
+ struct {
+ unsigned char dir_v_type: DIR$S_TYPE;
+#define dir$v_type dir__b_flags.dir___b_flags.dir_v_type
+ unsigned char: 3;
+ unsigned char dir_v_nextrec: 1;
+#define dir$v_nextrec dir__b_flags.dir___b_flags.dir_v_nextrec
+ unsigned char dir_v_prevrec: 1;
+#define dir$v_prevrec dir__b_flags.dir___b_flags.dir_v_prevrec
+ } dir___b_flags;
+ } dir__b_flags;
+ unsigned char dir$b_namecount;
+ char dir$t_name[];
+} dir$_dirdef; /* only the fixed first part */
+
+typedef struct dir$_version {
+ short dir$w_version;
+ short dir$w_fid_num;
+ short dir$w_fid_seq;
+ union {
+ short dir_w_fid_rvn;
+#define dir$w_fid_rvn dir__w_fid_rvn.dir_w_fid_rvn
+ struct {
+ char dir_b_fid_rvn;
+#define dir$b_fid_rvn dir__w_fid_rvn.dir___w_fid_rvn.dir_b_fid_rvn
+ char dir_b_fid_nmx;
+#define dir$b_fid_nmx dir__w_fid_rvn.dir___w_fid_rvn.dir_b_fid_nmx
+ } dir___w_fid_rvn;
+ } dir__w_fid_rvn;
+} dir$_dirdef1; /* one for each version of the file */
+
+typedef
+struct dir$_linkname {
+ char dir$t_linkname[];
+} dir$_dirdef2;
+
+#endif
diff --git a/src/vmsfns.c b/src/vmsfns.c
index 512ab21679a..0885fb694d0 100644
--- a/src/vmsfns.c
+++ b/src/vmsfns.c
@@ -310,7 +310,7 @@ DEFUN ("spawn-subprocess", Fspawn_subprocess, Sspawn_subprocess, 1, 3, 0,
prev->next = next;
else
process_list = next;
- if (! NULL (ptr->exit_handler))
+ if (! NILP (ptr->exit_handler))
Feval (Fcons (ptr->exit_handler, Fcons (make_number (ptr->name),
Qnil)));
sys$dassgn (ptr->mbx_chan);
@@ -327,7 +327,7 @@ DEFUN ("spawn-subprocess", Fspawn_subprocess, Sspawn_subprocess, 1, 3, 0,
free (ptr);
return Qnil;
}
- if (NULL (input_handler))
+ if (NILP (input_handler))
input_handler = Qdefault_subproc_input_handler;
ptr->input_handler = input_handler;
ptr->exit_handler = exit_handler;
@@ -447,7 +447,7 @@ process_command_input ()
have_process_input = 0;
start_mbx_input ();
clear_waiting_for_input (); /* Otherwise Ctl-g will cause crash. JCB */
- if (! NULL (expr))
+ if (! NILP (expr))
Feval (expr);
}
@@ -471,7 +471,7 @@ process_exit ()
prev->next = next;
else
process_list = next;
- if (! NULL (ptr->exit_handler))
+ if (! NILP (ptr->exit_handler))
Feval (Fcons (ptr->exit_handler, Fcons (make_number (ptr->name),
Qnil)));
sys$dassgn (ptr->mbx_chan);
@@ -605,9 +605,9 @@ or nil depending upon whether the privilege is already enabled.")
}
if (! found)
error ("Unknown privilege name %s", XSTRING (priv)->data);
- if (NULL (getprv))
+ if (NILP (getprv))
{
- if (sys$setprv (NULL (value) ? 0 : 1, prvmask, 0, 0) == SS$_NORMAL)
+ if (sys$setprv (NILP (value) ? 0 : 1, prvmask, 0, 0) == SS$_NORMAL)
return Qt;
return Qnil;
}
@@ -679,7 +679,7 @@ translate_id (pid, owner)
char * p;
int prcnam[2];
- if (NULL (pid)
+ if (NILP (pid)
|| XTYPE (pid) == Lisp_String && XSTRING (pid)->size == 0
|| XTYPE (pid) == Lisp_Int && XFASTINT (pid) == 0)
{
diff --git a/src/vmsmap.c b/src/vmsmap.c
new file mode 100644
index 00000000000..aa135302858
--- /dev/null
+++ b/src/vmsmap.c
@@ -0,0 +1,224 @@
+/* VMS mapping of data and alloc arena for GNU Emacs.
+ Copyright (C) 1986, 1987 Free Software Foundation, Inc.
+
+ This file is part of GNU Emacs.
+
+GNU Emacs is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+GNU Emacs is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Emacs; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+/* Written by Mukesh Prasad. */
+
+#ifdef VMS
+
+#include "config.h"
+#include "lisp.h"
+#include <rab.h>
+#include <fab.h>
+#include <rmsdef.h>
+#include <secdef.h>
+
+/* RMS block size */
+#define BLOCKSIZE 512
+
+/* Maximum number of bytes to be written in one RMS write.
+ * Must be a multiple of BLOCKSIZE.
+ */
+#define MAXWRITE (BLOCKSIZE * 30)
+
+/* This funniness is to ensure that sdata occurs alphabetically BEFORE the
+ $DATA psect and that edata occurs after ALL Emacs psects. This is
+ because the VMS linker sorts all psects in a cluster alphabetically
+ during the linking, unless you use the cluster_psect command. Emacs
+ uses the cluster command to group all Emacs psects into one cluster;
+ this keeps the dumped data separate from any loaded libraries. */
+
+globaldef {"$D$ATA"} char sdata[512]; /* Start of saved data area */
+globaldef {"__DATA"} char edata[512]; /* End of saved data area */
+
+/* Structure to write into first block of map file.
+ */
+
+struct map_data
+{
+ char * sdata; /* Start of data area */
+ char * edata; /* End of data area */
+ int datablk; /* Block in file to map data area from/to */
+};
+
+static void fill_fab (), fill_rab ();
+static int write_data ();
+
+extern char *start_of_data ();
+extern int vms_out_initial; /* Defined in malloc.c */
+
+/* Maps in the data and alloc area from the map file.
+ */
+
+int
+mapin_data (name)
+ char * name;
+{
+ struct FAB fab;
+ struct RAB rab;
+ int status, size;
+ int inadr[2];
+ struct map_data map_data;
+
+ /* Open map file. */
+ fab = cc$rms_fab;
+ fab.fab$b_fac = FAB$M_BIO|FAB$M_GET;
+ fab.fab$l_fna = name;
+ fab.fab$b_fns = strlen (name);
+ status = sys$open (&fab);
+ if (status != RMS$_NORMAL)
+ {
+ printf ("Map file not available, running bare Emacs....\n");
+ return 0; /* Map file not available */
+ }
+ /* Connect the RAB block */
+ rab = cc$rms_rab;
+ rab.rab$l_fab = &fab;
+ rab.rab$b_rac = RAB$C_SEQ;
+ rab.rab$l_rop = RAB$M_BIO;
+ status = sys$connect (&rab);
+ if (status != RMS$_NORMAL)
+ lib$stop (status);
+ /* Read the header data */
+ rab.rab$l_ubf = &map_data;
+ rab.rab$w_usz = sizeof (map_data);
+ rab.rab$l_bkt = 0;
+ status = sys$read (&rab);
+ if (status != RMS$_NORMAL)
+ lib$stop (status);
+ status = sys$close (&fab);
+ if (status != RMS$_NORMAL)
+ lib$stop (status);
+ if (map_data.sdata != start_of_data ())
+ {
+ printf ("Start of data area has moved: cannot map in data.\n");
+ return 0;
+ }
+ if (map_data.edata != edata)
+ {
+ printf ("End of data area has moved: cannot map in data.\n");
+ return 0;
+ }
+ fab.fab$l_fop |= FAB$M_UFO;
+ status = sys$open (&fab);
+ if (status != RMS$_NORMAL)
+ lib$stop (status);
+ /* Map data area. */
+ inadr[0] = map_data.sdata;
+ inadr[1] = map_data.edata;
+ status = sys$crmpsc (inadr, 0, 0, SEC$M_CRF | SEC$M_WRT, 0, 0, 0,
+ fab.fab$l_stv, 0, map_data.datablk, 0, 0);
+ if (! (status & 1))
+ lib$stop (status);
+}
+
+/* Writes the data and alloc area to the map file.
+ */
+mapout_data (into)
+ char * into;
+{
+ struct FAB fab;
+ struct RAB rab;
+ int status;
+ struct map_data map_data;
+ int datasize, msize;
+
+ if (vms_out_initial)
+ {
+ error ("Out of initial allocation. Must rebuild emacs with more memory (VMS_ALLOCATION_SIZE).");
+ return 0;
+ }
+ map_data.sdata = start_of_data ();
+ map_data.edata = edata;
+ datasize = map_data.edata - map_data.sdata + 1;
+ map_data.datablk = 2 + (sizeof (map_data) + BLOCKSIZE - 1) / BLOCKSIZE;
+ /* Create map file. */
+ fab = cc$rms_fab;
+ fab.fab$b_fac = FAB$M_BIO|FAB$M_PUT;
+ fab.fab$l_fna = into;
+ fab.fab$b_fns = strlen (into);
+ fab.fab$l_fop = FAB$M_CBT;
+ fab.fab$b_org = FAB$C_SEQ;
+ fab.fab$b_rat = 0;
+ fab.fab$b_rfm = FAB$C_VAR;
+ fab.fab$l_alq = 1 + map_data.datablk +
+ ((datasize + BLOCKSIZE - 1) / BLOCKSIZE);
+ status = sys$create (&fab);
+ if (status != RMS$_NORMAL)
+ {
+ error ("Could not create map file");
+ return 0;
+ }
+ /* Connect the RAB block */
+ rab = cc$rms_rab;
+ rab.rab$l_fab = &fab;
+ rab.rab$b_rac = RAB$C_SEQ;
+ rab.rab$l_rop = RAB$M_BIO;
+ status = sys$connect (&rab);
+ if (status != RMS$_NORMAL)
+ {
+ error ("RMS connect to map file failed");
+ return 0;
+ }
+ /* Write the header */
+ rab.rab$l_rbf = &map_data;
+ rab.rab$w_rsz = sizeof (map_data);
+ status = sys$write (&rab);
+ if (status != RMS$_NORMAL)
+ {
+ error ("RMS write (header) to map file failed");
+ return 0;
+ }
+ if (! write_data (&rab, map_data.datablk, map_data.sdata, datasize))
+ return 0;
+ status = sys$close (&fab);
+ if (status != RMS$_NORMAL)
+ {
+ error ("RMS close on map file failed");
+ return 0;
+ }
+ return 1;
+}
+
+static int
+write_data (rab, firstblock, data, length)
+ struct RAB * rab;
+ char * data;
+{
+ int status;
+
+ rab->rab$l_bkt = firstblock;
+ while (length > 0)
+ {
+ rab->rab$l_rbf = data;
+ rab->rab$w_rsz = length > MAXWRITE ? MAXWRITE : length;
+ status = sys$write (rab, 0, 0);
+ if (status != RMS$_NORMAL)
+ {
+ error ("RMS write to map file failed");
+ return 0;
+ }
+ data = &data[MAXWRITE];
+ length -= MAXWRITE;
+ rab->rab$l_bkt = 0;
+ }
+ return 1;
+} /* write_data */
+
+#endif /* VMS */
+
diff --git a/src/vmspaths.h b/src/vmspaths.h
new file mode 100644
index 00000000000..ac16c07b0d0
--- /dev/null
+++ b/src/vmspaths.h
@@ -0,0 +1,15 @@
+/* the default search path for Lisp function "load" */
+#define PATH_LOADSEARCH "EMACS_LIBRARY:[LISP]"
+
+/* the extra search path for programs to invoke.
+ This is appended to whatever the PATH environment variable says. */
+#define PATH_EXEC "EMACS_LIBRARY:[ETC]"
+
+/* the name of the directory that contains lock files
+ with which we record what files are being modified in Emacs.
+ This directory should be writable by everyone. */
+#define PATH_LOCK "EMACS_LIBRARY:[LOCK]"
+
+/* the name of the file !!!SuperLock!!! in the directory
+ specified by PATH_LOCK. Yes, this is redundant. */
+#define PATH_SUPERLOCK "EMACS_LIBRARY:[LOCK]$$$SUPERLOCK$$$."
diff --git a/src/vmsproc.c b/src/vmsproc.c
index ec9678f78a4..fff0aec6d60 100644
--- a/src/vmsproc.c
+++ b/src/vmsproc.c
@@ -437,7 +437,7 @@ if you quit, the process is killed.")
CHECK_STRING (args[0], 0);
- if (nargs <= 1 || NULL (args[1]))
+ if (nargs <= 1 || NILP (args[1]))
args[1] = build_string ("NLA0:");
else
args[1] = Fexpand_file_name (args[1], current_buffer->directory);
@@ -589,12 +589,12 @@ if you quit, the process is killed.")
if (vs->iosb[0] & 1)
{
immediate_quit = 0;
- if (!NULL (buffer))
+ if (!NILP (buffer))
{
vs->iosb[1] = clean_vms_buffer (vs->inputBuffer, vs->iosb[1]);
InsCStr (vs->inputBuffer, vs->iosb[1]);
}
- if (!NULL (display) && INTERACTIVE)
+ if (!NILP (display) && INTERACTIVE)
redisplay_preserve_echo_area ();
immediate_quit = 1;
QUIT;
diff --git a/src/vmsproc.h b/src/vmsproc.h
new file mode 100644
index 00000000000..f6faddf6a3e
--- /dev/null
+++ b/src/vmsproc.h
@@ -0,0 +1,21 @@
+/*
+ Structure for storing VMS specific information for an EMACS process
+
+ We use the event flags 1-23 for processes, keyboard input and timer
+*/
+
+/*
+ Same as MAXDESC in process.c
+*/
+#define MAX_EVENT_FLAGS 23
+
+typedef struct {
+ char inputBuffer[1024];
+ short inputChan;
+ short outputChan;
+ short busy;
+ int pid;
+ int eventFlag;
+ int exitStatus;
+ short iosb[4];
+} VMS_PROC_STUFF;