aboutsummaryrefslogtreecommitdiff
path: root/src/bin/psql
diff options
context:
space:
mode:
Diffstat (limited to 'src/bin/psql')
-rw-r--r--src/bin/psql/command.c54
-rw-r--r--src/bin/psql/command.h4
-rw-r--r--src/bin/psql/common.c39
-rw-r--r--src/bin/psql/common.h8
-rw-r--r--src/bin/psql/help.c14
-rw-r--r--src/bin/psql/input.c4
-rw-r--r--src/bin/psql/mainloop.c43
-rw-r--r--src/bin/psql/mainloop.h10
-rw-r--r--src/bin/psql/startup.c36
-rw-r--r--src/bin/psql/tab-complete.c16
10 files changed, 153 insertions, 75 deletions
diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c
index 02bcb9335f3..c7b4577e822 100644
--- a/src/bin/psql/command.c
+++ b/src/bin/psql/command.c
@@ -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;
}
diff --git a/src/bin/psql/command.h b/src/bin/psql/command.h
index 4fcbf61fced..1fec5346faa 100644
--- a/src/bin/psql/command.h
+++ b/src/bin/psql/command.h
@@ -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
diff --git a/src/bin/psql/common.c b/src/bin/psql/common.c
index c86a2f3d834..cb352793a21 100644
--- a/src/bin/psql/common.c
+++ b/src/bin/psql/common.c
@@ -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
diff --git a/src/bin/psql/common.h b/src/bin/psql/common.h
index af6f04965da..6a7be3ec202 100644
--- a/src/bin/psql/common.h
+++ b/src/bin/psql/common.h
@@ -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);
diff --git a/src/bin/psql/help.c b/src/bin/psql/help.c
index 30d2307e892..8fa9187d2da 100644
--- a/src/bin/psql/help.c
+++ b/src/bin/psql/help.c
@@ -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");
diff --git a/src/bin/psql/input.c b/src/bin/psql/input.c
index 2e509aad0b1..6d7143467c0 100644
--- a/src/bin/psql/input.c
+++ b/src/bin/psql/input.c
@@ -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);
}
diff --git a/src/bin/psql/mainloop.c b/src/bin/psql/mainloop.c
index 28d7b58bb06..9b3834cca7d 100644
--- a/src/bin/psql/mainloop.c
+++ b/src/bin/psql/mainloop.c
@@ -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);
diff --git a/src/bin/psql/mainloop.h b/src/bin/psql/mainloop.h
index 72d46d76dbd..a9cc61b7f66 100644
--- a/src/bin/psql/mainloop.h
+++ b/src/bin/psql/mainloop.h
@@ -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 */
diff --git a/src/bin/psql/startup.c b/src/bin/psql/startup.c
index ccb5f477e65..7f538048acd 100644
--- a/src/bin/psql/startup.c
+++ b/src/bin/psql/startup.c
@@ -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[] =
diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c
index f1492e11ed3..9edfc6b6da8 100644
--- a/src/bin/psql/tab-complete.c
+++ b/src/bin/psql/tab-complete.c
@@ -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';