Add :application-type parameter for save-lisp-and-die on Windows.
[sbcl.git] / src / runtime / save.c
index f9b6867..3795d2e 100644 (file)
@@ -79,7 +79,7 @@ write_bytes_to_file(FILE * file, char *addr, long bytes, int compression)
 {
     if (compression == COMPRESSION_LEVEL_NONE) {
         while (bytes > 0) {
-            long count = fwrite(addr, 1, bytes, file);
+            sword_t count = fwrite(addr, 1, bytes, file);
             if (count > 0) {
                 bytes -= count;
                 addr += count;
@@ -309,19 +309,19 @@ save_to_filehandle(FILE *file, char *filename, lispobj init_function,
 
 #ifdef LISP_FEATURE_GENCGC
     {
-        size_t size = (last_free_page*sizeof(long)+os_vm_page_size-1)
+        size_t size = (last_free_page*sizeof(sword_t)+os_vm_page_size-1)
             &~(os_vm_page_size-1);
         uword_t *data = calloc(size, 1);
         if (data) {
             uword_t word;
-            long offset;
+            sword_t offset;
             page_index_t i;
             for (i = 0; i < last_free_page; i++) {
                 /* Thanks to alignment requirements, the two low bits
                  * are always zero, so we can use them to store the
                  * allocation type -- region is always closed, so only
                  * the two low bits of allocation flags matter. */
-                word = page_table[i].region_start_offset;
+                word = page_table[i].scan_start_offset;
                 gc_assert((word & 0x03) == 0);
                 data[i] = word | (0x03 & page_table[i].allocated);
             }
@@ -435,11 +435,35 @@ lose:
 }
 
 boolean
-save_runtime_to_filehandle(FILE *output, void *runtime, size_t runtime_size)
+save_runtime_to_filehandle(FILE *output, void *runtime, size_t runtime_size,
+                           int application_type)
 {
     size_t padding;
     void *padbytes;
 
+#ifdef LISP_FEATURE_WIN32
+    {
+        PIMAGE_DOS_HEADER dos_header = (PIMAGE_DOS_HEADER)runtime;
+        PIMAGE_NT_HEADERS nt_header = (PIMAGE_NT_HEADERS)((char *)dos_header +
+                                                          dos_header->e_lfanew);
+
+        int sub_system;
+        switch (application_type) {
+        case 0:
+            sub_system = IMAGE_SUBSYSTEM_WINDOWS_CUI;
+            break;
+        case 1:
+            sub_system = IMAGE_SUBSYSTEM_WINDOWS_GUI;
+            break;
+        default:
+            fprintf(stderr, "Invalid application type %d\n", application_type);
+            return 0;
+        }
+
+        nt_header->OptionalHeader.Subsystem = sub_system;
+    }
+#endif
+
     if (runtime_size != fwrite(runtime, 1, runtime_size, output)) {
         perror("Error saving runtime");
         return 0;
@@ -498,7 +522,8 @@ prepare_to_save(char *filename, boolean prepend_runtime, void **runtime_bytes,
 
 boolean
 save(char *filename, lispobj init_function, boolean prepend_runtime,
-     boolean save_runtime_options, boolean compressed, int compression_level)
+     boolean save_runtime_options, boolean compressed, int compression_level,
+     int application_type)
 {
     FILE *file;
     void *runtime_bytes = NULL;
@@ -509,7 +534,7 @@ save(char *filename, lispobj init_function, boolean prepend_runtime,
         return 1;
 
     if (prepend_runtime)
-        save_runtime_to_filehandle(file, runtime_bytes, runtime_size);
+        save_runtime_to_filehandle(file, runtime_bytes, runtime_size, application_type);
 
     return save_to_filehandle(file, filename, init_function, prepend_runtime,
                               save_runtime_options,