Commit 718bb2cc authored by Peter Eisentraut's avatar Peter Eisentraut

Moved psql \eset and \eshow to \encoding

Improved psql's Ctrl-C handling
Fixed configure test for sigsetjmp that now even recognizes it if it's a macro
parent 5253c518
......@@ -3,7 +3,7 @@
*
* Copyright 2000 by PostgreSQL Global Development Group
*
* $Header: /cvsroot/pgsql/src/bin/psql/command.c,v 1.21 2000/02/20 02:37:40 tgl Exp $
* $Header: /cvsroot/pgsql/src/bin/psql/command.c,v 1.22 2000/02/20 14:28:20 petere Exp $
*/
#include "postgres.h"
#include "command.h"
......@@ -36,6 +36,9 @@
#ifdef MULTIBYTE
#include "miscadmin.h"
#include "mb/pg_wchar.h"
#else
/* Grand unified hard-coded badness */
#define pg_encoding_to_char(x) "SQL_ASCII"
#endif
......@@ -351,30 +354,29 @@ exec_command(const char *cmd,
fputs("\n", fout);
}
#ifdef MULTIBYTE
/* \eset -- set client side encoding */
else if (strcmp(cmd, "eset") == 0)
/* \encoding -- set client side encoding */
else if (strcmp(cmd, "encoding") == 0)
{
char *encoding = scan_option(&string, OT_NORMAL, NULL);
if (PQsetClientEncoding(pset.db, encoding) == -1)
{
psql_error("\\%s: invalid encoding\n", cmd);
}
/* save encoding info into psql internal data */
pset.encoding = PQclientEncoding(pset.db);
free(encoding);
}
/* \eshow -- show encoding info */
else if (strcmp(cmd, "eshow") == 0)
{
int encoding = PQclientEncoding(pset.db);
if (encoding == -1)
{
psql_error("\\%s: there is no connection\n", cmd);
}
printf("%s\n", pg_encoding_to_char(encoding));
}
if (!encoding)
puts(pg_encoding_to_char(pset.encoding));
else
{
#ifdef MULTIBYTE
if (PQsetClientEncoding(pset.db, encoding) == -1)
psql_error("%s: invalid encoding name\n", encoding);
/* save encoding info into psql internal data */
pset.encoding = PQclientEncoding(pset.db);
SetVariable(pset.vars, "ENCODING", pg_encoding_to_char(pset.encoding));
#else
psql_error("\\%s: multi-byte support is not enabled\n", cmd);
#endif
}
free(encoding);
}
/* \f -- change field separator */
else if (strcmp(cmd, "f") == 0)
{
......@@ -425,7 +427,7 @@ exec_command(const char *cmd,
}
else
{
success = process_file(fname);
success = process_file(fname) == EXIT_SUCCESS;
free (fname);
}
}
......@@ -1148,6 +1150,7 @@ do_connect(const char *new_dbname, const char *new_user)
SetVariable(pset.vars, "USER", NULL);
SetVariable(pset.vars, "HOST", NULL);
SetVariable(pset.vars, "PORT", NULL);
SetVariable(pset.vars, "ENCODING", NULL);
/* If dbname is "" then use old name, else new one (even if NULL) */
if (oldconn && new_dbname && PQdb(oldconn) && strcmp(new_dbname, "") == 0)
......@@ -1247,6 +1250,7 @@ do_connect(const char *new_dbname, const char *new_user)
SetVariable(pset.vars, "USER", PQuser(pset.db));
SetVariable(pset.vars, "HOST", PQhost(pset.db));
SetVariable(pset.vars, "PORT", PQport(pset.db));
SetVariable(pset.vars, "ENCODING", pg_encoding_to_char(pset.encoding));
pset.issuper = test_superuser(PQuser(pset.db));
......@@ -1471,7 +1475,7 @@ do_edit(const char *filename_arg, PQExpBuffer query_buf)
* Read commands from filename and then them to the main processing loop
* Handler for \i, but can be used for other things as well.
*/
bool
int
process_file(char *filename)
{
FILE *fd;
......@@ -1494,7 +1498,7 @@ process_file(char *filename)
result = MainLoop(fd);
fclose(fd);
pset.inputfile = oldfilename;
return (result == EXIT_SUCCESS);
return result;
}
......
......@@ -3,7 +3,7 @@
*
* Copyright 2000 by PostgreSQL Global Development Group
*
* $Header: /cvsroot/pgsql/src/bin/psql/command.h,v 1.8 2000/02/16 13:15:26 momjian Exp $
* $Header: /cvsroot/pgsql/src/bin/psql/command.h,v 1.9 2000/02/20 14:28:20 petere Exp $
*/
#ifndef COMMAND_H
#define COMMAND_H
......@@ -31,7 +31,7 @@ HandleSlashCmds(const char *line,
PQExpBuffer query_buf,
const char **end_of_cmd);
bool
int
process_file(char *filename);
bool
......
......@@ -3,7 +3,7 @@
*
* Copyright 2000 by PostgreSQL Global Development Group
*
* $Header: /cvsroot/pgsql/src/bin/psql/common.c,v 1.15 2000/02/20 02:37:40 tgl Exp $
* $Header: /cvsroot/pgsql/src/bin/psql/common.c,v 1.16 2000/02/20 14:28:20 petere Exp $
*/
#include "postgres.h"
#include "common.h"
......@@ -19,6 +19,7 @@
#include <signal.h>
#ifndef WIN32
#include <unistd.h> /* for write() */
#include <setjmp.h>
#else
#include <io.h> /* for _write() */
#include <win32.h>
......@@ -34,7 +35,7 @@
#include "copy.h"
#include "prompt.h"
#include "print.h"
#include "mainloop.h"
/*
......@@ -184,7 +185,7 @@ simple_prompt(const char *prompt, int maxlen, bool echo)
if (!destination)
return NULL;
if (prompt)
fputs(prompt, stdout);
fputs(prompt, stderr);
#ifdef HAVE_TERMIOS_H
if (!echo)
......@@ -238,14 +239,22 @@ simple_prompt(const char *prompt, int maxlen, bool echo)
*/
static PGconn *cancelConn;
volatile bool cancel_pressed;
#define write_stderr(String) write(fileno(stderr), String, strlen(String))
static void
void
handle_sigint(SIGNAL_ARGS)
{
if (cancelConn == NULL)
#ifndef WIN32
siglongjmp(main_loop_jmp, 1);
#else
return;
#endif
cancel_pressed = true;
/* Try to send cancel request */
if (PQrequestCancel(cancelConn))
write_stderr("\nCancel request sent\n");
......@@ -287,15 +296,8 @@ PSQLexec(const char *query)
return NULL;
cancelConn = pset.db;
#ifndef WIN32
pqsignal(SIGINT, handle_sigint); /* control-C => cancel */
#endif
res = PQexec(pset.db, query);
#ifndef WIN32
pqsignal(SIGINT, SIG_DFL); /* now control-C is back to normal */
#endif
cancelConn = NULL;
if (PQstatus(pset.db) == CONNECTION_BAD)
{
......@@ -316,6 +318,7 @@ PSQLexec(const char *query)
SetVariable(pset.vars, "HOST", NULL);
SetVariable(pset.vars, "PORT", NULL);
SetVariable(pset.vars, "USER", NULL);
SetVariable(pset.vars, "ENCODING", NULL);
return NULL;
}
else
......@@ -359,7 +362,7 @@ SendQuery(const char *query)
if (!pset.db)
{
psql_error("you are currently not connected to a database.\n");
psql_error("You are currently not connected to a database.\n");
return false;
}
......@@ -384,15 +387,8 @@ SendQuery(const char *query)
}
cancelConn = pset.db;
#ifndef WIN32
pqsignal(SIGINT, handle_sigint);
#endif
results = PQexec(pset.db, query);
#ifndef WIN32
pqsignal(SIGINT, SIG_DFL);
#endif
cancelConn = NULL;
if (results == NULL)
{
......@@ -494,6 +490,7 @@ SendQuery(const char *query)
SetVariable(pset.vars, "HOST", NULL);
SetVariable(pset.vars, "PORT", NULL);
SetVariable(pset.vars, "USER", NULL);
SetVariable(pset.vars, "ENCODING", NULL);
return false;
}
else
......
......@@ -3,11 +3,14 @@
*
* Copyright 2000 by PostgreSQL Global Development Group
*
* $Header: /cvsroot/pgsql/src/bin/psql/common.h,v 1.6 2000/02/16 13:15:26 momjian Exp $
* $Header: /cvsroot/pgsql/src/bin/psql/common.h,v 1.7 2000/02/20 14:28:20 petere Exp $
*/
#ifndef COMMON_H
#define COMMON_H
#include "postgres.h"
#include <signal.h>
#include "pqsignal.h"
#include "libpq-fe.h"
char * xstrdup(const char *string);
......@@ -25,6 +28,9 @@ void NoticeProcessor(void * arg, const char * message);
char * simple_prompt(const char *prompt, int maxlen, bool echo);
extern volatile bool cancel_pressed;
void handle_sigint(SIGNAL_ARGS);
PGresult * PSQLexec(const char *query);
bool SendQuery(const char *query);
......
......@@ -3,7 +3,7 @@
*
* Copyright 2000 by PostgreSQL Global Development Group
*
* $Header: /cvsroot/pgsql/src/bin/psql/help.c,v 1.21 2000/02/20 02:37:40 tgl Exp $
* $Header: /cvsroot/pgsql/src/bin/psql/help.c,v 1.22 2000/02/20 14:28:20 petere Exp $
*/
#include "postgres.h"
#include "help.h"
......@@ -29,6 +29,13 @@
#include "common.h"
#include "sql_help.h"
/*
* PLEASE:
* If you change something in this file, also make the same changes
* in the DocBook documentation, file ref/psql-ref.sgml. If you don't
* know how to do it, please find someone who can help you.
*/
/*
* usage
......@@ -200,10 +207,7 @@ slashUsage(void)
fprintf(fout, " \\dT list data types\n");
fprintf(fout, " \\e [fname] edit the current query buffer or <fname> with external editor\n");
fprintf(fout, " \\echo <text> write text to stdout\n");
#ifdef MULTIBYTE
fprintf(fout, " \\eset <encoding> set client encoding\n");
fprintf(fout, " \\eshow show client encoding\n");
#endif
fprintf(fout, " \\encoding <encoding> set client encoding\n");
fprintf(fout, " \\g [fname] send query to backend (and results in <fname> or |pipe)\n");
fprintf(fout, " \\h [cmd] help on syntax of sql commands, * for all commands\n");
fprintf(fout, " \\i <fname> read and execute queries from filename\n");
......
......@@ -3,7 +3,7 @@
*
* Copyright 2000 by PostgreSQL Global Development Group
*
* $Header: /cvsroot/pgsql/src/bin/psql/input.c,v 1.11 2000/02/20 02:37:40 tgl Exp $
* $Header: /cvsroot/pgsql/src/bin/psql/input.c,v 1.12 2000/02/20 14:28:20 petere Exp $
*/
#include "postgres.h"
#include "input.h"
......@@ -148,6 +148,8 @@ initializeInput(int flags)
}
}
#endif
atexit(finishInput);
}
......
......@@ -3,7 +3,7 @@
*
* Copyright 2000 by PostgreSQL Global Development Group
*
* $Header: /cvsroot/pgsql/src/bin/psql/mainloop.c,v 1.21 2000/02/20 02:37:40 tgl Exp $
* $Header: /cvsroot/pgsql/src/bin/psql/mainloop.c,v 1.22 2000/02/20 14:28:20 petere Exp $
*/
#include "postgres.h"
#include "mainloop.h"
......@@ -16,6 +16,11 @@
#include "common.h"
#include "command.h"
#ifndef WIN32
#include <setjmp.h>
sigjmp_buf main_loop_jmp;
#endif
/*
......@@ -88,6 +93,40 @@ MainLoop(FILE *source)
/* main loop to get queries and execute them */
while (1)
{
/*
* Welcome code for Control-C
*/
if (cancel_pressed)
{
cancel_pressed = false;
if (!pset.cur_cmd_interactive)
{
/*
* You get here if you stopped a script with Ctrl-C and a query
* cancel was issued. In that case we don't do the longjmp, so
* the query routine can finish nicely.
*/
successResult = EXIT_USER;
break;
}
}
#ifndef WIN32
if (sigsetjmp(main_loop_jmp, 1) != 0)
{
/* got here with longjmp */
if (pset.cur_cmd_interactive)
{
fputc('\n', stdout);
resetPQExpBuffer(query_buf);
}
else
{
successResult = EXIT_USER;
break;
}
}
#endif
if (slashCmdStatus == CMD_NEWEDIT)
{
/*
......@@ -213,7 +252,7 @@ MainLoop(FILE *source)
/* echo back if flag is set */
var = GetVariable(pset.vars, "ECHO");
if (var && strcmp(var, "all")==0)
if (!pset.cur_cmd_interactive && var && strcmp(var, "all")==0)
puts(line);
fflush(stdout);
......
......@@ -3,11 +3,19 @@
*
* Copyright 2000 by PostgreSQL Global Development Group
*
* $Header: /cvsroot/pgsql/src/bin/psql/mainloop.h,v 1.7 2000/02/16 13:15:26 momjian Exp $
* $Header: /cvsroot/pgsql/src/bin/psql/mainloop.h,v 1.8 2000/02/20 14:28:20 petere Exp $
*/
#ifndef MAINLOOP_H
#define MAINLOOP_H
#include "postgres.h"
#include <stdio.h>
#ifndef WIN32
#include <setjmp.h>
extern sigjmp_buf main_loop_jmp;
#endif
int MainLoop(FILE *source);
#endif /* MAINLOOP_H */
......@@ -3,7 +3,7 @@
*
* Copyright 2000 by PostgreSQL Global Development Group
*
* $Header: /cvsroot/pgsql/src/bin/psql/startup.c,v 1.24 2000/02/16 13:15:26 momjian Exp $
* $Header: /cvsroot/pgsql/src/bin/psql/startup.c,v 1.25 2000/02/20 14:28:20 petere Exp $
*/
#include "postgres.h"
......@@ -34,6 +34,14 @@
#include "settings.h"
#include "variables.h"
#ifdef MULTIBYTE
#include "miscadmin.h"
#include "mb/pg_wchar.h"
#else
/* XXX Grand unified hard-coded badness; this should go into libpq */
#define pg_encoding_to_char(x) "SQL_ASCII"
#endif
/*
* Global psql options
*/
......@@ -65,7 +73,7 @@ struct adhoc_opts
};
static void
parse_options(int argc, char *argv[], struct adhoc_opts * options);
parse_psql_options(int argc, char *argv[], struct adhoc_opts * options);
static void
process_psqlrc(void);
......@@ -121,7 +129,7 @@ main(int argc, char *argv[])
pset.getPassword = false;
#endif
parse_options(argc, argv, &options);
parse_psql_options(argc, argv, &options);
if (!pset.popt.topt.fieldSep)
pset.popt.topt.fieldSep = xstrdup(DEFAULT_FIELD_SEP);
......@@ -191,6 +199,11 @@ main(int argc, char *argv[])
SetVariable(pset.vars, "USER", PQuser(pset.db));
SetVariable(pset.vars, "HOST", PQhost(pset.db));
SetVariable(pset.vars, "PORT", PQport(pset.db));
SetVariable(pset.vars, "ENCODING", pg_encoding_to_char(pset.encoding));
#ifndef WIN32
pqsignal(SIGINT, handle_sigint); /* control-C => cancel */
#endif
/*
* Now find something to do
......@@ -200,7 +213,7 @@ main(int argc, char *argv[])
* process file given by -f
*/
if (options.action == ACT_FILE)
successResult = process_file(options.action_string) ? 0 : 1;
successResult = process_file(options.action_string);
/*
* process slash command if one was given to -c
*/
......@@ -208,9 +221,10 @@ main(int argc, char *argv[])
{
const char * value;
if ((value = GetVariable(pset.vars, "ECHO")) && strcmp(value, "full")==0)
if ((value = GetVariable(pset.vars, "ECHO")) && strcmp(value, "all")==0)
puts(options.action_string);
successResult = HandleSlashCmds(options.action_string, NULL, NULL) != CMD_ERROR ? 0 : 1;
successResult = HandleSlashCmds(options.action_string, NULL, NULL) != CMD_ERROR
? EXIT_SUCCESS : EXIT_FAILURE;
}
/*
* If the query given to -c was a normal one, send it
......@@ -219,9 +233,10 @@ main(int argc, char *argv[])
{
const char * value;
if ((value = GetVariable(pset.vars, "ECHO")) && strcmp(value, "full")==0)
if ((value = GetVariable(pset.vars, "ECHO")) && strcmp(value, "all")==0)
puts(options.action_string);
successResult = SendQuery(options.action_string) ? 0 : 1;
successResult = SendQuery(options.action_string)
? EXIT_SUCCESS : EXIT_FAILURE;
}
/*
* or otherwise enter interactive main loop
......@@ -246,14 +261,11 @@ main(int argc, char *argv[])
if (!pset.notty)
initializeInput(options.no_readline ? 0 : 1);
successResult = MainLoop(stdin);
if (!pset.notty)
finishInput();
}
/* clean up */
PQfinish(pset.db);
setQFout(NULL);
DestroyVariableSpace(pset.vars);
return successResult;
}
......@@ -272,7 +284,7 @@ char *__progname = "psql";
#endif
static void
parse_options(int argc, char *argv[], struct adhoc_opts * options)
parse_psql_options(int argc, char *argv[], struct adhoc_opts * options)
{
#ifdef HAVE_GETOPT_LONG
static struct option long_options[] =
......
......@@ -3,7 +3,7 @@
*
* Copyright 2000 by PostgreSQL Global Development Group
*
* $Header: /cvsroot/pgsql/src/bin/psql/tab-complete.c,v 1.13 2000/02/20 02:37:40 tgl Exp $
* $Header: /cvsroot/pgsql/src/bin/psql/tab-complete.c,v 1.14 2000/02/20 14:28:20 petere Exp $
*/
/*-----------
......@@ -198,14 +198,19 @@ char ** psql_completion(char *text, int start, int end)
static char * backslash_commands[] = {
"\\connect", "\\copy", "\\d", "\\di", "\\di", "\\ds", "\\dS", "\\dv",
"\\da", "\\df", "\\do", "\\dt", "\\e", "\\echo", "\\g", "\\h", "\\i", "\\l",
"\\da", "\\df", "\\do", "\\dt", "\\e", "\\echo", "\\encoding",
"\\g", "\\h", "\\i", "\\l",
"\\lo_import", "\\lo_export", "\\lo_list", "\\lo_unlink",
"\\o", "\\p", "\\pset", "\\q", "\\qecho", "\\r", "\\set", "\\t", "\\x",
"\\w", "\\z", "\\!", NULL
"\\o", "\\p", "\\pset", "\\q", "\\qecho", "\\r", "\\set", "\\t", "\\unset",
"\\x", "\\w", "\\z", "\\!", NULL
};
(void)end; /* not used */
#ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER
rl_completion_append_character = ' ';
#endif
/* Clear a few things. */
completion_charp = NULL;
completion_charpp = NULL;
......@@ -547,7 +552,8 @@ char ** psql_completion(char *text, int start, int end)
/* If we still don't have anything to match we have to fabricate some sort
of default list. If we were to just return NULL, readline automatically
attempts filename completion, and that's usually no good. */
if (matches == NULL) {
if (matches == NULL)
{
COMPLETE_WITH_CONST("");
#ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER
rl_completion_append_character = '\0';
......
This diff is collapsed.
......@@ -737,7 +737,7 @@ dnl Checks for library functions.
AC_FUNC_MEMCMP
AC_TYPE_SIGNAL
AC_FUNC_VPRINTF
AC_CHECK_FUNCS(memmove sigsetjmp sysconf)
AC_CHECK_FUNCS(memmove sysconf)
AC_CHECK_FUNCS(sigprocmask waitpid setsid fcvt)
AC_CHECK_FUNCS(fpclass fp_class fp_class_d class)
dnl We use our snprintf.c emulation if either snprintf() or vsnprintf()
......@@ -856,6 +856,15 @@ AC_TRY_LINK([#include <math.h>],
[AC_DEFINE(HAVE_FINITE) AC_MSG_RESULT(yes)],
AC_MSG_RESULT(no))
dnl Cannot use AC_CHECK_FUNC because sigsetjmp may be a macro
dnl (especially on GNU libc)
dnl See also comments in config.h.
AC_MSG_CHECKING(for sigsetjmp)
AC_TRY_LINK([#include <setjmp.h>],
[sigjmp_buf x; sigsetjmp(x, 1);],
[AC_DEFINE(HAVE_SIGSETJMP) AC_MSG_RESULT(yes)],
AC_MSG_RESULT(no))
dnl Check to see if we have a working 64-bit integer type.
dnl This breaks down into two steps:
dnl (1) figure out if the compiler has a 64-bit int type with working
......
......@@ -403,6 +403,17 @@ extern int inet_aton(const char *cp, struct in_addr * addr);
/* Set to 1 if you have sigsetjmp() */
#undef HAVE_SIGSETJMP
/*
* When there is no sigsetjmp, its functionality is provided by plain
* setjmp. Incidentally, nothing provides setjmp's functionality in
* that case.
*/
#ifndef HAVE_SIGSETJMP
# define sigjmp_buf jmp_buf
# define sigsetjmp(x,y) setjmp(x)
# define siglongjmp longjmp
#endif
/* Set to 1 if you have sysconf() */
#undef HAVE_SYSCONF
......
......@@ -33,12 +33,6 @@ typedef unsigned int slock_t;
#ifdef HAVE_INT_TIMEZONE
#undef HAVE_INT_TIMEZONE
#endif
/*
* currently undefined as I (teunis@computersupportcentre.com) have not
* checked this yet
*/
/* #define HAVE_SIGSETJMP 1 */
#endif
#if defined(__powerpc__)
......
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: tcopprot.h,v 1.24 2000/01/26 05:58:35 momjian Exp $
* $Id: tcopprot.h,v 1.25 2000/02/20 14:28:28 petere Exp $
*
* OLD COMMENTS
* This file was created so that other c files could get the two
......@@ -23,20 +23,6 @@
#include "executor/execdesc.h"
#include "parser/parse_node.h"
/* Autoconf's test for HAVE_SIGSETJMP fails on Linux 2.0.x because the test
* explicitly disallows sigsetjmp being a #define, which is how it
* is declared in Linux. So, to avoid compiler warnings about
* sigsetjmp() being redefined, let's not redefine unless necessary.
* - thomas 1997-12-27
* Autoconf really ought to be brighter about macro-ized system functions...
* and this code really ought to be in config.h ...
*/
#if !defined(HAVE_SIGSETJMP) && !defined(sigsetjmp)
#define sigjmp_buf jmp_buf
#define sigsetjmp(x,y) setjmp(x)
#define siglongjmp longjmp
#endif
extern DLLIMPORT sigjmp_buf Warn_restart;
extern bool Warn_restart_ready;
extern bool InError;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment