Partially sync files.el from XEmacs 21.5 for wildcard support.
[sxemacs] / src / dumper.c
index d035d7b..8e72ea4 100644 (file)
@@ -34,6 +34,9 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>. */
 #include <sys/mman.h>
 #endif
 
+/* For PATH_EXEC */
+#include <sxe-paths.h>
+
 #ifndef SEPCHAR
 #define SEPCHAR ':'
 #endif
@@ -554,9 +557,10 @@ pdump_register_object(Lisp_Object obj)
 
        if (imp->description) {
                int me = depth++;
-               if (me > 65536) {
+               if (me >= 65536) {
                        stderr_out("Backtrace overflow, loop ?\n");
                        abort();
+                       return;
                }
                backtrace[me].obj = objh;
                backtrace[me].position = 0;
@@ -586,19 +590,20 @@ pdump_register_struct(const void *data,
                if (me >= 65536) {
                        stderr_out("Backtrace overflow, loop ?\n");
                        abort();
+               } else {
+                       backtrace[me].obj = 0;
+                       backtrace[me].position = 0;
+                       backtrace[me].offset = 0;
+                       
+                       pdump_add_entry(pdump_get_entry_list(sdesc),
+                                       data, sdesc->size, count);
+                       for (i = 0; i < count; i++) {
+                               pdump_register_sub(
+                                       ((const char*)data) + sdesc->size * i,
+                                       sdesc->description, me);
+                       }
+                       --depth;
                }
-               backtrace[me].obj = 0;
-               backtrace[me].position = 0;
-               backtrace[me].offset = 0;
-
-               pdump_add_entry(pdump_get_entry_list(sdesc),
-                               data, sdesc->size, count);
-               for (i = 0; i < count; i++) {
-                       pdump_register_sub(
-                               ((const char*)data) + sdesc->size * i,
-                               sdesc->description, me);
-               }
-               --depth;
        }
 }
 
@@ -1070,38 +1075,40 @@ pdump(const char *dumpfile)
        pdump_fd = open(dumpfile,
                        O_WRONLY | O_CREAT | O_TRUNC | OPEN_BINARY, 0666);
        if ( pdump_fd < 0 ) {
-               stderr_out("Could not open dump file:");
-               stderr_out(dumpfile);
+               stderr_out("Could not open dump file: %s", dumpfile);
                abort();
-       }
-       pdump_out = fdopen(pdump_fd, "w");
-       if ( pdump_out < 0 ) {
-               stderr_out("Could not fdopen dump file");
-               abort();
-       }
+       } else {
+               pdump_out = fdopen(pdump_fd, "w");
+               if ( pdump_out < 0 ) {
+                       stderr_out("Could not fdopen dump file: %s %d",
+                                  dumpfile, pdump_fd);
+                       abort();
+               } else {
 
-       fwrite(&header, sizeof(header), 1, pdump_out);
-       PDUMP_ALIGN_OUTPUT(max_align_t);
+                       fwrite(&header, sizeof(header), 1, pdump_out);
+                       PDUMP_ALIGN_OUTPUT(max_align_t);
 
-       pdump_scan_by_alignment(pdump_dump_data);
+                       pdump_scan_by_alignment(pdump_dump_data);
 
-       fseek(pdump_out, header.stab_offset, SEEK_SET);
+                       fseek(pdump_out, header.stab_offset, SEEK_SET);
 
-       pdump_dump_root_struct_ptrs();
-       pdump_dump_opaques();
-       pdump_dump_rtables();
-       pdump_dump_root_objects();
+                       pdump_dump_root_struct_ptrs();
+                       pdump_dump_opaques();
+                       pdump_dump_rtables();
+                       pdump_dump_root_objects();
 
-       fclose(pdump_out);
-       close(pdump_fd);
+                       fclose(pdump_out);
+                       close(pdump_fd);
 
-       xfree(pdump_buf);
+                       xfree(pdump_buf);
 
-       xfree(pdump_hash);
+                       xfree(pdump_hash);
 
-       Vterminal_console = t_console;
-       Vterminal_frame = t_frame;
-       Vterminal_device = t_device;
+                       Vterminal_console = t_console;
+                       Vterminal_frame = t_frame;
+                       Vterminal_device = t_device;
+               }
+       }
 }
 
 static int pdump_load_check(void)
@@ -1262,57 +1269,26 @@ static int pdump_file_get(const char *path)
        return 1;
 }
 
-static int pdump_file_try(char *exe_path, size_t size)
+static int
+pdump_file_try(char *exe_path, size_t size)
 {
-        char *w = exe_path + strlen(exe_path);
-        size -= strlen(exe_path);
-
-       do {
-
-#ifdef EMACS_PATCH_LEVEL
-               snprintf(w, size, "-%d.%d.%d-%08x.dmp", 
-                         EMACS_MAJOR_VERSION, EMACS_MINOR_VERSION,
-                         EMACS_PATCH_LEVEL, dump_id);
+       static const char pdump_ext[] = ".dmp";
+       size_t exe_path_len = strlen(exe_path);
+       char *w = exe_path + exe_path_len;
+
+       if (exe_path_len + sizeof(pdump_ext) <= size) {
+               /* just hammer the pdump extension onto w */
+               memcpy(w, pdump_ext, sizeof(pdump_ext));
+               /* exists? */
                if (pdump_file_get(exe_path)) {
+                       /* works? */
                        if (pdump_load_check()) {
                                return 1;
                        }
+                       /* bugger */
                        pdump_free();
                }
-#endif /* EMACS_PATCH_LEVEL */
-#ifdef EMACS_BETA_VERSION
-               snprintf(w, size, "-%d.%d.%d-%08x.dmp", 
-                         EMACS_MAJOR_VERSION, EMACS_MINOR_VERSION,
-                         EMACS_BETA_VERSION, dump_id);
-               if (pdump_file_get(exe_path)) {
-                       if (pdump_load_check()) {
-                               return 1;
-                       }
-                       pdump_free();
-               }
-#endif /* EMACS_BETA_VERSION */
-
-               snprintf(w, size, "-%08x.dmp", dump_id);
-               if (pdump_file_get(exe_path)) {
-                       if (pdump_load_check()) {
-                               return 1;
-                       }
-                       pdump_free();
-               }
-
-               snprintf(w, size, ".dmp");
-               if (pdump_file_get(exe_path)) {
-                       if (pdump_load_check()) {
-                               return 1;
-                       }
-                       pdump_free();
-               }
-
-               do {
-                       w--;
-               } while (w > exe_path && !IS_DIRECTORY_SEP(*w) && (*w != '-')
-                        && (*w != '.'));
-       } while (w > exe_path && !IS_DIRECTORY_SEP(*w));
+       }
        return 0;
 }
 
@@ -1351,6 +1327,7 @@ wipe_out_libtool_stuff(char *path)
 int pdump_load(const char *argv0)
 {
        char exe_path[PATH_MAX], real_exe_path[PATH_MAX];
+       char libarchdir_path[PATH_MAX] = PATH_EXEC "/sxemacs";
        char *w;
        const char *dir, *p;
 
@@ -1369,8 +1346,8 @@ int pdump_load(const char *argv0)
        if (p != dir) {
                /* invocation-name includes a directory component -- presumably it
                   is relative to cwd, not $PATH */
-                assert(strlen(dir) < sizeof(exe_path));
-                strncpy(exe_path, dir, sizeof(exe_path)-1);
+               assert(strlen(dir) < sizeof(exe_path));
+               xstrncpy(exe_path, dir, sizeof(exe_path));
                exe_path[sizeof(exe_path)-1]='\0';
        } else {
                const char *path = getenv("PATH");
@@ -1378,8 +1355,8 @@ int pdump_load(const char *argv0)
 
                assert(path != NULL);
                for (;;) {
-                        int remain = sizeof(exe_path)-1;
-                        exe_path[remain] = '\0';
+                       int remain = sizeof(exe_path)-1;
+                       exe_path[remain] = '\0';
 
                        p = path;
                        while (*p && *p != SEPCHAR) {
@@ -1388,23 +1365,22 @@ int pdump_load(const char *argv0)
                        if (p == path) {
                                exe_path[0] = '.';
                                w = exe_path + 1;
-                                --remain;
+                               --remain;
                        } else {
-                                size_t len = (p - path) <= remain
-                                           ? (p-path) 
-                                           : remain;
+                               size_t len = (p - path) <= remain
+                                          ? (p-path)
+                                          : remain;
                                memcpy(exe_path, path, len);
                                w = exe_path + len;
-                                remain -= len;
+                               remain -= len;
                        }
                        if (!IS_DIRECTORY_SEP(w[-1]) && (remain > 0) ) {
                                *w++ = '/';
-                                remain--;
+                               remain--;
+                       }
+                       if (remain > 0) {
+                               xstrncpy(w, name, remain);
                        }
-                        if (remain > 0) {
-                                strncpy(w, name, remain);
-                                w[remain]='\0';
-                        }
 
                        /* Check that exe_path is executable and not a
                         * directory */
@@ -1420,8 +1396,9 @@ int pdump_load(const char *argv0)
 
                        if (!*p) {
                                /* Oh well, let's have some kind of default */
-                               snprintf(exe_path, sizeof(exe_path),
-                                        "./%s", name);
+                               int sz = snprintf(exe_path, sizeof(exe_path),
+                                                 "./%s", name);
+                               assert(sz >= 0 && (size_t)sz < sizeof(exe_path));
                                break;
                        }
                        path = p + 1;
@@ -1435,11 +1412,12 @@ int pdump_load(const char *argv0)
 #endif
 
        /* Save exe_path because pdump_file_try() modifies it */
-        assert(strlen(exe_path) < sizeof(real_exe_path));
-        strcpy(real_exe_path, exe_path);
-        if (pdump_file_try(exe_path,sizeof(exe_path))
+       assert(strlen(exe_path) < sizeof(real_exe_path));
+       xstrncpy(real_exe_path, exe_path, sizeof(real_exe_path));
+       if (pdump_file_try(exe_path,sizeof(exe_path))
            || (xrealpath(real_exe_path, real_exe_path)
-               && pdump_file_try(real_exe_path,sizeof(real_exe_path)))) {
+               && pdump_file_try(real_exe_path,sizeof(real_exe_path)))
+           || pdump_file_try(libarchdir_path,sizeof(libarchdir_path)) ) {
                pdump_load_finish();
                return 1;
        }