nano-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Nano-devel] 1.1.6 Memory leaks . . . and fixes


From: Steven Kneizys
Subject: [Nano-devel] 1.1.6 Memory leaks . . . and fixes
Date: Sun, 17 Feb 2002 19:54:55 -0800 (PST)

I took my previous patch for 1.0.8 and applied it to the 1.1.6 source
tree as modified by recent CVS additions.  After getting that in, I
added a couple routines and features.  One was that I moved the
full_operating_dir to global.c so that it can be cleaned up.  

One feature I added was that if the -o switch is specified to restrict
the directory and a Control-R is entered, the status bar shows the
actual path specified instead of the './' it normally does.

I fixed a couple more leaks in search and path checking routines, and I
returned memory (using the new routines) for toggles and shortcuts. 
Int the previous patch I had a couple things the compiler complained
about, like calling the ret variable an in instead of a char *, got
them better this time.

take care,

Steve...

__________________________________________________
Do You Yahoo!?
Yahoo! Sports - Coverage of the 2002 Olympic Games
http://sports.yahoo.com
diff -u nano-1.1.6/files.c nano-1.1.6.new/files.c
--- nano-1.1.6/files.c  Sun Feb 17 19:03:38 2002
+++ nano-1.1.6.new/files.c      Sun Feb 17 22:02:29 2002
@@ -343,7 +343,17 @@
     currshortcut = insertfile_list;
 #endif
 
-    i = statusq(1, insertfile_list, "", _("File to insert [from ./] "));
+#ifndef DISABLE_OPERATINGDIR
+    if ((operating_dir) && (strcmp(operating_dir,"."))){
+       i = statusq(1, insertfile_list, "", _("File to insert [from %s] "),
+               operating_dir);
+    } else {
+#endif
+       i = statusq(1, insertfile_list, "", _("File to insert [from ./] "));
+#ifndef DISABLE_OPERATINGDIR
+    }
+#endif
+
     if (i != -1) {
 
 #ifdef DEBUG
@@ -365,19 +375,24 @@
 #endif
 
 #ifdef DISABLE_TABCOMP
+            if (realname != NULL) free(realname);
            realname = NULL;
 #endif
-           if  (tmp != NULL)
-               realname = mallocstrcpy(realname, tmp);
-           else
-               return do_insertfile(loading_file);
-       }
+           if (tmp != NULL) {
+               realname = mallocstrcpy(realname, tmp);
+               free(tmp);
+           } else {
+               if (realname != NULL) free(realname);
+               return do_insertfile(loading_file);
+           }
+       }
 #endif
 
 #ifndef DISABLE_OPERATINGDIR
        if (operating_dir) {
            if (check_operating_dir(realname, 0)) {
                statusbar(_("Can't insert file from outside of %s"), 
operating_dir);
+               if (realname != NULL) free(realname);
                return 0;
            }
        }
@@ -988,8 +1003,10 @@
                        strcat(d_there, "/");
                    }
                }
-               else
+               else {
+                   free(newpath);
                    return NULL;
+               }
            }
 
            /* finally, go back to where we were before, d_here (no error
@@ -1156,10 +1173,10 @@
  */
 int check_operating_dir(char *currpath, int allow_tabcomp)
 {
-    /* this is static so that we only need to get it the first time this
-       function is called; also, a relative operating directory path will
+    /* The char *full_operating_dir is global for mem cleanup, and
+       therefore we only need to get it the first time this function
+       is called; also, a relative operating directory path will
        only be handled properly if this is done */
-    static char *full_operating_dir = NULL;
 
     char *fullpath, *whereami1, *whereami2 = NULL;
 
@@ -1206,17 +1223,22 @@
        whereami2 = strstr(full_operating_dir, fullpath);
 
     /* if both searches failed, we're outside the operating directory */
-    if (!whereami1 && !whereami2)
+    if (!whereami1 && !whereami2) {
+       free(fullpath);
        return 1;
+    }
 
     /* check the search results; if the full operating directory path is
        not at the beginning of the full current path (for normal usage)
        and vice versa (for tab completion, if we're allowing it), we're
        outside the operating directory */
-    if (whereami1 != fullpath && whereami2 != full_operating_dir)
+    if (whereami1 != fullpath && whereami2 != full_operating_dir) {
+       free(fullpath);
        return 1;
+    }
 
     /* otherwise, we're still inside it */
+    free(fullpath);
     return 0;
 }
 #endif
@@ -1238,11 +1260,11 @@
 int write_file(char *name, int tmp, int append, int nonamechange)
 {
     long size, lineswritten = 0;
-    static char *buf = NULL;
+    char *buf = NULL;
     filestruct *fileptr;
     int fd, mask = 0, realexists, anyexists;
     struct stat st, lst;
-    static char *realname = NULL;
+    char *realname = NULL;
 
     if (!strcmp(name, "")) {
        statusbar(_("Cancelled"));
@@ -1251,12 +1273,6 @@
     titlebar(NULL);
     fileptr = fileage;
 
-    if (realname != NULL)
-       free(realname);
-
-    if (buf != NULL)
-       free(buf);
-
 #ifndef DISABLE_TABCOMP
     realname = real_dir_from_tilde(name);
 #else
@@ -1269,7 +1285,7 @@
           operating directory, so skip the operating directory test */
        if (check_operating_dir(realname, 0)) {
            statusbar(_("Can't write outside of %s"), operating_dir);
-
+           free(realname);
            return -1;
        }
     }
@@ -1282,8 +1298,13 @@
     anyexists = lstat(realname, &lst);
 
     /* New case: if the file exists, just give up */
-    if (tmp && anyexists != -1)
+    if (tmp && anyexists != -1) {
+       if (realname != NULL) 
+           free(realname);
+       if (buf != NULL)
+           free(buf);
        return -1;
+    }
     /* NOTE: If you change this statement, you MUST CHANGE the if 
        statement below (that says:
                if (realexists == -1 || tmp || (!ISSET(FOLLOW_SYMLINKS) &&
@@ -1301,6 +1322,10 @@
 
        /* First, just give up if we couldn't even open the file */
        if (fd == -1) {
+           if (realname != NULL) 
+               free(realname);
+           if (buf != NULL)
+               free(buf);
            if (!tmp && ISSET(TEMP_OPT)) {
                UNSET(TEMP_OPT);
                return do_writeout(filename, 1, 0);
@@ -1317,6 +1342,10 @@
        strncpy(buf, realname, strlen(realname)+1);
        strcat(buf, ".XXXXXX");
        if ((fd = mkstemp(buf)) == -1) {
+           if (realname != NULL) 
+               free(realname);
+           if (buf != NULL)
+               free(buf);
            if (ISSET(TEMP_OPT)) {
                UNSET(TEMP_OPT);
                return do_writeout(filename, 1, 0);
@@ -1337,6 +1366,10 @@
        if (size == -1) {
            statusbar(_("Could not open file for writing: %s"),
                      strerror(errno));
+           if (realname != NULL) 
+               free(realname);
+           if (buf != NULL)
+               free(buf);
            return -1;
        } else {
 #ifdef DEBUG
@@ -1360,6 +1393,10 @@
        if (size == -1) {
            statusbar(_("Could not open file for writing: %s"),
                      strerror(errno));
+           if (realname != NULL) 
+               free(realname);
+           if (buf != NULL)
+               free(buf);
            return -1;
        } else if (size > 0) {
 #ifndef NANO_SMALL
@@ -1369,6 +1406,10 @@
                if (size == -1) {
                    statusbar(_("Could not open file for writing: %s"),
                          strerror(errno));
+                   if (realname != NULL) 
+                       free(realname);
+                   if (buf != NULL)
+                       free(buf);
                    return -1;
                }
            }
@@ -1381,6 +1422,10 @@
                if (size == -1) {
                    statusbar(_("Could not open file for writing: %s"),
                          strerror(errno));
+                   if (realname != NULL) 
+                       free(realname);
+                   if (buf != NULL)
+                       free(buf);
                    return -1;
                }
            }
@@ -1391,6 +1436,10 @@
     if (close(fd) == -1) {
        statusbar(_("Could not close %s: %s"), realname, strerror(errno));
        unlink(buf);
+       if (realname != NULL) 
+           free(realname);
+       if (buf != NULL)
+           free(buf);
        return -1;
     }
 
@@ -1415,6 +1464,10 @@
                statusbar(_("Could not open %s for writing: %s"),
                          realname, strerror(errno));
                unlink(buf);
+               if (realname != NULL) 
+                   free(realname);
+               if (buf != NULL)
+                   free(buf);
                return -1;
            }
        }
@@ -1424,11 +1477,19 @@
            statusbar(_("Could not open %s for writing: %s"),
                      name, strerror(errno));
            unlink(buf);
+           if (realname != NULL) 
+               free(realname);
+           if (buf != NULL)
+               free(buf);
            return -1;
        } else if (rename(buf, realname) == -1) {       /* Try a rename?? */
            statusbar(_("Could not open %s for writing: %s"),
                      realname, strerror(errno));
            unlink(buf);
+           if (realname != NULL) 
+               free(realname);
+           if (buf != NULL)
+               free(buf);
            return -1;
        }
     }
@@ -1444,6 +1505,10 @@
        UNSET(MODIFIED);
        titlebar(NULL);
     }
+    if (realname != NULL) 
+       free(realname);
+    if (buf != NULL)
+       free(buf);
     return 1;
 }
 
@@ -2178,7 +2243,7 @@
 {
     int i;
 
-    for (i = 0; i < len - 1; i++)
+    for (i = 0; i < len; i++)
        free(array[i]);
     free(array);
 }
@@ -2217,7 +2282,10 @@
     if (tmp != foo)
        *tmp = 0;
     else
+    { /* SPK may need to make a 'default' path here */
+        if (*tmp != '/') *(tmp) = '.';
        *(tmp+1) = 0;
+    }
 
     return;
 }
@@ -2411,6 +2479,17 @@
            }
 #endif
 
+           /* SPK for '.' path, get the current path via getcwd */
+           if (!strcmp(path, "./..")) {
+               free(path);
+               path = getcwd(NULL, 0);
+               striponedir(path);                  
+               align(&path);
+               free_charptrarray(filelist, numents);
+               free(foo);
+               return do_browser(path);
+           }
+
            st = filestat(path);
            if (S_ISDIR(st.st_mode)) {
                if ((test_dir = opendir(path)) == NULL) {
@@ -2431,6 +2510,8 @@
                }
 
                /* Start over again with the new path value */
+               free_charptrarray(filelist, numents);
+               free(foo);
                return do_browser(path);
            } else {
                retval = path;
@@ -2465,7 +2546,7 @@
                char *saveanswer = NULL;
 
                saveanswer = mallocstrcpy(saveanswer, answer);
-               answer = realloc(answer, strlen(path) + strlen(saveanswer) + 2);
+               answer = nrealloc(answer, strlen(path) + strlen(saveanswer) + 
2);
                sprintf(answer, "%s/%s", path, saveanswer);
                free(saveanswer);
            }
@@ -2583,6 +2664,8 @@
     /* cleanup */
     free_charptrarray(filelist, numents);
     free(foo);
+    if (path != NULL) free(path);
+    path = NULL;
     return retval;
 }
 
@@ -2592,6 +2675,7 @@
 {
     struct stat st;
     char *tmp = NULL;
+    char *ret;
 
     tmp = mallocstrcpy(tmp, inpath);
 
@@ -2603,23 +2687,31 @@
 #else
        char *from = getcwd(NULL, 0);
 #endif /* PATH_MAX */
-       return do_browser(from ? from : "./");
+        if (tmp != NULL) free(tmp); 
+       ret = do_browser(from ? from : "./");
+        if (from != NULL) free(from); 
+       return ret;
     }
 
     /* If the string is a directory, pass do_browser that */
     st = filestat(tmp);
-    if (S_ISDIR(st.st_mode))
-       return do_browser(tmp);
+    if (S_ISDIR(st.st_mode)){
+       ret = do_browser(tmp);
+       free(tmp);
+       return ret;
+    }
 
     /* Okay, there's a dir in there, but not at the end of the string... 
        try stripping it off */
     striponedir(tmp);
     align(&tmp);
-    return do_browser(tmp);
-
+    ret = do_browser(tmp);
+    free(tmp);
+    return ret;
 }
 
 
 
 #endif
+
 
diff -u nano-1.1.6/global.c nano-1.1.6.new/global.c
--- nano-1.1.6/global.c Sun Feb 17 19:03:51 2002
+++ nano-1.1.6.new/global.c     Sun Feb 17 21:23:52 2002
@@ -76,8 +76,8 @@
 int mark_beginx;               /* X value in the string to start */
 
 #ifndef DISABLE_OPERATINGDIR
-char *operating_dir = NULL;    /* Operating directory, which we can't go
-                                  higher than */
+char *operating_dir = NULL;    /* Operating directory, which we can't */
+char *full_operating_dir = NULL;/* go higher than */
 #endif
 
 #ifndef DISABLE_SPELLER
@@ -87,7 +87,7 @@
 shortcut *main_list = NULL;
 shortcut *whereis_list = NULL;
 shortcut *replace_list = NULL;
-shortcut *replace_list_2;      /* 2nd half of replace dialog */
+shortcut *replace_list_2 = NULL;       /* 2nd half of replace dialog */
 shortcut *goto_list = NULL;
 shortcut *gotodir_list = NULL;
 shortcut *writefile_list = NULL;
@@ -654,4 +654,103 @@
 #endif
 
     toggle_init();
+}
+
+/* delete the structure */
+void free_shortcutage(shortcut **shortcutage)
+{
+    shortcut *s,*ps;
+
+    s = *shortcutage;
+    if (s == NULL) {
+       return;
+    } else {
+       s = *shortcutage;
+       do {
+               ps = s;
+               s = s->next; 
+               free(ps);
+       } while (s->next != NULL);
+       free(s);
+       *shortcutage == NULL;
+    }
+}
+
+#ifndef NANO_SMALL
+/* clear the toggles */
+void free_toggles(void)
+{
+    toggle *u,*lu;
+
+    if (toggles == NULL) {
+       return;
+    } else {
+       lu = NULL;
+       for (u = toggles; u->next != NULL; u = u->next) {
+               if (lu != NULL) free(lu);
+               lu = u;
+       }
+       if (lu != NULL) free(lu);
+       if (u != NULL) free(u);
+    }
+}
+#endif
+
+/* added by SPK for memory cleanup, gracefully return our malloc()s */
+int thanks_for_the_memories(void) 
+{
+    if (operating_dir != NULL)
+       free(operating_dir);
+    if (full_operating_dir != NULL)
+       free(full_operating_dir);
+    if (last_search != NULL)
+       free(last_search);
+    if (last_replace != NULL)
+       free(last_replace);
+    if (hblank != NULL)
+       free(hblank);
+    if (alt_speller != NULL)
+       free(alt_speller);
+    if (help_text != NULL)
+       free(help_text);
+    if (filename != NULL)
+       free(filename);
+    if (answer != NULL)
+       free(answer);
+#ifdef ENABLE_MULTIBUFFER
+    if (open_files != NULL){
+        while (open_files->next != NULL) {
+           open_files = open_files->next;
+           free_filestruct(open_files->prev);
+        }
+        free_filestruct(open_files);
+    }
+#endif
+#ifndef ENABLE_MULTIBUFFER
+    if (fileage != NULL)
+        free_filestruct(fileage);
+#endif
+    if (cutbuffer != NULL)
+        free_filestruct(cutbuffer);
+
+    free_shortcutage(&main_list);
+    free_shortcutage(&whereis_list);
+    free_shortcutage(&replace_list);
+    free_shortcutage(&replace_list_2);
+    free_shortcutage(&help_list);
+    free_shortcutage(&writefile_list);
+    free_shortcutage(&insertfile_list);
+    free_shortcutage(&spell_list);
+#ifndef DISABLE_BROWSER
+    free_shortcutage(&browser_list);
+#endif
+    free_shortcutage(&gotodir_list);
+    free_shortcutage(&goto_list);
+
+#ifndef NANO_SMALL
+    free_toggles();
+#endif
+
+    /* that is all for now */
+
 }
diff -u nano-1.1.6/nano.c nano-1.1.6.new/nano.c
--- nano-1.1.6/nano.c   Sun Feb 17 19:04:07 2002
+++ nano-1.1.6.new/nano.c       Sun Feb 17 20:49:42 2002
@@ -100,6 +100,8 @@
     /* Restore the old term settings */
     tcsetattr(0, TCSANOW, &oldterm);
 
+    thanks_for_the_memories();
+
     exit(sigage);
 }
 
@@ -3358,3 +3360,5 @@
     finish(0);
 
 }
+
+
diff -u nano-1.1.6/proto.h nano-1.1.6.new/proto.h
--- nano-1.1.6/proto.h  Sun Feb 17 19:17:30 2002
+++ nano-1.1.6.new/proto.h      Sun Feb 17 21:36:23 2002
@@ -47,6 +50,7 @@
 extern char *last_replace;
 #ifndef DISABLE_OPERATINGDIR
 extern char *operating_dir;
+extern char *full_operating_dir;
 #endif
 #ifndef DISABLE_SPELLER
 extern  char *alt_speller;
diff -u nano-1.1.6/search.c nano-1.1.6.new/search.c
--- nano-1.1.6/search.c Sun Feb 17 19:04:33 2002
+++ nano-1.1.6.new/search.c     Sun Feb 17 21:46:35 2002
@@ -151,6 +151,7 @@
        reset_cursor();
        free(backupstring);
        backupstring = NULL;
+       free(buf);
        return -1;
     } else 
     switch (i) {
@@ -191,22 +192,27 @@
                TOGGLE(t->flag);
 #endif
 
+       free(buf);
        return 1;
     case NANO_OTHERSEARCH_KEY:
        backupstring = mallocstrcpy(backupstring, answer);
+       free(buf);
        return -2;              /* Call the opposite search function */
     case NANO_FROMSEARCHTOGOTO_KEY:
        free(backupstring);
        backupstring = NULL;
        do_gotoline_void();
+       free(buf);
        return -3;
     default:
        do_early_abort();
        free(backupstring);
        backupstring = NULL;
+       free(buf);
        return -3;
     }
 
+    free(buf);
     return 0;
 }
 
@@ -711,7 +717,7 @@
     int i, numreplaced, beginx;
     filestruct *begin;
     char *prevanswer = NULL, *buf = NULL;
-
+    
     if (ISSET(VIEW_MODE)) {
        print_view_warning();
        replace_abort();
@@ -795,6 +801,8 @@
     edit_update(current, CENTER);
     print_replaced(numreplaced);
     replace_abort();
+    free(prevanswer);
+    if (buf != NULL) free(buf);
     return 1;
 }
 

reply via email to

[Prev in Thread] Current Thread [Next in Thread]