Fix for pager and \? - Mailing list pgsql-patches

From Bruce Momjian
Subject Fix for pager and \?
Date
Msg-id 200207150155.g6F1trR13992@candle.pha.pa.us
Whole thread Raw
List pgsql-patches
I received email from Bruno Wolff III mentioning that \pset pager and \?
didn't work as expected.  The following patch fixes this, and makes the
\? pager handling similar to the other pager handling.

--
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026
Index: doc/src/sgml/ref/psql-ref.sgml
===================================================================
RCS file: /cvsroot/pgsql/doc/src/sgml/ref/psql-ref.sgml,v
retrieving revision 1.67
diff -c -r1.67 psql-ref.sgml
*** doc/src/sgml/ref/psql-ref.sgml    20 Jun 2002 16:00:43 -0000    1.67
--- doc/src/sgml/ref/psql-ref.sgml    15 Jul 2002 01:50:47 -0000
***************
*** 1036,1042 ****
        <term><literal>pager</literal></term>
        <listitem>
        <para>
!       Toggles the list of a pager to do table output. If the
        environment variable <envar>PAGER</envar> is set, the output
        is piped to the specified program. Otherwise
        <filename>more</filename> is used.
--- 1036,1042 ----
        <term><literal>pager</literal></term>
        <listitem>
        <para>
!       Toggles the use of a pager for query and psql help output. If the
        environment variable <envar>PAGER</envar> is set, the output
        is piped to the specified program. Otherwise
        <filename>more</filename> is used.
***************
*** 1050,1056 ****
        of the printing routines it is not always possible to predict
        the number of lines that will actually be printed. For that
        reason <application>psql</application> might not appear very
!       discriminating about when to use the pager and when not to.
        </para>
        </listitem>
        </varlistentry>
--- 1050,1056 ----
        of the printing routines it is not always possible to predict
        the number of lines that will actually be printed. For that
        reason <application>psql</application> might not appear very
!       discriminating about when to use the pager.
        </para>
        </listitem>
        </varlistentry>
Index: src/bin/psql/command.c
===================================================================
RCS file: /cvsroot/pgsql/src/bin/psql/command.c,v
retrieving revision 1.72
diff -c -r1.72 command.c
*** src/bin/psql/command.c    24 Apr 2002 05:24:00 -0000    1.72
--- src/bin/psql/command.c    15 Jul 2002 01:50:48 -0000
***************
*** 846,852 ****

      /* \? -- slash command help */
      else if (strcmp(cmd, "?") == 0)
!         slashUsage();

  #if 0

--- 846,852 ----

      /* \? -- slash command help */
      else if (strcmp(cmd, "?") == 0)
!         slashUsage(pset.popt.topt.pager);

  #if 0

Index: src/bin/psql/help.c
===================================================================
RCS file: /cvsroot/pgsql/src/bin/psql/help.c,v
retrieving revision 1.51
diff -c -r1.51 help.c
*** src/bin/psql/help.c    20 Jun 2002 20:29:42 -0000    1.51
--- src/bin/psql/help.c    15 Jul 2002 01:50:49 -0000
***************
*** 6,11 ****
--- 6,12 ----
   * $Header: /cvsroot/pgsql/src/bin/psql/help.c,v 1.51 2002/06/20 20:29:42 momjian Exp $
   */
  #include "postgres_fe.h"
+ #include "print.h"
  #include "help.h"

  #include <signal.h>
***************
*** 138,144 ****
  }


-
  /*
   * slashUsage
   *
--- 139,144 ----
***************
*** 154,251 ****
  #endif

  void
! slashUsage(void)
  {
!     bool        usePipe = false;
!     const char *pagerenv;
!     FILE       *fout;
!     struct winsize screen_size;

! #ifdef TIOCGWINSZ
!     if (pset.notty == 0 &&
!         (ioctl(fileno(stdout), TIOCGWINSZ, &screen_size) == -1 ||
!          screen_size.ws_col == 0 ||
!          screen_size.ws_row == 0))
      {
  #endif
!         screen_size.ws_row = 24;
!         screen_size.ws_col = 80;
  #ifdef TIOCGWINSZ
!     }
  #endif

!     if (pset.notty == 0 &&
!         (pagerenv = getenv("PAGER")) &&
!         (pagerenv[0] != '\0') &&
!         screen_size.ws_row <= 46 &&
!         (fout = popen(pagerenv, "w")))
      {
!         usePipe = true;
  #ifndef WIN32
          pqsignal(SIGPIPE, SIG_IGN);
  #endif
      }
      else
!         fout = stdout;

      /* if you add/remove a line here, change the row test above */
      /*      if this " is the start of the string then it ought to end there to fit in 80 columns >> " */
!     fprintf(fout, _(" \\a             toggle between unaligned and aligned output mode\n"));
!     fprintf(fout, _(" \\c[onnect] [DBNAME|- [USER]]\n"
                      "                connect to new database (currently \"%s\")\n"),
              PQdb(pset.db));
!     fprintf(fout, _(" \\C [STRING]    set table title, or unset if none\n"));
!     fprintf(fout, _(" \\cd [DIR]      change the current working directory\n"));
!     fprintf(fout, _(" \\copy ...      perform SQL COPY with data stream to the client host\n"));
!     fprintf(fout, _(" \\copyright     show PostgreSQL usage and distribution terms\n"));
!     fprintf(fout, _(" \\d [NAME]      describe table (or view, index, sequence)\n"));
!     fprintf(fout, _(" \\d{t|i|s|v|S} [PATTERN]\n"));
!     fprintf(fout, _("                list tables/indexes/sequences/views/system tables\n"));
!     fprintf(fout, _(" \\da [PATTERN]  list aggregate functions\n"));
!     fprintf(fout, _(" \\dd [PATTERN]  show comment for object\n"));
!     fprintf(fout, _(" \\dD [PATTERN]  list domains\n"));
!     fprintf(fout, _(" \\df [PATTERN]  list functions\n"));
!     fprintf(fout, _(" \\do [NAME]     list operators\n"));
!     fprintf(fout, _(" \\dl            list large objects, same as lo_list\n"));
!     fprintf(fout, _(" \\dp [PATTERN]  list table access privileges\n"));
!     fprintf(fout, _(" \\dT [PATTERN]  list data types\n"));
!     fprintf(fout, _(" \\du [PATTERN]  list users\n"));
!     fprintf(fout, _(" \\e [FILE]      edit the query buffer (or file) with external editor\n"));
!     fprintf(fout, _(" \\echo [STRING] write string to standard output\n"));
!     fprintf(fout, _(" \\encoding [ENCODING]  show or set client encoding\n"));
!     fprintf(fout, _(" \\f [STRING]    show or set field separator for unaligned query output\n"));
!     fprintf(fout, _(" \\g [FILE]      send query buffer to server (and results to file or |pipe)\n"));
!     fprintf(fout, _(" \\h [NAME]      help on syntax of SQL commands, * for all commands\n"));
!     fprintf(fout, _(" \\H             toggle HTML output mode (currently %s)\n"),
              ON(pset.popt.topt.format == PRINT_HTML));
!     fprintf(fout, _(" \\i FILE        execute commands from file\n"));
!     fprintf(fout, _(" \\l             list all databases\n"));
!     fprintf(fout, _(" \\lo_export, \\lo_import, \\lo_list, \\lo_unlink\n"
                      "                large object operations\n"));
!     fprintf(fout, _(" \\o FILE        send all query results to file or |pipe\n"));
!     fprintf(fout, _(" \\p             show the contents of the query buffer\n"));
!     fprintf(fout, _(" \\pset NAME [VALUE]  set table output option (NAME := {format|border|expanded|\n"
                      "                fieldsep|null|recordsep|tuples_only|title|tableattr|pager})\n"));
!     fprintf(fout, _(" \\q             quit psql\n"));
!     fprintf(fout, _(" \\qecho [STRING]  write string to query output stream (see \\o)\n"));
!     fprintf(fout, _(" \\r             reset (clear) the query buffer\n"));
!     fprintf(fout, _(" \\s [FILE]      display history or save it to file\n"));
!     fprintf(fout, _(" \\set [NAME [VALUE]]  set internal variable, or list all if no parameters\n"));
!     fprintf(fout, _(" \\t             show only rows (currently %s)\n"),
              ON(pset.popt.topt.tuples_only));
!     fprintf(fout, _(" \\T [STRING]    set HTML <table>-tag attributes, or unset if none\n"));
!     fprintf(fout, _(" \\timing        toggle timing of queries (currently %s)\n"),
              ON(pset.timing));
!     fprintf(fout, _(" \\unset NAME    unset (delete) internal variable\n"));
!     fprintf(fout, _(" \\w [FILE]      write query buffer to file\n"));
!     fprintf(fout, _(" \\x             toggle expanded output (currently %s)\n"),
              ON(pset.popt.topt.expanded));
!     fprintf(fout, _(" \\z [PATTERN]   list table access privileges (same as \\dp)\n"));
!     fprintf(fout, _(" \\! [COMMAND]   execute command in shell or start interactive shell\n"));

!     if (usePipe)
      {
!         pclose(fout);
  #ifndef WIN32
          pqsignal(SIGPIPE, SIG_DFL);
  #endif
--- 154,259 ----
  #endif

  void
! slashUsage(bool pager)
  {
!     FILE       *output, *pagerfd = NULL;

!     /* check whether we need / can / are supposed to use pager */
!     if (pager
! #ifndef WIN32
!         &&
!         isatty(fileno(stdin)) &&
!         isatty(fileno(stdout))
! #endif
!         )
      {
+         const char *pagerprog;
+
+ #ifdef TIOCGWINSZ
+         int            result;
+         struct winsize screen_size;
+
+         result = ioctl(fileno(stdout), TIOCGWINSZ, &screen_size);
+         if (result == -1 || 50 > screen_size.ws_row)
+         {
  #endif
!             pagerprog = getenv("PAGER");
!             if (!pagerprog)
!                 pagerprog = DEFAULT_PAGER;
!             pagerfd = popen(pagerprog, "w");
  #ifdef TIOCGWINSZ
!         }
  #endif
+     }

!     if (pagerfd)
      {
!         output = pagerfd;
  #ifndef WIN32
          pqsignal(SIGPIPE, SIG_IGN);
  #endif
      }
      else
!         output = stdout;

      /* if you add/remove a line here, change the row test above */
      /*      if this " is the start of the string then it ought to end there to fit in 80 columns >> " */
!     fprintf(output, _(" \\a             toggle between unaligned and aligned output mode\n"));
!     fprintf(output, _(" \\c[onnect] [DBNAME|- [USER]]\n"
                      "                connect to new database (currently \"%s\")\n"),
              PQdb(pset.db));
!     fprintf(output, _(" \\C [STRING]    set table title, or unset if none\n"));
!     fprintf(output, _(" \\cd [DIR]      change the current working directory\n"));
!     fprintf(output, _(" \\copy ...      perform SQL COPY with data stream to the client host\n"));
!     fprintf(output, _(" \\copyright     show PostgreSQL usage and distribution terms\n"));
!     fprintf(output, _(" \\d [NAME]      describe table (or view, index, sequence)\n"));
!     fprintf(output, _(" \\d{t|i|s|v|S} [PATTERN]\n"));
!     fprintf(output, _("                list tables/indexes/sequences/views/system tables\n"));
!     fprintf(output, _(" \\da [PATTERN]  list aggregate functions\n"));
!     fprintf(output, _(" \\dd [PATTERN]  show comment for object\n"));
!     fprintf(output, _(" \\dD [PATTERN]  list domains\n"));
!     fprintf(output, _(" \\df [PATTERN]  list functions\n"));
!     fprintf(output, _(" \\do [NAME]     list operators\n"));
!     fprintf(output, _(" \\dl            list large objects, same as lo_list\n"));
!     fprintf(output, _(" \\dp [PATTERN]  list table access privileges\n"));
!     fprintf(output, _(" \\dT [PATTERN]  list data types\n"));
!     fprintf(output, _(" \\du [PATTERN]  list users\n"));
!     fprintf(output, _(" \\e [FILE]      edit the query buffer (or file) with external editor\n"));
!     fprintf(output, _(" \\echo [STRING] write string to standard output\n"));
!     fprintf(output, _(" \\encoding [ENCODING]  show or set client encoding\n"));
!     fprintf(output, _(" \\f [STRING]    show or set field separator for unaligned query output\n"));
!     fprintf(output, _(" \\g [FILE]      send query buffer to server (and results to file or |pipe)\n"));
!     fprintf(output, _(" \\h [NAME]      help on syntax of SQL commands, * for all commands\n"));
!     fprintf(output, _(" \\H             toggle HTML output mode (currently %s)\n"),
              ON(pset.popt.topt.format == PRINT_HTML));
!     fprintf(output, _(" \\i FILE        execute commands from file\n"));
!     fprintf(output, _(" \\l             list all databases\n"));
!     fprintf(output, _(" \\lo_export, \\lo_import, \\lo_list, \\lo_unlink\n"
                      "                large object operations\n"));
!     fprintf(output, _(" \\o FILE        send all query results to file or |pipe\n"));
!     fprintf(output, _(" \\p             show the contents of the query buffer\n"));
!     fprintf(output, _(" \\pset NAME [VALUE]  set table output option (NAME := {format|border|expanded|\n"
                      "                fieldsep|null|recordsep|tuples_only|title|tableattr|pager})\n"));
!     fprintf(output, _(" \\q             quit psql\n"));
!     fprintf(output, _(" \\qecho [STRING]  write string to query output stream (see \\o)\n"));
!     fprintf(output, _(" \\r             reset (clear) the query buffer\n"));
!     fprintf(output, _(" \\s [FILE]      display history or save it to file\n"));
!     fprintf(output, _(" \\set [NAME [VALUE]]  set internal variable, or list all if no parameters\n"));
!     fprintf(output, _(" \\t             show only rows (currently %s)\n"),
              ON(pset.popt.topt.tuples_only));
!     fprintf(output, _(" \\T [STRING]    set HTML <table>-tag attributes, or unset if none\n"));
!     fprintf(output, _(" \\timing        toggle timing of queries (currently %s)\n"),
              ON(pset.timing));
!     fprintf(output, _(" \\unset NAME    unset (delete) internal variable\n"));
!     fprintf(output, _(" \\w [FILE]      write query buffer to file\n"));
!     fprintf(output, _(" \\x             toggle expanded output (currently %s)\n"),
              ON(pset.popt.topt.expanded));
!     fprintf(output, _(" \\z [PATTERN]   list table access privileges (same as \\dp)\n"));
!     fprintf(output, _(" \\! [COMMAND]   execute command in shell or start interactive shell\n"));

!     if (pagerfd)
      {
!         pclose(pagerfd);
  #ifndef WIN32
          pqsignal(SIGPIPE, SIG_DFL);
  #endif
Index: src/bin/psql/help.h
===================================================================
RCS file: /cvsroot/pgsql/src/bin/psql/help.h,v
retrieving revision 1.8
diff -c -r1.8 help.h
*** src/bin/psql/help.h    28 Oct 2001 06:25:58 -0000    1.8
--- src/bin/psql/help.h    15 Jul 2002 01:50:49 -0000
***************
*** 10,16 ****

  void        usage(void);

! void        slashUsage(void);

  void        helpSQL(const char *topic);

--- 10,16 ----

  void        usage(void);

! void        slashUsage(bool pager);

  void        helpSQL(const char *topic);

Index: src/bin/psql/print.c
===================================================================
RCS file: /cvsroot/pgsql/src/bin/psql/print.c,v
retrieving revision 1.26
diff -c -r1.26 print.c
*** src/bin/psql/print.c    24 Apr 2002 15:56:38 -0000    1.26
--- src/bin/psql/print.c    15 Jul 2002 01:50:49 -0000
***************
*** 23,34 ****

  #include "settings.h"

- #ifndef __CYGWIN__
- #define DEFAULT_PAGER "more"
- #else
- #define DEFAULT_PAGER "less"
- #endif
-
  #ifdef HAVE_TERMIOS_H
  #include <termios.h>
  #endif
--- 23,28 ----
***************
*** 1033,1039 ****
  {
      const char *default_footer[] = {NULL};
      unsigned short int border = opt->border;
!     FILE       *pager = NULL,
                 *output;


--- 1027,1033 ----
  {
      const char *default_footer[] = {NULL};
      unsigned short int border = opt->border;
!     FILE       *pagerfd = NULL,
                 *output;


***************
*** 1090,1104 ****
              pagerprog = getenv("PAGER");
              if (!pagerprog)
                  pagerprog = DEFAULT_PAGER;
!             pager = popen(pagerprog, "w");
  #ifdef TIOCGWINSZ
          }
  #endif
      }

!     if (pager)
      {
!         output = pager;
  #ifndef WIN32
          pqsignal(SIGPIPE, SIG_IGN);
  #endif
--- 1084,1098 ----
              pagerprog = getenv("PAGER");
              if (!pagerprog)
                  pagerprog = DEFAULT_PAGER;
!             pagerfd = popen(pagerprog, "w");
  #ifdef TIOCGWINSZ
          }
  #endif
      }

!     if (pagerfd)
      {
!         output = pagerfd;
  #ifndef WIN32
          pqsignal(SIGPIPE, SIG_IGN);
  #endif
***************
*** 1139,1151 ****
              fprintf(stderr, "+ Oops, you shouldn't see this!\n");
      }

!     if (pager)
      {
!         pclose(pager);
  #ifndef WIN32
          pqsignal(SIGPIPE, SIG_DFL);
  #endif
-
      }
  }

--- 1133,1144 ----
              fprintf(stderr, "+ Oops, you shouldn't see this!\n");
      }

!     if (pagerfd)
      {
!         pclose(pagerfd);
  #ifndef WIN32
          pqsignal(SIGPIPE, SIG_DFL);
  #endif
      }
  }

Index: src/bin/psql/print.h
===================================================================
RCS file: /cvsroot/pgsql/src/bin/psql/print.h,v
retrieving revision 1.12
diff -c -r1.12 print.h
*** src/bin/psql/print.h    5 Nov 2001 17:46:31 -0000    1.12
--- src/bin/psql/print.h    15 Jul 2002 01:50:49 -0000
***************
*** 72,78 ****
   *
   * It calls the printTable above with all the things set straight.
   */
! void
!             printQuery(const PGresult *result, const printQueryOpt *opt, FILE *fout);

  #endif   /* PRINT_H */
--- 72,83 ----
   *
   * It calls the printTable above with all the things set straight.
   */
! void printQuery(const PGresult *result, const printQueryOpt *opt, FILE *fout);
!
! #ifndef __CYGWIN__
! #define DEFAULT_PAGER "more"
! #else
! #define DEFAULT_PAGER "less"
! #endif

  #endif   /* PRINT_H */

pgsql-patches by date:

Previous
From: Bruce Momjian
Date:
Subject: Re: CLUSTER patch
Next
From: Joe Conway
Date:
Subject: Re: show() function