2000-02-27  Mike Alexander  <mta@arbortext.com>

	* xemacs.rc: Include the portable dump data if INCLUDE_DUMP is defined

	* xemacs.mak: Add the portable dump data to the EXE as a resource

2000-02-27  Mike Alexander  <mta@arbortext.com>

	* sysdep.h: Declare pdump_read_file

	* sysdep.c (pdump_read_file): New function

	* alloc.c (pdump_load): Call pdump_read_file to get the portable
	dump data


Index: nt/xemacs.mak
===================================================================
RCS file: /usr/CVSroot/XEmacs/xemacs/nt/xemacs.mak,v
retrieving revision 1.41.2.41
diff -u -r1.41.2.41 xemacs.mak
--- nt/xemacs.mak	2000/02/07 20:53:56	1.41.2.41
+++ nt/xemacs.mak	2000/02/25 07:33:21
@@ -770,7 +771,7 @@
 TEMACS_LFLAGS=-nologo $(LIBRARIES) $(DEBUG_FLAGS) -base:0x1000000\
  -stack:0x800000 $(TEMACS_ENTRYPOINT) -subsystem:console\
  -pdb:$(TEMACS_DIR)\temacs.pdb -map:$(TEMACS_DIR)\temacs.map \
- -heap:0x00100000 -out:$@ -nodefaultlib
+ -heap:0x00100000 -nodefaultlib -incremental:no
 TEMACS_CPP_FLAGS=-c \
  $(CFLAGS) $(INCLUDES) $(DEFINES) $(DEBUG_DEFINES) \
  -DEMACS_MAJOR_VERSION=$(emacs_major_version) \
@@ -946,8 +947,7 @@
 	$(OUTDIR)\tparam.obj \
 	$(OUTDIR)\undo.obj \
 	$(OUTDIR)\widget.obj \
-	$(OUTDIR)\window.obj \
-	$(OUTDIR)\xemacs.res
+	$(OUTDIR)\window.obj
 
 # Rules
 
@@ -977,7 +977,7 @@
 #$(TEMACS_SRC)\paths.h: $(TEMACS_SRC)\paths.h.in
 #	!"cd $(TEMACS_SRC); cp paths.h.in paths.h"
 
-$(TEMACS): $(TEMACS_INCLUDES) $(TEMACS_OBJS)
+$(TEMACS): $(TEMACS_INCLUDES) $(TEMACS_OBJS) $(OUTDIR)\xemacs.res
 !if $(DEBUG_XEMACS)
 	@dir /b/s $(OUTDIR)\*.sbr > bscmake.tmp
 	bscmake -nologo -o$(TEMACS_BROWSE) @bscmake.tmp
@@ -985,10 +985,14 @@
 !endif
 !if $(USE_PORTABLE_DUMPER)
 	@if exist $(TEMACS_DIR)\xemacs.dmp del $(TEMACS_DIR)\xemacs.dmp
-!endif
+	link.exe @<<
+  $(TEMACS_LFLAGS) -out:$@ $(TEMACS_OBJS) $(TEMACS_LIBS)
+<<
+!else
 	link.exe @<<
-  $(TEMACS_LFLAGS) $(TEMACS_OBJS) $(TEMACS_LIBS)
+  $(TEMACS_LFLAGS) -out:$@ $(TEMACS_OBJS) $(OUTDIR)\xemacs.res $(TEMACS_LIBS)
 <<
+!endif
 
 $(OUTDIR)\xemacs.res: xemacs.rc
 	rc -Fo$@ xemacs.rc
@@ -1258,7 +1262,14 @@
 	set EMACSBOOTSTRAPMODULEPATH=$(MODULES)
 	-1 $(TEMACS) -batch -l $(TEMACS_DIR)\..\lisp\loadup.el dump
 !if $(USE_PORTABLE_DUMPER)
-	copy temacs.exe xemacs.exe
+	rc -d INCLUDE_DUMP -Fo $(OUTDIR)\xemacs.res $(NT)\xemacs.rc
+	link.exe @<<
+  $(TEMACS_LFLAGS) -out:xemacs.exe $(TEMACS_OBJS) $(OUTDIR)\xemacs.res $(TEMACS_LIBS)
+<<
+# Make the resource section read/write since almost all of it is the dump
+# data which needs to be writable.  This avoids having to copy it.
+	editbin -nologo -section:.rsrc,rw xemacs.exe
+	del $(TEMACS_DIR)\xemacs.dmp
 !endif
 	cd $(NT)
 	@if not exist $(TEMACS_DIR)\SATISFIED nmake -nologo -f xemacs.mak $@
@@ -1283,9 +1294,6 @@
 	@copy $(LIB_SRC)\DOC "$(INSTALL_DIR)\$(EMACS_CONFIGURATION)"
 	@copy $(CONFIG_VALUES) "$(INSTALL_DIR)\$(EMACS_CONFIGURATION)"
 	@copy $(XEMACS)\src\xemacs.exe "$(INSTALL_DIR)\$(EMACS_CONFIGURATION)"
-!if $(USE_PORTABLE_DUMPER)
-	@copy $(XEMACS)\src\xemacs.dmp "$(INSTALL_DIR)\$(EMACS_CONFIGURATION)"
-!endif
 	@copy $(RUNEMACS) "$(INSTALL_DIR)\$(EMACS_CONFIGURATION)"
 	@xcopy /e /q $(XEMACS)\etc  "$(INSTALL_DIR)\etc\"
 	@xcopy /e /q $(XEMACS)\info "$(INSTALL_DIR)\info\"
Index: nt/xemacs.rc
===================================================================
RCS file: /usr/CVSroot/XEmacs/xemacs/nt/xemacs.rc,v
retrieving revision 1.2
diff -u -r1.2 xemacs.rc
--- nt/xemacs.rc	1998/06/20 00:58:40	1.2
+++ nt/xemacs.rc	2000/02/25 07:33:21
@@ -1,3 +1,7 @@
+#ifdef INCLUDE_DUMP
+101    DUMP      "xemacs.dmp"
+#endif
+
 XEmacs icon preload "xemacs.ico"
 XEmacsFile icon "File.ico"
 XEmacsLisp icon "Lisp.ico"
Index: src/alloc.c
===================================================================
RCS file: /usr/CVSroot/XEmacs/xemacs/src/alloc.c,v
retrieving revision 1.42.2.51
diff -u -r1.42.2.51 alloc.c
--- src/alloc.c	2000/02/21 23:07:07	1.42.2.51
+++ src/alloc.c	2000/02/25 07:33:27
@@ -56,6 +56,7 @@
 #include "redisplay.h"
 #include "specifier.h"
 #include "sysfile.h"
+#include "sysdep.h"
 #include "window.h"
 #include "console-stream.h"
 
@@ -5057,27 +5058,8 @@
 
   pdump_start = pdump_end = 0;
 
-  pdump_fd = open ("xemacs.dmp", O_RDONLY | OPEN_BINARY);
-  if (pdump_fd<0)
+  if (pdump_read_file (&pdump_start, &length) == 0)
     return 0;
-
-  length = lseek (pdump_fd, 0, SEEK_END);
-  lseek (pdump_fd, 0, SEEK_SET);
-
-#ifdef HAVE_MMAP
-  pdump_start = (char *) mmap (0, length, PROT_READ|PROT_WRITE, MAP_PRIVATE, pdump_fd, 0);
-  if (pdump_start == MAP_FAILED)
-    pdump_start = 0;
-#endif
-
-  if (!pdump_start)
-    {
-      pdump_start = (char *)((((unsigned long)(xmalloc(length+255))) + 255) & ~255);
-      read (pdump_fd, pdump_start, length);
-    }
-
-  close (pdump_fd);
-
   pdump_end = pdump_start + length;
 
   staticidx = ((dump_header *)(pdump_start))->nb_staticpro;
Index: src/sysdep.c
===================================================================
RCS file: /usr/CVSroot/XEmacs/xemacs/src/sysdep.c,v
retrieving revision 1.32.2.25
diff -u -r1.32.2.25 sysdep.c
--- src/sysdep.c	2000/02/20 04:13:43	1.32.2.25
+++ src/sysdep.c	2000/02/25 07:33:32
@@ -4053,3 +4053,141 @@
   return (cm[*us1] - cm[*--us2]);
 }
 #endif /* !HAVE_STRCASECMP */
+
+
+#ifdef PDUMP
+
+/************************************************************************/
+/*                   Handle portable dump file                          */
+/************************************************************************/
+
+/* Read the PDUMP file.  This probably belongs in a separate fine, but
+   exactly where is still under discussion.  For now it's arguably better
+   here than in alloc.c.
+*/
+
+int pdump_read_file (char **pdump_start, size_t *pdump_length)
+{
+  int pdump_fd = -1;
+  size_t length = 0;
+  char *pd_start = 0;
+
+#ifdef WINDOWSNT
+
+  {
+    char *dump_path = NULL;
+    size_t path_size = 50;
+    DWORD path_len = 1000;
+    HANDLE hFile;
+    HANDLE hMap;
+    while (path_len >= path_size)
+      {
+        path_size = 2 * path_size;
+        dump_path = realloc (dump_path, path_size);
+        path_len = GetModuleFileName (NULL, dump_path, path_size);
+      }
+    if (path_len > 0
+        && strcmp (dump_path + path_len - 4, ".exe") == 0)
+      {
+        strcpy (dump_path + path_len - 4, ".dmp");
+      }
+    else
+      {
+	strcpy (dump_path, "xemacs.dmp");
+      }
+    hFile = CreateFile (dump_path, 
+			GENERIC_READ + GENERIC_WRITE,  /* Required for copy on write */
+			0,		    /* Not shared */
+			NULL,		    /* Not inheritable */
+			OPEN_EXISTING, 
+			FILE_ATTRIBUTE_NORMAL,
+			NULL);		    /* No template file */
+    if (hFile != INVALID_HANDLE_VALUE)
+      {
+	length = GetFileSize (hFile, NULL);
+	hMap = CreateFileMapping (hFile,
+				  NULL,		    /* No security attributes */
+				  PAGE_WRITECOPY,   /* Copy on write */
+				  0,		    /* Max size, high half */
+				  0,		    /* Max size, low half */
+				  NULL);	    /* Unnamed */
+	if (hMap != INVALID_HANDLE_VALUE)
+	  {
+	    pd_start = MapViewOfFile (hMap,
+				      FILE_MAP_COPY,  /* Copy on write */
+				      0,	      /* Start at zero */
+				      0,
+				      0);	      /* Map all of it */
+	  }
+      }
+    free (dump_path);
+  }
+
+  /* If we didn't find the dump file, look for a resource */
+  if (!pd_start)
+    {
+      HRSRC hRes;	      /* Handle to dump resource */
+      HRSRC hResLoad;	      /* Handle to loaded dump resource */
+
+      /* See Q126630 which describes how Windows NT and 95 trap writes to
+      resource sections and duplicate the page to allow the write to proceed.
+      It also describes how to make the resource section read/write (and hence
+      private to each process).  Doing this avoids the exceptions and related
+      overhead, but causes the resource section to be private to each process
+      that is running XEmacs.  Since the resource section contains little
+      other than the dumped data, which should be private to each process, we
+      make the whole resource section read/write so we don't have to copy it. */
+
+      hRes = FindResource (NULL, MAKEINTRESOURCE(101), "DUMP");
+      if (hRes != NULL)
+	{
+	  /* Found it, use the data in the resource */
+	  hResLoad = LoadResource (NULL, hRes);
+	  if (hResLoad != NULL)
+	    {
+	      pd_start = LockResource (hResLoad);
+	      if (pd_start != NULL)
+		{
+		  length = SizeofResource (NULL, hRes);
+		  if (length <= 0)
+		    length = 0;
+		}
+	    }
+	}
+    }
+
+#else  /* WINDOWSNT */
+
+  pdump_fd = open ("xemacs.dmp", O_RDONLY | OPEN_BINARY);
+  if (pdump_fd >= 0)
+    {
+      length = lseek (pdump_fd, 0, SEEK_END);
+      lseek (pdump_fd, 0, SEEK_SET);
+
+#ifdef HAVE_MMAP
+      pd_start = (char *) mmap (0, length, PROT_READ|PROT_WRITE, MAP_PRIVATE, pdump_fd, 0);
+      if (pd_start == MAP_FAILED)
+	pd_start = 0;
+#endif
+
+      if (!pd_start)
+	{
+	  pd_start = (char *)((((unsigned long)(xmalloc(length+255))) + 255) & ~255);
+	  read (pdump_fd, pd_start, length);
+	}
+
+      close (pdump_fd);
+    }
+
+#endif /* WINDOWSNT */
+
+  if (pd_start == 0)
+    /* Failed to find a dump */
+    return 0;
+
+  *pdump_start = pd_start;
+  *pdump_length = length;
+  return 1;
+}
+
+#endif /* PDUMP */
Index: src/sysdep.h
===================================================================
RCS file: /usr/CVSroot/XEmacs/xemacs/src/sysdep.h,v
retrieving revision 1.11.2.8
diff -u -r1.11.2.8 sysdep.h
--- src/sysdep.h	2000/02/16 02:07:26	1.11.2.8
+++ src/sysdep.h	2000/02/25 07:33:32
@@ -29,6 +29,10 @@
 extern char **environ;
 #endif
 
+#ifdef PDUMP
+int pdump_read_file (char **pdump_start, size_t *pdump_length);
+#endif
+
 int eight_bit_tty (struct device *d);
 
 void stuff_char (struct console *con, int c);
