bug-readline
[Top][All Lists]
Advanced

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

[Bug-readline] Add the rl_free(void *buff) function to the readline libr


From: Borut Razem
Subject: [Bug-readline] Add the rl_free(void *buff) function to the readline library
Date: Wed, 01 Nov 2006 12:47:38 +0100

I suggest to add the rl_free(void *buff) function to the readline library.

The function rl_free() should be used instead of free() to deallocate the buffer returned by readline(), the buffer passed as the parameter to lhandler function installed by rl_callback_handler_install() and buffers allocated by readline library functions (history_expand(), remove_history(), ...)

Rationale:

It is always recommended to free the memory by the same module that allocated it. This fact becomes more evident when the module is dynamically linked: the main program and the shared library may use different memory allocation libraries, which might be problematic if the memory is allocated by the shared library and deallocated by the main program.

I came across this problem when dynamically linking readline.dll, generated by mingw gcc compiler, from the main program compiled with Visual Studio .NET: the memory allocation is done by msvcrt.dll called from readline.dll, while the deallocation is done by msvcr80.dll (or the statically linked equivalent) called from the main program, which seems to be incompatible.

I attached the patch which adds the rl_free() function to readline library and changes free() to rl_free() in examples directory. The documentation in doc directory should be updated accordingly.

I'm the developer and maintainer of WIN32 port on sdcc http://sdcc.sourceforge.net/ and gpsimWin32 http://gpsim.sourceforge.net/gpsimWin32/gpsimWin32.html projects, both using the readline library. The WIN32 port of readline 5.1 library is available at http://gpsim.sourceforge.net/gpsimWin32/packages/.

P.S.: The http://directory.fsf.org/readline.html page is not updated with the latest readline 5.2 version.

Borut




diff -ubr readline-5.2-orig/examples/excallback.c 
readline-5.2/examples/excallback.c
--- readline-5.2-orig/examples/excallback.c     2006-03-21 16:07:52.000000000 
+0100
+++ readline-5.2/examples/excallback.c  2006-11-01 11:18:13.343750000 +0100
@@ -157,7 +157,7 @@
     fprintf(stderr, "|%s|\n", line);
   }
 
-  free (line);
+  rl_free (line);
 }
 
 int
diff -ubr readline-5.2-orig/examples/fileman.c readline-5.2/examples/fileman.c
--- readline-5.2-orig/examples/fileman.c        2002-04-16 23:50:56.000000000 
+0200
+++ readline-5.2/examples/fileman.c     2006-11-01 11:18:45.203125000 +0100
@@ -145,7 +145,7 @@
           execute_line (s);
         }
 
-      free (line);
+      rl_free (line);
     }
   exit (0);
 }
diff -ubr readline-5.2-orig/examples/histexamp.c 
readline-5.2/examples/histexamp.c
--- readline-5.2-orig/examples/histexamp.c      2005-08-02 23:21:36.000000000 
+0200
+++ readline-5.2/examples/histexamp.c   2006-11-01 11:35:02.484375000 +0100
@@ -67,13 +67,13 @@
 
          if (result < 0 || result == 2)
            {
-             free (expansion);
+             rl_free (expansion);
              continue;
            }
 
          add_history (expansion);
          strncpy (line, expansion, sizeof (line) - 1);
-         free (expansion);
+         rl_free (expansion);
        }
 
       if (strcmp (line, "quit") == 0)
@@ -111,8 +111,8 @@
                fprintf (stderr, "No such entry %d\n", which);
              else
                {
-                 free (entry->line);
-                 free (entry);
+                 rl_free (entry->line);
+                 rl_free (entry);
                }
            }
          else
diff -ubr readline-5.2-orig/examples/manexamp.c readline-5.2/examples/manexamp.c
--- readline-5.2-orig/examples/manexamp.c       2002-04-16 23:53:02.000000000 
+0200
+++ readline-5.2/examples/manexamp.c    2006-11-01 11:36:21.875000000 +0100
@@ -40,7 +40,7 @@
      to the free pool. */
   if (line_read)
     {
-      free (line_read);
+      rl_free (line_read);
       line_read = (char *)NULL;
     }
 
diff -ubr readline-5.2-orig/examples/readlinebuf.h 
readline-5.2/examples/readlinebuf.h
--- readline-5.2-orig/examples/readlinebuf.h    2001-09-24 15:39:34.000000000 
+0200
+++ readline-5.2/examples/readlinebuf.h 2006-11-01 11:37:17.234375000 +0100
@@ -72,7 +72,7 @@
                        
                if ( rd < n ) {
                        low_ = high_ = 0;
-                       free( line_ ); // free( NULL ) is a noop
+                       rl_free( line_ ); // free( NULL ) is a noop
                        line_ = readline( prompt_ );
                        if ( line_ ) {
                                high_ = strlen( line_ );
@@ -87,7 +87,7 @@
        virtual int_type underflow() {
                if ( high_ == low_ ) {
                        low_ = high_ = 0;
-                       free( line_ ); // free( NULL ) is a noop
+                       rl_free( line_ ); // free( NULL ) is a noop
                        line_ = readline( prompt_ );
                        if ( line_ ) {
                                high_ = strlen( line_ );
diff -ubr readline-5.2-orig/examples/rl-fgets.c readline-5.2/examples/rl-fgets.c
--- readline-5.2-orig/examples/rl-fgets.c       2004-04-22 23:52:18.000000000 
+0200
+++ readline-5.2/examples/rl-fgets.c    2006-11-01 11:44:27.296875000 +0100
@@ -336,26 +336,26 @@
     ) ;
     if ( ! strncmp(my_fgets_line, "_fgets_reset_", 13) ) {
       my_fgets_reset () ;
-      free ( my_fgets_line ) ;
+      rl_free ( my_fgets_line ) ;
       strcpy ( s, "\n" ) ;
       return ( s ) ;
     }
     if ( ! strncmp(my_fgets_line, "_fgets_dump_", 12) ) {
       my_fgets_dump () ;
-      free ( my_fgets_line ) ;
+      rl_free ( my_fgets_line ) ;
       strcpy ( s, "\n" ) ;
       return ( s ) ;
     }
     if ( ! strncmp(my_fgets_line, "_fgets_debug_", 13) ) {
       my_fgets_debug_toggle () ;
-      free ( my_fgets_line ) ;
+      rl_free ( my_fgets_line ) ;
       strcpy ( s, "\n" ) ;
       return ( s ) ;
     }
     (void) strncpy ( s, my_fgets_line, n-1 ) ;
     (void) strcat ( s, "\n" ) ;
     if ( *my_fgets_line ) add_history ( my_fgets_line ) ;
-    free ( my_fgets_line ) ;
+    rl_free ( my_fgets_line ) ;
     return ( s ) ;
   } else {
     static fgets_t _fgets ;
diff -ubr readline-5.2-orig/examples/rlfe/rlfe.c 
readline-5.2/examples/rlfe/rlfe.c
--- readline-5.2-orig/examples/rlfe/rlfe.c      2004-11-04 23:32:14.000000000 
+0100
+++ readline-5.2/examples/rlfe/rlfe.c   2006-11-01 11:39:56.750000000 +0100
@@ -338,7 +338,7 @@
           if (*line)
             add_history (line);
         }
-      free (line);
+      rl_free (line);
     }
   rl_callback_handler_remove ();
   buf_count = 0;
diff -ubr readline-5.2-orig/examples/rltest.c readline-5.2/examples/rltest.c
--- readline-5.2-orig/examples/rltest.c 2005-08-02 23:25:10.000000000 +0200
+++ readline-5.2/examples/rltest.c      2006-11-01 11:45:13.296875000 +0100
@@ -87,7 +87,7 @@
                fprintf (stderr, "%d: %s\r\n", i, list[i]->line);
            }
        }
-      free (temp);
+      rl_free (temp);
     }
   exit (0);
 }
diff -ubr readline-5.2-orig/readline.c readline-5.2/readline.c
--- readline-5.2-orig/readline.c        2006-08-16 22:00:36.000000000 +0200
+++ readline-5.2/readline.c     2006-11-01 11:50:30.234375000 +0100
@@ -1212,3 +1212,16 @@
 
   return (0);
 }
+
+/* Free the buffer returned by readline(), the buffer passed as the
+   parameter to lhandler function installed by rl_callback_handler_install()
+   and buffers allocated by readline library functions.
+   Use this funtion instead of free().
+   This function MUST be used instead free() if readline is linked as
+   DLL on WIN32 */
+void
+rl_free (buff)
+     void *buff;
+{
+  free(buff);
+}
diff -ubr readline-5.2-orig/readline.h readline-5.2/readline.h
--- readline-5.2-orig/readline.h        2006-08-16 22:17:00.000000000 +0200
+++ readline-5.2/readline.h     2006-11-01 11:50:27.578125000 +0100
@@ -279,6 +279,13 @@
 /* Readline functions. */
 /* Read a line of input.  Prompt with PROMPT.  A NULL PROMPT means none. */
 extern char *readline PARAMS((const char *));
+/* Free the buffer returned by readline(), the buffer passed as the
+   parameter to lhandler function installed by rl_callback_handler_install()
+   and buffers allocated by readline library functions.
+   Use this funtion instead of free().
+   This function MUST be used instead free() if readline is linked as
+   DLL on WIN32 */
+extern void rl_free PARAMS((void *));
 
 extern int rl_set_prompt PARAMS((const char *));
 extern int rl_expand_prompt PARAMS((char *));

reply via email to

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