aboutsummaryrefslogtreecommitdiff
path: root/readline/examples/rl-fgets.c
diff options
context:
space:
mode:
Diffstat (limited to 'readline/examples/rl-fgets.c')
-rw-r--r--readline/examples/rl-fgets.c374
1 files changed, 0 insertions, 374 deletions
diff --git a/readline/examples/rl-fgets.c b/readline/examples/rl-fgets.c
deleted file mode 100644
index 5512b94..0000000
--- a/readline/examples/rl-fgets.c
+++ /dev/null
@@ -1,374 +0,0 @@
-/*
-Date: Tue, 16 Mar 2004 19:38:40 -0800
-From: Harold Levy <Harold.Levy@synopsys.com>
-Subject: fgets(stdin) --> readline() redirector
-To: chet@po.cwru.edu
-
-Hi Chet,
-
-Here is something you may find useful enough to include in the readline
-distribution. It is a shared library that redirects calls to fgets(stdin)
-to readline() via LD_PRELOAD, and it supports a custom prompt and list of
-command names. Many people have asked me for this file, so I thought I'd
-pass it your way in hope of just including it with readline to begin with.
-
-Best Regards,
-
--Harold
-*/
-
-/******************************************************************************
-*******************************************************************************
-
- FILE NAME: fgets.c TARGET: libfgets.so
- AUTHOR: Harold Levy VERSION: 1.0
- hlevy@synopsys.com
-
- ABSTRACT: Customize fgets() behavior via LD_PRELOAD in the following ways:
-
- -- If fgets(stdin) is called, redirect to GNU readline() to obtain
- command-line editing, file-name completion, history, etc.
-
- -- A list of commands for command-name completion can be configured by
- setting the environment-variable FGETS_COMMAND_FILE to a file containing
- the list of commands to be used.
-
- -- Command-line editing with readline() works best when the prompt string
- is known; you can set this with the FGETS_PROMPT environment variable.
-
- -- There special strings that libfgets will interpret as internal commands:
-
- _fgets_reset_ reset the command list
-
- _fgets_dump_ dump status
-
- _fgets_debug_ toggle debug messages
-
- HOW TO BUILD: Here are examples of how to build libfgets.so on various
- platforms; you will have to add -I and -L flags to configure access to
- the readline header and library files.
-
- (32-bit builds with gcc)
- AIX: gcc -fPIC fgets.c -shared -o libfgets.so -lc -ldl -lreadline -ltermcap
- HP-UX: gcc -fPIC fgets.c -shared -o libfgets.so -lc -ldld -lreadline
- Linux: gcc -fPIC fgets.c -shared -o libfgets.so -lc -ldl -lreadline
- SunOS: gcc -fPIC fgets.c -shared -o libfgets.so -lc -ldl -lgen -lreadline
-
- (64-bit builds without gcc)
- SunOS: SUNWspro/bin/cc -D_LARGEFILE64_SOURCE=1 -xtarget=ultra -xarch=v9 \
- -KPIC fgets.c -Bdynamic -lc -ldl -lgen -ltermcap -lreadline
-
- HOW TO USE: Different operating systems have different levels of support
- for the LD_PRELOAD concept. The generic method for 32-bit platforms is to
- put libtermcap.so, libfgets.so, and libreadline.so (with absolute paths)
- in the LD_PRELOAD environment variable, and to put their parent directories
- in the LD_LIBRARY_PATH environment variable. Unfortunately there is no
- generic method for 64-bit platforms; e.g. for 64-bit SunOS, you would have
- to build both 32-bit and 64-bit libfgets and libreadline libraries, and
- use the LD_FLAGS_32 and LD_FLAGS_64 environment variables with preload and
- library_path configurations (a mix of 32-bit and 64-bit calls are made under
- 64-bit SunOS).
-
- EXAMPLE WRAPPER: Here is an example shell script wrapper around the
- program "foo" that uses fgets() for command-line input:
-
- #!/bin/csh
- #### replace this with the libtermcap.so directory:
- set dir1 = "/usr/lib"
- #### replace this with the libfgets.so directory:
- set dir2 = "/usr/fgets"
- #### replace this with the libreadline.so directory:
- set dir3 = "/usr/local/lib"
- set lib1 = "${dir1}/libtermcap.so"
- set lib2 = "${dir2}/libfgets.so"
- set lib3 = "${dir3}/libreadline.so"
- if ( "${?LD_PRELOAD}" ) then
- setenv LD_PRELOAD "${lib1}:${lib2}:${lib3}:${LD_PRELOAD}"
- else
- setenv LD_PRELOAD "${lib1}:${lib2}:${lib3}"
- endif
- if ( "${?LD_LIBRARY_PATH}" ) then
- setenv LD_LIBRARY_PATH "${dir1}:${dir2}:${dir3}:${LD_LIBRARY_PATH}"
- else
- setenv LD_LIBRARY_PATH "${dir1}:${dir2}:${dir3}"
- endif
- setenv FGETS_COMMAND_FILE "${dir2}/foo.commands"
- setenv FGETS_PROMPT "foo> "
- exec "foo" $*
-
- Copyright (C)©2003-2004 Harold Levy.
-
- This code links to the GNU readline library, and as such is bound by the
- terms of the GNU General Public License as published by the Free Software
- Foundation, either version 2 or (at your option) any later version.
-
- The GNU General Public License is often shipped with GNU software, and is
- generally kept in a file called COPYING or LICENSE. If you do not have a
- copy of the license, write to the Free Software Foundation, 59 Temple Place,
- Suite 330, Boston, MA 02111 USA.
-
- This program is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
- details.
-
-*******************************************************************************
-******************************************************************************/
-
-
-
-#include <dlfcn.h>
-#include <stdio.h>
-#include <strings.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-#include <readline/readline.h>
-#include <readline/history.h>
-
-
-
-/* for dynamically connecting to the native fgets() */
-#if defined(RTLD_NEXT)
-#define REAL_LIBC RTLD_NEXT
-#else
-#define REAL_LIBC ((void *) -1L)
-#endif
-typedef char * ( * fgets_t ) ( char * s, int n, FILE * stream ) ;
-
-
-
-/* private data */
-/* -- writeable data is stored in the shared library's data segment
- -- every process that uses the shared library gets a private memory copy of
- its entire data segment
- -- static data in the shared library is not copied to the application
- -- only read-only (i.e. 'const') data is stored in the shared library's
- text segment
-*/
-static char ** my_fgets_names = NULL ;
-static int my_fgets_number_of_names = 0 ;
-static int my_fgets_debug_flag = 0 ;
-
-
-
-/* invoked with _fgets_reset_ */
-static void
-my_fgets_reset (
- void
-) {
- if ( my_fgets_names && (my_fgets_number_of_names > 0) ) {
- int i ;
- if ( my_fgets_debug_flag ) {
- printf ( "libfgets: removing command list\n" ) ;
- }
- for ( i = 0 ; i < my_fgets_number_of_names ; i ++ ) {
- if ( my_fgets_names[i] ) free ( my_fgets_names[i] ) ;
- }
- free ( my_fgets_names ) ;
- }
- my_fgets_names = NULL ;
- my_fgets_number_of_names = 0 ;
-}
-
-
-
-/* invoked with _fgets_dump_ */
-static void
-my_fgets_dump (
- void
-) {
- char * s ;
- printf ( "\n" ) ;
- s = getenv ( "FGETS_PROMPT" ) ;
- printf ( "FGETS_PROMPT = %s\n", s ? s : "" ) ;
- s = getenv ( "FGETS_COMMAND_FILE" ) ;
- printf ( "FGETS_COMMAND_FILE = %s\n", s ? s : "" ) ;
- printf ( "debug flag = %d\n", my_fgets_debug_flag ) ;
- printf ( "#commands = %d\n", my_fgets_number_of_names ) ;
- if ( my_fgets_debug_flag ) {
- if ( my_fgets_names && (my_fgets_number_of_names > 0) ) {
- int i ;
- for ( i = 0 ; i < my_fgets_number_of_names ; i ++ ) {
- printf ( "%s\n", my_fgets_names[i] ) ;
- }
- }
- }
- printf ( "\n" ) ;
-}
-
-
-
-/* invoked with _fgets_debug_ */
-static void
-my_fgets_debug_toggle (
- void
-) {
- my_fgets_debug_flag = my_fgets_debug_flag ? 0 : 1 ;
- if ( my_fgets_debug_flag ) {
- printf ( "libfgets: debug flag = %d\n", my_fgets_debug_flag ) ;
- }
-}
-
-
-
-/* read the command list if needed, return the i-th name */
-static char *
-my_fgets_lookup (
- int index
-) {
- if ( (! my_fgets_names) || (! my_fgets_number_of_names) ) {
- char * fname ;
- FILE * fp ;
- fgets_t _fgets ;
- int i ;
- char buf1[256], buf2[256] ;
- fname = getenv ( "FGETS_COMMAND_FILE" ) ;
- if ( ! fname ) {
- if ( my_fgets_debug_flag ) {
- printf ( "libfgets: empty or unset FGETS_COMMAND_FILE\n" ) ;
- }
- return NULL ;
- }
- fp = fopen ( fname, "r" ) ;
- if ( ! fp ) {
- if ( my_fgets_debug_flag ) {
- printf ( "libfgets: cannot open '%s' for reading\n", fname ) ;
- }
- return NULL ;
- }
- _fgets = (fgets_t) dlsym ( REAL_LIBC, "fgets" ) ;
- if ( ! _fgets ) {
- fprintf ( stderr,
- "libfgets: failed to dynamically link to native fgets()\n"
- ) ;
- return NULL ;
- }
- for ( i = 0 ; _fgets(buf1,255,fp) ; i ++ ) ;
- if ( ! i ) { fclose(fp) ; return NULL ; }
- my_fgets_names = (char**) calloc ( i, sizeof(char*) ) ;
- rewind ( fp ) ;
- i = 0 ;
- while ( _fgets(buf1,255,fp) ) {
- buf1[255] = 0 ;
- if ( 1 == sscanf(buf1,"%s",buf2) ) {
- my_fgets_names[i] = strdup(buf2) ;
- i ++ ;
- }
- }
- fclose ( fp ) ;
- my_fgets_number_of_names = i ;
- if ( my_fgets_debug_flag ) {
- printf ( "libfgets: successfully read %d commands\n", i ) ;
- }
- }
- if ( index < my_fgets_number_of_names ) {
- return my_fgets_names[index] ;
- } else {
- return NULL ;
- }
-}
-
-
-
-/* generate a list of partial name matches for readline() */
-static char *
-my_fgets_generator (
- const char * text,
- int state
-)
-{
- static int list_index, len ;
- char * name ;
- if ( ! state ) {
- list_index = 0 ;
- len = strlen ( text ) ;
- }
- while ( ( name = my_fgets_lookup(list_index) ) ) {
- list_index ++ ;
- if ( ! strncmp ( name, text, len ) ) {
- return ( strdup ( name ) ) ;
- }
- }
- return ( NULL ) ;
-}
-
-
-
-/* partial name completion callback for readline() */
-static char **
-my_fgets_completion (
- const char * text,
- int start,
- int end
-)
-{
- char ** matches ;
- matches = NULL ;
- if ( ! start ) {
- matches = rl_completion_matches ( text, my_fgets_generator ) ;
- }
- return ( matches ) ;
-}
-
-
-
-/* fgets() intercept */
-char *
-fgets (
- char * s,
- int n,
- FILE * stream
-)
-{
- if ( ! s ) return NULL ;
- if ( stream == stdin ) {
- char * prompt ;
- char * my_fgets_line ;
- rl_already_prompted = 1 ;
- rl_attempted_completion_function = my_fgets_completion ;
- rl_catch_signals = 1 ;
- rl_catch_sigwinch = 1 ;
- rl_set_signals () ;
- prompt = getenv ( "FGETS_PROMPT" ) ;
- for (
- my_fgets_line = 0 ; ! my_fgets_line ; my_fgets_line=readline(prompt)
- ) ;
- if ( ! strncmp(my_fgets_line, "_fgets_reset_", 13) ) {
- my_fgets_reset () ;
- free ( my_fgets_line ) ;
- strcpy ( s, "\n" ) ;
- return ( s ) ;
- }
- if ( ! strncmp(my_fgets_line, "_fgets_dump_", 12) ) {
- my_fgets_dump () ;
- 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 ) ;
- 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 ) ;
- return ( s ) ;
- } else {
- static fgets_t _fgets ;
- _fgets = (fgets_t) dlsym ( REAL_LIBC, "fgets" ) ;
- if ( ! _fgets ) {
- fprintf ( stderr,
- "libfgets: failed to dynamically link to native fgets()\n"
- ) ;
- strcpy ( s, "\n" ) ;
- return ( s ) ;
- }
- return (
- _fgets ( s, n, stream )
- ) ;
- }
-}