summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--acinclude.m439
-rw-r--r--client/mysql.cc14
-rw-r--r--cmd-line-utils/libedit/chared.c55
-rw-r--r--cmd-line-utils/libedit/chared.h12
-rw-r--r--cmd-line-utils/libedit/common.c96
-rw-r--r--cmd-line-utils/libedit/el.c85
-rw-r--r--cmd-line-utils/libedit/el.h18
-rw-r--r--cmd-line-utils/libedit/el_term.h131
-rw-r--r--cmd-line-utils/libedit/emacs.c109
-rw-r--r--cmd-line-utils/libedit/fgetln.c185
-rw-r--r--cmd-line-utils/libedit/hist.c28
-rw-r--r--cmd-line-utils/libedit/hist.h8
-rw-r--r--cmd-line-utils/libedit/histedit.h37
-rw-r--r--cmd-line-utils/libedit/history.c67
-rw-r--r--cmd-line-utils/libedit/key.c54
-rw-r--r--cmd-line-utils/libedit/key.h37
-rw-r--r--cmd-line-utils/libedit/map.c58
-rw-r--r--cmd-line-utils/libedit/map.h8
-rw-r--r--cmd-line-utils/libedit/parse.c34
-rw-r--r--cmd-line-utils/libedit/parse.h8
-rw-r--r--cmd-line-utils/libedit/prompt.c23
-rw-r--r--cmd-line-utils/libedit/prompt.h8
-rw-r--r--cmd-line-utils/libedit/read.c147
-rw-r--r--cmd-line-utils/libedit/read.h4
-rw-r--r--cmd-line-utils/libedit/readline.c1241
-rw-r--r--cmd-line-utils/libedit/readline/readline.h83
-rw-r--r--cmd-line-utils/libedit/refresh.c29
-rw-r--r--cmd-line-utils/libedit/refresh.h8
-rw-r--r--cmd-line-utils/libedit/search.c84
-rw-r--r--cmd-line-utils/libedit/search.h10
-rw-r--r--cmd-line-utils/libedit/sig.c17
-rw-r--r--cmd-line-utils/libedit/sig.h8
-rw-r--r--cmd-line-utils/libedit/strlcpy.c83
-rw-r--r--cmd-line-utils/libedit/sys.h34
-rw-r--r--cmd-line-utils/libedit/term.c143
-rw-r--r--cmd-line-utils/libedit/tokenizer.c100
-rw-r--r--cmd-line-utils/libedit/tty.c162
-rw-r--r--cmd-line-utils/libedit/tty.h8
-rw-r--r--cmd-line-utils/libedit/unvis.c311
-rw-r--r--cmd-line-utils/libedit/vi.c149
-rw-r--r--cmd-line-utils/libedit/vis.c392
-rw-r--r--cmd-line-utils/libedit/vis.h92
-rw-r--r--configure.in2
-rw-r--r--innobase/dict/dict0dict.c12
-rw-r--r--innobase/fil/fil0fil.c9
-rw-r--r--innobase/include/dict0dict.h7
-rw-r--r--mysql-test/r/archive.result16
-rw-r--r--mysql-test/r/blackhole.result41
-rw-r--r--mysql-test/t/archive.test13
-rw-r--r--mysql-test/t/blackhole.test30
-rw-r--r--ndb/include/kernel/signaldata/BackupImpl.hpp12
-rw-r--r--ndb/include/kernel/signaldata/BackupSignalData.hpp3
-rw-r--r--ndb/src/common/debugger/signaldata/BackupImpl.cpp6
-rw-r--r--ndb/src/kernel/blocks/backup/Backup.cpp1495
-rw-r--r--ndb/src/kernel/blocks/backup/Backup.hpp36
-rw-r--r--ndb/src/kernel/blocks/backup/Backup.txt25
-rw-r--r--ndb/src/kernel/blocks/backup/BackupInit.cpp2
-rw-r--r--ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp1
-rw-r--r--ndb/src/kernel/blocks/dbacc/Dbacc.hpp6
-rw-r--r--ndb/src/kernel/blocks/dbacc/DbaccMain.cpp215
-rw-r--r--ndb/src/kernel/blocks/dbdict/Dbdict.cpp37
-rw-r--r--ndb/src/kernel/blocks/dblqh/Dblqh.hpp3
-rw-r--r--ndb/src/kernel/blocks/dblqh/DblqhMain.cpp66
-rw-r--r--ndb/src/kernel/blocks/ndbfs/OpenFiles.hpp10
-rw-r--r--ndb/src/mgmapi/mgmapi.cpp4
-rw-r--r--ndb/src/mgmsrv/MgmtSrvr.cpp29
-rw-r--r--ndb/src/mgmsrv/MgmtSrvr.hpp4
-rw-r--r--ndb/src/mgmsrv/MgmtSrvrGeneralSignalHandling.cpp6
-rw-r--r--ndb/src/ndbapi/Ndbif.cpp8
-rw-r--r--ndb/src/ndbapi/ndberror.c11
-rw-r--r--ndb/test/ndbapi/testBackup.cpp14
-rw-r--r--ndb/test/ndbapi/testIndex.cpp2
-rw-r--r--ndb/test/ndbapi/testOperations.cpp80
-rw-r--r--ndb/test/run-test/daily-basic-tests.txt48
-rw-r--r--ndb/test/src/NdbBackup.cpp46
-rw-r--r--sql/examples/ha_archive.cc24
-rw-r--r--sql/examples/ha_archive.h1
-rw-r--r--sql/mysqld.cc2
78 files changed, 4150 insertions, 2395 deletions
diff --git a/acinclude.m4 b/acinclude.m4
index 74426bc2061..61b37294377 100644
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -97,10 +97,10 @@ undefine([AC_CV_NAME])dnl
AC_DEFUN([MYSQL_TYPE_ACCEPT],
[ac_save_CXXFLAGS="$CXXFLAGS"
AC_CACHE_CHECK([base type of last arg to accept], mysql_cv_btype_last_arg_accept,
-AC_LANG_SAVE
-AC_LANG_CPLUSPLUS
+AC_LANG_PUSH(C++)
if test "$ac_cv_prog_gxx" = "yes"
then
+ # Add -Werror, remove -fbranch-probabilities (Bug #268)
CXXFLAGS=`echo $CXXFLAGS -Werror | sed 's/-fbranch-probabilities//'`
fi
mysql_cv_btype_last_arg_accept=none
@@ -127,7 +127,7 @@ fi
if test "$mysql_cv_btype_last_arg_accept" = "none"; then
mysql_cv_btype_last_arg_accept=int
fi)
-AC_LANG_RESTORE
+AC_LANG_POP(C++)
AC_DEFINE_UNQUOTED([SOCKET_SIZE_TYPE], [$mysql_cv_btype_last_arg_accept],
[The base type of the last arg to accept])
CXXFLAGS="$ac_save_CXXFLAGS"
@@ -153,6 +153,35 @@ then
fi
])
+#---START: Figure out whether to use 'struct rlimit' or 'struct rlimit64'
+AC_DEFUN([MYSQL_TYPE_STRUCT_RLIMIT],
+[ac_save_CXXFLAGS="$CXXFLAGS"
+AC_CACHE_CHECK([struct type to use with setrlimit], mysql_cv_btype_struct_rlimit,
+AC_LANG_PUSH(C++)
+if test "$ac_cv_prog_gxx" = "yes"
+then
+ # Add -Werror, remove -fbranch-probabilities (Bug #268)
+ CXXFLAGS=`echo $CXXFLAGS -Werror | sed 's/-fbranch-probabilities//'`
+fi
+mysql_cv_btype_struct_rlimit=none
+[AC_TRY_COMPILE([#if defined(inline)
+#undef inline
+#endif
+#include <stdlib.h>
+#include <sys/resource.h>
+],
+[struct rlimit64 rl; setrlimit(RLIMIT_CORE, &rl);],
+mysql_cv_btype_struct_rlimit="struct rlimit64")]
+if test "$mysql_cv_btype_struct_rlimit" = "none"; then
+mysql_cv_btype_struct_rlimit="struct rlimit"
+fi)
+AC_LANG_POP(C++)
+AC_DEFINE_UNQUOTED([STRUCT_RLIMIT], [$mysql_cv_btype_struct_rlimit],
+ [The struct rlimit type to use with setrlimit])
+CXXFLAGS="$ac_save_CXXFLAGS"
+])
+#---END:
+
AC_DEFUN([MYSQL_TIMESPEC_TS],
[AC_CACHE_CHECK([if struct timespec has a ts_sec member], mysql_cv_timespec_ts,
[AC_TRY_COMPILE([#include <pthread.h>
@@ -1940,8 +1969,8 @@ m4_define([_AC_PROG_CXX_EXIT_DECLARATION],
'void exit (int);' \
'#include <stdlib.h>'
do
- _AC_COMPILE_IFELSE([AC_LANG_PROGRAM([@%:@include <stdlib.h>
-$ac_declaration],
+ _AC_COMPILE_IFELSE([AC_LANG_PROGRAM([$ac_declaration
+@%:@include <stdlib.h>],
[exit (42);])],
[],
[continue])
diff --git a/client/mysql.cc b/client/mysql.cc
index 0c229796c1e..f27db0de8d8 100644
--- a/client/mysql.cc
+++ b/client/mysql.cc
@@ -691,8 +691,16 @@ static void usage(int version)
#ifdef __NETWARE__
#define printf consoleprintf
#endif
- printf("%s Ver %s Distrib %s, for %s (%s)\n",
- my_progname, VER, MYSQL_SERVER_VERSION, SYSTEM_TYPE, MACHINE_TYPE);
+
+#if defined(USE_LIBEDIT_INTERFACE)
+ const char* readline= "";
+#else
+ const char* readline= "readline";
+#endif
+
+ printf("%s Ver %s Distrib %s, for %s (%s) using %s %s\n",
+ my_progname, VER, MYSQL_SERVER_VERSION, SYSTEM_TYPE, MACHINE_TYPE,
+ readline, rl_library_version);
if (version)
return;
printf("\
@@ -1306,7 +1314,7 @@ static void initialize_readline (char *name)
setlocale(LC_ALL,""); /* so as libedit use isprint */
#endif
rl_attempted_completion_function= (CPPFunction*)&new_mysql_completion;
- rl_completion_entry_function= (CPFunction*)&no_completion;
+ rl_completion_entry_function= (Function*)&no_completion;
#else
rl_attempted_completion_function= (CPPFunction*)&new_mysql_completion;
rl_completion_entry_function= (Function*)&no_completion;
diff --git a/cmd-line-utils/libedit/chared.c b/cmd-line-utils/libedit/chared.c
index 62a407e66a8..21fc8bc2c1d 100644
--- a/cmd-line-utils/libedit/chared.c
+++ b/cmd-line-utils/libedit/chared.c
@@ -1,4 +1,4 @@
-/* $NetBSD: chared.c,v 1.18 2002/11/20 16:50:08 christos Exp $ */
+/* $NetBSD: chared.c,v 1.22 2004/08/13 12:10:38 mycroft Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -15,11 +15,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
@@ -36,14 +32,7 @@
* SUCH DAMAGE.
*/
-#include "config.h"
-#if !defined(lint) && !defined(SCCSID)
-#if 0
-static char sccsid[] = "@(#)chared.c 8.1 (Berkeley) 6/4/93";
-#else
-__RCSID("$NetBSD: chared.c,v 1.18 2002/11/20 16:50:08 christos Exp $");
-#endif
-#endif /* not lint && not SCCSID */
+#include <config.h>
/*
* chared.c: Character editor utilities
@@ -62,13 +51,13 @@ cv_undo(EditLine *el)
{
c_undo_t *vu = &el->el_chared.c_undo;
c_redo_t *r = &el->el_chared.c_redo;
- int size;
+ uint size;
/* Save entire line for undo */
size = el->el_line.lastchar - el->el_line.buffer;
vu->len = size;
vu->cursor = el->el_line.cursor - el->el_line.buffer;
- memcpy(vu->buf, el->el_line.buffer, (size_t)size);
+ memcpy(vu->buf, el->el_line.buffer, size);
/* save command info for redo */
r->count = el->el_state.doingarg ? el->el_state.argument : 0;
@@ -139,6 +128,21 @@ c_delafter(EditLine *el, int num)
}
+/* c_delafter1():
+ * Delete the character after the cursor, do not yank
+ */
+protected void
+c_delafter1(EditLine *el)
+{
+ char *cp;
+
+ for (cp = el->el_line.cursor; cp <= el->el_line.lastchar; cp++)
+ *cp = cp[1];
+
+ el->el_line.lastchar--;
+}
+
+
/* c_delbefore():
* Delete num characters before the cursor
*/
@@ -167,6 +171,21 @@ c_delbefore(EditLine *el, int num)
}
+/* c_delbefore1():
+ * Delete the character before the cursor, do not yank
+ */
+protected void
+c_delbefore1(EditLine *el)
+{
+ char *cp;
+
+ for (cp = el->el_line.cursor - 1; cp <= el->el_line.lastchar; cp++)
+ *cp = cp[1];
+
+ el->el_line.lastchar--;
+}
+
+
/* ce__isword():
* Return if p is part of a word according to emacs
*/
@@ -460,8 +479,8 @@ ch_init(EditLine *el)
el->el_state.argument = 1;
el->el_state.lastcmd = ED_UNASSIGNED;
- el->el_chared.c_macro.nline = NULL;
el->el_chared.c_macro.level = -1;
+ el->el_chared.c_macro.offset = 0;
el->el_chared.c_macro.macro = (char **) el_malloc(EL_MAXMACRO *
sizeof(char *));
if (el->el_chared.c_macro.macro == NULL)
@@ -582,7 +601,7 @@ ch_enlargebufs(el, addlen)
return 0;
/* Safe to set enlarged buffer size */
- el->el_line.limit = &newbuffer[newsz - EL_LEAVE];
+ el->el_line.limit = &el->el_line.buffer[newsz - EL_LEAVE];
return 1;
}
diff --git a/cmd-line-utils/libedit/chared.h b/cmd-line-utils/libedit/chared.h
index d2e6f742413..2dd0a5795c7 100644
--- a/cmd-line-utils/libedit/chared.h
+++ b/cmd-line-utils/libedit/chared.h
@@ -1,4 +1,4 @@
-/* $NetBSD: chared.h,v 1.11 2002/11/20 16:50:08 christos Exp $ */
+/* $NetBSD: chared.h,v 1.14 2004/08/13 12:10:39 mycroft Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -15,11 +15,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
@@ -66,8 +62,8 @@
typedef struct c_macro_t {
int level;
+ int offset;
char **macro;
- char *nline;
} c_macro_t;
/*
@@ -158,7 +154,9 @@ protected char *c__next_word(char *, char *, int, int (*)(int));
protected char *c__prev_word(char *, char *, int, int (*)(int));
protected void c_insert(EditLine *, int);
protected void c_delbefore(EditLine *, int);
+protected void c_delbefore1(EditLine *);
protected void c_delafter(EditLine *, int);
+protected void c_delafter1(EditLine *);
protected int c_gets(EditLine *, char *, const char *);
protected int c_hpos(EditLine *);
diff --git a/cmd-line-utils/libedit/common.c b/cmd-line-utils/libedit/common.c
index f290057568a..81bf9bf29ff 100644
--- a/cmd-line-utils/libedit/common.c
+++ b/cmd-line-utils/libedit/common.c
@@ -1,4 +1,4 @@
-/* $NetBSD: common.c,v 1.14 2002/11/20 16:50:08 christos Exp $ */
+/* $NetBSD: common.c,v 1.16 2003/08/07 16:44:30 agc Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -15,11 +15,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
@@ -36,14 +32,7 @@
* SUCH DAMAGE.
*/
-#include "config.h"
-#if !defined(lint) && !defined(SCCSID)
-#if 0
-static char sccsid[] = "@(#)common.c 8.1 (Berkeley) 6/4/93";
-#else
-__RCSID("$NetBSD: common.c,v 1.14 2002/11/20 16:50:08 christos Exp $");
-#endif
-#endif /* not lint && not SCCSID */
+#include <config.h>
/*
* common.c: Common Editor functions
@@ -56,7 +45,7 @@ __RCSID("$NetBSD: common.c,v 1.14 2002/11/20 16:50:08 christos Exp $");
*/
protected el_action_t
/*ARGSUSED*/
-ed_end_of_file(EditLine *el, int c __attribute__((unused)))
+ed_end_of_file(EditLine *el, int c __attribute__((__unused__)))
{
re_goto_bottom(el);
@@ -113,7 +102,7 @@ ed_insert(EditLine *el, int c)
*/
protected el_action_t
/*ARGSUSED*/
-ed_delete_prev_word(EditLine *el, int c __attribute__((unused)))
+ed_delete_prev_word(EditLine *el, int c __attribute__((__unused__)))
{
char *cp, *p, *kp;
@@ -141,7 +130,7 @@ ed_delete_prev_word(EditLine *el, int c __attribute__((unused)))
*/
protected el_action_t
/*ARGSUSED*/
-ed_delete_next_char(EditLine *el, int c __attribute__((unused)))
+ed_delete_next_char(EditLine *el, int c __attribute__((__unused__)))
{
#ifdef notdef /* XXX */
#define EL el->el_line
@@ -192,7 +181,7 @@ ed_delete_next_char(EditLine *el, int c __attribute__((unused)))
*/
protected el_action_t
/*ARGSUSED*/
-ed_kill_line(EditLine *el, int c __attribute__((unused)))
+ed_kill_line(EditLine *el, int c __attribute__((__unused__)))
{
char *kp, *cp;
@@ -213,7 +202,7 @@ ed_kill_line(EditLine *el, int c __attribute__((unused)))
*/
protected el_action_t
/*ARGSUSED*/
-ed_move_to_end(EditLine *el, int c __attribute__((unused)))
+ed_move_to_end(EditLine *el, int c __attribute__((__unused__)))
{
el->el_line.cursor = el->el_line.lastchar;
@@ -236,7 +225,7 @@ ed_move_to_end(EditLine *el, int c __attribute__((unused)))
*/
protected el_action_t
/*ARGSUSED*/
-ed_move_to_beg(EditLine *el, int c __attribute__((unused)))
+ed_move_to_beg(EditLine *el, int c __attribute__((__unused__)))
{
el->el_line.cursor = el->el_line.buffer;
@@ -285,7 +274,7 @@ ed_transpose_chars(EditLine *el, int c)
*/
protected el_action_t
/*ARGSUSED*/
-ed_next_char(EditLine *el, int c __attribute__((unused)))
+ed_next_char(EditLine *el, int c __attribute__((__unused__)))
{
char *lim = el->el_line.lastchar;
@@ -314,7 +303,7 @@ ed_next_char(EditLine *el, int c __attribute__((unused)))
*/
protected el_action_t
/*ARGSUSED*/
-ed_prev_word(EditLine *el, int c __attribute__((unused)))
+ed_prev_word(EditLine *el, int c __attribute__((__unused__)))
{
if (el->el_line.cursor == el->el_line.buffer)
@@ -340,7 +329,7 @@ ed_prev_word(EditLine *el, int c __attribute__((unused)))
*/
protected el_action_t
/*ARGSUSED*/
-ed_prev_char(EditLine *el, int c __attribute__((unused)))
+ed_prev_char(EditLine *el, int c __attribute__((__unused__)))
{
if (el->el_line.cursor > el->el_line.buffer) {
@@ -437,8 +426,7 @@ ed_argument_digit(EditLine *el, int c)
*/
protected el_action_t
/*ARGSUSED*/
-ed_unassigned(EditLine *el __attribute__((unused)),
- int c __attribute__((unused)))
+ed_unassigned(EditLine *el, int c __attribute__((__unused__)))
{
return (CC_ERROR);
@@ -455,8 +443,8 @@ ed_unassigned(EditLine *el __attribute__((unused)),
*/
protected el_action_t
/*ARGSUSED*/
-ed_tty_sigint(EditLine *el __attribute__((unused)),
- int c __attribute__((unused)))
+ed_tty_sigint(EditLine *el __attribute__((__unused__)),
+ int c __attribute__((__unused__)))
{
return (CC_NORM);
@@ -469,8 +457,8 @@ ed_tty_sigint(EditLine *el __attribute__((unused)),
*/
protected el_action_t
/*ARGSUSED*/
-ed_tty_dsusp(EditLine *el __attribute__((unused)),
- int c __attribute__((unused)))
+ed_tty_dsusp(EditLine *el __attribute__((__unused__)),
+ int c __attribute__((__unused__)))
{
return (CC_NORM);
@@ -483,8 +471,8 @@ ed_tty_dsusp(EditLine *el __attribute__((unused)),
*/
protected el_action_t
/*ARGSUSED*/
-ed_tty_flush_output(EditLine *el __attribute__((unused)),
- int c __attribute__((unused)))
+ed_tty_flush_output(EditLine *el __attribute__((__unused__)),
+ int c __attribute__((__unused__)))
{
return (CC_NORM);
@@ -497,8 +485,8 @@ ed_tty_flush_output(EditLine *el __attribute__((unused)),
*/
protected el_action_t
/*ARGSUSED*/
-ed_tty_sigquit(EditLine *el __attribute__((unused)),
- int c __attribute__((unused)))
+ed_tty_sigquit(EditLine *el __attribute__((__unused__)),
+ int c __attribute__((__unused__)))
{
return (CC_NORM);
@@ -511,8 +499,8 @@ ed_tty_sigquit(EditLine *el __attribute__((unused)),
*/
protected el_action_t
/*ARGSUSED*/
-ed_tty_sigtstp(EditLine *el __attribute__((unused)),
- int c __attribute__((unused)))
+ed_tty_sigtstp(EditLine *el __attribute__((__unused__)),
+ int c __attribute__((__unused__)))
{
return (CC_NORM);
@@ -525,8 +513,8 @@ ed_tty_sigtstp(EditLine *el __attribute__((unused)),
*/
protected el_action_t
/*ARGSUSED*/
-ed_tty_stop_output(EditLine *el __attribute__((unused)),
- int c __attribute__((unused)))
+ed_tty_stop_output(EditLine *el __attribute__((__unused__)),
+ int c __attribute__((__unused__)))
{
return (CC_NORM);
@@ -539,8 +527,8 @@ ed_tty_stop_output(EditLine *el __attribute__((unused)),
*/
protected el_action_t
/*ARGSUSED*/
-ed_tty_start_output(EditLine *el __attribute__((unused)),
- int c __attribute__((unused)))
+ed_tty_start_output(EditLine *el __attribute__((__unused__)),
+ int c __attribute__((__unused__)))
{
return (CC_NORM);
@@ -553,7 +541,7 @@ ed_tty_start_output(EditLine *el __attribute__((unused)),
*/
protected el_action_t
/*ARGSUSED*/
-ed_newline(EditLine *el, int c __attribute__((unused)))
+ed_newline(EditLine *el, int c __attribute__((__unused__)))
{
re_goto_bottom(el);
@@ -569,7 +557,7 @@ ed_newline(EditLine *el, int c __attribute__((unused)))
*/
protected el_action_t
/*ARGSUSED*/
-ed_delete_prev_char(EditLine *el, int c __attribute__((unused)))
+ed_delete_prev_char(EditLine *el, int c __attribute__((__unused__)))
{
if (el->el_line.cursor <= el->el_line.buffer)
@@ -589,7 +577,7 @@ ed_delete_prev_char(EditLine *el, int c __attribute__((unused)))
*/
protected el_action_t
/*ARGSUSED*/
-ed_clear_screen(EditLine *el, int c __attribute__((unused)))
+ed_clear_screen(EditLine *el, int c __attribute__((__unused__)))
{
term_clear_screen(el); /* clear the whole real screen */
@@ -604,8 +592,8 @@ ed_clear_screen(EditLine *el, int c __attribute__((unused)))
*/
protected el_action_t
/*ARGSUSED*/
-ed_redisplay(EditLine *el __attribute__((unused)),
- int c __attribute__((unused)))
+ed_redisplay(EditLine *el __attribute__((__unused__)),
+ int c __attribute__((__unused__)))
{
return (CC_REDISPLAY);
@@ -618,7 +606,7 @@ ed_redisplay(EditLine *el __attribute__((unused)),
*/
protected el_action_t
/*ARGSUSED*/
-ed_start_over(EditLine *el, int c __attribute__((unused)))
+ed_start_over(EditLine *el, int c __attribute__((__unused__)))
{
ch_reset(el);
@@ -632,8 +620,8 @@ ed_start_over(EditLine *el, int c __attribute__((unused)))
*/
protected el_action_t
/*ARGSUSED*/
-ed_sequence_lead_in(EditLine *el __attribute__((unused)),
- int c __attribute__((unused)))
+ed_sequence_lead_in(EditLine *el __attribute__((__unused__)),
+ int c __attribute__((__unused__)))
{
return (CC_NORM);
@@ -646,7 +634,7 @@ ed_sequence_lead_in(EditLine *el __attribute__((unused)),
*/
protected el_action_t
/*ARGSUSED*/
-ed_prev_history(EditLine *el, int c __attribute__((unused)))
+ed_prev_history(EditLine *el, int c __attribute__((__unused__)))
{
char beep = 0;
int sv_event = el->el_history.eventno;
@@ -684,7 +672,7 @@ ed_prev_history(EditLine *el, int c __attribute__((unused)))
*/
protected el_action_t
/*ARGSUSED*/
-ed_next_history(EditLine *el, int c __attribute__((unused)))
+ed_next_history(EditLine *el, int c __attribute__((__unused__)))
{
el_action_t beep = CC_REFRESH, rval;
@@ -711,7 +699,7 @@ ed_next_history(EditLine *el, int c __attribute__((unused)))
*/
protected el_action_t
/*ARGSUSED*/
-ed_search_prev_history(EditLine *el, int c __attribute__((unused)))
+ed_search_prev_history(EditLine *el, int c __attribute__((__unused__)))
{
const char *hp;
int h;
@@ -779,7 +767,7 @@ ed_search_prev_history(EditLine *el, int c __attribute__((unused)))
*/
protected el_action_t
/*ARGSUSED*/
-ed_search_next_history(EditLine *el, int c __attribute__((unused)))
+ed_search_next_history(EditLine *el, int c __attribute__((__unused__)))
{
const char *hp;
int h;
@@ -833,7 +821,7 @@ ed_search_next_history(EditLine *el, int c __attribute__((unused)))
*/
protected el_action_t
/*ARGSUSED*/
-ed_prev_line(EditLine *el, int c __attribute__((unused)))
+ed_prev_line(EditLine *el, int c __attribute__((__unused__)))
{
char *ptr;
int nchars = c_hpos(el);
@@ -876,7 +864,7 @@ ed_prev_line(EditLine *el, int c __attribute__((unused)))
*/
protected el_action_t
/*ARGSUSED*/
-ed_next_line(EditLine *el, int c __attribute__((unused)))
+ed_next_line(EditLine *el, int c __attribute__((__unused__)))
{
char *ptr;
int nchars = c_hpos(el);
@@ -910,7 +898,7 @@ ed_next_line(EditLine *el, int c __attribute__((unused)))
*/
protected el_action_t
/*ARGSUSED*/
-ed_command(EditLine *el, int c __attribute__((unused)))
+ed_command(EditLine *el, int c __attribute__((__unused__)))
{
char tmpbuf[EL_BUFSIZ];
int tmplen;
diff --git a/cmd-line-utils/libedit/el.c b/cmd-line-utils/libedit/el.c
index 1b445d40f1c..c32a01b2151 100644
--- a/cmd-line-utils/libedit/el.c
+++ b/cmd-line-utils/libedit/el.c
@@ -1,4 +1,4 @@
-/* $NetBSD: el.c,v 1.30 2002/11/12 00:00:23 thorpej Exp $ */
+/* $NetBSD: el.c,v 1.39 2004/07/08 00:51:36 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -15,11 +15,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
@@ -36,14 +32,7 @@
* SUCH DAMAGE.
*/
-#include "config.h"
-#if !defined(lint) && !defined(SCCSID)
-#if 0
-static char sccsid[] = "@(#)el.c 8.2 (Berkeley) 1/3/94";
-#else
-__RCSID("$NetBSD: el.c,v 1.30 2002/11/12 00:00:23 thorpej Exp $");
-#endif
-#endif /* not lint && not SCCSID */
+#include <config.h>
/*
* el.c: EditLine interface functions
@@ -72,7 +61,10 @@ el_init(const char *prog, FILE *fin, FILE *fout, FILE *ferr)
el->el_infd = fileno(fin);
el->el_outfile = fout;
el->el_errfile = ferr;
- el->el_prog = strdup(prog);
+ if ((el->el_prog = el_strdup(prog)) == NULL) {
+ el_free(el);
+ return NULL;
+ }
/*
* Initialize all the modules. Order is important!!!
@@ -80,11 +72,11 @@ el_init(const char *prog, FILE *fin, FILE *fout, FILE *ferr)
el->el_flags = 0;
if (term_init(el) == -1) {
- free(el->el_prog);
+ el_free(el->el_prog);
el_free(el);
return NULL;
}
- (void) el_key_init(el);
+ (void) key_init(el);
(void) map_init(el);
if (tty_init(el) == -1)
el->el_flags |= NO_TTY;
@@ -112,7 +104,7 @@ el_end(EditLine *el)
el_reset(el);
term_end(el);
- el_key_end(el);
+ key_end(el);
map_end(el);
tty_end(el);
ch_end(el);
@@ -257,6 +249,27 @@ el_set(EditLine *el, int op, ...)
el->el_data = va_arg(va, void *);
break;
+ case EL_UNBUFFERED:
+ rv = va_arg(va, int);
+ if (rv && !(el->el_flags & UNBUFFERED)) {
+ el->el_flags |= UNBUFFERED;
+ read_prepare(el);
+ } else if (!rv && (el->el_flags & UNBUFFERED)) {
+ el->el_flags &= ~UNBUFFERED;
+ read_finish(el);
+ }
+ rv = 0;
+ break;
+
+ case EL_PREP_TERM:
+ rv = va_arg(va, int);
+ if (rv)
+ (void) tty_rawmode(el);
+ else
+ (void) tty_cookedmode(el);
+ rv = 0;
+ break;
+
default:
rv = -1;
break;
@@ -297,21 +310,22 @@ el_get(EditLine *el, int op, void *ret)
rv = 0;
break;
-#if 0 /* XXX */
case EL_TERMINAL:
- rv = term_get(el, (const char *) &ret);
+ term_get(el, (const char **)ret);
+ rv = 0;
break;
+#if 0 /* XXX */
case EL_BIND:
case EL_TELLTC:
case EL_SETTC:
case EL_ECHOTC:
case EL_SETTY:
{
- char *argv[20];
+ const char *argv[20];
int i;
- for (i = 1; i < 20; i++)
+ for (i = 1; i < sizeof(argv) / sizeof(argv[0]); i++)
if ((argv[i] = va_arg(va, char *)) == NULL)
break;
@@ -378,6 +392,11 @@ el_get(EditLine *el, int op, void *ret)
rv = 0;
break;
+ case EL_UNBUFFERED:
+ *((int *) ret) = (!(el->el_flags & UNBUFFERED));
+ rv = 0;
+ break;
+
default:
rv = -1;
}
@@ -409,12 +428,17 @@ el_source(EditLine *el, const char *fname)
fp = NULL;
if (fname == NULL) {
-#ifdef HAVE_ISSETUGID
static const char elpath[] = "/.editrc";
+#ifdef MAXPATHLEN
char path[MAXPATHLEN];
+#else
+ char path[4096];
+#endif
+#ifdef HAVE_ISSETUGID
if (issetugid())
return (-1);
+#endif
if ((ptr = getenv("HOME")) == NULL)
return (-1);
if (strlcpy(path, ptr, sizeof(path)) >= sizeof(path))
@@ -422,14 +446,6 @@ el_source(EditLine *el, const char *fname)
if (strlcat(path, elpath, sizeof(path)) >= sizeof(path))
return (-1);
fname = path;
-#else
- /*
- * If issetugid() is missing, always return an error, in order
- * to keep from inadvertently opening up the user to a security
- * hole.
- */
- return (-1);
-#endif
}
if (fp == NULL)
fp = fopen(fname, "r");
@@ -496,10 +512,13 @@ el_editmode(EditLine *el, int argc, const char **argv)
return (-1);
how = argv[1];
- if (strcmp(how, "on") == 0)
+ if (strcmp(how, "on") == 0) {
el->el_flags &= ~EDIT_DISABLED;
- else if (strcmp(how, "off") == 0)
+ tty_rawmode(el);
+ } else if (strcmp(how, "off") == 0) {
+ tty_cookedmode(el);
el->el_flags |= EDIT_DISABLED;
+ }
else {
(void) fprintf(el->el_errfile, "edit: Bad value `%s'.\n", how);
return (-1);
diff --git a/cmd-line-utils/libedit/el.h b/cmd-line-utils/libedit/el.h
index 49bd462ad3b..c4b6cff2186 100644
--- a/cmd-line-utils/libedit/el.h
+++ b/cmd-line-utils/libedit/el.h
@@ -1,4 +1,4 @@
-/* $NetBSD: el.h,v 1.13 2002/11/15 14:32:33 christos Exp $ */
+/* $NetBSD: el.h,v 1.16 2003/10/18 23:48:42 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -15,11 +15,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
@@ -55,9 +51,10 @@
#define EL_BUFSIZ 1024 /* Maximum line size */
-#define HANDLE_SIGNALS 1<<0
-#define NO_TTY 1<<1
-#define EDIT_DISABLED 1<<2
+#define HANDLE_SIGNALS 0x01
+#define NO_TTY 0x02
+#define EDIT_DISABLED 0x04
+#define UNBUFFERED 0x08
typedef int bool_t; /* True or not */
@@ -91,6 +88,7 @@ typedef struct el_state_t {
/*
* Until we come up with something better...
*/
+#define el_strdup(a) strdup(a)
#define el_malloc(a) malloc(a)
#define el_realloc(a,b) realloc(a, b)
#define el_free(a) free(a)
@@ -98,7 +96,7 @@ typedef struct el_state_t {
#include "tty.h"
#include "prompt.h"
#include "key.h"
-#include "libedit_term.h"
+#include "el_term.h"
#include "refresh.h"
#include "chared.h"
#include "common.h"
diff --git a/cmd-line-utils/libedit/el_term.h b/cmd-line-utils/libedit/el_term.h
new file mode 100644
index 00000000000..9e5588ee96f
--- /dev/null
+++ b/cmd-line-utils/libedit/el_term.h
@@ -0,0 +1,131 @@
+/* $NetBSD: term.h,v 1.15 2003/09/14 21:48:55 christos Exp $ */
+
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Christos Zoulas of Cornell University.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)term.h 8.1 (Berkeley) 6/4/93
+ */
+
+/*
+ * el.term.h: Termcap header
+ */
+#ifndef _h_el_term
+#define _h_el_term
+
+#include "histedit.h"
+
+typedef struct { /* Symbolic function key bindings */
+ const char *name; /* name of the key */
+ int key; /* Index in termcap table */
+ key_value_t fun; /* Function bound to it */
+ int type; /* Type of function */
+} fkey_t;
+
+typedef struct {
+ const char *t_name; /* the terminal name */
+ coord_t t_size; /* # lines and cols */
+ int t_flags;
+#define TERM_CAN_INSERT 0x001 /* Has insert cap */
+#define TERM_CAN_DELETE 0x002 /* Has delete cap */
+#define TERM_CAN_CEOL 0x004 /* Has CEOL cap */
+#define TERM_CAN_TAB 0x008 /* Can use tabs */
+#define TERM_CAN_ME 0x010 /* Can turn all attrs. */
+#define TERM_CAN_UP 0x020 /* Can move up */
+#define TERM_HAS_META 0x040 /* Has a meta key */
+#define TERM_HAS_AUTO_MARGINS 0x080 /* Has auto margins */
+#define TERM_HAS_MAGIC_MARGINS 0x100 /* Has magic margins */
+ char *t_buf; /* Termcap buffer */
+ int t_loc; /* location used */
+ char **t_str; /* termcap strings */
+ int *t_val; /* termcap values */
+ char *t_cap; /* Termcap buffer */
+ fkey_t *t_fkey; /* Array of keys */
+} el_term_t;
+
+/*
+ * fKey indexes
+ */
+#define A_K_DN 0
+#define A_K_UP 1
+#define A_K_LT 2
+#define A_K_RT 3
+#define A_K_HO 4
+#define A_K_EN 5
+#define A_K_NKEYS 6
+
+#ifdef _SUNOS
+extern int tgetent(char *, const char *);
+extern int tgetflag(char *);
+extern int tgetnum(char *);
+extern int tputs(const char *, int, int (*)(int));
+extern char* tgoto(const char*, int, int);
+extern char* tgetstr(char*, char**);
+#endif
+
+protected void term_move_to_line(EditLine *, int);
+protected void term_move_to_char(EditLine *, int);
+protected void term_clear_EOL(EditLine *, int);
+protected void term_overwrite(EditLine *, const char *, int);
+protected void term_insertwrite(EditLine *, char *, int);
+protected void term_deletechars(EditLine *, int);
+protected void term_clear_screen(EditLine *);
+protected void term_beep(EditLine *);
+protected int term_change_size(EditLine *, int, int);
+protected int term_get_size(EditLine *, int *, int *);
+protected int term_init(EditLine *);
+protected void term_bind_arrow(EditLine *);
+protected void term_print_arrow(EditLine *, const char *);
+protected int term_clear_arrow(EditLine *, const char *);
+protected int term_set_arrow(EditLine *, const char *, key_value_t *, int);
+protected void term_end(EditLine *);
+protected void term_get(EditLine *, const char **);
+protected int term_set(EditLine *, const char *);
+protected int term_settc(EditLine *, int, const char **);
+protected int term_telltc(EditLine *, int, const char **);
+protected int term_echotc(EditLine *, int, const char **);
+protected int term__putc(int);
+protected void term__flush(void);
+
+/*
+ * Easy access macros
+ */
+#define EL_FLAGS (el)->el_term.t_flags
+
+#define EL_CAN_INSERT (EL_FLAGS & TERM_CAN_INSERT)
+#define EL_CAN_DELETE (EL_FLAGS & TERM_CAN_DELETE)
+#define EL_CAN_CEOL (EL_FLAGS & TERM_CAN_CEOL)
+#define EL_CAN_TAB (EL_FLAGS & TERM_CAN_TAB)
+#define EL_CAN_ME (EL_FLAGS & TERM_CAN_ME)
+#define EL_HAS_META (EL_FLAGS & TERM_HAS_META)
+#define EL_HAS_AUTO_MARGINS (EL_FLAGS & TERM_HAS_AUTO_MARGINS)
+#define EL_HAS_MAGIC_MARGINS (EL_FLAGS & TERM_HAS_MAGIC_MARGINS)
+
+#endif /* _h_el_term */
diff --git a/cmd-line-utils/libedit/emacs.c b/cmd-line-utils/libedit/emacs.c
index d58d1620693..79f2bf0c818 100644
--- a/cmd-line-utils/libedit/emacs.c
+++ b/cmd-line-utils/libedit/emacs.c
@@ -1,4 +1,4 @@
-/* $NetBSD: emacs.c,v 1.12 2002/11/15 14:32:33 christos Exp $ */
+/* $NetBSD: emacs.c,v 1.19 2004/10/28 21:14:52 dsl Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -15,11 +15,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
@@ -36,14 +32,7 @@
* SUCH DAMAGE.
*/
-#include "config.h"
-#if !defined(lint) && !defined(SCCSID)
-#if 0
-static char sccsid[] = "@(#)emacs.c 8.1 (Berkeley) 6/4/93";
-#else
-__RCSID("$NetBSD: emacs.c,v 1.12 2002/11/15 14:32:33 christos Exp $");
-#endif
-#endif /* not lint && not SCCSID */
+#include <config.h>
/*
* emacs.c: Emacs functions
@@ -56,7 +45,7 @@ __RCSID("$NetBSD: emacs.c,v 1.12 2002/11/15 14:32:33 christos Exp $");
*/
protected el_action_t
/*ARGSUSED*/
-em_delete_or_list(EditLine *el, int c __attribute__((unused)))
+em_delete_or_list(EditLine *el, int c __attribute__((__unused__)))
{
if (el->el_line.cursor == el->el_line.lastchar) {
@@ -75,7 +64,10 @@ em_delete_or_list(EditLine *el, int c __attribute__((unused)))
return (CC_ERROR);
}
} else {
- c_delafter(el, el->el_state.argument); /* delete after dot */
+ if (el->el_state.doingarg)
+ c_delafter(el, el->el_state.argument);
+ else
+ c_delafter1(el);
if (el->el_line.cursor > el->el_line.lastchar)
el->el_line.cursor = el->el_line.lastchar;
/* bounds check */
@@ -90,7 +82,7 @@ em_delete_or_list(EditLine *el, int c __attribute__((unused)))
*/
protected el_action_t
/*ARGSUSED*/
-em_delete_next_word(EditLine *el, int c __attribute__((unused)))
+em_delete_next_word(EditLine *el, int c __attribute__((__unused__)))
{
char *cp, *p, *kp;
@@ -119,14 +111,12 @@ em_delete_next_word(EditLine *el, int c __attribute__((unused)))
*/
protected el_action_t
/*ARGSUSED*/
-em_yank(EditLine *el, int c __attribute__((unused)))
+em_yank(EditLine *el, int c __attribute__((__unused__)))
{
char *kp, *cp;
- if (el->el_chared.c_kill.last == el->el_chared.c_kill.buf) {
- if (!ch_enlargebufs(el, 1))
- return (CC_ERROR);
- }
+ if (el->el_chared.c_kill.last == el->el_chared.c_kill.buf)
+ return (CC_NORM);
if (el->el_line.lastchar +
(el->el_chared.c_kill.last - el->el_chared.c_kill.buf) >=
@@ -156,7 +146,7 @@ em_yank(EditLine *el, int c __attribute__((unused)))
*/
protected el_action_t
/*ARGSUSED*/
-em_kill_line(EditLine *el, int c __attribute__((unused)))
+em_kill_line(EditLine *el, int c __attribute__((__unused__)))
{
char *kp, *cp;
@@ -178,7 +168,7 @@ em_kill_line(EditLine *el, int c __attribute__((unused)))
*/
protected el_action_t
/*ARGSUSED*/
-em_kill_region(EditLine *el, int c __attribute__((unused)))
+em_kill_region(EditLine *el, int c __attribute__((__unused__)))
{
char *kp, *cp;
@@ -211,7 +201,7 @@ em_kill_region(EditLine *el, int c __attribute__((unused)))
*/
protected el_action_t
/*ARGSUSED*/
-em_copy_region(EditLine *el, int c __attribute__((unused)))
+em_copy_region(EditLine *el, int c __attribute__((__unused__)))
{
char *kp, *cp;
@@ -235,12 +225,12 @@ em_copy_region(EditLine *el, int c __attribute__((unused)))
}
-/* em_gosmacs_traspose():
+/* em_gosmacs_transpose():
* Exchange the two characters before the cursor
* Gosling emacs transpose chars [^T]
*/
protected el_action_t
-em_gosmacs_traspose(EditLine *el, int c)
+em_gosmacs_transpose(EditLine *el, int c)
{
if (el->el_line.cursor > &el->el_line.buffer[1]) {
@@ -260,7 +250,7 @@ em_gosmacs_traspose(EditLine *el, int c)
*/
protected el_action_t
/*ARGSUSED*/
-em_next_word(EditLine *el, int c __attribute__((unused)))
+em_next_word(EditLine *el, int c __attribute__((__unused__)))
{
if (el->el_line.cursor == el->el_line.lastchar)
return (CC_ERROR);
@@ -285,7 +275,7 @@ em_next_word(EditLine *el, int c __attribute__((unused)))
*/
protected el_action_t
/*ARGSUSED*/
-em_upper_case(EditLine *el, int c __attribute__((unused)))
+em_upper_case(EditLine *el, int c __attribute__((__unused__)))
{
char *cp, *ep;
@@ -293,8 +283,8 @@ em_upper_case(EditLine *el, int c __attribute__((unused)))
el->el_state.argument, ce__isword);
for (cp = el->el_line.cursor; cp < ep; cp++)
- if (islower((unsigned char) *cp))
- *cp = toupper(*cp);
+ if (islower((unsigned char)*cp))
+ *cp = toupper((unsigned char)*cp);
el->el_line.cursor = ep;
if (el->el_line.cursor > el->el_line.lastchar)
@@ -309,7 +299,7 @@ em_upper_case(EditLine *el, int c __attribute__((unused)))
*/
protected el_action_t
/*ARGSUSED*/
-em_capitol_case(EditLine *el, int c __attribute__((unused)))
+em_capitol_case(EditLine *el, int c __attribute__((__unused__)))
{
char *cp, *ep;
@@ -317,16 +307,16 @@ em_capitol_case(EditLine *el, int c __attribute__((unused)))
el->el_state.argument, ce__isword);
for (cp = el->el_line.cursor; cp < ep; cp++) {
- if (isalpha((unsigned char) *cp)) {
- if (islower((unsigned char) *cp))
- *cp = toupper(*cp);
+ if (isalpha((unsigned char)*cp)) {
+ if (islower((unsigned char)*cp))
+ *cp = toupper((unsigned char)*cp);
cp++;
break;
}
}
for (; cp < ep; cp++)
- if (isupper((unsigned char) *cp))
- *cp = tolower(*cp);
+ if (isupper((unsigned char)*cp))
+ *cp = tolower((unsigned char)*cp);
el->el_line.cursor = ep;
if (el->el_line.cursor > el->el_line.lastchar)
@@ -341,7 +331,7 @@ em_capitol_case(EditLine *el, int c __attribute__((unused)))
*/
protected el_action_t
/*ARGSUSED*/
-em_lower_case(EditLine *el, int c __attribute__((unused)))
+em_lower_case(EditLine *el, int c __attribute__((__unused__)))
{
char *cp, *ep;
@@ -349,8 +339,8 @@ em_lower_case(EditLine *el, int c __attribute__((unused)))
el->el_state.argument, ce__isword);
for (cp = el->el_line.cursor; cp < ep; cp++)
- if (isupper((unsigned char) *cp))
- *cp = tolower(*cp);
+ if (isupper((unsigned char)*cp))
+ *cp = tolower((unsigned char)*cp);
el->el_line.cursor = ep;
if (el->el_line.cursor > el->el_line.lastchar)
@@ -365,7 +355,7 @@ em_lower_case(EditLine *el, int c __attribute__((unused)))
*/
protected el_action_t
/*ARGSUSED*/
-em_set_mark(EditLine *el, int c __attribute__((unused)))
+em_set_mark(EditLine *el, int c __attribute__((__unused__)))
{
el->el_chared.c_kill.mark = el->el_line.cursor;
@@ -379,7 +369,7 @@ em_set_mark(EditLine *el, int c __attribute__((unused)))
*/
protected el_action_t
/*ARGSUSED*/
-em_exchange_mark(EditLine *el, int c __attribute__((unused)))
+em_exchange_mark(EditLine *el, int c __attribute__((__unused__)))
{
char *cp;
@@ -396,7 +386,7 @@ em_exchange_mark(EditLine *el, int c __attribute__((unused)))
*/
protected el_action_t
/*ARGSUSED*/
-em_universal_argument(EditLine *el, int c __attribute__((unused)))
+em_universal_argument(EditLine *el, int c __attribute__((__unused__)))
{ /* multiply current argument by 4 */
if (el->el_state.argument > 1000000)
@@ -413,7 +403,7 @@ em_universal_argument(EditLine *el, int c __attribute__((unused)))
*/
protected el_action_t
/*ARGSUSED*/
-em_meta_next(EditLine *el, int c __attribute__((unused)))
+em_meta_next(EditLine *el, int c __attribute__((__unused__)))
{
el->el_state.metanext = 1;
@@ -426,7 +416,7 @@ em_meta_next(EditLine *el, int c __attribute__((unused)))
*/
protected el_action_t
/*ARGSUSED*/
-em_toggle_overwrite(EditLine *el, int c __attribute__((unused)))
+em_toggle_overwrite(EditLine *el, int c __attribute__((__unused__)))
{
el->el_state.inputmode = (el->el_state.inputmode == MODE_INSERT) ?
@@ -440,7 +430,7 @@ em_toggle_overwrite(EditLine *el, int c __attribute__((unused)))
*/
protected el_action_t
/*ARGSUSED*/
-em_copy_prev_word(EditLine *el, int c __attribute__((unused)))
+em_copy_prev_word(EditLine *el, int c __attribute__((__unused__)))
{
char *cp, *oldc, *dp;
@@ -467,7 +457,7 @@ em_copy_prev_word(EditLine *el, int c __attribute__((unused)))
*/
protected el_action_t
/*ARGSUSED*/
-em_inc_search_next(EditLine *el, int c __attribute__((unused)))
+em_inc_search_next(EditLine *el, int c __attribute__((__unused__)))
{
el->el_search.patlen = 0;
@@ -480,9 +470,32 @@ em_inc_search_next(EditLine *el, int c __attribute__((unused)))
*/
protected el_action_t
/*ARGSUSED*/
-em_inc_search_prev(EditLine *el, int c __attribute__((unused)))
+em_inc_search_prev(EditLine *el, int c __attribute__((__unused__)))
{
el->el_search.patlen = 0;
return (ce_inc_search(el, ED_SEARCH_PREV_HISTORY));
}
+
+
+/* em_delete_prev_char():
+ * Delete the character to the left of the cursor
+ * [^?]
+ */
+protected el_action_t
+/*ARGSUSED*/
+em_delete_prev_char(EditLine *el, int c __attribute__((__unused__)))
+{
+
+ if (el->el_line.cursor <= el->el_line.buffer)
+ return (CC_ERROR);
+
+ if (el->el_state.doingarg)
+ c_delbefore(el, el->el_state.argument);
+ else
+ c_delbefore1(el);
+ el->el_line.cursor -= el->el_state.argument;
+ if (el->el_line.cursor < el->el_line.buffer)
+ el->el_line.cursor = el->el_line.buffer;
+ return (CC_REFRESH);
+}
diff --git a/cmd-line-utils/libedit/fgetln.c b/cmd-line-utils/libedit/fgetln.c
index 4f7416a4c8d..5b95b2f6584 100644
--- a/cmd-line-utils/libedit/fgetln.c
+++ b/cmd-line-utils/libedit/fgetln.c
@@ -1,109 +1,88 @@
+/* $NetBSD: fgetln.c,v 1.2 2003/12/10 01:30:27 lukem Exp $ */
+
+/*-
+ * Copyright (c) 1998 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Christos Zoulas.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <config.h>
#include <stdio.h>
-#include "compat.h"
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
-#ifndef HAVE_FGETLN
-#ifdef HAVE_GETLINE
-
-extern int getline (char **lineptr, size_t *n, FILE *stream);
-
-#else
-
-/* The interface here is that of GNU libc's getline */
-static int
-getline (char **lineptr, size_t *n, FILE *stream)
+char *
+fgetln(FILE *fp, size_t *len)
{
-#define EXPAND_CHUNK 16
-
- int n_read = 0;
- char *line = *lineptr;
-
- if (lineptr == NULL) return -1;
- if (n == NULL) return -1;
- if (stream == NULL) return -1;
- if (*lineptr == NULL || *n == 0) return -1;
-
-#ifdef HAVE_FLOCKFILE
- flockfile (stream);
-#endif
-
- while (1)
- {
- int c;
-
-#ifdef HAVE_FLOCKFILE
- c = getc_unlocked (stream);
-#else
- c = getc (stream);
-#endif
-
- if (c == EOF)
- {
- if (n_read > 0)
- line[n_read] = '\0';
- break;
- }
-
- if (n_read + 2 >= *n)
- {
- size_t new_size;
-
- if (*n == 0)
- new_size = 16;
- else
- new_size = *n * 2;
-
- if (*n >= new_size) /* Overflowed size_t */
- line = NULL;
- else
- line = (char *) (*lineptr ? (char*) realloc(*lineptr, new_size) :
- (char*) malloc(new_size));
-
- if (line)
- {
- *lineptr = line;
- *n = new_size;
- }
- else
- {
- if (*n > 0)
- {
- (*lineptr)[*n - 1] = '\0';
- n_read = *n - 2;
- }
- break;
- }
- }
-
- line[n_read] = c;
- n_read++;
-
- if (c == '\n')
- {
- line[n_read] = '\0';
- break;
- }
- }
-
-#ifdef HAVE_FLOCKFILE
- funlockfile (stream);
-#endif
-
- return n_read - 1;
+ static char *buf = NULL;
+ static size_t bufsiz = 0;
+ char *ptr;
+
+
+ if (buf == NULL) {
+ bufsiz = BUFSIZ;
+ if ((buf = malloc(bufsiz)) == NULL)
+ return NULL;
+ }
+
+ if (fgets(buf, bufsiz, fp) == NULL)
+ return NULL;
+ *len = 0;
+
+ while ((ptr = strchr(&buf[*len], '\n')) == NULL) {
+ size_t nbufsiz = bufsiz + BUFSIZ;
+ char *nbuf = realloc(buf, nbufsiz);
+
+ if (nbuf == NULL) {
+ int oerrno = errno;
+ free(buf);
+ errno = oerrno;
+ buf = NULL;
+ return NULL;
+ } else
+ buf = nbuf;
+
+ *len = bufsiz;
+ if (fgets(&buf[bufsiz], BUFSIZ, fp) == NULL)
+ return buf;
+
+ bufsiz = nbufsiz;
+ }
+
+ *len = (ptr - buf) + 1;
+ return buf;
}
-#endif /* ! HAVE_GETLINE */
-char *fgetln(FILE *stream, size_t *len)
-{
- char *ptr = NULL;
- int sz;
- size_t length= 0;
-
- sz = getline(&ptr, &length, stream);
- if(len) {
- *len = sz;
- }
-
- return sz >= 0 ? ptr : NULL;
-}
-#endif
diff --git a/cmd-line-utils/libedit/hist.c b/cmd-line-utils/libedit/hist.c
index 59c2f39dd34..e8f5c0f39ba 100644
--- a/cmd-line-utils/libedit/hist.c
+++ b/cmd-line-utils/libedit/hist.c
@@ -1,4 +1,4 @@
-/* $NetBSD: hist.c,v 1.12 2003/01/21 18:40:23 christos Exp $ */
+/* $NetBSD: hist.c,v 1.15 2003/11/01 23:36:39 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -15,11 +15,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
@@ -36,14 +32,7 @@
* SUCH DAMAGE.
*/
-#include "config.h"
-#if !defined(lint) && !defined(SCCSID)
-#if 0
-static char sccsid[] = "@(#)hist.c 8.1 (Berkeley) 6/4/93";
-#else
-__RCSID("$NetBSD: hist.c,v 1.12 2003/01/21 18:40:23 christos Exp $");
-#endif
-#endif /* not lint && not SCCSID */
+#include <config.h>
/*
* hist.c: History access functions
@@ -157,7 +146,6 @@ hist_get(EditLine *el)
* process a history command
*/
protected int
-/*ARGSUSED*/
hist_command(EditLine *el, int argc, const char **argv)
{
const char *str;
@@ -167,7 +155,7 @@ hist_command(EditLine *el, int argc, const char **argv)
if (el->el_history.ref == NULL)
return (-1);
- if (argc == 0 || strcmp(argv[0], "list") == 1) {
+ if (argc == 1 || strcmp(argv[1], "list") == 0) {
/* List history entries */
for (str = HIST_LAST(el); str != NULL; str = HIST_PREV(el))
@@ -176,15 +164,15 @@ hist_command(EditLine *el, int argc, const char **argv)
return (0);
}
- if (argc != 2)
+ if (argc != 3)
return (-1);
- num = (int)strtol(argv[1], NULL, 0);
+ num = (int)strtol(argv[2], NULL, 0);
- if (strcmp(argv[0], "size") == 0)
+ if (strcmp(argv[1], "size") == 0)
return history(el->el_history.ref, &ev, H_SETSIZE, num);
- if (strcmp(argv[0], "unique") == 0)
+ if (strcmp(argv[1], "unique") == 0)
return history(el->el_history.ref, &ev, H_SETUNIQUE, num);
return -1;
diff --git a/cmd-line-utils/libedit/hist.h b/cmd-line-utils/libedit/hist.h
index b713281b382..46e14634adf 100644
--- a/cmd-line-utils/libedit/hist.h
+++ b/cmd-line-utils/libedit/hist.h
@@ -1,4 +1,4 @@
-/* $NetBSD: hist.h,v 1.9 2003/01/21 18:40:23 christos Exp $ */
+/* $NetBSD: hist.h,v 1.10 2003/08/07 16:44:31 agc Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -15,11 +15,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
diff --git a/cmd-line-utils/libedit/histedit.h b/cmd-line-utils/libedit/histedit.h
index 3137bd680a7..c58eb62dcfa 100644
--- a/cmd-line-utils/libedit/histedit.h
+++ b/cmd-line-utils/libedit/histedit.h
@@ -1,4 +1,4 @@
-/* $NetBSD: histedit.h,v 1.21 2003/01/21 18:40:24 christos Exp $ */
+/* $NetBSD: histedit.h,v 1.25 2003/12/05 13:37:48 lukem Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -15,11 +15,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
@@ -45,7 +41,7 @@
#define _HISTEDIT_H_
#define LIBEDIT_MAJOR 2
-#define LIBEDIT_MINOR 6
+#define LIBEDIT_MINOR 9
#include <sys/types.h>
#include <stdio.h>
@@ -53,6 +49,7 @@
/*
* ==== Editing ====
*/
+
typedef struct editline EditLine;
/*
@@ -64,7 +61,6 @@ typedef struct lineinfo {
const char *lastchar;
} LineInfo;
-
/*
* EditLine editor function return codes.
* For user-defined function interface
@@ -84,9 +80,8 @@ typedef struct lineinfo {
* Initialization, cleanup, and resetting
*/
EditLine *el_init(const char *, FILE *, FILE *, FILE *);
-void el_reset(EditLine *);
void el_end(EditLine *);
-
+void el_reset(EditLine *);
/*
* Get a line, a character or push a string back in the input queue
@@ -131,6 +126,8 @@ int el_get(EditLine *, int, void *);
#define EL_RPROMPT 12 /* , el_pfunc_t); */
#define EL_GETCFN 13 /* , el_rfunc_t); */
#define EL_CLIENTDATA 14 /* , void *); */
+#define EL_UNBUFFERED 15 /* , int); */
+#define EL_PREP_TERM 16 /* , int); */
#define EL_BUILTIN_GETCFN (NULL)
@@ -146,7 +143,6 @@ int el_source(EditLine *, const char *);
*/
void el_resize(EditLine *);
-
/*
* User-defined function interface.
*/
@@ -154,6 +150,7 @@ const LineInfo *el_line(EditLine *);
int el_insertstr(EditLine *, const char *);
void el_deletestr(EditLine *, int);
+
/*
* ==== History ====
*/
@@ -196,4 +193,22 @@ int history(History *, HistEvent *, int, ...);
#define H_SETUNIQUE 20 /* , int); */
#define H_GETUNIQUE 21 /* , void); */
+
+/*
+ * ==== Tokenization ====
+ */
+
+typedef struct tokenizer Tokenizer;
+
+/*
+ * String tokenization functions, using simplified sh(1) quoting rules
+ */
+Tokenizer *tok_init(const char *);
+void tok_end(Tokenizer *);
+void tok_reset(Tokenizer *);
+int tok_line(Tokenizer *, const LineInfo *,
+ int *, const char ***, int *, int *);
+int tok_str(Tokenizer *, const char *,
+ int *, const char ***);
+
#endif /* _HISTEDIT_H_ */
diff --git a/cmd-line-utils/libedit/history.c b/cmd-line-utils/libedit/history.c
index 53648203bf0..1da6a864181 100644
--- a/cmd-line-utils/libedit/history.c
+++ b/cmd-line-utils/libedit/history.c
@@ -1,4 +1,4 @@
-/* $NetBSD: history.c,v 1.22 2003/01/21 18:40:24 christos Exp $ */
+/* $NetBSD: history.c,v 1.28 2004/11/27 18:31:45 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -15,11 +15,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
@@ -36,14 +32,7 @@
* SUCH DAMAGE.
*/
-#include "config.h"
-#if !defined(lint) && !defined(SCCSID)
-#if 0
-static char sccsid[] = "@(#)history.c 8.1 (Berkeley) 6/4/93";
-#else
-__RCSID("$NetBSD: history.c,v 1.22 2003/01/21 18:40:24 christos Exp $");
-#endif
-#endif /* not lint && not SCCSID */
+#include <config.h>
/*
* hist.c: History access functions
@@ -51,11 +40,7 @@ __RCSID("$NetBSD: history.c,v 1.22 2003/01/21 18:40:24 christos Exp $");
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
-#ifdef HAVE_VIS_H
#include <vis.h>
-#else
-#include "np/vis.h"
-#endif
#include <sys/stat.h>
static const char hist_cookie[] = "_HiStOrY_V2_\n";
@@ -91,6 +76,7 @@ struct history {
#define HENTER(h, ev, str) (*(h)->h_enter)((h)->h_ref, ev, str)
#define HADD(h, ev, str) (*(h)->h_add)((h)->h_ref, ev, str)
+#define h_strdup(a) strdup(a)
#define h_malloc(a) malloc(a)
#define h_realloc(a, b) realloc((a), (b))
#define h_free(a) free(a)
@@ -249,20 +235,19 @@ history_def_next(ptr_t p, HistEvent *ev)
{
history_t *h = (history_t *) p;
- if (h->cursor != &h->list)
- h->cursor = h->cursor->next;
- else {
+ if (h->cursor == &h->list) {
he_seterrev(ev, _HE_EMPTY_LIST);
return (-1);
}
- if (h->cursor != &h->list)
- *ev = h->cursor->ev;
- else {
+ if (h->cursor->next == &h->list) {
he_seterrev(ev, _HE_END_REACHED);
return (-1);
}
+ h->cursor = h->cursor->next;
+ *ev = h->cursor->ev;
+
return (0);
}
@@ -275,21 +260,20 @@ history_def_prev(ptr_t p, HistEvent *ev)
{
history_t *h = (history_t *) p;
- if (h->cursor != &h->list)
- h->cursor = h->cursor->prev;
- else {
+ if (h->cursor == &h->list) {
he_seterrev(ev,
(h->cur > 0) ? _HE_END_REACHED : _HE_EMPTY_LIST);
return (-1);
}
- if (h->cursor != &h->list)
- *ev = h->cursor->ev;
- else {
+ if (h->cursor->prev == &h->list) {
he_seterrev(ev, _HE_START_REACHED);
return (-1);
}
+ h->cursor = h->cursor->prev;
+ *ev = h->cursor->ev;
+
return (0);
}
@@ -374,7 +358,8 @@ history_def_add(ptr_t p, HistEvent *ev, const char *str)
*/
/* ARGSUSED */
private void
-history_def_delete(history_t *h, HistEvent *ev __attribute__((unused)), hentry_t *hp)
+history_def_delete(history_t *h,
+ HistEvent *ev __attribute__((__unused__)), hentry_t *hp)
{
HistEventPrivate *evp = (void *)&hp->ev;
if (hp == &h->list)
@@ -397,7 +382,7 @@ history_def_insert(history_t *h, HistEvent *ev, const char *str)
h->cursor = (hentry_t *) h_malloc(sizeof(hentry_t));
if (h->cursor == NULL)
goto oomem;
- if ((h->cursor->ev.str = strdup(str)) == NULL) {
+ if ((h->cursor->ev.str = h_strdup(str)) == NULL) {
h_free((ptr_t)h->cursor);
goto oomem;
}
@@ -447,7 +432,7 @@ history_def_enter(ptr_t p, HistEvent *ev, const char *str)
*/
/* ARGSUSED */
private int
-history_def_init(ptr_t *p, HistEvent *ev __attribute__((unused)), int n)
+history_def_init(ptr_t *p, HistEvent *ev __attribute__((__unused__)), int n)
{
history_t *h = (history_t *) h_malloc(sizeof(history_t));
if (h == NULL)
@@ -661,6 +646,12 @@ history_load(History *h, const char *fname)
if ((fp = fopen(fname, "r")) == NULL)
return (i);
+ if ((line = fgetln(fp, &sz)) == NULL)
+ goto done;
+
+ if (strncmp(line, hist_cookie, sz) != 0)
+ goto done;
+
ptr = h_malloc(max_size = 1024);
if (ptr == NULL)
goto done;
@@ -674,7 +665,7 @@ history_load(History *h, const char *fname)
if (max_size < sz) {
char *nptr;
- max_size = (sz + 1023) & ~1023;
+ max_size = (sz + 1024) & ~1023;
nptr = h_realloc(ptr, max_size);
if (nptr == NULL) {
i = -1;
@@ -714,16 +705,18 @@ history_save(History *h, const char *fname)
if (fchmod(fileno(fp), S_IRUSR|S_IWUSR) == -1)
goto done;
+ if (fputs(hist_cookie, fp) == EOF)
+ goto done;
ptr = h_malloc(max_size = 1024);
if (ptr == NULL)
goto done;
for (i = 0, retval = HLAST(h, &ev);
retval != -1;
retval = HPREV(h, &ev), i++) {
- len = strlen(ev.str) * 4 + 1;
+ len = strlen(ev.str) * 4;
if (len >= max_size) {
char *nptr;
- max_size = (len + 1023) & ~1023;
+ max_size = (len + 1024) & ~1023;
nptr = h_realloc(ptr, max_size);
if (nptr == NULL) {
i = -1;
@@ -732,7 +725,7 @@ history_save(History *h, const char *fname)
ptr = nptr;
}
(void) strvis(ptr, ev.str, VIS_WHITE);
- (void) fprintf(fp, "%s\n", ev.str);
+ (void) fprintf(fp, "%s\n", ptr);
}
oomem:
h_free((ptr_t)ptr);
diff --git a/cmd-line-utils/libedit/key.c b/cmd-line-utils/libedit/key.c
index e75db00ce1b..090a2684e92 100644
--- a/cmd-line-utils/libedit/key.c
+++ b/cmd-line-utils/libedit/key.c
@@ -1,4 +1,4 @@
-/* $NetBSD: key.c,v 1.13 2002/03/18 16:00:55 christos Exp $ */
+/* $NetBSD: key.c,v 1.15 2003/10/18 23:48:42 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -15,11 +15,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
@@ -36,14 +32,7 @@
* SUCH DAMAGE.
*/
-#include "config.h"
-#if !defined(lint) && !defined(SCCSID)
-#if 0
-static char sccsid[] = "@(#)key.c 8.1 (Berkeley) 6/4/93";
-#else
-__RCSID("$NetBSD: key.c,v 1.13 2002/03/18 16:00:55 christos Exp $");
-#endif
-#endif /* not lint && not SCCSID */
+#include <config.h>
/*
* key.c: This module contains the procedures for maintaining
@@ -103,14 +92,14 @@ private int key__decode_char(char *, int, int);
* Initialize the key maps
*/
protected int
-el_key_init(EditLine *el)
+key_init(EditLine *el)
{
el->el_key.buf = (char *) el_malloc(KEY_BUFSIZ);
if (el->el_key.buf == NULL)
return (-1);
el->el_key.map = NULL;
- el_key_reset(el);
+ key_reset(el);
return (0);
}
@@ -119,7 +108,7 @@ el_key_init(EditLine *el)
* Free the key maps
*/
protected void
-el_key_end(EditLine *el)
+key_end(EditLine *el)
{
el_free((ptr_t) el->el_key.buf);
@@ -133,7 +122,7 @@ el_key_end(EditLine *el)
* Associate cmd with a key value
*/
protected key_value_t *
-el_key_map_cmd(EditLine *el, int cmd)
+key_map_cmd(EditLine *el, int cmd)
{
el->el_key.val.cmd = (el_action_t) cmd;
@@ -145,7 +134,7 @@ el_key_map_cmd(EditLine *el, int cmd)
* Associate str with a key value
*/
protected key_value_t *
-el_key_map_str(EditLine *el, char *str)
+key_map_str(EditLine *el, char *str)
{
el->el_key.val.str = str;
@@ -159,7 +148,7 @@ el_key_map_str(EditLine *el, char *str)
* [Always bind the ansi arrow keys?]
*/
protected void
-el_key_reset(EditLine *el)
+key_reset(EditLine *el)
{
node__put(el, el->el_key.map);
@@ -177,7 +166,7 @@ el_key_reset(EditLine *el)
* The last character read is returned in *ch.
*/
protected int
-el_key_get(EditLine *el, char *ch, key_value_t *val)
+key_get(EditLine *el, char *ch, key_value_t *val)
{
return (node_trav(el, el->el_key.map, ch, val));
@@ -191,7 +180,7 @@ el_key_get(EditLine *el, char *ch, key_value_t *val)
* out str or a unix command.
*/
protected void
-el_key_add(EditLine *el, const char *key, key_value_t *val, int ntype)
+key_add(EditLine *el, const char *key, key_value_t *val, int ntype)
{
if (key[0] == '\0') {
@@ -219,7 +208,7 @@ el_key_add(EditLine *el, const char *key, key_value_t *val, int ntype)
*
*/
protected void
-el_key_clear(EditLine *el, el_action_t *map, const char *in)
+key_clear(EditLine *el, el_action_t *map, const char *in)
{
if ((map[(unsigned char)*in] == ED_SEQUENCE_LEAD_IN) &&
@@ -227,7 +216,7 @@ el_key_clear(EditLine *el, el_action_t *map, const char *in)
el->el_map.alt[(unsigned char)*in] != ED_SEQUENCE_LEAD_IN) ||
(map == el->el_map.alt &&
el->el_map.key[(unsigned char)*in] != ED_SEQUENCE_LEAD_IN)))
- (void) el_key_delete(el, in);
+ (void) key_delete(el, in);
}
@@ -236,7 +225,7 @@ el_key_clear(EditLine *el, el_action_t *map, const char *in)
* they exists.
*/
protected int
-el_key_delete(EditLine *el, const char *key)
+key_delete(EditLine *el, const char *key)
{
if (key[0] == '\0') {
@@ -257,7 +246,7 @@ el_key_delete(EditLine *el, const char *key)
* Print entire el->el_key.map if null
*/
protected void
-el_key_print(EditLine *el, const char *key)
+key_print(EditLine *el, const char *key)
{
/* do nothing if el->el_key.map is empty and null key specified */
@@ -356,7 +345,8 @@ node__try(EditLine *el, key_node_t *ptr, const char *str, key_value_t *val, int
break;
case XK_STR:
case XK_EXE:
- ptr->val.str = strdup(val->str);
+ if ((ptr->val.str = el_strdup(val->str)) == NULL)
+ return -1;
break;
default:
EL_ABORT((el->el_errfile, "Bad XK_ type %d\n", ntype));
@@ -504,7 +494,7 @@ node_lookup(EditLine *el, const char *str, key_node_t *ptr, int cnt)
if (str[1] == 0) {
el->el_key.buf[ncnt + 1] = '"';
el->el_key.buf[ncnt + 2] = '\0';
- el_key_kprint(el, el->el_key.buf,
+ key_kprint(el, el->el_key.buf,
&ptr->val, ptr->type);
return (0);
} else
@@ -552,7 +542,7 @@ node_enum(EditLine *el, key_node_t *ptr, int cnt)
/* print this key and function */
el->el_key.buf[ncnt + 1] = '"';
el->el_key.buf[ncnt + 2] = '\0';
- el_key_kprint(el, el->el_key.buf, &ptr->val, ptr->type);
+ key_kprint(el, el->el_key.buf, &ptr->val, ptr->type);
} else
(void) node_enum(el, ptr->next, ncnt + 1);
@@ -568,7 +558,7 @@ node_enum(EditLine *el, key_node_t *ptr, int cnt)
* function specified by val
*/
protected void
-el_key_kprint(EditLine *el, const char *key, key_value_t *val, int ntype)
+key_kprint(EditLine *el, const char *key, key_value_t *val, int ntype)
{
el_bindings_t *fp;
char unparsbuf[EL_BUFSIZ];
@@ -579,7 +569,7 @@ el_key_kprint(EditLine *el, const char *key, key_value_t *val, int ntype)
case XK_STR:
case XK_EXE:
(void) fprintf(el->el_outfile, fmt, key,
- el_key__decode_str(val->str, unparsbuf,
+ key__decode_str(val->str, unparsbuf,
ntype == XK_STR ? "\"\"" : "[]"));
break;
case XK_CMD:
@@ -644,7 +634,7 @@ key__decode_char(char *buf, int cnt, int ch)
* Make a printable version of the ey
*/
protected char *
-el_key__decode_str(const char *str, char *buf, const char *sep)
+key__decode_str(const char *str, char *buf, const char *sep)
{
char *b;
const char *p;
diff --git a/cmd-line-utils/libedit/key.h b/cmd-line-utils/libedit/key.h
index 9d83d7c2521..39a075c504e 100644
--- a/cmd-line-utils/libedit/key.h
+++ b/cmd-line-utils/libedit/key.h
@@ -1,4 +1,4 @@
-/* $NetBSD: key.h,v 1.6 2002/03/18 16:00:55 christos Exp $ */
+/* $NetBSD: key.h,v 1.8 2003/08/07 16:44:32 agc Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -15,11 +15,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
@@ -62,19 +58,22 @@ typedef struct el_key_t {
#define XK_NOD 2
#define XK_EXE 3
-protected int el_key_init(EditLine *);
-protected void el_key_end(EditLine *);
-protected key_value_t *el_key_map_cmd(EditLine *, int);
-protected key_value_t *el_key_map_str(EditLine *, char *);
-protected void el_key_reset(EditLine *);
-protected int el_key_get(EditLine *, char *, key_value_t *);
-protected void el_key_add(EditLine *,
- const char *, key_value_t *, int);
-protected void el_key_clear(EditLine *, el_action_t *, const char *);
-protected int el_key_delete(EditLine *, const char *);
-protected void el_key_print(EditLine *, const char *);
-protected void el_key_kprint(EditLine *, const char *, key_value_t *,
+#undef key_end
+#undef key_clear
+#undef key_print
+
+protected int key_init(EditLine *);
+protected void key_end(EditLine *);
+protected key_value_t *key_map_cmd(EditLine *, int);
+protected key_value_t *key_map_str(EditLine *, char *);
+protected void key_reset(EditLine *);
+protected int key_get(EditLine *, char *, key_value_t *);
+protected void key_add(EditLine *, const char *, key_value_t *, int);
+protected void key_clear(EditLine *, el_action_t *, const char *);
+protected int key_delete(EditLine *, const char *);
+protected void key_print(EditLine *, const char *);
+protected void key_kprint(EditLine *, const char *, key_value_t *,
int);
-protected char *el_key__decode_str(const char *, char *, const char *);
+protected char *key__decode_str(const char *, char *, const char *);
#endif /* _h_el_key */
diff --git a/cmd-line-utils/libedit/map.c b/cmd-line-utils/libedit/map.c
index a16625311ae..d99c36ff665 100644
--- a/cmd-line-utils/libedit/map.c
+++ b/cmd-line-utils/libedit/map.c
@@ -1,4 +1,4 @@
-/* $NetBSD: map.c,v 1.18 2002/11/15 14:32:33 christos Exp $ */
+/* $NetBSD: map.c,v 1.20 2004/08/13 12:10:39 mycroft Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -15,11 +15,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
@@ -36,14 +32,7 @@
* SUCH DAMAGE.
*/
-#include "config.h"
-#if !defined(lint) && !defined(SCCSID)
-#if 0
-static char sccsid[] = "@(#)map.c 8.1 (Berkeley) 6/4/93";
-#else
-__RCSID("$NetBSD: map.c,v 1.18 2002/11/15 14:32:33 christos Exp $");
-#endif
-#endif /* not lint && not SCCSID */
+#include <config.h>
/*
* map.c: Editor function definitions
@@ -71,7 +60,7 @@ private const el_action_t el_map_emacs[] = {
/* 5 */ ED_MOVE_TO_END, /* ^E */
/* 6 */ ED_NEXT_CHAR, /* ^F */
/* 7 */ ED_UNASSIGNED, /* ^G */
- /* 8 */ ED_DELETE_PREV_CHAR, /* ^H */
+ /* 8 */ EM_DELETE_PREV_CHAR, /* ^H */
/* 9 */ ED_UNASSIGNED, /* ^I */
/* 10 */ ED_NEWLINE, /* ^J */
/* 11 */ ED_KILL_LINE, /* ^K */
@@ -190,7 +179,7 @@ private const el_action_t el_map_emacs[] = {
/* 124 */ ED_INSERT, /* | */
/* 125 */ ED_INSERT, /* } */
/* 126 */ ED_INSERT, /* ~ */
- /* 127 */ ED_DELETE_PREV_CHAR, /* ^? */
+ /* 127 */ EM_DELETE_PREV_CHAR, /* ^? */
/* 128 */ ED_UNASSIGNED, /* M-^@ */
/* 129 */ ED_UNASSIGNED, /* M-^A */
/* 130 */ ED_UNASSIGNED, /* M-^B */
@@ -1011,8 +1000,7 @@ map_init_meta(EditLine *el)
break;
default:
buf[1] = i & 0177;
- el_key_add(el, buf,
- el_key_map_cmd(el, (int) map[i]), XK_CMD);
+ key_add(el, buf, key_map_cmd(el, (int) map[i]), XK_CMD);
break;
}
map[(int) buf[0]] = ED_SEQUENCE_LEAD_IN;
@@ -1034,7 +1022,7 @@ map_init_vi(EditLine *el)
el->el_map.type = MAP_VI;
el->el_map.current = el->el_map.key;
- el_key_reset(el);
+ key_reset(el);
for (i = 0; i < N_KEYS; i++) {
key[i] = vii[i];
@@ -1063,7 +1051,7 @@ map_init_emacs(EditLine *el)
el->el_map.type = MAP_EMACS;
el->el_map.current = el->el_map.key;
- el_key_reset(el);
+ key_reset(el);
for (i = 0; i < N_KEYS; i++) {
key[i] = emacs[i];
@@ -1076,7 +1064,7 @@ map_init_emacs(EditLine *el)
buf[0] = CONTROL('X');
buf[1] = CONTROL('X');
buf[2] = 0;
- el_key_add(el, buf, el_key_map_cmd(el, EM_EXCHANGE_MARK), XK_CMD);
+ key_add(el, buf, key_map_cmd(el, EM_EXCHANGE_MARK), XK_CMD);
tty_bind_char(el, 1);
term_bind_arrow(el);
@@ -1133,7 +1121,7 @@ map_print_key(EditLine *el, el_action_t *map, const char *in)
el_bindings_t *bp;
if (in[0] == '\0' || in[1] == '\0') {
- (void) el_key__decode_str(in, outbuf, "");
+ (void) key__decode_str(in, outbuf, "");
for (bp = el->el_map.help; bp->name != NULL; bp++)
if (bp->func == map[(unsigned char) *in]) {
(void) fprintf(el->el_outfile,
@@ -1141,7 +1129,7 @@ map_print_key(EditLine *el, el_action_t *map, const char *in)
return;
}
} else
- el_key_print(el, in);
+ key_print(el, in);
}
@@ -1163,20 +1151,20 @@ map_print_some_keys(EditLine *el, el_action_t *map, int first, int last)
if (first == last)
(void) fprintf(el->el_outfile,
"%-15s-> is undefined\n",
- el_key__decode_str(firstbuf, unparsbuf, STRQQ));
+ key__decode_str(firstbuf, unparsbuf, STRQQ));
return;
}
for (bp = el->el_map.help; bp->name != NULL; bp++) {
if (bp->func == map[first]) {
if (first == last) {
(void) fprintf(el->el_outfile, "%-15s-> %s\n",
- el_key__decode_str(firstbuf, unparsbuf, STRQQ),
+ key__decode_str(firstbuf, unparsbuf, STRQQ),
bp->name);
} else {
(void) fprintf(el->el_outfile,
"%-4s to %-7s-> %s\n",
- el_key__decode_str(firstbuf, unparsbuf, STRQQ),
- el_key__decode_str(lastbuf, extrabuf, STRQQ),
+ key__decode_str(firstbuf, unparsbuf, STRQQ),
+ key__decode_str(lastbuf, extrabuf, STRQQ),
bp->name);
}
return;
@@ -1230,7 +1218,7 @@ map_print_all_keys(EditLine *el)
map_print_some_keys(el, el->el_map.alt, prev, i - 1);
(void) fprintf(el->el_outfile, "Multi-character bindings\n");
- el_key_print(el, "");
+ key_print(el, "");
(void) fprintf(el->el_outfile, "Arrow key bindings\n");
term_print_arrow(el, "");
}
@@ -1323,9 +1311,9 @@ map_bind(EditLine *el, int argc, const char **argv)
return (-1);
}
if (in[1])
- (void) el_key_delete(el, in);
+ (void) key_delete(el, in);
else if (map[(unsigned char) *in] == ED_SEQUENCE_LEAD_IN)
- (void) el_key_delete(el, in);
+ (void) key_delete(el, in);
else
map[(unsigned char) *in] = ED_UNASSIGNED;
return (0);
@@ -1353,9 +1341,9 @@ map_bind(EditLine *el, int argc, const char **argv)
return (-1);
}
if (key)
- term_set_arrow(el, in, el_key_map_str(el, out), ntype);
+ term_set_arrow(el, in, key_map_str(el, out), ntype);
else
- el_key_add(el, in, el_key_map_str(el, out), ntype);
+ key_add(el, in, key_map_str(el, out), ntype);
map[(unsigned char) *in] = ED_SEQUENCE_LEAD_IN;
break;
@@ -1366,13 +1354,13 @@ map_bind(EditLine *el, int argc, const char **argv)
return (-1);
}
if (key)
- term_set_arrow(el, in, el_key_map_str(el, out), ntype);
+ term_set_arrow(el, in, key_map_str(el, out), ntype);
else {
if (in[1]) {
- el_key_add(el, in, el_key_map_cmd(el, cmd), ntype);
+ key_add(el, in, key_map_cmd(el, cmd), ntype);
map[(unsigned char) *in] = ED_SEQUENCE_LEAD_IN;
} else {
- el_key_clear(el, map, in);
+ key_clear(el, map, in);
map[(unsigned char) *in] = cmd;
}
}
diff --git a/cmd-line-utils/libedit/map.h b/cmd-line-utils/libedit/map.h
index 3c9948ccf88..3b08f48be7a 100644
--- a/cmd-line-utils/libedit/map.h
+++ b/cmd-line-utils/libedit/map.h
@@ -1,4 +1,4 @@
-/* $NetBSD: map.h,v 1.7 2002/03/18 16:00:56 christos Exp $ */
+/* $NetBSD: map.h,v 1.8 2003/08/07 16:44:32 agc Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -15,11 +15,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
diff --git a/cmd-line-utils/libedit/parse.c b/cmd-line-utils/libedit/parse.c
index d09b890c1ab..993cf5b752d 100644
--- a/cmd-line-utils/libedit/parse.c
+++ b/cmd-line-utils/libedit/parse.c
@@ -1,4 +1,4 @@
-/* $NetBSD: parse.c,v 1.16 2003/01/21 18:40:24 christos Exp $ */
+/* $NetBSD: parse.c,v 1.20 2003/12/05 13:37:48 lukem Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -15,11 +15,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
@@ -36,14 +32,7 @@
* SUCH DAMAGE.
*/
-#include "config.h"
-#if !defined(lint) && !defined(SCCSID)
-#if 0
-static char sccsid[] = "@(#)parse.c 8.1 (Berkeley) 6/4/93";
-#else
-__RCSID("$NetBSD: parse.c,v 1.16 2003/01/21 18:40:24 christos Exp $");
-#endif
-#endif /* not lint && not SCCSID */
+#include <config.h>
/*
* parse.c: parse an editline extended command
@@ -59,7 +48,6 @@ __RCSID("$NetBSD: parse.c,v 1.16 2003/01/21 18:40:24 christos Exp $");
* setty
*/
#include "el.h"
-#include "tokenizer.h"
#include <stdlib.h>
private const struct {
@@ -87,9 +75,8 @@ parse_line(EditLine *el, const char *line)
int argc;
Tokenizer *tok;
- if (!(tok = tok_init(NULL)))
- return -1;
- tok_line(tok, line, &argc, &argv);
+ tok = tok_init(NULL);
+ tok_str(tok, line, &argc, &argv);
argc = el_parse(el, argc, argv);
tok_end(tok);
return (argc);
@@ -207,7 +194,7 @@ parse__escape(const char **const ptr)
c = *p;
break;
}
- } else if (*p == '^' && isalpha((unsigned char) p[1])) {
+ } else if (*p == '^') {
p++;
c = (*p == '?') ? '\177' : (*p & 0237);
} else
@@ -215,6 +202,7 @@ parse__escape(const char **const ptr)
*ptr = ++p;
return (c);
}
+
/* parse__string():
* Parse the escapes from in and put the raw string out
*/
@@ -237,6 +225,14 @@ parse__string(char *out, const char *in)
*out++ = n;
break;
+ case 'M':
+ if (in[1] == '-' && in[2] != '\0') {
+ *out++ = '\033';
+ in += 2;
+ break;
+ }
+ /*FALLTHROUGH*/
+
default:
*out++ = *in++;
break;
diff --git a/cmd-line-utils/libedit/parse.h b/cmd-line-utils/libedit/parse.h
index 4aaef2f834a..4b796666b8e 100644
--- a/cmd-line-utils/libedit/parse.h
+++ b/cmd-line-utils/libedit/parse.h
@@ -1,4 +1,4 @@
-/* $NetBSD: parse.h,v 1.4 2000/09/04 22:06:31 lukem Exp $ */
+/* $NetBSD: parse.h,v 1.5 2003/08/07 16:44:32 agc Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -15,11 +15,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
diff --git a/cmd-line-utils/libedit/prompt.c b/cmd-line-utils/libedit/prompt.c
index 03d8309a991..455dd60331b 100644
--- a/cmd-line-utils/libedit/prompt.c
+++ b/cmd-line-utils/libedit/prompt.c
@@ -1,4 +1,4 @@
-/* $NetBSD: prompt.c,v 1.9 2002/03/18 16:00:56 christos Exp $ */
+/* $NetBSD: prompt.c,v 1.11 2003/08/07 16:44:32 agc Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -15,11 +15,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
@@ -36,14 +32,7 @@
* SUCH DAMAGE.
*/
-#include "config.h"
-#if !defined(lint) && !defined(SCCSID)
-#if 0
-static char sccsid[] = "@(#)prompt.c 8.1 (Berkeley) 6/4/93";
-#else
-__RCSID("$NetBSD: prompt.c,v 1.9 2002/03/18 16:00:56 christos Exp $");
-#endif
-#endif /* not lint && not SCCSID */
+#include <config.h>
/*
* prompt.c: Prompt printing functions
@@ -59,7 +48,7 @@ private char *prompt_default_r(EditLine *);
*/
private char *
/*ARGSUSED*/
-prompt_default(EditLine *el __attribute__((unused)))
+prompt_default(EditLine *el __attribute__((__unused__)))
{
static char a[3] = {'?', ' ', '\0'};
@@ -72,7 +61,7 @@ prompt_default(EditLine *el __attribute__((unused)))
*/
private char *
/*ARGSUSED*/
-prompt_default_r(EditLine *el __attribute__((unused)))
+prompt_default_r(EditLine *el __attribute__((__unused__)))
{
static char a[1] = {'\0'};
@@ -127,7 +116,7 @@ prompt_init(EditLine *el)
*/
protected void
/*ARGSUSED*/
-prompt_end(EditLine *el __attribute__((unused)))
+prompt_end(EditLine *el __attribute__((__unused__)))
{
}
diff --git a/cmd-line-utils/libedit/prompt.h b/cmd-line-utils/libedit/prompt.h
index 08810e22a0c..d18110861f8 100644
--- a/cmd-line-utils/libedit/prompt.h
+++ b/cmd-line-utils/libedit/prompt.h
@@ -1,4 +1,4 @@
-/* $NetBSD: prompt.h,v 1.5 2000/09/04 22:06:31 lukem Exp $ */
+/* $NetBSD: prompt.h,v 1.6 2003/08/07 16:44:32 agc Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -15,11 +15,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
diff --git a/cmd-line-utils/libedit/read.c b/cmd-line-utils/libedit/read.c
index 5eaa83bf482..40093d6647f 100644
--- a/cmd-line-utils/libedit/read.c
+++ b/cmd-line-utils/libedit/read.c
@@ -1,4 +1,4 @@
-/* $NetBSD: read.c,v 1.24 2002/11/20 16:50:08 christos Exp $ */
+/* $NetBSD: read.c,v 1.35 2005/03/09 23:55:02 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -15,11 +15,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
@@ -36,20 +32,14 @@
* SUCH DAMAGE.
*/
-#include "config.h"
-#if !defined(lint) && !defined(SCCSID)
-#if 0
-static char sccsid[] = "@(#)read.c 8.1 (Berkeley) 6/4/93";
-#else
-__RCSID("$NetBSD: read.c,v 1.24 2002/11/20 16:50:08 christos Exp $");
-#endif
-#endif /* not lint && not SCCSID */
+#include <config.h>
/*
* read.c: Clean this junk up! This is horrible code.
* Terminal read functions
*/
#include <errno.h>
+#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include "el.h"
@@ -97,6 +87,10 @@ el_read_getfn(EditLine *el)
}
+#ifndef MIN
+#define MIN(A,B) ((A) < (B) ? (A) : (B))
+#endif
+
#ifdef DEBUG_EDIT
private void
read_debug(EditLine *el)
@@ -121,11 +115,7 @@ read_debug(EditLine *el)
*/
/* ARGSUSED */
private int
-read__fixio(int fd
-#if !(defined(TRY_AGAIN) && (defined(FIONBIO) || (defined(F_SETFL) && defined(O_NDELAY))))
- __attribute__((unused))
-#endif /* !(defined(TRY_AGAIN) && (defined(FIONBIO) || (defined(F_SETFL) && defined(O_NDELAY)))) */
-, int e)
+read__fixio(int fd __attribute__((__unused__)), int e)
{
switch (e) {
@@ -190,18 +180,10 @@ read_preread(EditLine *el)
{
int chrs = 0;
- if (el->el_chared.c_macro.nline) {
- el_free((ptr_t) el->el_chared.c_macro.nline);
- el->el_chared.c_macro.nline = NULL;
- }
if (el->el_tty.t_mode == ED_IO)
return (0);
#ifdef FIONREAD
-
-#ifndef MIN // definition of MIN is lacking on hpux..
-#define MIN(x,y) (((x)<(y))?(x):(y))
-#endif
(void) ioctl(el->el_infd, FIONREAD, (ioctl_t) & chrs);
if (chrs > 0) {
char buf[EL_BUFSIZ];
@@ -210,8 +192,7 @@ read_preread(EditLine *el)
(size_t) MIN(chrs, EL_BUFSIZ - 1));
if (chrs > 0) {
buf[chrs] = '\0';
- el->el_chared.c_macro.nline = strdup(buf);
- el_push(el, el->el_chared.c_macro.nline);
+ el_push(el, buf);
}
}
#endif /* FIONREAD */
@@ -230,11 +211,12 @@ el_push(EditLine *el, char *str)
if (str != NULL && ma->level + 1 < EL_MAXMACRO) {
ma->level++;
- ma->macro[ma->level] = str;
- } else {
- term_beep(el);
- term__flush();
+ if ((ma->macro[ma->level] = el_strdup(str)) != NULL)
+ return;
+ ma->level--;
}
+ term_beep(el);
+ term__flush();
}
@@ -266,7 +248,7 @@ read_getcmd(EditLine *el, el_action_t *cmdnum, char *ch)
cmd = el->el_map.current[(unsigned char) *ch];
if (cmd == ED_SEQUENCE_LEAD_IN) {
key_value_t val;
- switch (el_key_get(el, ch, &val)) {
+ switch (key_get(el, ch, &val)) {
case XK_CMD:
cmd = val.cmd;
break;
@@ -331,14 +313,16 @@ el_getc(EditLine *el, char *cp)
if (ma->level < 0)
break;
- if (*ma->macro[ma->level] == 0) {
- ma->level--;
+ if (ma->macro[ma->level][ma->offset] == '\0') {
+ el_free(ma->macro[ma->level--]);
+ ma->offset = 0;
continue;
}
- *cp = *ma->macro[ma->level]++ & 0377;
- if (*ma->macro[ma->level] == 0) { /* Needed for QuoteMode
- * On */
- ma->level--;
+ *cp = ma->macro[ma->level][ma->offset++] & 0377;
+ if (ma->macro[ma->level][ma->offset] == '\0') {
+ /* Needed for QuoteMode On */
+ el_free(ma->macro[ma->level--]);
+ ma->offset = 0;
}
return (1);
}
@@ -359,6 +343,35 @@ el_getc(EditLine *el, char *cp)
return (num_read);
}
+protected void
+read_prepare(EditLine *el)
+{
+ if (el->el_flags & HANDLE_SIGNALS)
+ sig_set(el);
+ if (el->el_flags & NO_TTY)
+ return;
+ if ((el->el_flags & (UNBUFFERED|EDIT_DISABLED)) == UNBUFFERED)
+ tty_rawmode(el);
+
+ /* This is relatively cheap, and things go terribly wrong if
+ we have the wrong size. */
+ el_resize(el);
+ re_clear_display(el); /* reset the display stuff */
+ ch_reset(el);
+ re_refresh(el); /* print the prompt */
+
+ if (el->el_flags & UNBUFFERED)
+ term__flush();
+}
+
+protected void
+read_finish(EditLine *el)
+{
+ if ((el->el_flags & UNBUFFERED) == 0)
+ (void) tty_cookedmode(el);
+ if (el->el_flags & HANDLE_SIGNALS)
+ sig_clr(el);
+}
public const char *
el_gets(EditLine *el, int *nread)
@@ -367,13 +380,11 @@ el_gets(EditLine *el, int *nread)
el_action_t cmdnum = 0;
int num; /* how many chars we have read at NL */
char ch;
+ int crlf = 0;
#ifdef FIONREAD
c_macro_t *ma = &el->el_chared.c_macro;
#endif /* FIONREAD */
- if (el->el_flags & HANDLE_SIGNALS)
- sig_set(el);
-
if (el->el_flags & NO_TTY) {
char *cp = el->el_line.buffer;
size_t idx;
@@ -387,6 +398,8 @@ el_gets(EditLine *el, int *nread)
cp = &el->el_line.buffer[idx];
}
cp++;
+ if (el->el_flags & UNBUFFERED)
+ break;
if (cp[-1] == '\r' || cp[-1] == '\n')
break;
}
@@ -398,12 +411,6 @@ el_gets(EditLine *el, int *nread)
return (el->el_line.buffer);
}
- /* This is relatively cheap, and things go terribly wrong if
- we have the wrong size. */
- el_resize(el);
-
- re_clear_display(el); /* reset the display stuff */
- ch_reset(el);
#ifdef FIONREAD
if (el->el_tty.t_mode == EX_IO && ma->level < 0) {
@@ -420,11 +427,16 @@ el_gets(EditLine *el, int *nread)
}
#endif /* FIONREAD */
- re_refresh(el); /* print the prompt */
+ if ((el->el_flags & UNBUFFERED) == 0)
+ read_prepare(el);
if (el->el_flags & EDIT_DISABLED) {
- char *cp = el->el_line.buffer;
+ char *cp;
size_t idx;
+ if ((el->el_flags & UNBUFFERED) == 0)
+ cp = el->el_line.buffer;
+ else
+ cp = el->el_line.lastchar;
term__flush();
@@ -439,7 +451,10 @@ el_gets(EditLine *el, int *nread)
if (*cp == 4) /* ought to be stty eof */
break;
cp++;
- if (cp[-1] == '\r' || cp[-1] == '\n')
+ crlf = cp[-1] == '\r' || cp[-1] == '\n';
+ if (el->el_flags & UNBUFFERED)
+ break;
+ if (crlf)
break;
}
@@ -463,8 +478,7 @@ el_gets(EditLine *el, int *nread)
#endif /* DEBUG_READ */
break;
}
- if ((unsigned int)cmdnum >= (unsigned int)(el->el_map.nfunc))
- { /* BUG CHECK command */
+ if ((uint)cmdnum >= el->el_map.nfunc) { /* BUG CHECK command */
#ifdef DEBUG_EDIT
(void) fprintf(el->el_errfile,
"ERROR: illegal command from key 0%o\r\n", ch);
@@ -494,7 +508,7 @@ el_gets(EditLine *el, int *nread)
el->el_chared.c_redo.pos < el->el_chared.c_redo.lim) {
if (cmdnum == VI_DELETE_PREV_CHAR &&
el->el_chared.c_redo.pos != el->el_chared.c_redo.buf
- && isprint(el->el_chared.c_redo.pos[-1]))
+ && isprint((unsigned char)el->el_chared.c_redo.pos[-1]))
el->el_chared.c_redo.pos--;
else
*el->el_chared.c_redo.pos++ = ch;
@@ -536,7 +550,13 @@ el_gets(EditLine *el, int *nread)
continue; /* keep going... */
case CC_EOF: /* end of file typed */
- num = 0;
+ if ((el->el_flags & UNBUFFERED) == 0)
+ num = 0;
+ else if (num == -1) {
+ *el->el_line.lastchar++ = CONTROL('d');
+ el->el_line.cursor = el->el_line.lastchar;
+ num = 1;
+ }
break;
case CC_NEWLINE: /* normal end of line */
@@ -567,14 +587,19 @@ el_gets(EditLine *el, int *nread)
el->el_state.argument = 1;
el->el_state.doingarg = 0;
el->el_chared.c_vcmd.action = NOP;
+ if (el->el_flags & UNBUFFERED)
+ break;
}
term__flush(); /* flush any buffered output */
/* make sure the tty is set up correctly */
- (void) tty_cookedmode(el);
- if (el->el_flags & HANDLE_SIGNALS)
- sig_clr(el);
- if (nread)
- *nread = num;
+ if ((el->el_flags & UNBUFFERED) == 0) {
+ read_finish(el);
+ if (nread)
+ *nread = num;
+ } else {
+ if (nread)
+ *nread = el->el_line.lastchar - el->el_line.buffer;
+ }
return (num ? el->el_line.buffer : NULL);
}
diff --git a/cmd-line-utils/libedit/read.h b/cmd-line-utils/libedit/read.h
index b01e77db239..1982f47253b 100644
--- a/cmd-line-utils/libedit/read.h
+++ b/cmd-line-utils/libedit/read.h
@@ -1,4 +1,4 @@
-/* $NetBSD: read.h,v 1.1 2001/09/27 19:29:50 christos Exp $ */
+/* $NetBSD: read.h,v 1.4 2004/02/27 14:52:18 christos Exp $ */
/*-
* Copyright (c) 2001 The NetBSD Foundation, Inc.
@@ -49,6 +49,8 @@ typedef struct el_read_t {
} el_read_t;
protected int read_init(EditLine *);
+protected void read_prepare(EditLine *);
+protected void read_finish(EditLine *);
protected int el_read_setfn(EditLine *, el_rfunc_t);
protected el_rfunc_t el_read_getfn(EditLine *);
diff --git a/cmd-line-utils/libedit/readline.c b/cmd-line-utils/libedit/readline.c
index 5b40ade582c..3a38e8a99ab 100644
--- a/cmd-line-utils/libedit/readline.c
+++ b/cmd-line-utils/libedit/readline.c
@@ -1,4 +1,4 @@
-/* $NetBSD: readline.c,v 1.28 2003/03/10 01:14:54 christos Exp $ */
+/* $NetBSD: readline.c,v 1.49 2005/03/10 19:34:46 christos Exp $ */
/*-
* Copyright (c) 1997 The NetBSD Foundation, Inc.
@@ -36,10 +36,25 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
-#include "config.h"
-#if !defined(lint) && !defined(SCCSID)
-__RCSID("$NetBSD: readline.c,v 1.28 2003/03/10 01:14:54 christos Exp $");
-#endif /* not lint && not SCCSID */
+/* AIX requires this to be the first thing in the file. */
+#if defined (_AIX) && !defined (__GNUC__)
+ #pragma alloca
+#endif
+
+#include <config.h>
+
+#ifdef __GNUC__
+# undef alloca
+# define alloca(n) __builtin_alloca (n)
+#else
+# ifdef HAVE_ALLOCA_H
+# include <alloca.h>
+# else
+# ifndef _AIX
+extern char *alloca ();
+# endif
+# endif
+#endif
#include <sys/types.h>
#include <sys/stat.h>
@@ -51,19 +66,20 @@ __RCSID("$NetBSD: readline.c,v 1.28 2003/03/10 01:14:54 christos Exp $");
#include <stdlib.h>
#include <unistd.h>
#include <limits.h>
-#ifdef HAVE_ALLOCA_H
-#include <alloca.h>
-#endif
-#include "histedit.h"
-#include "readline/readline.h"
+#include <errno.h>
+#include <fcntl.h>
+#include <vis.h>
+
#include "el.h"
#include "fcns.h" /* for EL_NUM_FCNS */
+#include "histedit.h"
+#include "readline/readline.h"
/* for rl_complete() */
-#define TAB '\r'
+#define TAB '\r'
/* see comment at the #ifdef for sense of this */
-#define GDB_411_HACK
+/* #define GDB_411_HACK */
/* readline compatibility stuff - look at readline sources/documentation */
/* to see what these variables mean */
@@ -78,6 +94,9 @@ FILE *rl_outstream = NULL;
int rl_point = 0;
int rl_end = 0;
char *rl_line_buffer = NULL;
+VFunction *rl_linefunc = NULL;
+int rl_done = 0;
+VFunction *rl_event_hook = NULL;
int history_base = 1; /* probably never subject to change */
int history_length = 0;
@@ -86,16 +105,34 @@ char history_expansion_char = '!';
char history_subst_char = '^';
char *history_no_expand_chars = expand_chars;
Function *history_inhibit_expansion_function = NULL;
+char *history_arg_extract(int start, int end, const char *str);
int rl_inhibit_completion = 0;
int rl_attempted_completion_over = 0;
char *rl_basic_word_break_characters = break_chars;
char *rl_completer_word_break_characters = NULL;
char *rl_completer_quote_characters = NULL;
-CPFunction *rl_completion_entry_function = NULL;
+Function *rl_completion_entry_function = NULL;
CPPFunction *rl_attempted_completion_function = NULL;
+Function *rl_pre_input_hook = NULL;
+Function *rl_startup1_hook = NULL;
+Function *rl_getc_function = NULL;
+char *rl_terminal_name = NULL;
+int rl_already_prompted = 0;
+int rl_filename_completion_desired = 0;
+int rl_ignore_completion_duplicates = 0;
+int rl_catch_signals = 1;
+VFunction *rl_redisplay_function = NULL;
+Function *rl_startup_hook = NULL;
+VFunction *rl_completion_display_matches_hook = NULL;
+VFunction *rl_prep_term_function = NULL;
+VFunction *rl_deprep_term_function = NULL;
/*
+ * The current prompt string.
+ */
+char *rl_prompt = NULL;
+/*
* This is set to character indicating type of completion being done by
* rl_complete_internal(); this is available for application completion
* functions.
@@ -128,30 +165,30 @@ static int _rl_complete_show_all = 0;
static History *h = NULL;
static EditLine *e = NULL;
+static Function *map[256];
static int el_rl_complete_cmdnum = 0;
/* internal functions */
static unsigned char _el_rl_complete(EditLine *, int);
+static unsigned char _el_rl_tstp(EditLine *, int);
static char *_get_prompt(EditLine *);
static HIST_ENTRY *_move_history(int);
-static int _history_search_gen(const char *, int, int);
-static int _history_expand_command(const char *, size_t, char **);
+static int _history_expand_command(const char *, size_t, size_t,
+ char **);
static char *_rl_compat_sub(const char *, const char *,
- const char *, int);
-static int rl_complete_internal(int);
+ const char *, int);
+static int _rl_complete_internal(int);
static int _rl_qsort_string_compare(const void *, const void *);
-
-/*
- * needed for prompt switching in readline()
- */
-static char *el_rl_prompt = NULL;
+static int _rl_event_read_char(EditLine *, char *);
+static void _rl_update_pos(void);
/* ARGSUSED */
static char *
-_get_prompt(EditLine *el __attribute__((unused)))
+_get_prompt(EditLine *el __attribute__((__unused__)))
{
- return (el_rl_prompt);
+ rl_already_prompted = 1;
+ return (rl_prompt);
}
@@ -168,7 +205,7 @@ _move_history(int op)
return (HIST_ENTRY *) NULL;
rl_he.line = ev.str;
- rl_he.data = "";
+ rl_he.data = (histdata_t) &(ev.num);
return (&rl_he);
}
@@ -221,29 +258,41 @@ rl_initialize(void)
el_set(e, EL_HIST, history, h);
/* for proper prompt printing in readline() */
- el_rl_prompt = strdup("");
- if (el_rl_prompt == NULL) {
+ rl_prompt = strdup("");
+ if (rl_prompt == NULL) {
history_end(h);
el_end(e);
return -1;
}
el_set(e, EL_PROMPT, _get_prompt);
- el_set(e, EL_SIGNAL, 1);
+ el_set(e, EL_SIGNAL, rl_catch_signals);
/* set default mode to "emacs"-style and read setting afterwards */
/* so this can be overriden */
el_set(e, EL_EDITOR, "emacs");
+ if (rl_terminal_name != NULL)
+ el_set(e, EL_TERMINAL, rl_terminal_name);
+ else
+ el_get(e, EL_TERMINAL, &rl_terminal_name);
/*
- * Word completition - this has to go AFTER rebinding keys
+ * Word completion - this has to go AFTER rebinding keys
* to emacs-style.
*/
el_set(e, EL_ADDFN, "rl_complete",
- "ReadLine compatible completition function",
+ "ReadLine compatible completion function",
_el_rl_complete);
el_set(e, EL_BIND, "^I", "rl_complete", NULL);
/*
+ * Send TSTP when ^Z is pressed.
+ */
+ el_set(e, EL_ADDFN, "rl_tstp",
+ "ReadLine compatible suspend function",
+ _el_rl_tstp);
+ el_set(e, EL_BIND, "^Z", "rl_tstp", NULL);
+
+ /*
* Find out where the rl_complete function was added; this is
* used later to detect that lastcmd was also rl_complete.
*/
@@ -264,7 +313,10 @@ rl_initialize(void)
li = el_line(e);
/* a cheesy way to get rid of const cast. */
rl_line_buffer = memchr(li->buffer, *li->buffer, 1);
- rl_point = rl_end = 0;
+ _rl_update_pos();
+
+ if (rl_startup_hook)
+ (*rl_startup_hook)(NULL, 0);
return (0);
}
@@ -281,19 +333,38 @@ readline(const char *prompt)
int count;
const char *ret;
char *buf;
+ static int used_event_hook;
if (e == NULL || h == NULL)
rl_initialize();
+ rl_done = 0;
+
/* update prompt accordingly to what has been passed */
if (!prompt)
prompt = "";
- if (strcmp(el_rl_prompt, prompt) != 0) {
- free(el_rl_prompt);
- el_rl_prompt = strdup(prompt);
- if (el_rl_prompt == NULL)
+ if (strcmp(rl_prompt, prompt) != 0) {
+ free(rl_prompt);
+ rl_prompt = strdup(prompt);
+ if (rl_prompt == NULL)
return NULL;
}
+
+ if (rl_pre_input_hook)
+ (*rl_pre_input_hook)(NULL, 0);
+
+ if (rl_event_hook && !(e->el_flags&NO_TTY)) {
+ el_set(e, EL_GETCFN, _rl_event_read_char);
+ used_event_hook = 1;
+ }
+
+ if (!rl_event_hook && used_event_hook) {
+ el_set(e, EL_GETCFN, EL_BUILTIN_GETCFN);
+ used_event_hook = 0;
+ }
+
+ rl_already_prompted = 0;
+
/* get one line from input stream */
ret = el_gets(e, &count);
@@ -333,73 +404,178 @@ using_history(void)
/*
* substitute ``what'' with ``with'', returning resulting string; if
- * globally == 1, substitutes all occurences of what, otherwise only the
+ * globally == 1, substitutes all occurrences of what, otherwise only the
* first one
*/
static char *
_rl_compat_sub(const char *str, const char *what, const char *with,
int globally)
{
- char *result;
- const char *temp, *new;
- unsigned int len, with_len, what_len, add;
- size_t size, i;
+ const char *s;
+ char *r, *result;
+ size_t len, with_len, what_len;
- result = malloc((size = 16));
- if (result == NULL)
- return NULL;
- temp = str;
+ len = strlen(str);
with_len = strlen(with);
what_len = strlen(what);
- len = 0;
- do {
- new = strstr(temp, what);
- if (new) {
- i = new - temp;
- add = i + with_len;
- if (i + add + 1 >= size) {
- char *nresult;
- size += add + 1;
- nresult = realloc(result, size);
- if (nresult == NULL) {
- free(result);
- return NULL;
- }
- result = nresult;
- }
- (void) strncpy(&result[len], temp, i);
- len += i;
- (void) strcpy(&result[len], with); /* safe */
- len += with_len;
- temp = new + what_len;
- } else {
- add = strlen(temp);
- if (len + add + 1 >= size) {
- char *nresult;
- size += add + 1;
- nresult = realloc(result, size);
- if (nresult == NULL) {
- free(result);
- return NULL;
- }
- result = nresult;
+
+ /* calculate length we need for result */
+ s = str;
+ while (*s) {
+ if (*s == *what && !strncmp(s, what, what_len)) {
+ len += with_len - what_len;
+ if (!globally)
+ break;
+ s += what_len;
+ } else
+ s++;
+ }
+ r = result = malloc(len + 1);
+ if (result == NULL)
+ return NULL;
+ s = str;
+ while (*s) {
+ if (*s == *what && !strncmp(s, what, what_len)) {
+ (void)strncpy(r, with, with_len);
+ r += with_len;
+ s += what_len;
+ if (!globally) {
+ (void)strcpy(r, s);
+ return(result);
}
- (void) strcpy(&result[len], temp); /* safe */
- len += add;
- temp = NULL;
+ } else
+ *r++ = *s++;
+ }
+ *r = 0;
+ return(result);
+}
+
+static char *last_search_pat; /* last !?pat[?] search pattern */
+static char *last_search_match; /* last !?pat[?] that matched */
+
+const char *
+get_history_event(const char *cmd, int *cindex, int qchar)
+{
+ int idx, sign, sub, num, begin, ret;
+ size_t len;
+ char *pat;
+ const char *rptr;
+ HistEvent ev;
+
+ idx = *cindex;
+ if (cmd[idx++] != history_expansion_char)
+ return(NULL);
+
+ /* find out which event to take */
+ if (cmd[idx] == history_expansion_char || cmd[idx] == 0) {
+ if (history(h, &ev, H_FIRST) != 0)
+ return(NULL);
+ *cindex = cmd[idx]? (idx + 1):idx;
+ return(ev.str);
+ }
+ sign = 0;
+ if (cmd[idx] == '-') {
+ sign = 1;
+ idx++;
+ }
+
+ if ('0' <= cmd[idx] && cmd[idx] <= '9') {
+ HIST_ENTRY *rl_he;
+
+ num = 0;
+ while (cmd[idx] && '0' <= cmd[idx] && cmd[idx] <= '9') {
+ num = num * 10 + cmd[idx] - '0';
+ idx++;
}
- } while (temp && globally);
- result[len] = '\0';
+ if (sign)
+ num = history_length - num + 1;
- return (result);
-}
+ if (!(rl_he = history_get(num)))
+ return(NULL);
+
+ *cindex = idx;
+ return(rl_he->line);
+ }
+ sub = 0;
+ if (cmd[idx] == '?') {
+ sub = 1;
+ idx++;
+ }
+ begin = idx;
+ while (cmd[idx]) {
+ if (cmd[idx] == '\n')
+ break;
+ if (sub && cmd[idx] == '?')
+ break;
+ if (!sub && (cmd[idx] == ':' || cmd[idx] == ' '
+ || cmd[idx] == '\t' || cmd[idx] == qchar))
+ break;
+ idx++;
+ }
+ len = idx - begin;
+ if (sub && cmd[idx] == '?')
+ idx++;
+ if (sub && len == 0 && last_search_pat && *last_search_pat)
+ pat = last_search_pat;
+ else if (len == 0)
+ return(NULL);
+ else {
+ if ((pat = malloc(len + 1)) == NULL)
+ return NULL;
+ (void)strncpy(pat, cmd + begin, len);
+ pat[len] = '\0';
+ }
+ if (history(h, &ev, H_CURR) != 0) {
+ if (pat != last_search_pat)
+ free(pat);
+ return (NULL);
+ }
+ num = ev.num;
+
+ if (sub) {
+ if (pat != last_search_pat) {
+ if (last_search_pat)
+ free(last_search_pat);
+ last_search_pat = pat;
+ }
+ ret = history_search(pat, -1);
+ } else
+ ret = history_search_prefix(pat, -1);
+
+ if (ret == -1) {
+ /* restore to end of list on failed search */
+ history(h, &ev, H_FIRST);
+ (void)fprintf(rl_outstream, "%s: Event not found\n", pat);
+ if (pat != last_search_pat)
+ free(pat);
+ return(NULL);
+ }
+
+ if (sub && len) {
+ if (last_search_match && last_search_match != pat)
+ free(last_search_match);
+ last_search_match = pat;
+ }
+
+ if (pat != last_search_pat)
+ free(pat);
+
+ if (history(h, &ev, H_CURR) != 0)
+ return(NULL);
+ *cindex = idx;
+ rptr = ev.str;
+
+ /* roll back to original position */
+ (void)history(h, &ev, H_SET, num);
+
+ return rptr;
+}
/*
* the real function doing history expansion - takes as argument command
* to do and data upon which the command should be executed
* does expansion the way I've understood readline documentation
- * word designator ``%'' isn't supported (yet ?)
*
* returns 0 if data was not modified, 1 if it was and 2 if the string
* should be only printed and not executed; in case of error,
@@ -407,144 +583,145 @@ _rl_compat_sub(const char *str, const char *what, const char *with,
* it's callers responsibility to free() string returned in *result
*/
static int
-_history_expand_command(const char *command, size_t cmdlen, char **result)
+_history_expand_command(const char *command, size_t offs, size_t cmdlen,
+ char **result)
{
- char **arr, *tempcmd, *line, *search = NULL, *cmd;
- const char *event_data = NULL;
+ char *tmp, *search = NULL, *aptr;
+ const char *ptr, *cmd;
static char *from = NULL, *to = NULL;
- int start = -1, end = -1, max, i, idx;
- int h_on = 0, t_on = 0, r_on = 0, e_on = 0, p_on = 0, g_on = 0;
- int event_num = 0, retval;
- size_t cmdsize;
+ int start, end, idx, has_mods = 0;
+ int p_on = 0, g_on = 0;
*result = NULL;
+ aptr = NULL;
+ ptr = NULL;
- cmd = alloca(cmdlen + 1);
- (void) strncpy(cmd, command, cmdlen);
- cmd[cmdlen] = 0;
+ /* First get event specifier */
+ idx = 0;
- idx = 1;
- /* find out which event to take */
- if (cmd[idx] == history_expansion_char) {
- event_num = history_length;
- idx++;
+ if (strchr(":^*$", command[offs + 1])) {
+ char str[4];
+ /*
+ * "!:" is shorthand for "!!:".
+ * "!^", "!*" and "!$" are shorthand for
+ * "!!:^", "!!:*" and "!!:$" respectively.
+ */
+ str[0] = str[1] = '!';
+ str[2] = '0';
+ ptr = get_history_event(str, &idx, 0);
+ idx = (command[offs + 1] == ':')? 1:0;
+ has_mods = 1;
} else {
- int off, num;
- size_t len;
- off = idx;
- while (cmd[off] && !strchr(":^$*-%", cmd[off]))
- off++;
- num = atoi(&cmd[idx]);
- if (num != 0) {
- event_num = num;
- if (num < 0)
- event_num += history_length + 1;
+ if (command[offs + 1] == '#') {
+ /* use command so far */
+ if ((aptr = malloc(offs + 1)) == NULL)
+ return -1;
+ (void)strncpy(aptr, command, offs);
+ aptr[offs] = '\0';
+ idx = 1;
} else {
- int prefix = 1, curr_num;
- HistEvent ev;
-
- len = off - idx;
- if (cmd[idx] == '?') {
- idx++, len--;
- if (cmd[off - 1] == '?')
- len--;
- else if (cmd[off] != '\n' && cmd[off] != '\0')
- return (-1);
- prefix = 0;
- }
- search = alloca(len + 1);
- (void) strncpy(search, &cmd[idx], len);
- search[len] = '\0';
-
- if (history(h, &ev, H_CURR) != 0)
- return (-1);
- curr_num = ev.num;
+ int qchar;
- if (prefix)
- retval = history_search_prefix(search, -1);
- else
- retval = history_search(search, -1);
+ qchar = (offs > 0 && command[offs - 1] == '"')? '"':0;
+ ptr = get_history_event(command + offs, &idx, qchar);
+ }
+ has_mods = command[offs + idx] == ':';
+ }
- if (retval == -1) {
- fprintf(rl_outstream, "%s: Event not found\n",
- search);
- return (-1);
- }
- if (history(h, &ev, H_CURR) != 0)
- return (-1);
- event_data = ev.str;
+ if (ptr == NULL && aptr == NULL)
+ return(-1);
- /* roll back to original position */
- history(h, &ev, H_NEXT_EVENT, curr_num);
- }
- idx = off;
+ if (!has_mods) {
+ *result = strdup(aptr? aptr : ptr);
+ if (aptr)
+ free(aptr);
+ return(1);
}
- if (!event_data && event_num >= 0) {
- HIST_ENTRY *rl_he;
- rl_he = history_get(event_num);
- if (!rl_he)
- return (0);
- event_data = rl_he->line;
+ cmd = command + offs + idx + 1;
+
+ /* Now parse any word designators */
+
+ if (*cmd == '%') /* last word matched by ?pat? */
+ tmp = strdup(last_search_match? last_search_match:"");
+ else if (strchr("^*$-0123456789", *cmd)) {
+ start = end = -1;
+ if (*cmd == '^')
+ start = end = 1, cmd++;
+ else if (*cmd == '$')
+ start = -1, cmd++;
+ else if (*cmd == '*')
+ start = 1, cmd++;
+ else if (*cmd == '-' || isdigit((unsigned char) *cmd)) {
+ start = 0;
+ while (*cmd && '0' <= *cmd && *cmd <= '9')
+ start = start * 10 + *cmd++ - '0';
+
+ if (*cmd == '-') {
+ if (isdigit((unsigned char) cmd[1])) {
+ cmd++;
+ end = 0;
+ while (*cmd && '0' <= *cmd && *cmd <= '9')
+ end = end * 10 + *cmd++ - '0';
+ } else if (cmd[1] == '$') {
+ cmd += 2;
+ end = -1;
+ } else {
+ cmd++;
+ end = -2;
+ }
+ } else if (*cmd == '*')
+ end = -1, cmd++;
+ else
+ end = start;
+ }
+ tmp = history_arg_extract(start, end, aptr? aptr:ptr);
+ if (tmp == NULL) {
+ (void)fprintf(rl_outstream, "%s: Bad word specifier",
+ command + offs + idx);
+ if (aptr)
+ free(aptr);
+ return(-1);
+ }
} else
- return (-1);
+ tmp = strdup(aptr? aptr:ptr);
- if (cmd[idx] != ':')
- return (-1);
- cmd += idx + 1;
-
- /* recognize cmd */
- if (*cmd == '^')
- start = end = 1, cmd++;
- else if (*cmd == '$')
- start = end = -1, cmd++;
- else if (*cmd == '*')
- start = 1, end = -1, cmd++;
- else if (isdigit((unsigned char) *cmd)) {
- const char *temp;
- int shifted = 0;
-
- start = atoi(cmd);
- temp = cmd;
- for (; isdigit((unsigned char) *cmd); cmd++);
- if (temp != cmd)
- shifted = 1;
- if (shifted && *cmd == '-') {
- if (!isdigit((unsigned char) *(cmd + 1)))
- end = -2;
- else {
- end = atoi(cmd + 1);
- for (; isdigit((unsigned char) *cmd); cmd++);
- }
- } else if (shifted && *cmd == '*')
- end = -1, cmd++;
- else if (shifted)
- end = start;
+ if (aptr)
+ free(aptr);
+
+ if (*cmd == 0 || (cmd - (command + offs) >= cmdlen)) {
+ *result = tmp;
+ return(1);
}
- if (*cmd == ':')
- cmd++;
- line = strdup(event_data);
- if (line == NULL)
- return 0;
for (; *cmd; cmd++) {
if (*cmd == ':')
continue;
- else if (*cmd == 'h')
- h_on = 1 | g_on, g_on = 0;
- else if (*cmd == 't')
- t_on = 1 | g_on, g_on = 0;
- else if (*cmd == 'r')
- r_on = 1 | g_on, g_on = 0;
- else if (*cmd == 'e')
- e_on = 1 | g_on, g_on = 0;
- else if (*cmd == 'p')
- p_on = 1 | g_on, g_on = 0;
+ else if (*cmd == 'h') { /* remove trailing path */
+ if ((aptr = strrchr(tmp, '/')) != NULL)
+ *aptr = 0;
+ } else if (*cmd == 't') { /* remove leading path */
+ if ((aptr = strrchr(tmp, '/')) != NULL) {
+ aptr = strdup(aptr + 1);
+ free(tmp);
+ tmp = aptr;
+ }
+ } else if (*cmd == 'r') { /* remove trailing suffix */
+ if ((aptr = strrchr(tmp, '.')) != NULL)
+ *aptr = 0;
+ } else if (*cmd == 'e') { /* remove all but suffix */
+ if ((aptr = strrchr(tmp, '.')) != NULL) {
+ aptr = strdup(aptr);
+ free(tmp);
+ tmp = aptr;
+ }
+ } else if (*cmd == 'p') /* print only */
+ p_on = 1;
else if (*cmd == 'g')
g_on = 2;
else if (*cmd == 's' || *cmd == '&') {
char *what, *with, delim;
- unsigned int len, from_len;
+ size_t len, from_len;
size_t size;
if (*cmd == '&' && (from == NULL || to == NULL))
@@ -559,13 +736,12 @@ _history_expand_command(const char *command, size_t cmdlen, char **result)
}
len = 0;
for (; *cmd && *cmd != delim; cmd++) {
- if (*cmd == '\\'
- && *(cmd + 1) == delim)
+ if (*cmd == '\\' && cmd[1] == delim)
cmd++;
if (len >= size) {
char *nwhat;
nwhat = realloc(what,
- (size <<= 1));
+ (size <<= 1));
if (nwhat == NULL) {
free(what);
return 0;
@@ -612,7 +788,7 @@ _history_expand_command(const char *command, size_t cmdlen, char **result)
}
if (*cmd == '&') {
/* safe */
- (void) strcpy(&with[len], from);
+ (void)strcpy(&with[len], from);
len += from_len;
continue;
}
@@ -624,88 +800,18 @@ _history_expand_command(const char *command, size_t cmdlen, char **result)
}
with[len] = '\0';
to = with;
-
- tempcmd = _rl_compat_sub(line, from, to,
- (g_on) ? 1 : 0);
- if (tempcmd) {
- free(line);
- line = tempcmd;
- }
- g_on = 0;
}
- }
- }
-
- arr = history_tokenize(line);
- free(line); /* no more needed */
- if (arr && *arr == NULL)
- free(arr), arr = NULL;
- if (!arr)
- return (-1);
-
- /* find out max valid idx to array of array */
- max = 0;
- for (i = 0; arr[i]; i++)
- max++;
- max--;
-
- /* set boundaries to something relevant */
- if (start < 0)
- start = 1;
- if (end < 0)
- end = max - ((end < -1) ? 1 : 0);
-
- /* check boundaries ... */
- if (start > max || end > max || start > end)
- return (-1);
- for (i = 0; i <= max; i++) {
- char *temp;
- if (h_on && (i == 1 || h_on > 1) &&
- (temp = strrchr(arr[i], '/')))
- *(temp + 1) = '\0';
- if (t_on && (i == 1 || t_on > 1) &&
- (temp = strrchr(arr[i], '/')))
- (void) strcpy(arr[i], temp + 1);
- if (r_on && (i == 1 || r_on > 1) &&
- (temp = strrchr(arr[i], '.')))
- *temp = '\0';
- if (e_on && (i == 1 || e_on > 1) &&
- (temp = strrchr(arr[i], '.')))
- (void) strcpy(arr[i], temp);
- }
-
- cmdsize = 1, cmdlen = 0;
- if ((tempcmd = malloc(cmdsize)) == NULL)
- return 0;
- for (i = start; start <= i && i <= end; i++) {
- int arr_len;
-
- arr_len = strlen(arr[i]);
- if (cmdlen + arr_len + 1 >= cmdsize) {
- char *ntempcmd;
- cmdsize += arr_len + 1;
- ntempcmd = realloc(tempcmd, cmdsize);
- if (ntempcmd == NULL) {
- free(tempcmd);
- return 0;
+ aptr = _rl_compat_sub(tmp, from, to, g_on);
+ if (aptr) {
+ free(tmp);
+ tmp = aptr;
}
- tempcmd = ntempcmd;
+ g_on = 0;
}
- (void) strcpy(&tempcmd[cmdlen], arr[i]); /* safe */
- cmdlen += arr_len;
- tempcmd[cmdlen++] = ' '; /* add a space */
}
- while (cmdlen > 0 && isspace((unsigned char) tempcmd[cmdlen - 1]))
- cmdlen--;
- tempcmd[cmdlen] = '\0';
-
- *result = tempcmd;
-
- for (i = 0; i <= max; i++)
- free(arr[i]);
- free(arr), arr = (char **) NULL;
- return (p_on) ? 2 : 1;
+ *result = tmp;
+ return (p_on? 2:1);
}
@@ -715,27 +821,36 @@ _history_expand_command(const char *command, size_t cmdlen, char **result)
int
history_expand(char *str, char **output)
{
- int i, retval = 0, idx;
- size_t size;
- char *temp, *result;
+ int ret = 0;
+ size_t idx, i, size;
+ char *tmp, *result;
if (h == NULL || e == NULL)
rl_initialize();
- *output = strdup(str); /* do it early */
- if (*output == NULL)
- return 0;
+ if (history_expansion_char == 0) {
+ *output = strdup(str);
+ return(0);
+ }
+ *output = NULL;
if (str[0] == history_subst_char) {
/* ^foo^foo2^ is equivalent to !!:s^foo^foo2^ */
- temp = alloca(4 + strlen(str) + 1);
- temp[0] = temp[1] = history_expansion_char;
- temp[2] = ':';
- temp[3] = 's';
- (void) strcpy(temp + 4, str);
- str = temp;
+ *output = malloc(strlen(str) + 4 + 1);
+ if (*output == NULL)
+ return 0;
+ (*output)[0] = (*output)[1] = history_expansion_char;
+ (*output)[2] = ':';
+ (*output)[3] = 's';
+ (void)strcpy((*output) + 4, str);
+ str = *output;
+ } else {
+ *output = strdup(str);
+ if (*output == NULL)
+ return 0;
}
-#define ADD_STRING(what, len) \
+
+#define ADD_STRING(what, len) \
{ \
if (idx + len + 1 > size) { \
char *nresult = realloc(result, (size += len + 1));\
@@ -753,35 +868,35 @@ history_expand(char *str, char **output)
result = NULL;
size = idx = 0;
for (i = 0; str[i];) {
- int start, j, loop_again;
- size_t len;
+ int qchar, loop_again;
+ size_t len, start, j;
+ qchar = 0;
loop_again = 1;
start = j = i;
loop:
for (; str[j]; j++) {
if (str[j] == '\\' &&
str[j + 1] == history_expansion_char) {
- (void) strcpy(&str[j], &str[j + 1]);
+ (void)strcpy(&str[j], &str[j + 1]);
continue;
}
if (!loop_again) {
- if (str[j] == '?') {
- while (str[j] && str[++j] != '?');
- if (str[j] == '?')
- j++;
- } else if (isspace((unsigned char) str[j]))
+ if (isspace((unsigned char) str[j])
+ || str[j] == qchar)
break;
}
if (str[j] == history_expansion_char
&& !strchr(history_no_expand_chars, str[j + 1])
&& (!history_inhibit_expansion_function ||
- (*history_inhibit_expansion_function)(str, j) == 0))
+ (*history_inhibit_expansion_function)(str,
+ (int)j) == 0))
break;
}
- if (str[j] && str[j + 1] != '#' && loop_again) {
+ if (str[j] && loop_again) {
i = j;
+ qchar = (j > 0 && str[j - 1] == '"' )? '"':0;
j++;
if (str[j] == history_expansion_char)
j++;
@@ -789,61 +904,116 @@ loop:
goto loop;
}
len = i - start;
- temp = &str[start];
- ADD_STRING(temp, len);
+ tmp = &str[start];
+ ADD_STRING(tmp, len);
- if (str[i] == '\0' || str[i] != history_expansion_char
- || str[i + 1] == '#') {
+ if (str[i] == '\0' || str[i] != history_expansion_char) {
len = j - i;
- temp = &str[i];
- ADD_STRING(temp, len);
+ tmp = &str[i];
+ ADD_STRING(tmp, len);
if (start == 0)
- retval = 0;
+ ret = 0;
else
- retval = 1;
+ ret = 1;
break;
}
- retval = _history_expand_command(&str[i], (size_t) (j - i),
- &temp);
- if (retval != -1) {
- len = strlen(temp);
- ADD_STRING(temp, len);
+ ret = _history_expand_command (str, i, (j - i), &tmp);
+ if (ret > 0 && tmp) {
+ len = strlen(tmp);
+ ADD_STRING(tmp, len);
+ free(tmp);
}
i = j;
- } /* for(i ...) */
+ }
- if (retval == 2) {
- add_history(temp);
+ /* ret is 2 for "print only" option */
+ if (ret == 2) {
+ add_history(result);
#ifdef GDB_411_HACK
/* gdb 4.11 has been shipped with readline, where */
/* history_expand() returned -1 when the line */
/* should not be executed; in readline 2.1+ */
/* it should return 2 in such a case */
- retval = -1;
+ ret = -1;
#endif
}
free(*output);
*output = result;
- return (retval);
+ return (ret);
}
+/*
+* Return a string consisting of arguments of "str" from "start" to "end".
+*/
+char *
+history_arg_extract(int start, int end, const char *str)
+{
+ size_t i, len, max;
+ char **arr, *result;
+
+ arr = history_tokenize(str);
+ if (!arr)
+ return(NULL);
+ if (arr && *arr == NULL) {
+ free(arr);
+ return(NULL);
+ }
+
+ for (max = 0; arr[max]; max++)
+ continue;
+ max--;
+
+ if (start == '$')
+ start = max;
+ if (end == '$')
+ end = max;
+ if (end < 0)
+ end = max + end + 1;
+ if (start < 0)
+ start = end;
+
+ if (start < 0 || end < 0 || start > max || end > max || start > end)
+ return(NULL);
+
+ for (i = start, len = 0; i <= end; i++)
+ len += strlen(arr[i]) + 1;
+ len++;
+ result = malloc(len);
+ if (result == NULL)
+ return NULL;
+
+ for (i = start, len = 0; i <= end; i++) {
+ (void)strcpy(result + len, arr[i]);
+ len += strlen(arr[i]);
+ if (i < end)
+ result[len++] = ' ';
+ }
+ result[len] = 0;
+
+ for (i = 0; arr[i]; i++)
+ free(arr[i]);
+ free(arr);
+
+ return(result);
+}
/*
- * Parse the string into individual tokens, similarily to how shell would do it.
+ * Parse the string into individual tokens,
+ * similar to how shell would do it.
*/
char **
history_tokenize(const char *str)
{
- int size = 1, result_idx = 0, i, start;
+ int size = 1, idx = 0, i, start;
size_t len;
char **result = NULL, *temp, delim = '\0';
- for (i = 0; str[i]; i++) {
+ for (i = 0; str[i];) {
while (isspace((unsigned char) str[i]))
i++;
start = i;
- for (; str[i]; i++) {
+ for (; str[i];) {
if (str[i] == '\\') {
if (str[i+1] != '\0')
i++;
@@ -855,9 +1025,11 @@ history_tokenize(const char *str)
break;
else if (!delim && strchr("'`\"", str[i]))
delim = str[i];
+ if (str[i])
+ i++;
}
- if (result_idx + 2 >= size) {
+ if (idx + 2 >= size) {
char **nresult;
size <<= 1;
nresult = realloc(result, size * sizeof(char *));
@@ -870,15 +1042,18 @@ history_tokenize(const char *str)
len = i - start;
temp = malloc(len + 1);
if (temp == NULL) {
+ for (i = 0; i < idx; i++)
+ free(result[i]);
free(result);
return NULL;
}
- (void) strncpy(temp, &str[start], len);
+ (void)strncpy(temp, &str[start], len);
temp[len] = '\0';
- result[result_idx++] = temp;
- result[result_idx] = NULL;
+ result[idx++] = temp;
+ result[idx] = NULL;
+ if (str[i])
+ i++;
}
-
return (result);
}
@@ -962,28 +1137,29 @@ history_get(int num)
{
static HIST_ENTRY she;
HistEvent ev;
- int i = 1, curr_num;
+ int curr_num;
if (h == NULL || e == NULL)
rl_initialize();
- /* rewind to beginning */
+ /* save current position */
if (history(h, &ev, H_CURR) != 0)
return (NULL);
curr_num = ev.num;
- if (history(h, &ev, H_LAST) != 0)
+
+ /* start from most recent */
+ if (history(h, &ev, H_FIRST) != 0)
return (NULL); /* error */
- while (i < num && history(h, &ev, H_PREV) == 0)
- i++;
- if (i != num)
- return (NULL); /* not so many entries */
+
+ /* look backwards for event matching specified offset */
+ if (history(h, &ev, H_NEXT_EVENT, num))
+ return (NULL);
she.line = ev.str;
she.data = NULL;
- /* rewind history to the same event it was before */
- (void) history(h, &ev, H_FIRST);
- (void) history(h, &ev, H_NEXT_EVENT, curr_num);
+ /* restore pointer to where it was */
+ (void)history(h, &ev, H_SET, curr_num);
return (&she);
}
@@ -1000,11 +1176,11 @@ add_history(const char *line)
if (h == NULL || e == NULL)
rl_initialize();
- (void) history(h, &ev, H_ENTER, line);
+ (void)history(h, &ev, H_ENTER, line);
if (history(h, &ev, H_GETSIZE) == 0)
history_length = ev.num;
- return (!(history_length > 0)); /* return 0 if all is okay */
+ return (!(history_length > 0)); /* return 0 if all is okay */
}
@@ -1086,22 +1262,17 @@ int
history_set_pos(int pos)
{
HistEvent ev;
- int off, curr_num;
+ int curr_num;
if (pos > history_length || pos < 0)
return (-1);
history(h, &ev, H_CURR);
curr_num = ev.num;
- history(h, &ev, H_FIRST);
- off = 0;
- while (off < pos && history(h, &ev, H_NEXT) == 0)
- off++;
- if (off != pos) { /* do a rollback in case of error */
- history(h, &ev, H_FIRST);
- history(h, &ev, H_NEXT_EVENT, curr_num);
- return (-1);
+ if (history(h, &ev, H_SET, pos)) {
+ history(h, &ev, H_SET, curr_num);
+ return(-1);
}
return (0);
}
@@ -1130,10 +1301,10 @@ next_history(void)
/*
- * generic history search function
+ * searches for first history event containing the str
*/
-static int
-_history_search_gen(const char *str, int direction, int pos)
+int
+history_search(const char *str, int direction)
{
HistEvent ev;
const char *strp;
@@ -1144,38 +1315,25 @@ _history_search_gen(const char *str, int direction, int pos)
curr_num = ev.num;
for (;;) {
- strp = strstr(ev.str, str);
- if (strp && (pos < 0 || &ev.str[pos] == strp))
+ if ((strp = strstr(ev.str, str)) != NULL)
return (int) (strp - ev.str);
- if (history(h, &ev, direction < 0 ? H_PREV : H_NEXT) != 0)
+ if (history(h, &ev, direction < 0 ? H_NEXT:H_PREV) != 0)
break;
}
-
- history(h, &ev, direction < 0 ? H_NEXT_EVENT : H_PREV_EVENT, curr_num);
-
+ history(h, &ev, H_SET, curr_num);
return (-1);
}
/*
- * searches for first history event containing the str
- */
-int
-history_search(const char *str, int direction)
-{
-
- return (_history_search_gen(str, direction, -1));
-}
-
-
-/*
* searches for first history event beginning with str
*/
int
history_search_prefix(const char *str, int direction)
{
+ HistEvent ev;
- return (_history_search_gen(str, direction, 0));
+ return (history(h, &ev, direction < 0? H_PREV_STR:H_NEXT_STR, str));
}
@@ -1185,8 +1343,8 @@ history_search_prefix(const char *str, int direction)
*/
/* ARGSUSED */
int
-history_search_pos(const char *str,
- int direction __attribute__((unused)), int pos)
+history_search_pos(const char *str,
+ int direction __attribute__((__unused__)), int pos)
{
HistEvent ev;
int curr_num, off;
@@ -1217,7 +1375,7 @@ history_search_pos(const char *str,
/********************************/
-/* completition functions */
+/* completion functions */
/*
* does tilde expansion of strings of type ``~user/foo''
@@ -1246,7 +1404,7 @@ tilde_expand(char *txt)
temp = malloc(len);
if (temp == NULL)
return NULL;
- (void) strncpy(temp, txt + 1, len - 2);
+ (void)strncpy(temp, txt + 1, len - 2);
temp[len - 2] = '\0';
}
pass = getpwnam(temp);
@@ -1261,7 +1419,7 @@ tilde_expand(char *txt)
temp = malloc(strlen(pass->pw_dir) + 1 + strlen(txt) + 1);
if (temp == NULL)
return NULL;
- (void) sprintf(temp, "%s/%s", pass->pw_dir, txt);
+ (void)sprintf(temp, "%s/%s", pass->pw_dir, txt);
return (temp);
}
@@ -1295,7 +1453,7 @@ filename_completion_function(const char *text, int state)
return NULL;
}
filename = nptr;
- (void) strcpy(filename, temp);
+ (void)strcpy(filename, temp);
len = temp - text; /* including last slash */
nptr = realloc(dirname, len + 1);
if (nptr == NULL) {
@@ -1303,12 +1461,16 @@ filename_completion_function(const char *text, int state)
return NULL;
}
dirname = nptr;
- (void) strncpy(dirname, text, len);
+ (void)strncpy(dirname, text, len);
dirname[len] = '\0';
} else {
- filename = strdup(text);
- if (filename == NULL)
- return NULL;
+ if (*text == 0)
+ filename = NULL;
+ else {
+ filename = strdup(text);
+ if (filename == NULL)
+ return NULL;
+ }
dirname = NULL;
}
@@ -1324,13 +1486,11 @@ filename_completion_function(const char *text, int state)
return NULL;
}
dirname = nptr;
- (void) strcpy(dirname, temp); /* safe */
+ (void)strcpy(dirname, temp); /* safe */
free(temp); /* no longer needed */
}
/* will be used in cycle */
- filename_len = strlen(filename);
- if (filename_len == 0)
- return (NULL); /* no expansion possible */
+ filename_len = filename ? strlen(filename) : 0;
if (dir != NULL) {
(void)closedir(dir);
@@ -1342,14 +1502,17 @@ filename_completion_function(const char *text, int state)
}
/* find the match */
while ((entry = readdir(dir)) != NULL) {
+ /* skip . and .. */
+ if (entry->d_name[0] == '.' && (!entry->d_name[1]
+ || (entry->d_name[1] == '.' && !entry->d_name[2])))
+ continue;
+ if (filename_len == 0)
+ break;
/* otherwise, get first entry where first */
/* filename_len characters are equal */
if (entry->d_name[0] == filename[0]
-#ifndef STRUCT_DIRENT_HAS_D_NAMLEN
+ /* Some dirents have d_namlen, but it is not portable. */
&& strlen(entry->d_name) >= filename_len
-#else
- && entry->d_namlen >= filename_len
-#endif
&& strncmp(entry->d_name, filename,
filename_len) == 0)
break;
@@ -1358,16 +1521,13 @@ filename_completion_function(const char *text, int state)
if (entry) { /* match found */
struct stat stbuf;
-#ifndef STRUCT_DIRENT_HAS_D_NAMLEN
+ /* Some dirents have d_namlen, but it is not portable. */
len = strlen(entry->d_name) +
-#else
- len = entry->d_namlen +
-#endif
((dirname) ? strlen(dirname) : 0) + 1 + 1;
temp = malloc(len);
if (temp == NULL)
return NULL;
- (void) sprintf(temp, "%s%s",
+ (void)sprintf(temp, "%s%s",
dirname ? dirname : "", entry->d_name); /* safe */
/* test, if it's directory */
@@ -1420,32 +1580,43 @@ username_completion_function(const char *text, int state)
*/
/* ARGSUSED */
static unsigned char
-_el_rl_complete(EditLine *el __attribute__((unused)), int ch)
+_el_rl_complete(EditLine *el __attribute__((__unused__)), int ch)
{
return (unsigned char) rl_complete(0, ch);
}
+/*
+ * el-compatible wrapper to send TSTP on ^Z
+ */
+/* ARGSUSED */
+static unsigned char
+_el_rl_tstp(EditLine *el __attribute__((__unused__)), int ch __attribute__((__unused__)))
+{
+ (void)kill(0, SIGTSTP);
+ return CC_NORM;
+}
/*
- * returns list of completitions for text given
+ * returns list of completions for text given
*/
char **
completion_matches(const char *text, CPFunction *genfunc)
{
char **match_list = NULL, *retstr, *prevstr;
size_t match_list_len, max_equal, which, i;
- unsigned int matches;
+ size_t matches;
if (h == NULL || e == NULL)
rl_initialize();
matches = 0;
match_list_len = 1;
- while ((retstr = (*genfunc) (text, matches)) != NULL) {
+ while ((retstr = (*genfunc) (text, (int)matches)) != NULL) {
/* allow for list terminator here */
- if (matches + 2 >= match_list_len) {
+ if (matches + 3 >= match_list_len) {
char **nmatch_list;
- match_list_len <<= 1;
+ while (matches + 3 >= match_list_len)
+ match_list_len <<= 1;
nmatch_list = realloc(match_list,
match_list_len * sizeof(char *));
if (nmatch_list == NULL) {
@@ -1477,7 +1648,7 @@ completion_matches(const char *text, CPFunction *genfunc)
free(match_list);
return NULL;
}
- (void) strncpy(retstr, match_list[1], max_equal);
+ (void)strncpy(retstr, match_list[1], max_equal);
retstr[max_equal] = '\0';
match_list[0] = retstr;
@@ -1532,9 +1703,10 @@ rl_display_match_list (matches, len, max)
idx = 1;
for(; count > 0; count--) {
- for(i=0; i < limit && matches[idx]; i++, idx++)
- fprintf(e->el_outfile, "%-*s ", max, matches[idx]);
- fprintf(e->el_outfile, "\n");
+ for(i = 0; i < limit && matches[idx]; i++, idx++)
+ (void)fprintf(e->el_outfile, "%-*s ", max,
+ matches[idx]);
+ (void)fprintf(e->el_outfile, "\n");
}
}
@@ -1550,9 +1722,9 @@ rl_display_match_list (matches, len, max)
* Note: '*' support is not implemented
*/
static int
-rl_complete_internal(int what_to_do)
+_rl_complete_internal(int what_to_do)
{
- CPFunction *complet_func;
+ Function *complet_func;
const LineInfo *li;
char *temp, **matches;
const char *ctemp;
@@ -1565,7 +1737,7 @@ rl_complete_internal(int what_to_do)
complet_func = rl_completion_entry_function;
if (!complet_func)
- complet_func = filename_completion_function;
+ complet_func = (Function *)(void *)filename_completion_function;
/* We now look backwards for the start of a filename/variable word */
li = el_line(e);
@@ -1573,26 +1745,26 @@ rl_complete_internal(int what_to_do)
while (ctemp > li->buffer
&& !strchr(rl_basic_word_break_characters, ctemp[-1])
&& (!rl_special_prefixes
- || !strchr(rl_special_prefixes, ctemp[-1]) ) )
+ || !strchr(rl_special_prefixes, ctemp[-1]) ) )
ctemp--;
len = li->cursor - ctemp;
temp = alloca(len + 1);
- (void) strncpy(temp, ctemp, len);
+ (void)strncpy(temp, ctemp, len);
temp[len] = '\0';
/* these can be used by function called in completion_matches() */
/* or (*rl_attempted_completion_function)() */
- rl_point = li->cursor - li->buffer;
- rl_end = li->lastchar - li->buffer;
+ _rl_update_pos();
- if (!rl_attempted_completion_function)
- matches = completion_matches(temp, complet_func);
- else {
+ if (rl_attempted_completion_function) {
int end = li->cursor - li->buffer;
matches = (*rl_attempted_completion_function) (temp, (int)
(end - len), end);
- }
+ } else
+ matches = 0;
+ if (!rl_attempted_completion_function || !matches)
+ matches = completion_matches(temp, (CPFunction *)complet_func);
if (matches) {
int i, retval = CC_REFRESH;
@@ -1613,11 +1785,12 @@ rl_complete_internal(int what_to_do)
if (matches[2] == NULL && strcmp(matches[0], matches[1]) == 0) {
/*
* We found exact match. Add a space after
- * it, unless we do filename completition and the
+ * it, unless we do filename completion and the
* object is a directory.
*/
size_t alen = strlen(matches[0]);
- if ((complet_func != filename_completion_function
+ if ((complet_func !=
+ (Function *)filename_completion_function
|| (alen > 0 && (matches[0])[alen - 1] != '/'))
&& rl_completion_append_character) {
char buf[2];
@@ -1640,20 +1813,20 @@ rl_complete_internal(int what_to_do)
matches_num = i - 1;
/* newline to get on next line from command line */
- fprintf(e->el_outfile, "\n");
+ (void)fprintf(e->el_outfile, "\n");
/*
* If there are too many items, ask user for display
* confirmation.
*/
if (matches_num > rl_completion_query_items) {
- fprintf(e->el_outfile,
- "Display all %d possibilities? (y or n) ",
- matches_num);
- fflush(e->el_outfile);
+ (void)fprintf(e->el_outfile,
+ "Display all %d possibilities? (y or n) ",
+ matches_num);
+ (void)fflush(e->el_outfile);
if (getc(stdin) != 'y')
match_display = 0;
- fprintf(e->el_outfile, "\n");
+ (void)fprintf(e->el_outfile, "\n");
}
if (match_display)
@@ -1689,20 +1862,24 @@ rl_complete_internal(int what_to_do)
* complete word at current point
*/
int
+/*ARGSUSED*/
rl_complete(int ignore, int invoking_key)
{
if (h == NULL || e == NULL)
rl_initialize();
if (rl_inhibit_completion) {
- rl_insert(ignore, invoking_key);
+ char arr[2];
+ arr[0] = (char)invoking_key;
+ arr[1] = '\0';
+ el_insertstr(e, arr);
return (CC_REFRESH);
} else if (e->el_state.lastcmd == el_rl_complete_cmdnum)
- return rl_complete_internal('?');
+ return _rl_complete_internal('?');
else if (_rl_complete_show_all)
- return rl_complete_internal('!');
+ return _rl_complete_internal('!');
else
- return (rl_complete_internal(TAB));
+ return _rl_complete_internal(TAB);
}
@@ -1751,7 +1928,7 @@ rl_read_key(void)
*/
/* ARGSUSED */
void
-rl_reset_terminal(const char *p __attribute__((unused)))
+rl_reset_terminal(const char *p __attribute__((__unused__)))
{
if (h == NULL || e == NULL)
@@ -1780,3 +1957,211 @@ rl_insert(int count, int c)
return (0);
}
+
+/*ARGSUSED*/
+int
+rl_newline(int count, int c)
+{
+ /*
+ * Readline-4.0 appears to ignore the args.
+ */
+ return rl_insert(1, '\n');
+}
+
+/*ARGSUSED*/
+static unsigned char
+rl_bind_wrapper(EditLine *el, unsigned char c)
+{
+ if (map[c] == NULL)
+ return CC_ERROR;
+
+ _rl_update_pos();
+
+ (*map[c])(NULL, c);
+
+ /* If rl_done was set by the above call, deal with it here */
+ if (rl_done)
+ return CC_EOF;
+
+ return CC_NORM;
+}
+
+int
+rl_add_defun(const char *name, Function *fun, int c)
+{
+ char dest[8];
+ if (c >= sizeof(map) / sizeof(map[0]) || c < 0)
+ return -1;
+ map[(unsigned char)c] = fun;
+ el_set(e, EL_ADDFN, name, name, rl_bind_wrapper);
+ vis(dest, c, VIS_WHITE|VIS_NOSLASH, 0);
+ el_set(e, EL_BIND, dest, name);
+ return 0;
+}
+
+void
+rl_callback_read_char()
+{
+ int count = 0, done = 0;
+ const char *buf = el_gets(e, &count);
+ char *wbuf;
+
+ if (buf == NULL || count-- <= 0)
+ return;
+#ifdef CTRL2 /* _AIX */
+ if (count == 0 && buf[0] == CTRL2('d'))
+#else
+ if (count == 0 && buf[0] == CTRL('d'))
+#endif
+ done = 1;
+ if (buf[count] == '\n' || buf[count] == '\r')
+ done = 2;
+
+ if (done && rl_linefunc != NULL) {
+ el_set(e, EL_UNBUFFERED, 0);
+ if (done == 2) {
+ if ((wbuf = strdup(buf)) != NULL)
+ wbuf[count] = '\0';
+ } else
+ wbuf = NULL;
+ (*(void (*)(const char *))rl_linefunc)(wbuf);
+ el_set(e, EL_UNBUFFERED, 1);
+ }
+}
+
+void
+rl_callback_handler_install (const char *prompt, VFunction *linefunc)
+{
+ if (e == NULL) {
+ rl_initialize();
+ }
+ if (rl_prompt)
+ free(rl_prompt);
+ rl_prompt = prompt ? strdup(strchr(prompt, *prompt)) : NULL;
+ rl_linefunc = linefunc;
+ el_set(e, EL_UNBUFFERED, 1);
+}
+
+void
+rl_callback_handler_remove(void)
+{
+ el_set(e, EL_UNBUFFERED, 0);
+}
+
+void
+rl_redisplay(void)
+{
+ char a[2];
+#ifdef CTRL2 /* _AIX */
+ a[0] = CTRL2('r');
+#else
+ a[0] = CTRL('r');
+#endif
+ a[1] = '\0';
+ el_push(e, a);
+}
+
+int
+rl_get_previous_history(int count, int key)
+{
+ char a[2];
+ a[0] = key;
+ a[1] = '\0';
+ while (count--)
+ el_push(e, a);
+ return 0;
+}
+
+void
+/*ARGSUSED*/
+rl_prep_terminal(int meta_flag)
+{
+ el_set(e, EL_PREP_TERM, 1);
+}
+
+void
+rl_deprep_terminal()
+{
+ el_set(e, EL_PREP_TERM, 0);
+}
+
+int
+rl_read_init_file(const char *s)
+{
+ return(el_source(e, s));
+}
+
+int
+rl_parse_and_bind(const char *line)
+{
+ const char **argv;
+ int argc;
+ Tokenizer *tok;
+
+ tok = tok_init(NULL);
+ tok_str(tok, line, &argc, &argv);
+ argc = el_parse(e, argc, argv);
+ tok_end(tok);
+ return (argc ? 1 : 0);
+}
+
+void
+rl_stuff_char(int c)
+{
+ char buf[2];
+
+ buf[0] = c;
+ buf[1] = '\0';
+ el_insertstr(e, buf);
+}
+
+static int
+_rl_event_read_char(EditLine *el, char *cp)
+{
+ int n, num_read = 0;
+
+ *cp = 0;
+ while (rl_event_hook) {
+
+ (*rl_event_hook)();
+
+#if defined(FIONREAD)
+ if (ioctl(el->el_infd, FIONREAD, &n) < 0)
+ return(-1);
+ if (n)
+ num_read = read(el->el_infd, cp, 1);
+ else
+ num_read = 0;
+#elif defined(F_SETFL) && defined(O_NDELAY)
+ if ((n = fcntl(el->el_infd, F_GETFL, 0)) < 0)
+ return(-1);
+ if (fcntl(el->el_infd, F_SETFL, n|O_NDELAY) < 0)
+ return(-1);
+ num_read = read(el->el_infd, cp, 1);
+ if (fcntl(el->el_infd, F_SETFL, n))
+ return(-1);
+#else
+ /* not non-blocking, but what you gonna do? */
+ num_read = read(el->el_infd, cp, 1);
+ return(-1);
+#endif
+
+ if (num_read < 0 && errno == EAGAIN)
+ continue;
+ if (num_read == 0)
+ continue;
+ break;
+ }
+ if (!rl_event_hook)
+ el_set(el, EL_GETCFN, EL_BUILTIN_GETCFN);
+ return(num_read);
+}
+
+static void
+_rl_update_pos(void)
+{
+ const LineInfo *li = el_line(e);
+
+ rl_point = li->cursor - li->buffer;
+ rl_end = li->lastchar - li->buffer;
+}
diff --git a/cmd-line-utils/libedit/readline/readline.h b/cmd-line-utils/libedit/readline/readline.h
index 7485dde4052..902179c208a 100644
--- a/cmd-line-utils/libedit/readline/readline.h
+++ b/cmd-line-utils/libedit/readline/readline.h
@@ -1,4 +1,4 @@
-/* $NetBSD: readline.h,v 1.1 2001/01/05 21:15:50 jdolecek Exp $ */
+/* $NetBSD: readline.h,v 1.12 2004/09/08 18:15:37 christos Exp $ */
/*-
* Copyright (c) 1997 The NetBSD Foundation, Inc.
@@ -36,7 +36,7 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _READLINE_H_
-#define _READLINE_H_
+#define _READLINE_H_
#include <sys/types.h>
@@ -48,11 +48,45 @@ typedef void VFunction(void);
typedef char *CPFunction(const char *, int);
typedef char **CPPFunction(const char *, int, int);
+typedef void *histdata_t;
+
typedef struct _hist_entry {
const char *line;
- const char *data;
+ histdata_t *data;
} HIST_ENTRY;
+typedef struct _keymap_entry {
+ char type;
+#define ISFUNC 0
+#define ISKMAP 1
+#define ISMACR 2
+ Function *function;
+} KEYMAP_ENTRY;
+
+#define KEYMAP_SIZE 256
+
+typedef KEYMAP_ENTRY KEYMAP_ENTRY_ARRAY[KEYMAP_SIZE];
+typedef KEYMAP_ENTRY *Keymap;
+
+#define control_character_threshold 0x20
+#define control_character_bit 0x40
+
+#ifndef CTRL
+#include <sys/ioctl.h>
+#ifdef __GLIBC__
+#include <sys/ttydefaults.h>
+#endif
+#ifndef CTRL
+#define CTRL(c) ((c) & 037)
+#endif
+#endif
+#ifndef UNCTRL
+#define UNCTRL(c) (((c) - 'a' + 'A')|control_character_bit)
+#endif
+
+#define RUBOUT 0x7f
+#define ABORT_CHAR CTRL('G')
+
/* global variables used by readline enabled applications */
#ifdef __cplusplus
extern "C" {
@@ -68,12 +102,31 @@ extern int max_input_history;
extern char *rl_basic_word_break_characters;
extern char *rl_completer_word_break_characters;
extern char *rl_completer_quote_characters;
-extern CPFunction *rl_completion_entry_function;
+extern Function *rl_completion_entry_function;
extern CPPFunction *rl_attempted_completion_function;
extern int rl_completion_type;
extern int rl_completion_query_items;
extern char *rl_special_prefixes;
extern int rl_completion_append_character;
+extern int rl_inhibit_completion;
+extern Function *rl_pre_input_hook;
+extern Function *rl_startup_hook;
+extern char *rl_terminal_name;
+extern int rl_already_prompted;
+extern char *rl_prompt;
+/*
+ * The following is not implemented
+ */
+extern KEYMAP_ENTRY_ARRAY emacs_standard_keymap,
+ emacs_meta_keymap,
+ emacs_ctlx_keymap;
+extern int rl_filename_completion_desired;
+extern int rl_ignore_completion_duplicates;
+extern Function *rl_getc_function;
+extern VFunction *rl_redisplay_function;
+extern VFunction *rl_completion_display_matches_hook;
+extern VFunction *rl_prep_term_function;
+extern VFunction *rl_deprep_term_function;
/* supported functions */
char *readline(const char *);
@@ -99,6 +152,8 @@ int read_history(const char *);
int write_history(const char *);
int history_expand(char *, char **);
char **history_tokenize(const char *);
+const char *get_history_event(const char *, int *, int);
+char *history_arg_extract(int, int, const char *);
char *tilde_expand(char *);
char *filename_completion_function(const char *, int);
@@ -111,6 +166,26 @@ void rl_display_match_list(char **, int, int);
int rl_insert(int, int);
void rl_reset_terminal(const char *);
int rl_bind_key(int, int (*)(int, int));
+int rl_newline(int, int);
+void rl_callback_read_char(void);
+void rl_callback_handler_install(const char *, VFunction *);
+void rl_callback_handler_remove(void);
+void rl_redisplay(void);
+int rl_get_previous_history(int, int);
+void rl_prep_terminal(int);
+void rl_deprep_terminal(void);
+int rl_read_init_file(const char *);
+int rl_parse_and_bind(const char *);
+void rl_stuff_char(int);
+int rl_add_defun(const char *, Function *, int);
+
+/*
+ * The following are not implemented
+ */
+Keymap rl_get_keymap(void);
+Keymap rl_make_bare_keymap(void);
+int rl_generic_bind(int, const char *, const char *, Keymap);
+int rl_bind_key_in_map(int, Function *, Keymap);
#ifdef __cplusplus
}
#endif
diff --git a/cmd-line-utils/libedit/refresh.c b/cmd-line-utils/libedit/refresh.c
index e71bdba2b61..b2833d215c5 100644
--- a/cmd-line-utils/libedit/refresh.c
+++ b/cmd-line-utils/libedit/refresh.c
@@ -1,4 +1,4 @@
-/* $NetBSD: refresh.c,v 1.24 2003/03/10 21:18:49 christos Exp $ */
+/* $NetBSD: refresh.c,v 1.26 2003/08/07 16:44:33 agc Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -15,11 +15,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
@@ -36,14 +32,7 @@
* SUCH DAMAGE.
*/
-#include "config.h"
-#if !defined(lint) && !defined(SCCSID)
-#if 0
-static char sccsid[] = "@(#)refresh.c 8.1 (Berkeley) 6/4/93";
-#else
-__RCSID("$NetBSD: refresh.c,v 1.24 2003/03/10 21:18:49 christos Exp $");
-#endif
-#endif /* not lint && not SCCSID */
+#include <config.h>
/*
* refresh.c: Lower level screen refreshing functions
@@ -57,8 +46,8 @@ __RCSID("$NetBSD: refresh.c,v 1.24 2003/03/10 21:18:49 christos Exp $");
private void re_addc(EditLine *, int);
private void re_update_line(EditLine *, char *, char *, int);
-private void re_insert (EditLine *el, char *, int, int, char *, int);
-private void re_delete(EditLine *el, char *, int, int, int);
+private void re_insert (EditLine *, char *, int, int, char *, int);
+private void re_delete(EditLine *, char *, int, int, int);
private void re_fastputc(EditLine *, int);
private void re__strncopy(char *, char *, size_t);
private void re__copy_and_pad(char *, const char *, size_t);
@@ -338,8 +327,8 @@ re_goto_bottom(EditLine *el)
*/
private void
/*ARGSUSED*/
-re_insert(EditLine *el __attribute__((unused)),
- char *d, int dat, int dlen, char *s, int num)
+re_insert(EditLine *el __attribute__((__unused__)),
+ char *d, int dat, int dlen, char *s, int num)
{
char *a, *b;
@@ -382,8 +371,8 @@ re_insert(EditLine *el __attribute__((unused)),
*/
private void
/*ARGSUSED*/
-re_delete(EditLine *el __attribute__((unused)),
- char *d, int dat, int dlen, int num)
+re_delete(EditLine *el __attribute__((__unused__)),
+ char *d, int dat, int dlen, int num)
{
char *a, *b;
diff --git a/cmd-line-utils/libedit/refresh.h b/cmd-line-utils/libedit/refresh.h
index 33c0887c1b3..dd2bd02094b 100644
--- a/cmd-line-utils/libedit/refresh.h
+++ b/cmd-line-utils/libedit/refresh.h
@@ -1,4 +1,4 @@
-/* $NetBSD: refresh.h,v 1.4 2001/01/10 07:45:42 jdolecek Exp $ */
+/* $NetBSD: refresh.h,v 1.5 2003/08/07 16:44:33 agc Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -15,11 +15,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
diff --git a/cmd-line-utils/libedit/search.c b/cmd-line-utils/libedit/search.c
index 0957529485c..848429e091b 100644
--- a/cmd-line-utils/libedit/search.c
+++ b/cmd-line-utils/libedit/search.c
@@ -1,4 +1,4 @@
-/* $NetBSD: search.c,v 1.14 2002/11/20 16:50:08 christos Exp $ */
+/* $NetBSD: search.c,v 1.20 2004/11/04 01:16:03 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -15,11 +15,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
@@ -36,21 +32,13 @@
* SUCH DAMAGE.
*/
-#include "config.h"
-#if !defined(lint) && !defined(SCCSID)
-#if 0
-static char sccsid[] = "@(#)search.c 8.1 (Berkeley) 6/4/93";
-#else
-__RCSID("$NetBSD: search.c,v 1.14 2002/11/20 16:50:08 christos Exp $");
-#endif
-#endif /* not lint && not SCCSID */
+#include <config.h>
/*
* search.c: History and character search functions
*/
#include <stdlib.h>
#if defined(REGEX)
-#include <sys/types.h>
#include <regex.h>
#elif defined(REGEXP)
#include <regexp.h>
@@ -227,8 +215,11 @@ ce_inc_search(EditLine *el, int dir)
if (el->el_search.patlen == 0) { /* first round */
pchar = ':';
#ifdef ANCHOR
+#define LEN 2
el->el_search.patbuf[el->el_search.patlen++] = '.';
el->el_search.patbuf[el->el_search.patlen++] = '*';
+#else
+#define LEN 0
#endif
}
done = redo = 0;
@@ -237,7 +228,7 @@ ce_inc_search(EditLine *el, int dir)
*cp; *el->el_line.lastchar++ = *cp++)
continue;
*el->el_line.lastchar++ = pchar;
- for (cp = &el->el_search.patbuf[1];
+ for (cp = &el->el_search.patbuf[LEN];
cp < &el->el_search.patbuf[el->el_search.patlen];
*el->el_line.lastchar++ = *cp++)
continue;
@@ -250,7 +241,7 @@ ce_inc_search(EditLine *el, int dir)
switch (el->el_map.current[(unsigned char) ch]) {
case ED_INSERT:
case ED_DIGIT:
- if (el->el_search.patlen > EL_BUFSIZ - 3)
+ if (el->el_search.patlen >= EL_BUFSIZ - LEN)
term_beep(el);
else {
el->el_search.patbuf[el->el_search.patlen++] =
@@ -271,8 +262,9 @@ ce_inc_search(EditLine *el, int dir)
redo++;
break;
+ case EM_DELETE_PREV_CHAR:
case ED_DELETE_PREV_CHAR:
- if (el->el_search.patlen > 1)
+ if (el->el_search.patlen > LEN)
done++;
else
term_beep(el);
@@ -287,17 +279,18 @@ ce_inc_search(EditLine *el, int dir)
case 0027: /* ^W: Append word */
/* No can do if globbing characters in pattern */
- for (cp = &el->el_search.patbuf[1];; cp++)
- if (cp >= &el->el_search.patbuf[el->el_search.patlen]) {
+ for (cp = &el->el_search.patbuf[LEN];; cp++)
+ if (cp >= &el->el_search.patbuf[
+ el->el_search.patlen]) {
el->el_line.cursor +=
- el->el_search.patlen - 1;
+ el->el_search.patlen - LEN - 1;
cp = c__next_word(el->el_line.cursor,
el->el_line.lastchar, 1,
ce__isword);
while (el->el_line.cursor < cp &&
*el->el_line.cursor != '\n') {
- if (el->el_search.patlen >
- EL_BUFSIZ - 3) {
+ if (el->el_search.patlen >=
+ EL_BUFSIZ - LEN) {
term_beep(el);
break;
}
@@ -339,13 +332,13 @@ ce_inc_search(EditLine *el, int dir)
/* Can't search if unmatched '[' */
for (cp = &el->el_search.patbuf[el->el_search.patlen-1],
ch = ']';
- cp > el->el_search.patbuf;
+ cp >= &el->el_search.patbuf[LEN];
cp--)
if (*cp == '[' || *cp == ']') {
ch = *cp;
break;
}
- if (el->el_search.patlen > 1 && ch != '[') {
+ if (el->el_search.patlen > LEN && ch != '[') {
if (redo && newdir == dir) {
if (pchar == '?') { /* wrap around */
el->el_history.eventno =
@@ -375,9 +368,8 @@ ce_inc_search(EditLine *el, int dir)
'\0';
if (el->el_line.cursor < el->el_line.buffer ||
el->el_line.cursor > el->el_line.lastchar ||
- (ret = ce_search_line(el,
- &el->el_search.patbuf[1],
- newdir)) == CC_ERROR) {
+ (ret = ce_search_line(el, newdir))
+ == CC_ERROR) {
/* avoid c_setpat */
el->el_state.lastcmd =
(el_action_t) newdir;
@@ -390,11 +382,11 @@ ce_inc_search(EditLine *el, int dir)
el->el_line.lastchar :
el->el_line.buffer;
(void) ce_search_line(el,
- &el->el_search.patbuf[1],
newdir);
}
}
- el->el_search.patbuf[--el->el_search.patlen] =
+ el->el_search.patlen -= LEN;
+ el->el_search.patbuf[el->el_search.patlen] =
'\0';
if (ret == CC_ERROR) {
term_beep(el);
@@ -453,9 +445,6 @@ cv_search(EditLine *el, int dir)
#ifdef ANCHOR
tmpbuf[0] = '.';
tmpbuf[1] = '*';
-#define LEN 2
-#else
-#define LEN 0
#endif
tmplen = LEN;
@@ -521,24 +510,39 @@ cv_search(EditLine *el, int dir)
* Look for a pattern inside a line
*/
protected el_action_t
-ce_search_line(EditLine *el, char *pattern, int dir)
+ce_search_line(EditLine *el, int dir)
{
- char *cp;
+ char *cp = el->el_line.cursor;
+ char *pattern = el->el_search.patbuf;
+ char oc, *ocp;
+#ifdef ANCHOR
+ ocp = &pattern[1];
+ oc = *ocp;
+ *ocp = '^';
+#else
+ ocp = pattern;
+ oc = *ocp;
+#endif
if (dir == ED_SEARCH_PREV_HISTORY) {
- for (cp = el->el_line.cursor; cp >= el->el_line.buffer; cp--)
- if (el_match(cp, pattern)) {
+ for (; cp >= el->el_line.buffer; cp--) {
+ if (el_match(cp, ocp)) {
+ *ocp = oc;
el->el_line.cursor = cp;
return (CC_NORM);
}
+ }
+ *ocp = oc;
return (CC_ERROR);
} else {
- for (cp = el->el_line.cursor; *cp != '\0' &&
- cp < el->el_line.limit; cp++)
- if (el_match(cp, pattern)) {
+ for (; *cp != '\0' && cp < el->el_line.limit; cp++) {
+ if (el_match(cp, ocp)) {
+ *ocp = oc;
el->el_line.cursor = cp;
return (CC_NORM);
}
+ }
+ *ocp = oc;
return (CC_ERROR);
}
}
diff --git a/cmd-line-utils/libedit/search.h b/cmd-line-utils/libedit/search.h
index a7363072a4c..2aa8f985013 100644
--- a/cmd-line-utils/libedit/search.h
+++ b/cmd-line-utils/libedit/search.h
@@ -1,4 +1,4 @@
-/* $NetBSD: search.h,v 1.6 2002/11/15 14:32:34 christos Exp $ */
+/* $NetBSD: search.h,v 1.8 2003/10/18 23:27:36 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -15,11 +15,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
@@ -63,7 +59,7 @@ protected int c_hmatch(EditLine *, const char *);
protected void c_setpat(EditLine *);
protected el_action_t ce_inc_search(EditLine *, int);
protected el_action_t cv_search(EditLine *, int);
-protected el_action_t ce_search_line(EditLine *, char *, int);
+protected el_action_t ce_search_line(EditLine *, int);
protected el_action_t cv_repeat_srch(EditLine *, int);
protected el_action_t cv_csearch(EditLine *, int, int, int, int);
diff --git a/cmd-line-utils/libedit/sig.c b/cmd-line-utils/libedit/sig.c
index 3730067ed5f..8e70933d606 100644
--- a/cmd-line-utils/libedit/sig.c
+++ b/cmd-line-utils/libedit/sig.c
@@ -1,4 +1,4 @@
-/* $NetBSD: sig.c,v 1.10 2003/03/10 00:58:05 christos Exp $ */
+/* $NetBSD: sig.c,v 1.11 2003/08/07 16:44:33 agc Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -15,11 +15,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
@@ -36,14 +32,7 @@
* SUCH DAMAGE.
*/
-#include "config.h"
-#if !defined(lint) && !defined(SCCSID)
-#if 0
-static char sccsid[] = "@(#)sig.c 8.1 (Berkeley) 6/4/93";
-#else
-__RCSID("$NetBSD: sig.c,v 1.10 2003/03/10 00:58:05 christos Exp $");
-#endif
-#endif /* not lint && not SCCSID */
+#include <config.h>
/*
* sig.c: Signal handling stuff.
diff --git a/cmd-line-utils/libedit/sig.h b/cmd-line-utils/libedit/sig.h
index 8effea8e121..0bf1fc37e39 100644
--- a/cmd-line-utils/libedit/sig.h
+++ b/cmd-line-utils/libedit/sig.h
@@ -1,4 +1,4 @@
-/* $NetBSD: sig.h,v 1.4 2003/03/10 00:58:05 christos Exp $ */
+/* $NetBSD: sig.h,v 1.5 2003/08/07 16:44:33 agc Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -15,11 +15,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
diff --git a/cmd-line-utils/libedit/strlcpy.c b/cmd-line-utils/libedit/strlcpy.c
index 74317d99cd2..e38d6cf1c4b 100644
--- a/cmd-line-utils/libedit/strlcpy.c
+++ b/cmd-line-utils/libedit/strlcpy.c
@@ -1,28 +1,73 @@
+/* $NetBSD: strlcpy.c,v 1.14 2003/10/27 00:12:42 lukem Exp $ */
+/* $OpenBSD: strlcpy.c,v 1.7 2003/04/12 21:56:39 millert Exp $ */
+
+/*
+ * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND TODD C. MILLER DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL TODD C. MILLER BE LIABLE
+ * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <assert.h>
#include <string.h>
-#ifndef HAVE_STRLCPY
-size_t strlcpy(char *dst, const char *src, size_t size)
+#ifdef _LIBC
+# ifdef __weak_alias
+__weak_alias(strlcpy, _strlcpy)
+# endif
+#endif
+
+#if !HAVE_STRLCPY
+/*
+ * Copy src to string dst of size siz. At most siz-1 characters
+ * will be copied. Always NUL terminates (unless siz == 0).
+ * Returns strlen(src); if retval >= siz, truncation occurred.
+ */
+size_t
+#ifdef _LIBC
+_strlcpy(dst, src, siz)
+#else
+strlcpy(dst, src, siz)
+#endif
+ char *dst;
+ const char *src;
+ size_t siz;
{
- if(size) {
- strncpy(dst, src, size-1);
- dst[size-1] = '\0';
- } else {
- dst[0] = '\0';
+ char *d = dst;
+ const char *s = src;
+ size_t n = siz;
+
+ _DIAGASSERT(dst != NULL);
+ _DIAGASSERT(src != NULL);
+
+ /* Copy as many bytes as will fit */
+ if (n != 0 && --n != 0) {
+ do {
+ if ((*d++ = *s++) == 0)
+ break;
+ } while (--n != 0);
}
- return strlen(src);
-}
-size_t strlcat(char *dst, const char *src, size_t size)
-{
- int dl = strlen(dst);
- int sz = size-dl-1;
-
- if(sz >= 0) {
- strncat(dst, src, sz);
- dst[sz] = '\0';
+ /* Not enough room in dst, add NUL and traverse rest of src */
+ if (n == 0) {
+ if (siz != 0)
+ *d = '\0'; /* NUL-terminate dst */
+ while (*s++)
+ ;
}
- return dl+strlen(src);
+ return(s - src - 1); /* count does not include NUL */
}
-
#endif
diff --git a/cmd-line-utils/libedit/sys.h b/cmd-line-utils/libedit/sys.h
index a7477d2c5ba..c8a29dbfb05 100644
--- a/cmd-line-utils/libedit/sys.h
+++ b/cmd-line-utils/libedit/sys.h
@@ -1,4 +1,4 @@
-/* $NetBSD: sys.h,v 1.6 2003/03/10 00:57:38 christos Exp $ */
+/* $NetBSD: sys.h,v 1.9 2004/01/17 17:57:40 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -15,11 +15,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
@@ -48,6 +44,28 @@
#include <sys/cdefs.h>
#endif
+#if !defined(__attribute__) && (defined(__cplusplus) || !defined(__GNUC__) || __GNUC__ == 2 && __GNUC_MINOR__ < 8)
+# define __attribute__(A)
+#endif
+
+#ifndef __P
+# define __P(x) x
+#endif
+
+#ifndef _DIAGASSERT
+# define _DIAGASSERT(x)
+#endif
+
+#ifndef __BEGIN_DECLS
+# ifdef __cplusplus
+# define __BEGIN_DECLS extern "C" {
+# define __END_DECLS }
+# else
+# define __BEGIN_DECLS
+# define __END_DECLS
+# endif
+#endif
+
#ifndef public
# define public /* Externally visible functions/variables */
#endif
@@ -61,6 +79,10 @@
/* When we want to hide everything */
#endif
+#ifndef HAVE_U_INT32_T
+typedef unsigned int u_int32_t;
+#endif
+
#ifndef _PTR_T
# define _PTR_T
typedef void *ptr_t;
diff --git a/cmd-line-utils/libedit/term.c b/cmd-line-utils/libedit/term.c
index c4ee0d30aab..b516d6753c3 100644
--- a/cmd-line-utils/libedit/term.c
+++ b/cmd-line-utils/libedit/term.c
@@ -1,4 +1,4 @@
-/* $NetBSD: term.c,v 1.35 2002/03/18 16:00:59 christos Exp $ */
+/* $NetBSD: term.c,v 1.40 2004/05/22 23:21:28 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -15,11 +15,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
@@ -36,14 +32,7 @@
* SUCH DAMAGE.
*/
-#include "config.h"
-#if !defined(lint) && !defined(SCCSID)
-#if 0
-static char sccsid[] = "@(#)term.c 8.2 (Berkeley) 4/30/95";
-#else
-__RCSID("$NetBSD: term.c,v 1.35 2002/03/18 16:00:59 christos Exp $");
-#endif
-#endif /* not lint && not SCCSID */
+#include <config.h>
/*
* term.c: Editor/termcap-curses interface
@@ -55,24 +44,23 @@ __RCSID("$NetBSD: term.c,v 1.35 2002/03/18 16:00:59 christos Exp $");
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
-#ifdef HAVE_TERMCAP_H
-#include <termcap.h>
-#endif
+
#ifdef HAVE_CURSES_H
-#include <curses.h>
-#endif
-#ifdef HAVE_NCURSES_H
-#include <ncurses.h>
+# include <curses.h>
+#elif HAVE_NCURSES_H
+# include <ncurses.h>
#endif
-#include "el.h"
-
-#if !defined(HAVE_TERMCAP_H) && defined(HAVE_TERM_H)
-#include <term.h>
+/* Solaris's term.h does horrid things. */
+#if (defined(HAVE_TERM_H) && !defined(_SUNOS))
+# include <term.h>
#endif
+
#include <sys/types.h>
#include <sys/ioctl.h>
+#include "el.h"
+
/*
* IMPORTANT NOTE: these routines are allowed to look at the current screen
* and the current possition assuming that it is correct. If this is not
@@ -356,6 +344,7 @@ term_init(EditLine *el)
term_init_arrow(el);
return (0);
}
+
/* term_end():
* Clean up the terminal stuff
*/
@@ -372,6 +361,8 @@ term_end(EditLine *el)
el->el_term.t_str = NULL;
el_free((ptr_t) el->el_term.t_val);
el->el_term.t_val = NULL;
+ el_free((ptr_t) el->el_term.t_fkey);
+ el->el_term.t_fkey = NULL;
term_free_display(el);
}
@@ -648,7 +639,8 @@ mc_again:
* from col 0
*/
if (EL_CAN_TAB ?
- (((unsigned int)-del) > (((unsigned int) where >> 3) +
+ ((unsigned int)-del >
+ (((unsigned int) where >> 3) +
(where & 07)))
: (-del > where)) {
term__putc('\r'); /* do a CR */
@@ -876,6 +868,12 @@ term_clear_to_bottom(EditLine *el)
}
#endif
+protected void
+term_get(EditLine *el, const char **term)
+{
+ *term = el->el_term.t_name;
+}
+
/* term_set():
* Read in the terminal capabilities from the requested terminal
@@ -937,8 +935,11 @@ term_set(EditLine *el, const char *term)
/* Get the size */
Val(T_co) = tgetnum("co");
Val(T_li) = tgetnum("li");
- for (t = tstr; t->name != NULL; t++)
- term_alloc(el, t, tgetstr(t->name, &area));
+ for (t = tstr; t->name != NULL; t++) {
+ /* XXX: some systems tgetstr needs non const */
+ term_alloc(el, t, tgetstr(strchr(t->name, *t->name),
+ &area));
+ }
}
if (Val(T_co) < 2)
@@ -957,6 +958,7 @@ term_set(EditLine *el, const char *term)
return (-1);
(void) sigprocmask(SIG_SETMASK, &oset, NULL);
term_bind_arrow(el);
+ el->el_term.t_name = term;
return (i <= 0 ? -1 : 0);
}
@@ -1078,32 +1080,32 @@ term_reset_arrow(EditLine *el)
static const char stOH[] = {033, 'O', 'H', '\0'};
static const char stOF[] = {033, 'O', 'F', '\0'};
- el_key_add(el, strA, &arrow[A_K_UP].fun, arrow[A_K_UP].type);
- el_key_add(el, strB, &arrow[A_K_DN].fun, arrow[A_K_DN].type);
- el_key_add(el, strC, &arrow[A_K_RT].fun, arrow[A_K_RT].type);
- el_key_add(el, strD, &arrow[A_K_LT].fun, arrow[A_K_LT].type);
- el_key_add(el, strH, &arrow[A_K_HO].fun, arrow[A_K_HO].type);
- el_key_add(el, strF, &arrow[A_K_EN].fun, arrow[A_K_EN].type);
- el_key_add(el, stOA, &arrow[A_K_UP].fun, arrow[A_K_UP].type);
- el_key_add(el, stOB, &arrow[A_K_DN].fun, arrow[A_K_DN].type);
- el_key_add(el, stOC, &arrow[A_K_RT].fun, arrow[A_K_RT].type);
- el_key_add(el, stOD, &arrow[A_K_LT].fun, arrow[A_K_LT].type);
- el_key_add(el, stOH, &arrow[A_K_HO].fun, arrow[A_K_HO].type);
- el_key_add(el, stOF, &arrow[A_K_EN].fun, arrow[A_K_EN].type);
+ key_add(el, strA, &arrow[A_K_UP].fun, arrow[A_K_UP].type);
+ key_add(el, strB, &arrow[A_K_DN].fun, arrow[A_K_DN].type);
+ key_add(el, strC, &arrow[A_K_RT].fun, arrow[A_K_RT].type);
+ key_add(el, strD, &arrow[A_K_LT].fun, arrow[A_K_LT].type);
+ key_add(el, strH, &arrow[A_K_HO].fun, arrow[A_K_HO].type);
+ key_add(el, strF, &arrow[A_K_EN].fun, arrow[A_K_EN].type);
+ key_add(el, stOA, &arrow[A_K_UP].fun, arrow[A_K_UP].type);
+ key_add(el, stOB, &arrow[A_K_DN].fun, arrow[A_K_DN].type);
+ key_add(el, stOC, &arrow[A_K_RT].fun, arrow[A_K_RT].type);
+ key_add(el, stOD, &arrow[A_K_LT].fun, arrow[A_K_LT].type);
+ key_add(el, stOH, &arrow[A_K_HO].fun, arrow[A_K_HO].type);
+ key_add(el, stOF, &arrow[A_K_EN].fun, arrow[A_K_EN].type);
if (el->el_map.type == MAP_VI) {
- el_key_add(el, &strA[1], &arrow[A_K_UP].fun, arrow[A_K_UP].type);
- el_key_add(el, &strB[1], &arrow[A_K_DN].fun, arrow[A_K_DN].type);
- el_key_add(el, &strC[1], &arrow[A_K_RT].fun, arrow[A_K_RT].type);
- el_key_add(el, &strD[1], &arrow[A_K_LT].fun, arrow[A_K_LT].type);
- el_key_add(el, &strH[1], &arrow[A_K_HO].fun, arrow[A_K_HO].type);
- el_key_add(el, &strF[1], &arrow[A_K_EN].fun, arrow[A_K_EN].type);
- el_key_add(el, &stOA[1], &arrow[A_K_UP].fun, arrow[A_K_UP].type);
- el_key_add(el, &stOB[1], &arrow[A_K_DN].fun, arrow[A_K_DN].type);
- el_key_add(el, &stOC[1], &arrow[A_K_RT].fun, arrow[A_K_RT].type);
- el_key_add(el, &stOD[1], &arrow[A_K_LT].fun, arrow[A_K_LT].type);
- el_key_add(el, &stOH[1], &arrow[A_K_HO].fun, arrow[A_K_HO].type);
- el_key_add(el, &stOF[1], &arrow[A_K_EN].fun, arrow[A_K_EN].type);
+ key_add(el, &strA[1], &arrow[A_K_UP].fun, arrow[A_K_UP].type);
+ key_add(el, &strB[1], &arrow[A_K_DN].fun, arrow[A_K_DN].type);
+ key_add(el, &strC[1], &arrow[A_K_RT].fun, arrow[A_K_RT].type);
+ key_add(el, &strD[1], &arrow[A_K_LT].fun, arrow[A_K_LT].type);
+ key_add(el, &strH[1], &arrow[A_K_HO].fun, arrow[A_K_HO].type);
+ key_add(el, &strF[1], &arrow[A_K_EN].fun, arrow[A_K_EN].type);
+ key_add(el, &stOA[1], &arrow[A_K_UP].fun, arrow[A_K_UP].type);
+ key_add(el, &stOB[1], &arrow[A_K_DN].fun, arrow[A_K_DN].type);
+ key_add(el, &stOC[1], &arrow[A_K_RT].fun, arrow[A_K_RT].type);
+ key_add(el, &stOD[1], &arrow[A_K_LT].fun, arrow[A_K_LT].type);
+ key_add(el, &stOH[1], &arrow[A_K_HO].fun, arrow[A_K_HO].type);
+ key_add(el, &stOF[1], &arrow[A_K_EN].fun, arrow[A_K_EN].type);
}
}
@@ -1157,7 +1159,7 @@ term_print_arrow(EditLine *el, const char *name)
for (i = 0; i < A_K_NKEYS; i++)
if (*name == '\0' || strcmp(name, arrow[i].name) == 0)
if (arrow[i].type != XK_NOD)
- el_key_kprint(el, arrow[i].name, &arrow[i].fun,
+ key_kprint(el, arrow[i].name, &arrow[i].fun,
arrow[i].type);
}
@@ -1198,20 +1200,20 @@ term_bind_arrow(EditLine *el)
* unassigned key.
*/
if (arrow[i].type == XK_NOD)
- el_key_clear(el, map, p);
+ key_clear(el, map, p);
else {
if (p[1] && (dmap[j] == map[j] ||
map[j] == ED_SEQUENCE_LEAD_IN)) {
- el_key_add(el, p, &arrow[i].fun,
+ key_add(el, p, &arrow[i].fun,
arrow[i].type);
map[j] = ED_SEQUENCE_LEAD_IN;
} else if (map[j] == ED_UNASSIGNED) {
- el_key_clear(el, map, p);
+ key_clear(el, map, p);
if (arrow[i].type == XK_CMD)
map[j] = arrow[i].fun.cmd;
else
- el_key_add(el, p, &arrow[i].fun,
- arrow[i].type);
+ key_add(el, p, &arrow[i].fun,
+ arrow[i].type);
}
}
}
@@ -1244,12 +1246,10 @@ term__flush(void)
/* term_telltc():
* Print the current termcap characteristics
*/
-char *el_key__decode_str(const char *, char *, const char *);
-
protected int
/*ARGSUSED*/
-term_telltc(EditLine *el, int argc __attribute__((unused)),
- const char **argv __attribute__((unused)))
+term_telltc(EditLine *el, int argc __attribute__((__unused__)),
+ const char **argv __attribute__((__unused__)))
{
const struct termcapstr *t;
char **ts;
@@ -1273,7 +1273,7 @@ term_telltc(EditLine *el, int argc __attribute__((unused)),
(void) fprintf(el->el_outfile, "\t%25s (%s) == %s\n",
t->long_name,
t->name, *ts && **ts ?
- el_key__decode_str(*ts, upbuf, "") : "(empty)");
+ key__decode_str(*ts, upbuf, "") : "(empty)");
(void) fputc('\n', el->el_outfile);
return (0);
}
@@ -1284,8 +1284,8 @@ term_telltc(EditLine *el, int argc __attribute__((unused)),
*/
protected int
/*ARGSUSED*/
-term_settc(EditLine *el, int argc __attribute__((unused)),
- const char **argv __attribute__((unused)))
+term_settc(EditLine *el, int argc __attribute__((__unused__)),
+ const char **argv)
{
const struct termcapstr *ts;
const struct termcapval *tv;
@@ -1361,9 +1361,8 @@ term_settc(EditLine *el, int argc __attribute__((unused)),
*/
protected int
/*ARGSUSED*/
-term_echotc(EditLine *el __attribute__((unused)),
- int argc __attribute__((unused)),
- const char **argv __attribute__((unused)))
+term_echotc(EditLine *el, int argc __attribute__((__unused__)),
+ const char **argv)
{
char *cap, *scap, *ep;
int arg_need, arg_cols, arg_rows;
@@ -1422,7 +1421,7 @@ term_echotc(EditLine *el __attribute__((unused)),
}
(void) fprintf(el->el_outfile, fmtd, 0);
#else
- (void) fprintf(el->el_outfile, fmtd, el->el_tty.t_speed);
+ (void) fprintf(el->el_outfile, fmtd, (int)el->el_tty.t_speed);
#endif
return (0);
} else if (strcmp(*argv, "rows") == 0 || strcmp(*argv, "lines") == 0) {
@@ -1441,8 +1440,10 @@ term_echotc(EditLine *el __attribute__((unused)),
scap = el->el_term.t_str[t - tstr];
break;
}
- if (t->name == NULL)
- scap = tgetstr(*argv, &area);
+ if (t->name == NULL) {
+ /* XXX: some systems tgetstr needs non const */
+ scap = tgetstr(strchr(*argv, **argv), &area);
+ }
if (!scap || scap[0] == '\0') {
if (!silent)
(void) fprintf(el->el_errfile,
diff --git a/cmd-line-utils/libedit/tokenizer.c b/cmd-line-utils/libedit/tokenizer.c
index f6892d9954c..561b41740f8 100644
--- a/cmd-line-utils/libedit/tokenizer.c
+++ b/cmd-line-utils/libedit/tokenizer.c
@@ -1,4 +1,4 @@
-/* $NetBSD: tokenizer.c,v 1.11 2002/10/27 20:24:29 christos Exp $ */
+/* $NetBSD: tokenizer.c,v 1.14 2003/12/05 13:37:48 lukem Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -15,11 +15,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
@@ -36,21 +32,14 @@
* SUCH DAMAGE.
*/
-#include "config.h"
-#if !defined(lint) && !defined(SCCSID)
-#if 0
-static char sccsid[] = "@(#)tokenizer.c 8.1 (Berkeley) 6/4/93";
-#else
-__RCSID("$NetBSD: tokenizer.c,v 1.11 2002/10/27 20:24:29 christos Exp $");
-#endif
-#endif /* not lint && not SCCSID */
+#include <config.h>
/*
* tokenize.c: Bourne shell like tokenizer
*/
#include <string.h>
#include <stdlib.h>
-#include "tokenizer.h"
+#include "histedit.h"
typedef enum {
Q_none, Q_single, Q_double, Q_one, Q_doubleone
@@ -64,6 +53,7 @@ typedef enum {
#define WINCR 20
#define AINCR 10
+#define tok_strdup(a) strdup(a)
#define tok_malloc(a) malloc(a)
#define tok_free(a) free(a)
#define tok_realloc(a, b) realloc(a, b)
@@ -111,7 +101,7 @@ tok_init(const char *ifs)
if (tok == NULL)
return NULL;
- tok->ifs = strdup(ifs ? ifs : IFS);
+ tok->ifs = tok_strdup(ifs ? ifs : IFS);
if (tok->ifs == NULL) {
tok_free((ptr_t)tok);
return NULL;
@@ -173,21 +163,39 @@ tok_end(Tokenizer *tok)
/* tok_line():
- * Bourne shell like tokenizing
- * Return:
- * -1: Internal error
- * 3: Quoted return
- * 2: Unmatched double quote
- * 1: Unmatched single quote
- * 0: Ok
+ * Bourne shell (sh(1)) like tokenizing
+ * Arguments:
+ * tok current tokenizer state (setup with tok_init())
+ * line line to parse
+ * Returns:
+ * -1 Internal error
+ * 3 Quoted return
+ * 2 Unmatched double quote
+ * 1 Unmatched single quote
+ * 0 Ok
+ * Modifies (if return value is 0):
+ * argc number of arguments
+ * argv argument array
+ * cursorc if !NULL, argv element containing cursor
+ * cursorv if !NULL, offset in argv[cursorc] of cursor
*/
public int
-tok_line(Tokenizer *tok, const char *line, int *argc, const char ***argv)
+tok_line(Tokenizer *tok, const LineInfo *line,
+ int *argc, const char ***argv, int *cursorc, int *cursoro)
{
const char *ptr;
-
- for (;;) {
- switch (*(ptr = line++)) {
+ int cc, co;
+
+ cc = co = -1;
+ ptr = line->buffer;
+ for (ptr = line->buffer; ;ptr++) {
+ if (ptr >= line->lastchar)
+ ptr = "";
+ if (ptr == line->cursor) {
+ cc = tok->argc;
+ co = tok->wptr - tok->wstart;
+ }
+ switch (*ptr) {
case '\'':
tok->flags |= TOK_KEEP;
tok->flags &= ~TOK_EAT;
@@ -286,10 +294,7 @@ tok_line(Tokenizer *tok, const char *line, int *argc, const char ***argv)
tok->flags &= ~TOK_EAT;
switch (tok->quote) {
case Q_none:
- tok_finish(tok);
- *argv = (const char **)tok->argv;
- *argc = tok->argc;
- return (0);
+ goto tok_line_outok;
case Q_single:
case Q_double:
@@ -319,10 +324,7 @@ tok_line(Tokenizer *tok, const char *line, int *argc, const char ***argv)
tok->flags &= ~TOK_EAT;
return (3);
}
- tok_finish(tok);
- *argv = (const char **)tok->argv;
- *argc = tok->argc;
- return (0);
+ goto tok_line_outok;
case Q_single:
return (1);
@@ -407,4 +409,32 @@ tok_line(Tokenizer *tok, const char *line, int *argc, const char ***argv)
tok->argv = p;
}
}
+ tok_line_outok:
+ if (cc == -1 && co == -1) {
+ cc = tok->argc;
+ co = tok->wptr - tok->wstart;
+ }
+ if (cursorc != NULL)
+ *cursorc = cc;
+ if (cursoro != NULL)
+ *cursoro = co;
+ tok_finish(tok);
+ *argv = (const char **)tok->argv;
+ *argc = tok->argc;
+ return (0);
+}
+
+/* tok_str():
+ * Simpler version of tok_line, taking a NUL terminated line
+ * and splitting into words, ignoring cursor state.
+ */
+public int
+tok_str(Tokenizer *tok, const char *line, int *argc, const char ***argv)
+{
+ LineInfo li;
+
+ memset(&li, 0, sizeof(li));
+ li.buffer = line;
+ li.cursor = li.lastchar = strchr(line, '\0');
+ return (tok_line(tok, &li, argc, argv, NULL, NULL));
}
diff --git a/cmd-line-utils/libedit/tty.c b/cmd-line-utils/libedit/tty.c
index fe81762fb82..6f73fb4f9e7 100644
--- a/cmd-line-utils/libedit/tty.c
+++ b/cmd-line-utils/libedit/tty.c
@@ -1,4 +1,4 @@
-/* $NetBSD: tty.c,v 1.16 2002/03/18 16:01:01 christos Exp $ */
+/* $NetBSD: tty.c,v 1.21 2004/08/13 12:10:39 mycroft Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -15,11 +15,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
@@ -36,18 +32,12 @@
* SUCH DAMAGE.
*/
-#include "config.h"
-#if !defined(lint) && !defined(SCCSID)
-#if 0
-static char sccsid[] = "@(#)tty.c 8.1 (Berkeley) 6/4/93";
-#else
-__RCSID("$NetBSD: tty.c,v 1.16 2002/03/18 16:01:01 christos Exp $");
-#endif
-#endif /* not lint && not SCCSID */
+#include <config.h>
/*
* tty.c: tty interface stuff
*/
+#include <assert.h>
#include "tty.h"
#include "el.h"
@@ -124,11 +114,11 @@ private const ttychar_t ttychar = {
private const ttymap_t tty_map[] = {
#ifdef VERASE
{C_ERASE, VERASE,
- {ED_DELETE_PREV_CHAR, VI_DELETE_PREV_CHAR, ED_PREV_CHAR}},
+ {EM_DELETE_PREV_CHAR, VI_DELETE_PREV_CHAR, ED_PREV_CHAR}},
#endif /* VERASE */
#ifdef VERASE2
{C_ERASE2, VERASE2,
- {ED_DELETE_PREV_CHAR, VI_DELETE_PREV_CHAR, ED_PREV_CHAR}},
+ {EM_DELETE_PREV_CHAR, VI_DELETE_PREV_CHAR, ED_PREV_CHAR}},
#endif /* VERASE2 */
#ifdef VKILL
{C_KILL, VKILL,
@@ -455,6 +445,7 @@ private const ttymodes_t ttymodes[] = {
#define tty__geteightbit(td) (((td)->c_cflag & CSIZE) == CS8)
#define tty__cooked_mode(td) ((td)->c_lflag & ICANON)
+private int tty__getcharindex(int);
private void tty__getchar(struct termios *, unsigned char *);
private void tty__setchar(struct termios *, unsigned char *);
private speed_t tty__getspeed(struct termios *);
@@ -568,7 +559,7 @@ tty_init(EditLine *el)
*/
protected void
/*ARGSUSED*/
-tty_end(EditLine *el __attribute__((unused)))
+tty_end(EditLine *el __attribute__((__unused__)))
{
/* XXX: Maybe reset to an initial state? */
@@ -588,6 +579,113 @@ tty__getspeed(struct termios *td)
return (spd);
}
+/* tty__getspeed():
+ * Return the index of the asked char in the c_cc array
+ */
+private int
+tty__getcharindex(int i)
+{
+ switch (i) {
+#ifdef VINTR
+ case C_INTR:
+ return VINTR;
+#endif /* VINTR */
+#ifdef VQUIT
+ case C_QUIT:
+ return VQUIT;
+#endif /* VQUIT */
+#ifdef VERASE
+ case C_ERASE:
+ return VERASE;
+#endif /* VERASE */
+#ifdef VKILL
+ case C_KILL:
+ return VKILL;
+#endif /* VKILL */
+#ifdef VEOF
+ case C_EOF:
+ return VEOF;
+#endif /* VEOF */
+#ifdef VEOL
+ case C_EOL:
+ return VEOL;
+#endif /* VEOL */
+#ifdef VEOL2
+ case C_EOL2:
+ return VEOL2;
+#endif /* VEOL2 */
+#ifdef VSWTCH
+ case C_SWTCH:
+ return VSWTCH;
+#endif /* VSWTCH */
+#ifdef VDSWTCH
+ case C_DSWTCH:
+ return VDSWTCH;
+#endif /* VDSWTCH */
+#ifdef VERASE2
+ case C_ERASE2:
+ return VERASE2;
+#endif /* VERASE2 */
+#ifdef VSTART
+ case C_START:
+ return VSTART;
+#endif /* VSTART */
+#ifdef VSTOP
+ case C_STOP:
+ return VSTOP;
+#endif /* VSTOP */
+#ifdef VWERASE
+ case C_WERASE:
+ return VWERASE;
+#endif /* VWERASE */
+#ifdef VSUSP
+ case C_SUSP:
+ return VSUSP;
+#endif /* VSUSP */
+#ifdef VDSUSP
+ case C_DSUSP:
+ return VDSUSP;
+#endif /* VDSUSP */
+#ifdef VREPRINT
+ case C_REPRINT:
+ return VREPRINT;
+#endif /* VREPRINT */
+#ifdef VDISCARD
+ case C_DISCARD:
+ return VDISCARD;
+#endif /* VDISCARD */
+#ifdef VLNEXT
+ case C_LNEXT:
+ return VLNEXT;
+#endif /* VLNEXT */
+#ifdef VSTATUS
+ case C_STATUS:
+ return VSTATUS;
+#endif /* VSTATUS */
+#ifdef VPAGE
+ case C_PAGE:
+ return VPAGE;
+#endif /* VPAGE */
+#ifdef VPGOFF
+ case C_PGOFF:
+ return VPGOFF;
+#endif /* VPGOFF */
+#ifdef VKILL2
+ case C_KILL2:
+ return VKILL2;
+#endif /* KILL2 */
+#ifdef VMIN
+ case C_MIN:
+ return VMIN;
+#endif /* VMIN */
+#ifdef VTIME
+ case C_TIME:
+ return VTIME;
+#endif /* VTIME */
+ default:
+ return -1;
+ }
+}
/* tty__getchar():
* Get the tty characters
@@ -784,15 +882,15 @@ tty_bind_char(EditLine *el, int force)
if (new[0] == old[0] && !force)
continue;
/* Put the old default binding back, and set the new binding */
- el_key_clear(el, map, (char *)old);
+ key_clear(el, map, (char *)old);
map[old[0]] = dmap[old[0]];
- el_key_clear(el, map, (char *)new);
+ key_clear(el, map, (char *)new);
/* MAP_VI == 1, MAP_EMACS == 0... */
map[new[0]] = tp->bind[el->el_map.type];
if (dalt) {
- el_key_clear(el, alt, (char *)old);
+ key_clear(el, alt, (char *)old);
alt[old[0]] = dalt[old[0]];
- el_key_clear(el, alt, (char *)new);
+ key_clear(el, alt, (char *)new);
alt[new[0]] = tp->bind[el->el_map.type + 1];
}
}
@@ -1041,13 +1139,14 @@ tty_noquotemode(EditLine *el)
*/
protected int
/*ARGSUSED*/
-tty_stty(EditLine *el, int argc __attribute__((unused)), const char **argv)
+tty_stty(EditLine *el, int argc __attribute__((__unused__)), const char **argv)
{
const ttymodes_t *m;
char x;
int aflag = 0;
const char *s, *d;
const char *name;
+ struct termios *tios = &el->el_tty.t_ex;
int z = EX_IO;
if (argv == NULL)
@@ -1062,14 +1161,17 @@ tty_stty(EditLine *el, int argc __attribute__((unused)), const char **argv)
break;
case 'd':
argv++;
+ tios = &el->el_tty.t_ed;
z = ED_IO;
break;
case 'x':
argv++;
+ tios = &el->el_tty.t_ex;
z = EX_IO;
break;
case 'q':
argv++;
+ tios = &el->el_tty.t_ts;
z = QU_IO;
break;
default:
@@ -1119,6 +1221,7 @@ tty_stty(EditLine *el, int argc __attribute__((unused)), const char **argv)
return (0);
}
while (argv && (s = *argv++)) {
+ char *p;
switch (*s) {
case '+':
case '-':
@@ -1129,8 +1232,11 @@ tty_stty(EditLine *el, int argc __attribute__((unused)), const char **argv)
break;
}
d = s;
+ if ((p = strchr(s, '=')) != NULL)
+ *p++ = '\0';
for (m = ttymodes; m->m_name; m++)
- if (strcmp(m->m_name, d) == 0)
+ if (strcmp(m->m_name, d) == 0 &&
+ (p == NULL || m->m_type == MD_CHAR))
break;
if (!m->m_name) {
@@ -1138,6 +1244,16 @@ tty_stty(EditLine *el, int argc __attribute__((unused)), const char **argv)
"%s: Invalid argument `%s'.\n", name, d);
return (-1);
}
+ if (p) {
+ int c = ffs((int)m->m_value);
+ int v = *p ? parse__escape((const char **const) &p) :
+ el->el_tty.t_vdisable;
+ assert(c-- != 0);
+ c = tty__getcharindex(c);
+ assert(c != -1);
+ tios->c_cc[c] = v;
+ continue;
+ }
switch (x) {
case '+':
el->el_tty.t_t[z][m->m_type].t_setmask |= m->m_value;
diff --git a/cmd-line-utils/libedit/tty.h b/cmd-line-utils/libedit/tty.h
index e9597fceb2b..cc7c4ad8c66 100644
--- a/cmd-line-utils/libedit/tty.h
+++ b/cmd-line-utils/libedit/tty.h
@@ -1,4 +1,4 @@
-/* $NetBSD: tty.h,v 1.9 2002/03/18 16:01:01 christos Exp $ */
+/* $NetBSD: tty.h,v 1.10 2003/08/07 16:44:34 agc Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -15,11 +15,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
diff --git a/cmd-line-utils/libedit/unvis.c b/cmd-line-utils/libedit/unvis.c
new file mode 100644
index 00000000000..ffa8ac4251c
--- /dev/null
+++ b/cmd-line-utils/libedit/unvis.c
@@ -0,0 +1,311 @@
+/* $NetBSD: unvis.c,v 1.24 2003/08/07 16:42:59 agc Exp $ */
+
+/*-
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#define __LIBC12_SOURCE__
+
+#include <sys/types.h>
+
+#include <assert.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <vis.h>
+
+#ifdef __weak_alias
+__weak_alias(strunvis,_strunvis)
+__weak_alias(unvis,_unvis)
+#endif
+
+#ifdef __warn_references
+__warn_references(unvis,
+ "warning: reference to compatibility unvis(); include <vis.h> for correct reference")
+#endif
+
+#if !HAVE_VIS
+/*
+ * decode driven by state machine
+ */
+#define S_GROUND 0 /* haven't seen escape char */
+#define S_START 1 /* start decoding special sequence */
+#define S_META 2 /* metachar started (M) */
+#define S_META1 3 /* metachar more, regular char (-) */
+#define S_CTRL 4 /* control char started (^) */
+#define S_OCTAL2 5 /* octal digit 2 */
+#define S_OCTAL3 6 /* octal digit 3 */
+#define S_HEX1 7 /* hex digit */
+#define S_HEX2 8 /* hex digit 2 */
+
+#define isoctal(c) (((u_char)(c)) >= '0' && ((u_char)(c)) <= '7')
+#define xtod(c) (isdigit(c) ? (c - '0') : ((tolower(c) - 'a') + 10))
+
+int
+unvis(cp, c, astate, flag)
+ char *cp;
+ int c;
+ int *astate, flag;
+{
+ return __unvis13(cp, (int)c, astate, flag);
+}
+
+/*
+ * unvis - decode characters previously encoded by vis
+ */
+int
+__unvis13(cp, c, astate, flag)
+ char *cp;
+ int c;
+ int *astate, flag;
+{
+
+ _DIAGASSERT(cp != NULL);
+ _DIAGASSERT(astate != NULL);
+
+ if (flag & UNVIS_END) {
+ if (*astate == S_OCTAL2 || *astate == S_OCTAL3
+ || *astate == S_HEX2) {
+ *astate = S_GROUND;
+ return (UNVIS_VALID);
+ }
+ return (*astate == S_GROUND ? UNVIS_NOCHAR : UNVIS_SYNBAD);
+ }
+
+ switch (*astate) {
+
+ case S_GROUND:
+ *cp = 0;
+ if (c == '\\') {
+ *astate = S_START;
+ return (0);
+ }
+ if ((flag & VIS_HTTPSTYLE) && c == '%') {
+ *astate = S_HEX1;
+ return (0);
+ }
+ *cp = c;
+ return (UNVIS_VALID);
+
+ case S_START:
+ switch(c) {
+ case '\\':
+ *cp = c;
+ *astate = S_GROUND;
+ return (UNVIS_VALID);
+ case '0': case '1': case '2': case '3':
+ case '4': case '5': case '6': case '7':
+ *cp = (c - '0');
+ *astate = S_OCTAL2;
+ return (0);
+ case 'M':
+ *cp = (char)0200;
+ *astate = S_META;
+ return (0);
+ case '^':
+ *astate = S_CTRL;
+ return (0);
+ case 'n':
+ *cp = '\n';
+ *astate = S_GROUND;
+ return (UNVIS_VALID);
+ case 'r':
+ *cp = '\r';
+ *astate = S_GROUND;
+ return (UNVIS_VALID);
+ case 'b':
+ *cp = '\b';
+ *astate = S_GROUND;
+ return (UNVIS_VALID);
+ case 'a':
+ *cp = '\007';
+ *astate = S_GROUND;
+ return (UNVIS_VALID);
+ case 'v':
+ *cp = '\v';
+ *astate = S_GROUND;
+ return (UNVIS_VALID);
+ case 't':
+ *cp = '\t';
+ *astate = S_GROUND;
+ return (UNVIS_VALID);
+ case 'f':
+ *cp = '\f';
+ *astate = S_GROUND;
+ return (UNVIS_VALID);
+ case 's':
+ *cp = ' ';
+ *astate = S_GROUND;
+ return (UNVIS_VALID);
+ case 'E':
+ *cp = '\033';
+ *astate = S_GROUND;
+ return (UNVIS_VALID);
+ case '\n':
+ /*
+ * hidden newline
+ */
+ *astate = S_GROUND;
+ return (UNVIS_NOCHAR);
+ case '$':
+ /*
+ * hidden marker
+ */
+ *astate = S_GROUND;
+ return (UNVIS_NOCHAR);
+ }
+ *astate = S_GROUND;
+ return (UNVIS_SYNBAD);
+
+ case S_META:
+ if (c == '-')
+ *astate = S_META1;
+ else if (c == '^')
+ *astate = S_CTRL;
+ else {
+ *astate = S_GROUND;
+ return (UNVIS_SYNBAD);
+ }
+ return (0);
+
+ case S_META1:
+ *astate = S_GROUND;
+ *cp |= c;
+ return (UNVIS_VALID);
+
+ case S_CTRL:
+ if (c == '?')
+ *cp |= 0177;
+ else
+ *cp |= c & 037;
+ *astate = S_GROUND;
+ return (UNVIS_VALID);
+
+ case S_OCTAL2: /* second possible octal digit */
+ if (isoctal(c)) {
+ /*
+ * yes - and maybe a third
+ */
+ *cp = (*cp << 3) + (c - '0');
+ *astate = S_OCTAL3;
+ return (0);
+ }
+ /*
+ * no - done with current sequence, push back passed char
+ */
+ *astate = S_GROUND;
+ return (UNVIS_VALIDPUSH);
+
+ case S_OCTAL3: /* third possible octal digit */
+ *astate = S_GROUND;
+ if (isoctal(c)) {
+ *cp = (*cp << 3) + (c - '0');
+ return (UNVIS_VALID);
+ }
+ /*
+ * we were done, push back passed char
+ */
+ return (UNVIS_VALIDPUSH);
+ case S_HEX1:
+ if (isxdigit(c)) {
+ *cp = xtod(c);
+ *astate = S_HEX2;
+ return (0);
+ }
+ /*
+ * no - done with current sequence, push back passed char
+ */
+ *astate = S_GROUND;
+ return (UNVIS_VALIDPUSH);
+ case S_HEX2:
+ *astate = S_GROUND;
+ if (isxdigit(c)) {
+ *cp = xtod(c) | (*cp << 4);
+ return (UNVIS_VALID);
+ }
+ return (UNVIS_VALIDPUSH);
+ default:
+ /*
+ * decoder in unknown state - (probably uninitialized)
+ */
+ *astate = S_GROUND;
+ return (UNVIS_SYNBAD);
+ }
+}
+
+/*
+ * strunvis - decode src into dst
+ *
+ * Number of chars decoded into dst is returned, -1 on error.
+ * Dst is null terminated.
+ */
+
+int
+strunvisx(dst, src, flag)
+ char *dst;
+ const char *src;
+ int flag;
+{
+ char c;
+ char *start = dst;
+ int state = 0;
+
+ _DIAGASSERT(src != NULL);
+ _DIAGASSERT(dst != NULL);
+
+ while ((c = *src++) != '\0') {
+ again:
+ switch (__unvis13(dst, c, &state, flag)) {
+ case UNVIS_VALID:
+ dst++;
+ break;
+ case UNVIS_VALIDPUSH:
+ dst++;
+ goto again;
+ case 0:
+ case UNVIS_NOCHAR:
+ break;
+ default:
+ return (-1);
+ }
+ }
+ if (__unvis13(dst, c, &state, UNVIS_END) == UNVIS_VALID)
+ dst++;
+ *dst = '\0';
+ return (dst - start);
+}
+
+int
+strunvis(dst, src)
+ char *dst;
+ const char *src;
+{
+ return strunvisx(dst, src, 0);
+}
+#endif
diff --git a/cmd-line-utils/libedit/vi.c b/cmd-line-utils/libedit/vi.c
index 5380872cf65..4a0352859dd 100644
--- a/cmd-line-utils/libedit/vi.c
+++ b/cmd-line-utils/libedit/vi.c
@@ -1,4 +1,4 @@
-/* $NetBSD: vi.c,v 1.16 2003/03/10 11:09:25 dsl Exp $ */
+/* $NetBSD: vi.c,v 1.20 2004/08/13 12:10:39 mycroft Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -15,11 +15,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
@@ -36,18 +32,11 @@
* SUCH DAMAGE.
*/
-#include "config.h"
+#include <config.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
-#if !defined(lint) && !defined(SCCSID)
-#if 0
-static char sccsid[] = "@(#)vi.c 8.1 (Berkeley) 6/4/93";
-#else
-__RCSID("$NetBSD: vi.c,v 1.16 2003/03/10 11:09:25 dsl Exp $");
-#endif
-#endif /* not lint && not SCCSID */
/*
* vi.c: Vi mode commands.
@@ -123,7 +112,7 @@ cv_paste(EditLine *el, int c)
*/
protected el_action_t
/*ARGSUSED*/
-vi_paste_next(EditLine *el, int c __attribute__((unused)))
+vi_paste_next(EditLine *el, int c __attribute__((__unused__)))
{
return (cv_paste(el, 0));
@@ -136,7 +125,7 @@ vi_paste_next(EditLine *el, int c __attribute__((unused)))
*/
protected el_action_t
/*ARGSUSED*/
-vi_paste_prev(EditLine *el, int c __attribute__((unused)))
+vi_paste_prev(EditLine *el, int c __attribute__((__unused__)))
{
return (cv_paste(el, 1));
@@ -149,7 +138,7 @@ vi_paste_prev(EditLine *el, int c __attribute__((unused)))
*/
protected el_action_t
/*ARGSUSED*/
-vi_prev_big_word(EditLine *el, int c __attribute__((unused)))
+vi_prev_big_word(EditLine *el, int c)
{
if (el->el_line.cursor == el->el_line.buffer)
@@ -174,7 +163,7 @@ vi_prev_big_word(EditLine *el, int c __attribute__((unused)))
*/
protected el_action_t
/*ARGSUSED*/
-vi_prev_word(EditLine *el, int c __attribute__((unused)))
+vi_prev_word(EditLine *el, int c __attribute__((__unused__)))
{
if (el->el_line.cursor == el->el_line.buffer)
@@ -199,7 +188,7 @@ vi_prev_word(EditLine *el, int c __attribute__((unused)))
*/
protected el_action_t
/*ARGSUSED*/
-vi_next_big_word(EditLine *el, int c __attribute__((unused)))
+vi_next_big_word(EditLine *el, int c)
{
if (el->el_line.cursor >= el->el_line.lastchar - 1)
@@ -223,7 +212,7 @@ vi_next_big_word(EditLine *el, int c __attribute__((unused)))
*/
protected el_action_t
/*ARGSUSED*/
-vi_next_word(EditLine *el, int c __attribute__((unused)))
+vi_next_word(EditLine *el, int c __attribute__((__unused__)))
{
if (el->el_line.cursor >= el->el_line.lastchar - 1)
@@ -278,7 +267,7 @@ vi_change_case(EditLine *el, int c)
*/
protected el_action_t
/*ARGSUSED*/
-vi_change_meta(EditLine *el, int c __attribute__((unused)))
+vi_change_meta(EditLine *el, int c __attribute__((__unused__)))
{
/*
@@ -295,7 +284,7 @@ vi_change_meta(EditLine *el, int c __attribute__((unused)))
*/
protected el_action_t
/*ARGSUSED*/
-vi_insert_at_bol(EditLine *el, int c __attribute__((unused)))
+vi_insert_at_bol(EditLine *el, int c __attribute__((__unused__)))
{
el->el_line.cursor = el->el_line.buffer;
@@ -311,7 +300,7 @@ vi_insert_at_bol(EditLine *el, int c __attribute__((unused)))
*/
protected el_action_t
/*ARGSUSED*/
-vi_replace_char(EditLine *el, int c __attribute__((unused)))
+vi_replace_char(EditLine *el, int c __attribute__((__unused__)))
{
if (el->el_line.cursor >= el->el_line.lastchar)
@@ -330,7 +319,7 @@ vi_replace_char(EditLine *el, int c __attribute__((unused)))
*/
protected el_action_t
/*ARGSUSED*/
-vi_replace_mode(EditLine *el, int c __attribute__((unused)))
+vi_replace_mode(EditLine *el, int c __attribute__((__unused__)))
{
el->el_map.current = el->el_map.key;
@@ -346,7 +335,7 @@ vi_replace_mode(EditLine *el, int c __attribute__((unused)))
*/
protected el_action_t
/*ARGSUSED*/
-vi_substitute_char(EditLine *el, int c __attribute__((unused)))
+vi_substitute_char(EditLine *el, int c __attribute__((__unused__)))
{
c_delafter(el, el->el_state.argument);
@@ -361,7 +350,7 @@ vi_substitute_char(EditLine *el, int c __attribute__((unused)))
*/
protected el_action_t
/*ARGSUSED*/
-vi_substitute_line(EditLine *el, int c __attribute__((unused)))
+vi_substitute_line(EditLine *el, int c __attribute__((__unused__)))
{
cv_undo(el);
@@ -379,7 +368,7 @@ vi_substitute_line(EditLine *el, int c __attribute__((unused)))
*/
protected el_action_t
/*ARGSUSED*/
-vi_change_to_eol(EditLine *el, int c __attribute__((unused)))
+vi_change_to_eol(EditLine *el, int c __attribute__((__unused__)))
{
cv_undo(el);
@@ -397,7 +386,7 @@ vi_change_to_eol(EditLine *el, int c __attribute__((unused)))
*/
protected el_action_t
/*ARGSUSED*/
-vi_insert(EditLine *el, int c __attribute__((unused)))
+vi_insert(EditLine *el, int c __attribute__((__unused__)))
{
el->el_map.current = el->el_map.key;
@@ -412,7 +401,7 @@ vi_insert(EditLine *el, int c __attribute__((unused)))
*/
protected el_action_t
/*ARGSUSED*/
-vi_add(EditLine *el, int c __attribute__((unused)))
+vi_add(EditLine *el, int c __attribute__((__unused__)))
{
int ret;
@@ -437,7 +426,7 @@ vi_add(EditLine *el, int c __attribute__((unused)))
*/
protected el_action_t
/*ARGSUSED*/
-vi_add_at_eol(EditLine *el, int c __attribute__((unused)))
+vi_add_at_eol(EditLine *el, int c __attribute__((__unused__)))
{
el->el_map.current = el->el_map.key;
@@ -453,7 +442,7 @@ vi_add_at_eol(EditLine *el, int c __attribute__((unused)))
*/
protected el_action_t
/*ARGSUSED*/
-vi_delete_meta(EditLine *el, int c __attribute__((unused)))
+vi_delete_meta(EditLine *el, int c __attribute__((__unused__)))
{
return (cv_action(el, DELETE));
@@ -466,7 +455,7 @@ vi_delete_meta(EditLine *el, int c __attribute__((unused)))
*/
protected el_action_t
/*ARGSUSED*/
-vi_end_big_word(EditLine *el, int c __attribute__((unused)))
+vi_end_big_word(EditLine *el, int c)
{
if (el->el_line.cursor == el->el_line.lastchar)
@@ -490,7 +479,7 @@ vi_end_big_word(EditLine *el, int c __attribute__((unused)))
*/
protected el_action_t
/*ARGSUSED*/
-vi_end_word(EditLine *el, int c __attribute__((unused)))
+vi_end_word(EditLine *el, int c __attribute__((__unused__)))
{
if (el->el_line.cursor == el->el_line.lastchar)
@@ -514,7 +503,7 @@ vi_end_word(EditLine *el, int c __attribute__((unused)))
*/
protected el_action_t
/*ARGSUSED*/
-vi_undo(EditLine *el, int c __attribute__((unused)))
+vi_undo(EditLine *el, int c __attribute__((__unused__)))
{
c_undo_t un = el->el_chared.c_undo;
@@ -540,7 +529,7 @@ vi_undo(EditLine *el, int c __attribute__((unused)))
*/
protected el_action_t
/*ARGSUSED*/
-vi_command_mode(EditLine *el, int c __attribute__((unused)))
+vi_command_mode(EditLine *el, int c __attribute__((__unused__)))
{
/* [Esc] cancels pending action */
@@ -585,20 +574,14 @@ vi_zero(EditLine *el, int c)
*/
protected el_action_t
/*ARGSUSED*/
-vi_delete_prev_char(EditLine *el, int c __attribute__((unused)))
+vi_delete_prev_char(EditLine *el, int c __attribute__((__unused__)))
{
- char *cp;
- cp = el->el_line.cursor;
- if (cp <= el->el_line.buffer)
+ if (el->el_line.cursor <= el->el_line.buffer)
return (CC_ERROR);
- /* do the delete here so we dont mess up the undo and paste buffers */
- el->el_line.cursor = --cp;
- for (; cp < el->el_line.lastchar; cp++)
- cp[0] = cp[1];
- el->el_line.lastchar = cp - 1;
-
+ c_delbefore1(el);
+ el->el_line.cursor--;
return (CC_REFRESH);
}
@@ -609,23 +592,35 @@ vi_delete_prev_char(EditLine *el, int c __attribute__((unused)))
*/
protected el_action_t
/*ARGSUSED*/
-vi_list_or_eof(EditLine *el, int c __attribute__((unused)))
+vi_list_or_eof(EditLine *el, int c __attribute__((__unused__)))
{
-#ifdef notyet
- if (el->el_line.cursor == el->el_line.lastchar &&
- el->el_line.cursor == el->el_line.buffer) {
-#endif
- term_overwrite(el, STReof, 4); /* then do a EOF */
- term__flush();
- return (CC_EOF);
-#ifdef notyet
+ if (el->el_line.cursor == el->el_line.lastchar) {
+ if (el->el_line.cursor == el->el_line.buffer) {
+ term_overwrite(el, STReof, 4); /* then do a EOF */
+ term__flush();
+ return (CC_EOF);
+ } else {
+ /*
+ * Here we could list completions, but it is an
+ * error right now
+ */
+ term_beep(el);
+ return (CC_ERROR);
+ }
} else {
+#ifdef notyet
re_goto_bottom(el);
*el->el_line.lastchar = '\0'; /* just in case */
return (CC_LIST_CHOICES);
- }
+#else
+ /*
+ * Just complain for now.
+ */
+ term_beep(el);
+ return (CC_ERROR);
#endif
+ }
}
@@ -635,7 +630,7 @@ vi_list_or_eof(EditLine *el, int c __attribute__((unused)))
*/
protected el_action_t
/*ARGSUSED*/
-vi_kill_line_prev(EditLine *el, int c __attribute__((unused)))
+vi_kill_line_prev(EditLine *el, int c __attribute__((__unused__)))
{
char *kp, *cp;
@@ -656,7 +651,7 @@ vi_kill_line_prev(EditLine *el, int c __attribute__((unused)))
*/
protected el_action_t
/*ARGSUSED*/
-vi_search_prev(EditLine *el, int c __attribute__((unused)))
+vi_search_prev(EditLine *el, int c __attribute__((__unused__)))
{
return (cv_search(el, ED_SEARCH_PREV_HISTORY));
@@ -669,7 +664,7 @@ vi_search_prev(EditLine *el, int c __attribute__((unused)))
*/
protected el_action_t
/*ARGSUSED*/
-vi_search_next(EditLine *el, int c __attribute__((unused)))
+vi_search_next(EditLine *el, int c __attribute__((__unused__)))
{
return (cv_search(el, ED_SEARCH_NEXT_HISTORY));
@@ -682,7 +677,7 @@ vi_search_next(EditLine *el, int c __attribute__((unused)))
*/
protected el_action_t
/*ARGSUSED*/
-vi_repeat_search_next(EditLine *el, int c __attribute__((unused)))
+vi_repeat_search_next(EditLine *el, int c __attribute__((__unused__)))
{
if (el->el_search.patlen == 0)
@@ -698,7 +693,7 @@ vi_repeat_search_next(EditLine *el, int c __attribute__((unused)))
*/
/*ARGSUSED*/
protected el_action_t
-vi_repeat_search_prev(EditLine *el, int c __attribute__((unused)))
+vi_repeat_search_prev(EditLine *el, int c __attribute__((__unused__)))
{
if (el->el_search.patlen == 0)
@@ -716,7 +711,7 @@ vi_repeat_search_prev(EditLine *el, int c __attribute__((unused)))
*/
protected el_action_t
/*ARGSUSED*/
-vi_next_char(EditLine *el, int c __attribute__((unused)))
+vi_next_char(EditLine *el, int c __attribute__((__unused__)))
{
return cv_csearch(el, CHAR_FWD, -1, el->el_state.argument, 0);
}
@@ -728,7 +723,7 @@ vi_next_char(EditLine *el, int c __attribute__((unused)))
*/
protected el_action_t
/*ARGSUSED*/
-vi_prev_char(EditLine *el, int c __attribute__((unused)))
+vi_prev_char(EditLine *el, int c __attribute__((__unused__)))
{
return cv_csearch(el, CHAR_BACK, -1, el->el_state.argument, 0);
}
@@ -740,7 +735,7 @@ vi_prev_char(EditLine *el, int c __attribute__((unused)))
*/
protected el_action_t
/*ARGSUSED*/
-vi_to_next_char(EditLine *el, int c __attribute__((unused)))
+vi_to_next_char(EditLine *el, int c __attribute__((__unused__)))
{
return cv_csearch(el, CHAR_FWD, -1, el->el_state.argument, 1);
}
@@ -752,7 +747,7 @@ vi_to_next_char(EditLine *el, int c __attribute__((unused)))
*/
protected el_action_t
/*ARGSUSED*/
-vi_to_prev_char(EditLine *el, int c __attribute__((unused)))
+vi_to_prev_char(EditLine *el, int c __attribute__((__unused__)))
{
return cv_csearch(el, CHAR_BACK, -1, el->el_state.argument, 1);
}
@@ -764,7 +759,7 @@ vi_to_prev_char(EditLine *el, int c __attribute__((unused)))
*/
protected el_action_t
/*ARGSUSED*/
-vi_repeat_next_char(EditLine *el, int c __attribute__((unused)))
+vi_repeat_next_char(EditLine *el, int c __attribute__((__unused__)))
{
return cv_csearch(el, el->el_search.chadir, el->el_search.chacha,
@@ -778,7 +773,7 @@ vi_repeat_next_char(EditLine *el, int c __attribute__((unused)))
*/
protected el_action_t
/*ARGSUSED*/
-vi_repeat_prev_char(EditLine *el, int c __attribute__((unused)))
+vi_repeat_prev_char(EditLine *el, int c __attribute__((__unused__)))
{
el_action_t r;
int dir = el->el_search.chadir;
@@ -796,7 +791,7 @@ vi_repeat_prev_char(EditLine *el, int c __attribute__((unused)))
*/
protected el_action_t
/*ARGSUSED*/
-vi_match(EditLine *el, int c __attribute__((unused)))
+vi_match(EditLine *el, int c)
{
const char match_chars[] = "()[]{}";
char *cp;
@@ -843,7 +838,7 @@ vi_match(EditLine *el, int c __attribute__((unused)))
*/
protected el_action_t
/*ARGSUSED*/
-vi_undo_line(EditLine *el, int c __attribute__((unused)))
+vi_undo_line(EditLine *el, int c)
{
cv_undo(el);
@@ -857,7 +852,7 @@ vi_undo_line(EditLine *el, int c __attribute__((unused)))
*/
protected el_action_t
/*ARGSUSED*/
-vi_to_column(EditLine *el, int c __attribute__((unused)))
+vi_to_column(EditLine *el, int c)
{
el->el_line.cursor = el->el_line.buffer;
@@ -871,7 +866,7 @@ vi_to_column(EditLine *el, int c __attribute__((unused)))
*/
protected el_action_t
/*ARGSUSED*/
-vi_yank_end(EditLine *el, int c __attribute__((unused)))
+vi_yank_end(EditLine *el, int c)
{
cv_yank(el, el->el_line.cursor,
@@ -885,7 +880,7 @@ vi_yank_end(EditLine *el, int c __attribute__((unused)))
*/
protected el_action_t
/*ARGSUSED*/
-vi_yank(EditLine *el, int c __attribute__((unused)))
+vi_yank(EditLine *el, int c)
{
return cv_action(el, YANK);
@@ -897,7 +892,7 @@ vi_yank(EditLine *el, int c __attribute__((unused)))
*/
protected el_action_t
/*ARGSUSED*/
-vi_comment_out(EditLine *el, int c __attribute__((unused)))
+vi_comment_out(EditLine *el, int c)
{
el->el_line.cursor = el->el_line.buffer;
@@ -915,7 +910,7 @@ vi_comment_out(EditLine *el, int c __attribute__((unused)))
*/
protected el_action_t
/*ARGSUSED*/
-vi_alias(EditLine *el __attribute__((unused)), int c __attribute__((unused)))
+vi_alias(EditLine *el, int c)
{
#ifdef __weak_extern
char alias_name[3];
@@ -947,7 +942,7 @@ vi_alias(EditLine *el __attribute__((unused)), int c __attribute__((unused)))
*/
protected el_action_t
/*ARGSUSED*/
-vi_to_history_line(EditLine *el, int c __attribute__((unused)))
+vi_to_history_line(EditLine *el, int c)
{
int sv_event_no = el->el_history.eventno;
el_action_t rval;
@@ -992,7 +987,7 @@ vi_to_history_line(EditLine *el, int c __attribute__((unused)))
*/
protected el_action_t
/*ARGSUSED*/
-vi_histedit(EditLine *el, int c __attribute__((unused)))
+vi_histedit(EditLine *el, int c)
{
int fd;
pid_t pid;
@@ -1048,7 +1043,7 @@ vi_histedit(EditLine *el, int c __attribute__((unused)))
*/
protected el_action_t
/*ARGSUSED*/
-vi_history_word(EditLine *el, int c __attribute__((unused)))
+vi_history_word(EditLine *el, int c)
{
const char *wp = HIST_FIRST(el);
const char *wep, *wsp;
@@ -1097,7 +1092,7 @@ vi_history_word(EditLine *el, int c __attribute__((unused)))
*/
protected el_action_t
/*ARGSUSED*/
-vi_redo(EditLine *el, int c __attribute__((unused)))
+vi_redo(EditLine *el, int c)
{
c_redo_t *r = &el->el_chared.c_redo;
diff --git a/cmd-line-utils/libedit/vis.c b/cmd-line-utils/libedit/vis.c
new file mode 100644
index 00000000000..127d28733a8
--- /dev/null
+++ b/cmd-line-utils/libedit/vis.c
@@ -0,0 +1,392 @@
+/* $NetBSD: vis.c,v 1.27 2004/02/26 23:01:15 enami Exp $ */
+
+/*-
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*-
+ * Copyright (c) 1999 The NetBSD Foundation, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/* AIX requires this to be the first thing in the file. */
+#if defined (_AIX) && !defined (__GNUC__)
+ #pragma alloca
+#endif
+
+#include <config.h>
+
+#ifdef __GNUC__
+# undef alloca
+# define alloca(n) __builtin_alloca (n)
+#else
+# ifdef HAVE_ALLOCA_H
+# include <alloca.h>
+# else
+# ifndef _AIX
+extern char *alloca ();
+# endif
+# endif
+#endif
+
+#include <sys/types.h>
+
+#include <assert.h>
+#include <vis.h>
+#include <stdlib.h>
+
+#ifdef __weak_alias
+__weak_alias(strsvis,_strsvis)
+__weak_alias(strsvisx,_strsvisx)
+__weak_alias(strvis,_strvis)
+__weak_alias(strvisx,_strvisx)
+__weak_alias(svis,_svis)
+__weak_alias(vis,_vis)
+#endif
+
+#if !HAVE_VIS || !HAVE_SVIS
+#include <ctype.h>
+#include <limits.h>
+#include <stdio.h>
+#include <string.h>
+
+#undef BELL
+#define BELL '\a'
+
+#define isoctal(c) (((u_char)(c)) >= '0' && ((u_char)(c)) <= '7')
+#define iswhite(c) (c == ' ' || c == '\t' || c == '\n')
+#define issafe(c) (c == '\b' || c == BELL || c == '\r')
+#define xtoa(c) "0123456789abcdef"[c]
+
+#define MAXEXTRAS 5
+
+
+#define MAKEEXTRALIST(flag, extra, orig) \
+do { \
+ const char *o = orig; \
+ char *e; \
+ while (*o++) \
+ continue; \
+ extra = alloca((size_t)((o - orig) + MAXEXTRAS)); \
+ for (o = orig, e = extra; (*e++ = *o++) != '\0';) \
+ continue; \
+ e--; \
+ if (flag & VIS_SP) *e++ = ' '; \
+ if (flag & VIS_TAB) *e++ = '\t'; \
+ if (flag & VIS_NL) *e++ = '\n'; \
+ if ((flag & VIS_NOSLASH) == 0) *e++ = '\\'; \
+ *e = '\0'; \
+} while (/*CONSTCOND*/0)
+
+
+/*
+ * This is HVIS, the macro of vis used to HTTP style (RFC 1808)
+ */
+#define HVIS(dst, c, flag, nextc, extra) \
+do \
+ if (!isascii(c) || !isalnum(c) || strchr("$-_.+!*'(),", c) != NULL) { \
+ *dst++ = '%'; \
+ *dst++ = xtoa(((unsigned int)c >> 4) & 0xf); \
+ *dst++ = xtoa((unsigned int)c & 0xf); \
+ } else { \
+ SVIS(dst, c, flag, nextc, extra); \
+ } \
+while (/*CONSTCOND*/0)
+
+/*
+ * This is SVIS, the central macro of vis.
+ * dst: Pointer to the destination buffer
+ * c: Character to encode
+ * flag: Flag word
+ * nextc: The character following 'c'
+ * extra: Pointer to the list of extra characters to be
+ * backslash-protected.
+ */
+#define SVIS(dst, c, flag, nextc, extra) \
+do { \
+ int isextra; \
+ isextra = strchr(extra, c) != NULL; \
+ if (!isextra && isascii(c) && (isgraph(c) || iswhite(c) || \
+ ((flag & VIS_SAFE) && issafe(c)))) { \
+ *dst++ = c; \
+ break; \
+ } \
+ if (flag & VIS_CSTYLE) { \
+ switch (c) { \
+ case '\n': \
+ *dst++ = '\\'; *dst++ = 'n'; \
+ continue; \
+ case '\r': \
+ *dst++ = '\\'; *dst++ = 'r'; \
+ continue; \
+ case '\b': \
+ *dst++ = '\\'; *dst++ = 'b'; \
+ continue; \
+ case BELL: \
+ *dst++ = '\\'; *dst++ = 'a'; \
+ continue; \
+ case '\v': \
+ *dst++ = '\\'; *dst++ = 'v'; \
+ continue; \
+ case '\t': \
+ *dst++ = '\\'; *dst++ = 't'; \
+ continue; \
+ case '\f': \
+ *dst++ = '\\'; *dst++ = 'f'; \
+ continue; \
+ case ' ': \
+ *dst++ = '\\'; *dst++ = 's'; \
+ continue; \
+ case '\0': \
+ *dst++ = '\\'; *dst++ = '0'; \
+ if (isoctal(nextc)) { \
+ *dst++ = '0'; \
+ *dst++ = '0'; \
+ } \
+ continue; \
+ default: \
+ if (isgraph(c)) { \
+ *dst++ = '\\'; *dst++ = c; \
+ continue; \
+ } \
+ } \
+ } \
+ if (isextra || ((c & 0177) == ' ') || (flag & VIS_OCTAL)) { \
+ *dst++ = '\\'; \
+ *dst++ = (u_char)(((u_int32_t)(u_char)c >> 6) & 03) + '0'; \
+ *dst++ = (u_char)(((u_int32_t)(u_char)c >> 3) & 07) + '0'; \
+ *dst++ = (c & 07) + '0'; \
+ } else { \
+ if ((flag & VIS_NOSLASH) == 0) *dst++ = '\\'; \
+ if (c & 0200) { \
+ c &= 0177; *dst++ = 'M'; \
+ } \
+ if (iscntrl(c)) { \
+ *dst++ = '^'; \
+ if (c == 0177) \
+ *dst++ = '?'; \
+ else \
+ *dst++ = c + '@'; \
+ } else { \
+ *dst++ = '-'; *dst++ = c; \
+ } \
+ } \
+} while (/*CONSTCOND*/0)
+
+
+/*
+ * svis - visually encode characters, also encoding the characters
+ * pointed to by `extra'
+ */
+char *
+svis(dst, c, flag, nextc, extra)
+ char *dst;
+ int c, flag, nextc;
+ const char *extra;
+{
+ char *nextra;
+ _DIAGASSERT(dst != NULL);
+ _DIAGASSERT(extra != NULL);
+ MAKEEXTRALIST(flag, nextra, extra);
+ if (flag & VIS_HTTPSTYLE)
+ HVIS(dst, c, flag, nextc, nextra);
+ else
+ SVIS(dst, c, flag, nextc, nextra);
+ *dst = '\0';
+ return(dst);
+}
+
+
+/*
+ * strsvis, strsvisx - visually encode characters from src into dst
+ *
+ * Extra is a pointer to a \0-terminated list of characters to
+ * be encoded, too. These functions are useful e. g. to
+ * encode strings in such a way so that they are not interpreted
+ * by a shell.
+ *
+ * Dst must be 4 times the size of src to account for possible
+ * expansion. The length of dst, not including the trailing NULL,
+ * is returned.
+ *
+ * Strsvisx encodes exactly len bytes from src into dst.
+ * This is useful for encoding a block of data.
+ */
+int
+strsvis(dst, csrc, flag, extra)
+ char *dst;
+ const char *csrc;
+ int flag;
+ const char *extra;
+{
+ int c;
+ char *start;
+ char *nextra;
+ const unsigned char *src = (const unsigned char *)csrc;
+
+ _DIAGASSERT(dst != NULL);
+ _DIAGASSERT(src != NULL);
+ _DIAGASSERT(extra != NULL);
+ MAKEEXTRALIST(flag, nextra, extra);
+ if (flag & VIS_HTTPSTYLE) {
+ for (start = dst; (c = *src++) != '\0'; /* empty */)
+ HVIS(dst, c, flag, *src, nextra);
+ } else {
+ for (start = dst; (c = *src++) != '\0'; /* empty */)
+ SVIS(dst, c, flag, *src, nextra);
+ }
+ *dst = '\0';
+ return (dst - start);
+}
+
+
+int
+strsvisx(dst, csrc, len, flag, extra)
+ char *dst;
+ const char *csrc;
+ size_t len;
+ int flag;
+ const char *extra;
+{
+ int c;
+ char *start;
+ char *nextra;
+ const unsigned char *src = (const unsigned char *)csrc;
+
+ _DIAGASSERT(dst != NULL);
+ _DIAGASSERT(src != NULL);
+ _DIAGASSERT(extra != NULL);
+ MAKEEXTRALIST(flag, nextra, extra);
+
+ if (flag & VIS_HTTPSTYLE) {
+ for (start = dst; len > 0; len--) {
+ c = *src++;
+ HVIS(dst, c, flag, len ? *src : '\0', nextra);
+ }
+ } else {
+ for (start = dst; len > 0; len--) {
+ c = *src++;
+ SVIS(dst, c, flag, len ? *src : '\0', nextra);
+ }
+ }
+ *dst = '\0';
+ return (dst - start);
+}
+#endif
+
+#if !HAVE_VIS
+/*
+ * vis - visually encode characters
+ */
+char *
+vis(dst, c, flag, nextc)
+ char *dst;
+ int c, flag, nextc;
+
+{
+ char *extra;
+
+ _DIAGASSERT(dst != NULL);
+
+ MAKEEXTRALIST(flag, extra, "");
+ if (flag & VIS_HTTPSTYLE)
+ HVIS(dst, c, flag, nextc, extra);
+ else
+ SVIS(dst, c, flag, nextc, extra);
+ *dst = '\0';
+ return (dst);
+}
+
+
+/*
+ * strvis, strvisx - visually encode characters from src into dst
+ *
+ * Dst must be 4 times the size of src to account for possible
+ * expansion. The length of dst, not including the trailing NULL,
+ * is returned.
+ *
+ * Strvisx encodes exactly len bytes from src into dst.
+ * This is useful for encoding a block of data.
+ */
+int
+strvis(dst, src, flag)
+ char *dst;
+ const char *src;
+ int flag;
+{
+ char *extra;
+
+ MAKEEXTRALIST(flag, extra, "");
+ return (strsvis(dst, src, flag, extra));
+}
+
+
+int
+strvisx(dst, src, len, flag)
+ char *dst;
+ const char *src;
+ size_t len;
+ int flag;
+{
+ char *extra;
+
+ MAKEEXTRALIST(flag, extra, "");
+ return (strsvisx(dst, src, len, flag, extra));
+}
+#endif
diff --git a/cmd-line-utils/libedit/vis.h b/cmd-line-utils/libedit/vis.h
new file mode 100644
index 00000000000..44f6fc7d785
--- /dev/null
+++ b/cmd-line-utils/libedit/vis.h
@@ -0,0 +1,92 @@
+/* $NetBSD: vis.h,v 1.15 2005/02/03 04:39:32 perry Exp $ */
+
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)vis.h 8.1 (Berkeley) 6/2/93
+ */
+
+#ifndef _VIS_H_
+#define _VIS_H_
+
+#include <config.h>
+
+/*
+ * to select alternate encoding format
+ */
+#define VIS_OCTAL 0x01 /* use octal \ddd format */
+#define VIS_CSTYLE 0x02 /* use \[nrft0..] where appropiate */
+
+/*
+ * to alter set of characters encoded (default is to encode all
+ * non-graphic except space, tab, and newline).
+ */
+#define VIS_SP 0x04 /* also encode space */
+#define VIS_TAB 0x08 /* also encode tab */
+#define VIS_NL 0x10 /* also encode newline */
+#define VIS_WHITE (VIS_SP | VIS_TAB | VIS_NL)
+#define VIS_SAFE 0x20 /* only encode "unsafe" characters */
+
+/*
+ * other
+ */
+#define VIS_NOSLASH 0x40 /* inhibit printing '\' */
+#define VIS_HTTPSTYLE 0x80 /* http-style escape % HEX HEX */
+
+/*
+ * unvis return codes
+ */
+#define UNVIS_VALID 1 /* character valid */
+#define UNVIS_VALIDPUSH 2 /* character valid, push back passed char */
+#define UNVIS_NOCHAR 3 /* valid sequence, no character produced */
+#define UNVIS_SYNBAD -1 /* unrecognized escape sequence */
+#define UNVIS_ERROR -2 /* decoder in unknown state (unrecoverable) */
+
+/*
+ * unvis flags
+ */
+#define UNVIS_END 1 /* no more characters */
+
+__BEGIN_DECLS
+char *vis(char *, int, int, int);
+char *svis(char *, int, int, int, const char *);
+int strvis(char *, const char *, int);
+int strsvis(char *, const char *, int, const char *);
+int strvisx(char *, const char *, size_t, int);
+int strsvisx(char *, const char *, size_t, int, const char *);
+int strunvis(char *, const char *);
+int strunvisx(char *, const char *, int);
+#ifdef __LIBC12_SOURCE__
+int unvis(char *, int, int *, int);
+int __unvis13(char *, int, int *, int);
+#else
+int unvis(char *, int, int *, int);
+#endif
+__END_DECLS
+
+#endif /* !_VIS_H_ */
diff --git a/configure.in b/configure.in
index 87f7033309e..c9143d21a0f 100644
--- a/configure.in
+++ b/configure.in
@@ -1795,6 +1795,8 @@ AC_C_BIGENDIAN
MYSQL_TYPE_ACCEPT
#---END:
+# Figure out what type of struct rlimit to use with setrlimit
+MYSQL_TYPE_STRUCT_RLIMIT
# Find where the stack goes
MYSQL_STACK_DIRECTION
# We want to skip alloca on irix unconditionally. It may work on some version..
diff --git a/innobase/dict/dict0dict.c b/innobase/dict/dict0dict.c
index bbc47fe9c2b..b0327f77fd3 100644
--- a/innobase/dict/dict0dict.c
+++ b/innobase/dict/dict0dict.c
@@ -197,7 +197,17 @@ FILE* dict_foreign_err_file = NULL;
mutex_t dict_foreign_err_mutex; /* mutex protecting the foreign
and unique error buffers */
-
+/**********************************************************************
+Makes all characters in a NUL-terminated UTF-8 string lower case. */
+
+void
+dict_casedn_str(
+/*============*/
+ char* a) /* in/out: string to put in lower case */
+{
+ innobase_casedn_str(a);
+}
+
/************************************************************************
Checks if the database name in two table names is the same. */
diff --git a/innobase/fil/fil0fil.c b/innobase/fil/fil0fil.c
index 773bd709fb7..9d5def718a6 100644
--- a/innobase/fil/fil0fil.c
+++ b/innobase/fil/fil0fil.c
@@ -25,6 +25,7 @@ Created 10/25/1995 Heikki Tuuri
#include "srv0start.h"
#include "mtr0mtr.h"
#include "mtr0log.h"
+#include "dict0dict.h"
/*
@@ -2732,7 +2733,15 @@ fil_load_single_table_tablespace(
sprintf(filepath, "%s/%s/%s", fil_path_to_mysql_datadir, dbname,
filename);
srv_normalize_path_for_win(filepath);
+#ifdef __WIN__
+ /* If lower_case_table_names is 0 or 2, then MySQL allows database
+ directory names with upper case letters. On Windows, all table and
+ database names in InnoDB are internally always in lower case. Put the
+ file path to lower case, so that we are consistent with InnoDB's
+ internal data dictionary. */
+ dict_casedn_str(filepath);
+#endif
file = os_file_create_simple_no_error_handling(filepath, OS_FILE_OPEN,
OS_FILE_READ_ONLY, &success);
if (!success) {
diff --git a/innobase/include/dict0dict.h b/innobase/include/dict0dict.h
index 745a776bda1..3333385ec56 100644
--- a/innobase/include/dict0dict.h
+++ b/innobase/include/dict0dict.h
@@ -26,6 +26,13 @@ Created 1/8/1996 Heikki Tuuri
#include "ut0byte.h"
#include "trx0types.h"
+/**********************************************************************
+Makes all characters in a NUL-terminated UTF-8 string lower case. */
+
+void
+dict_casedn_str(
+/*============*/
+ char* a); /* in/out: string to put in lower case */
/************************************************************************
Get the database name length in a table name. */
diff --git a/mysql-test/r/archive.result b/mysql-test/r/archive.result
index 4adb8a5410e..993fe7e4213 100644
--- a/mysql-test/r/archive.result
+++ b/mysql-test/r/archive.result
@@ -2601,4 +2601,18 @@ auto fld1 companynr fld3 fld4 fld5 fld6
2 011401 37 breaking dreaded Steinberg W
3 011402 37 Romans scholastics jarring
4 011403 37 intercepted audiology tinily
-drop table t1, t2;
+create table t3 engine=archive select * from t2;
+select * from t3 where fld3='bonfire';
+auto fld1 companynr fld3 fld4 fld5 fld6
+1191 068504 00 bonfire corresponds positively
+select count(*) from t3;
+count(*)
+1203
+rename table t3 to t4;
+select * from t4 where fld3='bonfire';
+auto fld1 companynr fld3 fld4 fld5 fld6
+1191 068504 00 bonfire corresponds positively
+select count(*) from t4;
+count(*)
+1203
+drop table t1, t2, t4;
diff --git a/mysql-test/r/blackhole.result b/mysql-test/r/blackhole.result
index 20018dcb089..4b779094376 100644
--- a/mysql-test/r/blackhole.result
+++ b/mysql-test/r/blackhole.result
@@ -83,4 +83,43 @@ Full-text indexes are called collections
Only MyISAM tables support collections
select * from t1 where MATCH(a,b) AGAINST ("only");
a b
-drop table if exists t1,t2;
+reset master;
+drop table t1,t2;
+create table t1 (a int) engine=blackhole;
+delete from t1 where a=10;
+update t1 set a=11 where a=15;
+insert into t1 values(1);
+insert ignore into t1 values(1);
+replace into t1 values(100);
+create table t2 (a varchar(200)) engine=blackhole;
+load data infile '../../std_data/words.dat' into table t2;
+alter table t1 add b int;
+alter table t1 drop b;
+create table t3 like t1;
+insert into t1 select * from t3;
+replace into t1 select * from t3;
+select * from t1;
+a
+select * from t2;
+a
+select * from t3;
+a
+show binlog events;
+Log_name Pos Event_type Server_id Orig_log_pos Info
+master-bin.000001 # Start 1 # Server ver: VERSION, Binlog ver: 3
+master-bin.000001 # Query 1 # use `test`; drop table t1,t2
+master-bin.000001 # Query 1 # use `test`; create table t1 (a int) engine=blackhole
+master-bin.000001 # Query 1 # use `test`; delete from t1 where a=10
+master-bin.000001 # Query 1 # use `test`; update t1 set a=11 where a=15
+master-bin.000001 # Query 1 # use `test`; insert into t1 values(1)
+master-bin.000001 # Query 1 # use `test`; insert ignore into t1 values(1)
+master-bin.000001 # Query 1 # use `test`; replace into t1 values(100)
+master-bin.000001 # Query 1 # use `test`; create table t2 (a varchar(200)) engine=blackhole
+master-bin.000001 # Create_file 1 # db=test;table=t2;file_id=1;block_len=581
+master-bin.000001 # Exec_load 1 # ;file_id=1
+master-bin.000001 # Query 1 # use `test`; alter table t1 add b int
+master-bin.000001 # Query 1 # use `test`; alter table t1 drop b
+master-bin.000001 # Query 1 # use `test`; create table t3 like t1
+master-bin.000001 # Query 1 # use `test`; insert into t1 select * from t3
+master-bin.000001 # Query 1 # use `test`; replace into t1 select * from t3
+drop table t1,t2,t3;
diff --git a/mysql-test/t/archive.test b/mysql-test/t/archive.test
index ee78b53f9c8..b9e392870dc 100644
--- a/mysql-test/t/archive.test
+++ b/mysql-test/t/archive.test
@@ -1299,4 +1299,15 @@ INSERT INTO t2 VALUES (4,011403,37,'intercepted','audiology','tinily','');
SELECT * FROM t2;
OPTIMIZE TABLE t2;
SELECT * FROM t2;
-drop table t1, t2;
+
+#
+# Test rename of table
+#
+create table t3 engine=archive select * from t2;
+select * from t3 where fld3='bonfire';
+select count(*) from t3;
+rename table t3 to t4;
+select * from t4 where fld3='bonfire';
+select count(*) from t4;
+
+drop table t1, t2, t4;
diff --git a/mysql-test/t/blackhole.test b/mysql-test/t/blackhole.test
index 052574d6921..d1fcfc971a9 100644
--- a/mysql-test/t/blackhole.test
+++ b/mysql-test/t/blackhole.test
@@ -96,4 +96,32 @@ select * from t1 where MATCH(a,b) AGAINST ("indexes");
select * from t1 where MATCH(a,b) AGAINST ("indexes collections");
select * from t1 where MATCH(a,b) AGAINST ("only");
-drop table if exists t1,t2;
+# Test that every DML (except SELECT) and DDL gets into binlog
+# so that blackhole can be used as "binlog propagator"
+
+reset master;
+drop table t1,t2;
+create table t1 (a int) engine=blackhole;
+delete from t1 where a=10;
+update t1 set a=11 where a=15;
+insert into t1 values(1);
+insert ignore into t1 values(1);
+replace into t1 values(100);
+create table t2 (a varchar(200)) engine=blackhole;
+load data infile '../../std_data/words.dat' into table t2;
+alter table t1 add b int;
+alter table t1 drop b;
+create table t3 like t1;
+insert into t1 select * from t3;
+replace into t1 select * from t3;
+# Just to verify
+select * from t1;
+select * from t2;
+select * from t3;
+
+let $VERSION=`select version()`;
+--replace_result $VERSION VERSION
+--replace_column 2 # 5 #
+show binlog events;
+
+drop table t1,t2,t3;
diff --git a/ndb/include/kernel/signaldata/BackupImpl.hpp b/ndb/include/kernel/signaldata/BackupImpl.hpp
index 2ac91570aad..2032e2347b5 100644
--- a/ndb/include/kernel/signaldata/BackupImpl.hpp
+++ b/ndb/include/kernel/signaldata/BackupImpl.hpp
@@ -75,7 +75,7 @@ class DefineBackupRef {
friend bool printDEFINE_BACKUP_REF(FILE *, const Uint32 *, Uint32, Uint16);
public:
- STATIC_CONST( SignalLength = 3 );
+ STATIC_CONST( SignalLength = 4 );
enum ErrorCode {
Undefined = 1340,
@@ -92,6 +92,7 @@ private:
Uint32 backupId;
Uint32 backupPtr;
Uint32 errorCode;
+ Uint32 nodeId;
};
class DefineBackupConf {
@@ -158,7 +159,7 @@ class StartBackupRef {
friend bool printSTART_BACKUP_REF(FILE *, const Uint32 *, Uint32, Uint16);
public:
- STATIC_CONST( SignalLength = 4 );
+ STATIC_CONST( SignalLength = 5 );
enum ErrorCode {
FailedToAllocateTriggerRecord = 1
@@ -168,6 +169,7 @@ private:
Uint32 backupPtr;
Uint32 signalNo;
Uint32 errorCode;
+ Uint32 nodeId;
};
class StartBackupConf {
@@ -232,9 +234,8 @@ public:
private:
Uint32 backupId;
Uint32 backupPtr;
- Uint32 tableId;
- Uint32 fragmentNo;
Uint32 errorCode;
+ Uint32 nodeId;
};
class BackupFragmentConf {
@@ -296,12 +297,13 @@ class StopBackupRef {
friend bool printSTOP_BACKUP_REF(FILE *, const Uint32 *, Uint32, Uint16);
public:
- STATIC_CONST( SignalLength = 3 );
+ STATIC_CONST( SignalLength = 4 );
private:
Uint32 backupId;
Uint32 backupPtr;
Uint32 errorCode;
+ Uint32 nodeId;
};
class StopBackupConf {
diff --git a/ndb/include/kernel/signaldata/BackupSignalData.hpp b/ndb/include/kernel/signaldata/BackupSignalData.hpp
index fb018026a49..b38dd8d14b2 100644
--- a/ndb/include/kernel/signaldata/BackupSignalData.hpp
+++ b/ndb/include/kernel/signaldata/BackupSignalData.hpp
@@ -240,6 +240,9 @@ public:
FileOrScanError = 1325, // slave -> coordinator
BackupFailureDueToNodeFail = 1326, // slave -> slave
OkToClean = 1327 // master -> slave
+
+ ,AbortScan = 1328
+ ,IncompatibleVersions = 1329
};
private:
Uint32 requestType;
diff --git a/ndb/src/common/debugger/signaldata/BackupImpl.cpp b/ndb/src/common/debugger/signaldata/BackupImpl.cpp
index bdc34d614cf..e9b0188d93b 100644
--- a/ndb/src/common/debugger/signaldata/BackupImpl.cpp
+++ b/ndb/src/common/debugger/signaldata/BackupImpl.cpp
@@ -90,10 +90,8 @@ printBACKUP_FRAGMENT_REQ(FILE * out, const Uint32 * data, Uint32 l, Uint16 bno){
bool
printBACKUP_FRAGMENT_REF(FILE * out, const Uint32 * data, Uint32 l, Uint16 bno){
BackupFragmentRef* sig = (BackupFragmentRef*)data;
- fprintf(out, " backupPtr: %d backupId: %d\n",
- sig->backupPtr, sig->backupId);
- fprintf(out, " tableId: %d fragmentNo: %d errorCode: %d\n",
- sig->tableId, sig->fragmentNo, sig->errorCode);
+ fprintf(out, " backupPtr: %d backupId: %d nodeId: %d errorCode: %d\n",
+ sig->backupPtr, sig->backupId, sig->nodeId, sig->errorCode);
return true;
}
diff --git a/ndb/src/kernel/blocks/backup/Backup.cpp b/ndb/src/kernel/blocks/backup/Backup.cpp
index 2e62979ce8e..3ef73beb8d2 100644
--- a/ndb/src/kernel/blocks/backup/Backup.cpp
+++ b/ndb/src/kernel/blocks/backup/Backup.cpp
@@ -67,31 +67,6 @@ static const Uint32 BACKUP_SEQUENCE = 0x1F000000;
//#define DEBUG_ABORT
-//---------------------------------------------------------
-// Ignore this since a completed abort could have preceded
-// this message.
-//---------------------------------------------------------
-#define slaveAbortCheck() \
-if ((ptr.p->backupId != backupId) || \
- (ptr.p->slaveState.getState() == ABORTING)) { \
- jam(); \
- return; \
-}
-
-#define masterAbortCheck() \
-if ((ptr.p->backupId != backupId) || \
- (ptr.p->masterData.state.getState() == ABORTING)) { \
- jam(); \
- return; \
-}
-
-#define defineSlaveAbortCheck() \
- if (ptr.p->slaveState.getState() == ABORTING) { \
- jam(); \
- closeFiles(signal, ptr); \
- return; \
- }
-
static Uint32 g_TypeOfStart = NodeState::ST_ILLEGAL_TYPE;
void
@@ -221,12 +196,7 @@ Backup::execCONTINUEB(Signal* signal)
jam();
BackupRecordPtr ptr;
c_backupPool.getPtr(ptr, Tdata1);
-
- if (ptr.p->slaveState.getState() == ABORTING) {
- jam();
- closeFiles(signal, ptr);
- return;
- }//if
+
BackupFilePtr filePtr;
ptr.p->files.getPtr(filePtr, ptr.p->ctlFilePtr);
FsBuffer & buf = filePtr.p->operation.dataBuffer;
@@ -324,13 +294,7 @@ Backup::execDUMP_STATE_ORD(Signal* signal)
for(c_backups.first(ptr); ptr.i != RNIL; c_backups.next(ptr)){
infoEvent("BackupRecord %d: BackupId: %d MasterRef: %x ClientRef: %x",
ptr.i, ptr.p->backupId, ptr.p->masterRef, ptr.p->clientRef);
- if(ptr.p->masterRef == reference()){
- infoEvent(" MasterState: %d State: %d",
- ptr.p->masterData.state.getState(),
- ptr.p->slaveState.getState());
- } else {
- infoEvent(" State: %d", ptr.p->slaveState.getState());
- }
+ infoEvent(" State: %d", ptr.p->slaveState.getState());
BackupFilePtr filePtr;
for(ptr.p->files.first(filePtr); filePtr.i != RNIL;
ptr.p->files.next(filePtr)){
@@ -338,7 +302,7 @@ Backup::execDUMP_STATE_ORD(Signal* signal)
infoEvent(" file %d: type: %d open: %d running: %d done: %d scan: %d",
filePtr.i, filePtr.p->fileType, filePtr.p->fileOpened,
filePtr.p->fileRunning,
- filePtr.p->fileDone, filePtr.p->scanRunning);
+ filePtr.p->fileClosing, filePtr.p->scanRunning);
}
}
}
@@ -356,6 +320,17 @@ Backup::execDUMP_STATE_ORD(Signal* signal)
infoEvent("PagePool: %d",
c_pagePool.getSize());
+
+ if(signal->getLength() == 2 && signal->theData[1] == 2424)
+ {
+ ndbrequire(c_tablePool.getSize() == c_tablePool.getNoOfFree());
+ ndbrequire(c_attributePool.getSize() == c_attributePool.getNoOfFree());
+ ndbrequire(c_backupPool.getSize() == c_backupPool.getNoOfFree());
+ ndbrequire(c_backupFilePool.getSize() == c_backupFilePool.getNoOfFree());
+ ndbrequire(c_pagePool.getSize() == c_pagePool.getNoOfFree());
+ ndbrequire(c_fragmentPool.getSize() == c_fragmentPool.getNoOfFree());
+ ndbrequire(c_triggerPool.getSize() == c_triggerPool.getNoOfFree());
+ }
}
}
@@ -512,27 +487,6 @@ const char* triggerNameFormat[] = {
};
const Backup::State
-Backup::validMasterTransitions[] = {
- INITIAL, DEFINING,
- DEFINING, DEFINED,
- DEFINED, STARTED,
- STARTED, SCANNING,
- SCANNING, STOPPING,
- STOPPING, INITIAL,
-
- DEFINING, ABORTING,
- DEFINED, ABORTING,
- STARTED, ABORTING,
- SCANNING, ABORTING,
- STOPPING, ABORTING,
- ABORTING, ABORTING,
-
- DEFINING, INITIAL,
- ABORTING, INITIAL,
- INITIAL, INITIAL
-};
-
-const Backup::State
Backup::validSlaveTransitions[] = {
INITIAL, DEFINING,
DEFINING, DEFINED,
@@ -561,10 +515,6 @@ const Uint32
Backup::validSlaveTransitionsCount =
sizeof(Backup::validSlaveTransitions) / sizeof(Backup::State);
-const Uint32
-Backup::validMasterTransitionsCount =
-sizeof(Backup::validMasterTransitions) / sizeof(Backup::State);
-
void
Backup::CompoundState::setState(State newState){
bool found = false;
@@ -578,7 +528,8 @@ Backup::CompoundState::setState(State newState){
break;
}
}
- ndbrequire(found);
+
+ //ndbrequire(found);
if (newState == INITIAL)
abortState = INITIAL;
@@ -647,8 +598,7 @@ Backup::execNODE_FAILREP(Signal* signal)
Uint32 theFailedNodes[NodeBitmask::Size];
for (Uint32 i = 0; i < NodeBitmask::Size; i++)
theFailedNodes[i] = rep->theNodes[i];
-
-// NodeId old_master_node_id = getMasterNodeId();
+
c_masterNodeId = new_master_node_id;
NodePtr nodePtr;
@@ -686,15 +636,24 @@ Backup::execNODE_FAILREP(Signal* signal)
}
bool
-Backup::verifyNodesAlive(const NdbNodeBitmask& aNodeBitMask)
+Backup::verifyNodesAlive(BackupRecordPtr ptr,
+ const NdbNodeBitmask& aNodeBitMask)
{
+ Uint32 version = getNodeInfo(getOwnNodeId()).m_version;
for (Uint32 i = 0; i < MAX_NDB_NODES; i++) {
jam();
if(aNodeBitMask.get(i)) {
if(!c_aliveNodes.get(i)){
jam();
+ ptr.p->setErrorCode(AbortBackupOrd::BackupFailureDueToNodeFail);
return false;
}//if
+ if(getNodeInfo(i).m_version != version)
+ {
+ jam();
+ ptr.p->setErrorCode(AbortBackupOrd::IncompatibleVersions);
+ return false;
+ }
}//if
}//for
return true;
@@ -706,9 +665,9 @@ Backup::checkNodeFail(Signal* signal,
NodeId newCoord,
Uint32 theFailedNodes[NodeBitmask::Size])
{
- ndbrequire( ptr.p->nodes.get(newCoord)); /* just to make sure newCoord
- * is part of the backup
- */
+ NdbNodeBitmask mask;
+ mask.assign(2, theFailedNodes);
+
/* Update ptr.p->nodes to be up to date with current alive nodes
*/
NodePtr nodePtr;
@@ -730,26 +689,42 @@ Backup::checkNodeFail(Signal* signal,
return; // failed node is not part of backup process, safe to continue
}
- bool doMasterTakeover = false;
- if(NodeBitmask::get(theFailedNodes, refToNode(ptr.p->masterRef))){
- jam();
- doMasterTakeover = true;
- };
-
- if (newCoord == getOwnNodeId()){
- jam();
- if (doMasterTakeover) {
- /**
- * I'm new master
- */
- CRASH_INSERTION((10002));
-#ifdef DEBUG_ABORT
- ndbout_c("**** Master Takeover: Node failed: Master id = %u",
- refToNode(ptr.p->masterRef));
-#endif
- masterTakeOver(signal, ptr);
+ if(mask.get(refToNode(ptr.p->masterRef)))
+ {
+ /**
+ * Master died...abort
+ */
+ ptr.p->masterRef = reference();
+ ptr.p->nodes.clear();
+ ptr.p->nodes.set(getOwnNodeId());
+ ptr.p->setErrorCode(AbortBackupOrd::BackupFailureDueToNodeFail);
+ switch(ptr.p->m_gsn){
+ case GSN_DEFINE_BACKUP_REQ:
+ case GSN_START_BACKUP_REQ:
+ case GSN_BACKUP_FRAGMENT_REQ:
+ case GSN_STOP_BACKUP_REQ:
+ // I'm currently processing...reply to self and abort...
+ ptr.p->masterData.gsn = ptr.p->m_gsn;
+ ptr.p->masterData.sendCounter = ptr.p->nodes;
return;
- }//if
+ case GSN_DEFINE_BACKUP_REF:
+ case GSN_DEFINE_BACKUP_CONF:
+ case GSN_START_BACKUP_REF:
+ case GSN_START_BACKUP_CONF:
+ case GSN_BACKUP_FRAGMENT_REF:
+ case GSN_BACKUP_FRAGMENT_CONF:
+ case GSN_STOP_BACKUP_REF:
+ case GSN_STOP_BACKUP_CONF:
+ ptr.p->masterData.gsn = GSN_DEFINE_BACKUP_REQ;
+ masterAbort(signal, ptr);
+ return;
+ case GSN_ABORT_BACKUP_ORD:
+ // Already aborting
+ return;
+ }
+ }
+ else if (newCoord == getOwnNodeId())
+ {
/**
* I'm master for this backup
*/
@@ -759,62 +734,82 @@ Backup::checkNodeFail(Signal* signal,
ndbout_c("**** Master: Node failed: Master id = %u",
refToNode(ptr.p->masterRef));
#endif
- masterAbort(signal, ptr, false);
- return;
- }//if
- /**
- * If there's a new master, (it's not me)
- * but remember who it is
- */
- ptr.p->masterRef = calcBackupBlockRef(newCoord);
+ Uint32 gsn, len, pos;
+ ptr.p->nodes.bitANDC(mask);
+ switch(ptr.p->masterData.gsn){
+ case GSN_DEFINE_BACKUP_REQ:
+ {
+ DefineBackupRef * ref = (DefineBackupRef*)signal->getDataPtr();
+ ref->backupPtr = ptr.i;
+ ref->backupId = ptr.p->backupId;
+ ref->errorCode = AbortBackupOrd::BackupFailureDueToNodeFail;
+ gsn= GSN_DEFINE_BACKUP_REF;
+ len= DefineBackupRef::SignalLength;
+ pos= &ref->nodeId - signal->getDataPtr();
+ break;
+ }
+ case GSN_START_BACKUP_REQ:
+ {
+ StartBackupRef * ref = (StartBackupRef*)signal->getDataPtr();
+ ref->backupPtr = ptr.i;
+ ref->backupId = ptr.p->backupId;
+ ref->errorCode = AbortBackupOrd::BackupFailureDueToNodeFail;
+ ref->signalNo = ptr.p->masterData.startBackup.signalNo;
+ gsn= GSN_START_BACKUP_REF;
+ len= StartBackupRef::SignalLength;
+ pos= &ref->nodeId - signal->getDataPtr();
+ break;
+ }
+ case GSN_BACKUP_FRAGMENT_REQ:
+ {
+ BackupFragmentRef * ref = (BackupFragmentRef*)signal->getDataPtr();
+ ref->backupPtr = ptr.i;
+ ref->backupId = ptr.p->backupId;
+ ref->errorCode = AbortBackupOrd::BackupFailureDueToNodeFail;
+ gsn= GSN_BACKUP_FRAGMENT_REF;
+ len= BackupFragmentRef::SignalLength;
+ pos= &ref->nodeId - signal->getDataPtr();
+ break;
+ }
+ case GSN_STOP_BACKUP_REQ:
+ {
+ StopBackupRef * ref = (StopBackupRef*)signal->getDataPtr();
+ ref->backupPtr = ptr.i;
+ ref->backupId = ptr.p->backupId;
+ ref->errorCode = AbortBackupOrd::BackupFailureDueToNodeFail;
+ gsn= GSN_STOP_BACKUP_REF;
+ len= StopBackupRef::SignalLength;
+ pos= &ref->nodeId - signal->getDataPtr();
+ break;
+ }
+ case GSN_CREATE_TRIG_REQ:
+ case GSN_ALTER_TRIG_REQ:
+ case GSN_WAIT_GCP_REQ:
+ case GSN_UTIL_SEQUENCE_REQ:
+ case GSN_UTIL_LOCK_REQ:
+ case GSN_DROP_TRIG_REQ:
+ return;
+ }
+
+ for(Uint32 i = 0; (i = mask.find(i+1)) != NdbNodeBitmask::NotFound; )
+ {
+ signal->theData[pos] = i;
+ sendSignal(reference(), gsn, signal, len, JBB);
#ifdef DEBUG_ABORT
- ndbout_c("**** Slave: Node failed: Master id = %u",
- refToNode(ptr.p->masterRef));
+ ndbout_c("sending %d to self from %d", gsn, i);
#endif
+ }
+ return;
+ }//if
+
/**
* I abort myself as slave if not master
*/
CRASH_INSERTION((10021));
- // slaveAbort(signal, ptr);
}
void
-Backup::masterTakeOver(Signal* signal, BackupRecordPtr ptr)
-{
- ptr.p->masterRef = reference();
- ptr.p->masterData.gsn = MAX_GSN + 1;
-
- switch(ptr.p->slaveState.getState()){
- case INITIAL:
- jam();
- ptr.p->masterData.state.forceState(INITIAL);
- break;
- case ABORTING:
- jam();
- case DEFINING:
- jam();
- case DEFINED:
- jam();
- case STARTED:
- jam();
- case SCANNING:
- jam();
- ptr.p->masterData.state.forceState(STARTED);
- break;
- case STOPPING:
- jam();
- case CLEANING:
- jam();
- ptr.p->masterData.state.forceState(STOPPING);
- break;
- default:
- ndbrequire(false);
- }
- masterAbort(signal, ptr, false);
-}
-
-void
Backup::execINCL_NODEREQ(Signal* signal)
{
jamEntry();
@@ -895,8 +890,8 @@ Backup::execBACKUP_REQ(Signal* signal)
ndbrequire(ptr.p->pages.empty());
ndbrequire(ptr.p->tables.isEmpty());
- ptr.p->masterData.state.forceState(INITIAL);
- ptr.p->masterData.state.setState(DEFINING);
+ ptr.p->m_gsn = 0;
+ ptr.p->errorCode = 0;
ptr.p->clientRef = senderRef;
ptr.p->clientData = senderData;
ptr.p->masterRef = reference();
@@ -905,6 +900,7 @@ Backup::execBACKUP_REQ(Signal* signal)
ptr.p->backupKey[0] = 0;
ptr.p->backupKey[1] = 0;
ptr.p->backupDataLen = 0;
+ ptr.p->masterData.errorCode = 0;
ptr.p->masterData.dropTrig.tableId = RNIL;
ptr.p->masterData.alterTrig.tableId = RNIL;
@@ -928,7 +924,6 @@ Backup::execUTIL_SEQUENCE_REF(Signal* signal)
ndbrequire(ptr.i == RNIL);
c_backupPool.getPtr(ptr);
ndbrequire(ptr.p->masterData.gsn == GSN_UTIL_SEQUENCE_REQ);
- ptr.p->masterData.gsn = 0;
sendBackupRef(signal, ptr, BackupRef::SequenceFailure);
}//execUTIL_SEQUENCE_REF()
@@ -938,8 +933,7 @@ Backup::sendBackupRef(Signal* signal, BackupRecordPtr ptr, Uint32 errorCode)
{
jam();
sendBackupRef(ptr.p->clientRef, signal, ptr.p->clientData, errorCode);
- // ptr.p->masterData.state.setState(INITIAL);
- cleanupSlaveResources(ptr);
+ cleanup(signal, ptr);
}
void
@@ -968,7 +962,8 @@ Backup::execUTIL_SEQUENCE_CONF(Signal* signal)
UtilSequenceConf * conf = (UtilSequenceConf*)signal->getDataPtr();
- if(conf->requestType == UtilSequenceReq::Create) {
+ if(conf->requestType == UtilSequenceReq::Create)
+ {
jam();
sendSTTORRY(signal); // At startup in NDB
return;
@@ -979,18 +974,20 @@ Backup::execUTIL_SEQUENCE_CONF(Signal* signal)
c_backupPool.getPtr(ptr);
ndbrequire(ptr.p->masterData.gsn == GSN_UTIL_SEQUENCE_REQ);
- ptr.p->masterData.gsn = 0;
- if (ptr.p->masterData.state.getState() == ABORTING) {
+
+ if (ptr.p->checkError())
+ {
jam();
sendBackupRef(signal, ptr, ptr.p->errorCode);
return;
}//if
- if (ERROR_INSERTED(10023)) {
- ptr.p->masterData.state.setState(ABORTING);
+
+ if (ERROR_INSERTED(10023))
+ {
sendBackupRef(signal, ptr, 323);
return;
}//if
- ndbrequire(ptr.p->masterData.state.getState() == DEFINING);
+
{
Uint64 backupId;
@@ -1018,7 +1015,6 @@ Backup::defineBackupMutex_locked(Signal* signal, Uint32 ptrI, Uint32 retVal){
c_backupPool.getPtr(ptr);
ndbrequire(ptr.p->masterData.gsn == GSN_UTIL_LOCK_REQ);
- ptr.p->masterData.gsn = 0;
ptr.p->masterData.gsn = GSN_UTIL_LOCK_REQ;
Mutex mutex(signal, c_mutexMgr, ptr.p->masterData.m_dictCommitTableMutex);
@@ -1040,14 +1036,13 @@ Backup::dictCommitTableMutex_locked(Signal* signal, Uint32 ptrI,Uint32 retVal)
c_backupPool.getPtr(ptr);
ndbrequire(ptr.p->masterData.gsn == GSN_UTIL_LOCK_REQ);
- ptr.p->masterData.gsn = 0;
if (ERROR_INSERTED(10031)) {
- ptr.p->masterData.state.setState(ABORTING);
ptr.p->setErrorCode(331);
}//if
- if (ptr.p->masterData.state.getState() == ABORTING) {
+ if (ptr.p->checkError())
+ {
jam();
/**
@@ -1062,13 +1057,11 @@ Backup::dictCommitTableMutex_locked(Signal* signal, Uint32 ptrI,Uint32 retVal)
Mutex mutex2(signal, c_mutexMgr, ptr.p->masterData.m_defineBackupMutex);
jam();
mutex2.unlock(); // ignore response
-
+
sendBackupRef(signal, ptr, ptr.p->errorCode);
return;
}//if
- ndbrequire(ptr.p->masterData.state.getState() == DEFINING);
-
sendDefineBackupReq(signal, ptr);
}
@@ -1078,33 +1071,6 @@ Backup::dictCommitTableMutex_locked(Signal* signal, Uint32 ptrI,Uint32 retVal)
*
*****************************************************************************/
-void
-Backup::sendSignalAllWait(BackupRecordPtr ptr, Uint32 gsn, Signal *signal,
- Uint32 signalLength, bool executeDirect)
-{
- jam();
- ptr.p->masterData.gsn = gsn;
- ptr.p->masterData.sendCounter.clearWaitingFor();
- NodePtr node;
- for(c_nodes.first(node); node.i != RNIL; c_nodes.next(node)){
- jam();
- const Uint32 nodeId = node.p->nodeId;
- if(node.p->alive && ptr.p->nodes.get(nodeId)){
- jam();
-
- ptr.p->masterData.sendCounter.setWaitingFor(nodeId);
-
- const BlockReference ref = numberToRef(BACKUP, nodeId);
- if (!executeDirect || ref != reference()) {
- sendSignal(ref, gsn, signal, signalLength, JBB);
- }//if
- }//if
- }//for
- if (executeDirect) {
- EXECUTE_DIRECT(BACKUP, gsn, signal, signalLength);
- }
-}
-
bool
Backup::haveAllSignals(BackupRecordPtr ptr, Uint32 gsn, Uint32 nodeId)
{
@@ -1114,10 +1080,6 @@ Backup::haveAllSignals(BackupRecordPtr ptr, Uint32 gsn, Uint32 nodeId)
ndbrequire(ptr.p->masterData.sendCounter.isWaitingFor(nodeId));
ptr.p->masterData.sendCounter.clearWaitingFor(nodeId);
-
- if (ptr.p->masterData.sendCounter.done())
- ptr.p->masterData.gsn = 0;
-
return ptr.p->masterData.sendCounter.done();
}
@@ -1138,11 +1100,12 @@ Backup::sendDefineBackupReq(Signal *signal, BackupRecordPtr ptr)
req->nodes = ptr.p->nodes;
req->backupDataLen = ptr.p->backupDataLen;
- ptr.p->masterData.errorCode = 0;
- ptr.p->okToCleanMaster = false; // master must wait with cleaning to last
- sendSignalAllWait(ptr, GSN_DEFINE_BACKUP_REQ, signal,
- DefineBackupReq::SignalLength,
- true /* do execute direct on oneself */);
+ ptr.p->masterData.gsn = GSN_DEFINE_BACKUP_REQ;
+ ptr.p->masterData.sendCounter = ptr.p->nodes;
+ NodeReceiverGroup rg(BACKUP, ptr.p->nodes);
+ sendSignal(rg, GSN_DEFINE_BACKUP_REQ, signal,
+ DefineBackupReq::SignalLength, JBB);
+
/**
* Now send backup data
*/
@@ -1167,17 +1130,15 @@ Backup::execDEFINE_BACKUP_REF(Signal* signal)
jamEntry();
DefineBackupRef* ref = (DefineBackupRef*)signal->getDataPtr();
-
+
const Uint32 ptrI = ref->backupPtr;
- const Uint32 backupId = ref->backupId;
- const Uint32 nodeId = refToNode(signal->senderBlockRef());
-
+ //const Uint32 backupId = ref->backupId;
+ const Uint32 nodeId = ref->nodeId;
+
BackupRecordPtr ptr;
c_backupPool.getPtr(ptr, ptrI);
-
- masterAbortCheck(); // macro will do return if ABORTING
- ptr.p->masterData.errorCode = ref->errorCode;
+ ptr.p->setErrorCode(ref->errorCode);
defineBackupReply(signal, ptr, nodeId);
}
@@ -1188,17 +1149,16 @@ Backup::execDEFINE_BACKUP_CONF(Signal* signal)
DefineBackupConf* conf = (DefineBackupConf*)signal->getDataPtr();
const Uint32 ptrI = conf->backupPtr;
- const Uint32 backupId = conf->backupId;
+ //const Uint32 backupId = conf->backupId;
const Uint32 nodeId = refToNode(signal->senderBlockRef());
BackupRecordPtr ptr;
c_backupPool.getPtr(ptr, ptrI);
- masterAbortCheck(); // macro will do return if ABORTING
-
- if (ERROR_INSERTED(10024)) {
- ptr.p->masterData.errorCode = 324;
- }//if
+ if (ERROR_INSERTED(10024))
+ {
+ ptr.p->setErrorCode(324);
+ }
defineBackupReply(signal, ptr, nodeId);
}
@@ -1210,6 +1170,7 @@ Backup::defineBackupReply(Signal* signal, BackupRecordPtr ptr, Uint32 nodeId)
jam();
return;
}
+
/**
* Unlock mutexes
*/
@@ -1223,16 +1184,10 @@ Backup::defineBackupReply(Signal* signal, BackupRecordPtr ptr, Uint32 nodeId)
jam();
mutex2.unlock(); // ignore response
- if(ptr.p->errorCode) {
- jam();
- ptr.p->masterData.errorCode = ptr.p->errorCode;
- }
-
- if(ptr.p->masterData.errorCode){
+ if(ptr.p->checkError())
+ {
jam();
- ptr.p->setErrorCode(ptr.p->masterData.errorCode);
- sendAbortBackupOrd(signal, ptr, AbortBackupOrd::OkToClean);
- masterSendAbortBackup(signal, ptr);
+ masterAbort(signal, ptr);
return;
}
@@ -1252,7 +1207,6 @@ Backup::defineBackupReply(Signal* signal, BackupRecordPtr ptr, Uint32 nodeId)
ptr.p->nodes.copyto(NdbNodeBitmask::Size, signal->theData+3);
sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 3+NdbNodeBitmask::Size, JBB);
- ptr.p->masterData.state.setState(DEFINED);
/**
* Prepare Trig
*/
@@ -1286,7 +1240,6 @@ Backup::sendCreateTrig(Signal* signal,
{
CreateTrigReq * req =(CreateTrigReq *)signal->getDataPtrSend();
- ptr.p->errorCode = 0;
ptr.p->masterData.gsn = GSN_CREATE_TRIG_REQ;
ptr.p->masterData.sendCounter = 3;
ptr.p->masterData.createTrig.tableId = tabPtr.p->tableId;
@@ -1395,17 +1348,14 @@ Backup::createTrigReply(Signal* signal, BackupRecordPtr ptr)
return;
}//if
- ptr.p->masterData.gsn = 0;
+ if (ERROR_INSERTED(10025))
+ {
+ ptr.p->errorCode = 325;
+ }
if(ptr.p->checkError()) {
jam();
- masterAbort(signal, ptr, true);
- return;
- }//if
-
- if (ERROR_INSERTED(10025)) {
- ptr.p->errorCode = 325;
- masterAbort(signal, ptr, true);
+ masterAbort(signal, ptr);
return;
}//if
@@ -1425,10 +1375,7 @@ Backup::createTrigReply(Signal* signal, BackupRecordPtr ptr)
/**
* Finished with all tables, send StartBackupReq
*/
- ptr.p->masterData.state.setState(STARTED);
-
ptr.p->tables.first(tabPtr);
- ptr.p->errorCode = 0;
ptr.p->masterData.startBackup.signalNo = 0;
ptr.p->masterData.startBackup.noOfSignals =
(ptr.p->tables.noOfElements() + StartBackupReq::MaxTableTriggers - 1) /
@@ -1467,9 +1414,12 @@ Backup::sendStartBackup(Signal* signal, BackupRecordPtr ptr, TablePtr tabPtr)
}//for
req->noOfTableTriggers = i;
- sendSignalAllWait(ptr, GSN_START_BACKUP_REQ, signal,
- StartBackupReq::HeaderLength +
- (i * StartBackupReq::TableTriggerLength));
+ ptr.p->masterData.gsn = GSN_START_BACKUP_REQ;
+ ptr.p->masterData.sendCounter = ptr.p->nodes;
+ NodeReceiverGroup rg(BACKUP, ptr.p->nodes);
+ sendSignal(rg, GSN_START_BACKUP_REQ, signal,
+ StartBackupReq::HeaderLength +
+ (i * StartBackupReq::TableTriggerLength), JBB);
}
void
@@ -1479,15 +1429,13 @@ Backup::execSTART_BACKUP_REF(Signal* signal)
StartBackupRef* ref = (StartBackupRef*)signal->getDataPtr();
const Uint32 ptrI = ref->backupPtr;
- const Uint32 backupId = ref->backupId;
+ //const Uint32 backupId = ref->backupId;
const Uint32 signalNo = ref->signalNo;
- const Uint32 nodeId = refToNode(signal->senderBlockRef());
+ const Uint32 nodeId = ref->nodeId;
BackupRecordPtr ptr;
c_backupPool.getPtr(ptr, ptrI);
- masterAbortCheck(); // macro will do return if ABORTING
-
ptr.p->setErrorCode(ref->errorCode);
startBackupReply(signal, ptr, nodeId, signalNo);
}
@@ -1499,15 +1447,13 @@ Backup::execSTART_BACKUP_CONF(Signal* signal)
StartBackupConf* conf = (StartBackupConf*)signal->getDataPtr();
const Uint32 ptrI = conf->backupPtr;
- const Uint32 backupId = conf->backupId;
+ //const Uint32 backupId = conf->backupId;
const Uint32 signalNo = conf->signalNo;
const Uint32 nodeId = refToNode(signal->senderBlockRef());
BackupRecordPtr ptr;
c_backupPool.getPtr(ptr, ptrI);
- masterAbortCheck(); // macro will do return if ABORTING
-
startBackupReply(signal, ptr, nodeId, signalNo);
}
@@ -1524,17 +1470,16 @@ Backup::startBackupReply(Signal* signal, BackupRecordPtr ptr,
return;
}
+ if (ERROR_INSERTED(10026))
+ {
+ ptr.p->errorCode = 326;
+ }
+
if(ptr.p->checkError()){
jam();
- masterAbort(signal, ptr, true);
+ masterAbort(signal, ptr);
return;
}
-
- if (ERROR_INSERTED(10026)) {
- ptr.p->errorCode = 326;
- masterAbort(signal, ptr, true);
- return;
- }//if
TablePtr tabPtr;
c_tablePool.getPtr(tabPtr, ptr.p->masterData.startBackup.tablePtr);
@@ -1566,7 +1511,6 @@ Backup::sendAlterTrig(Signal* signal, BackupRecordPtr ptr)
{
AlterTrigReq * req =(AlterTrigReq *)signal->getDataPtrSend();
- ptr.p->errorCode = 0;
ptr.p->masterData.gsn = GSN_ALTER_TRIG_REQ;
ptr.p->masterData.sendCounter = 0;
@@ -1608,6 +1552,7 @@ Backup::sendAlterTrig(Signal* signal, BackupRecordPtr ptr)
return;
}//if
ptr.p->masterData.alterTrig.tableId = RNIL;
+
/**
* Finished with all tables
*/
@@ -1669,11 +1614,9 @@ Backup::alterTrigReply(Signal* signal, BackupRecordPtr ptr)
return;
}//if
- ptr.p->masterData.gsn = 0;
-
if(ptr.p->checkError()){
jam();
- masterAbort(signal, ptr, true);
+ masterAbort(signal, ptr);
return;
}//if
@@ -1719,11 +1662,10 @@ Backup::execWAIT_GCP_CONF(Signal* signal){
ndbrequire(ptr.p->masterRef == reference());
ndbrequire(ptr.p->masterData.gsn == GSN_WAIT_GCP_REQ);
- ptr.p->masterData.gsn = 0;
if(ptr.p->checkError()) {
jam();
- masterAbort(signal, ptr, true);
+ masterAbort(signal, ptr);
return;
}//if
@@ -1731,13 +1673,13 @@ Backup::execWAIT_GCP_CONF(Signal* signal){
jam();
CRASH_INSERTION((10008));
ptr.p->startGCP = gcp;
- ptr.p->masterData.state.setState(SCANNING);
+ ptr.p->masterData.sendCounter= 0;
+ ptr.p->masterData.gsn = GSN_BACKUP_FRAGMENT_REQ;
nextFragment(signal, ptr);
} else {
jam();
CRASH_INSERTION((10009));
ptr.p->stopGCP = gcp;
- ptr.p->masterData.state.setState(STOPPING);
sendDropTrig(signal, ptr); // regular dropping of triggers
}//if
}
@@ -1787,6 +1729,7 @@ Backup::nextFragment(Signal* signal, BackupRecordPtr ptr)
req->fragmentNo = i;
req->count = 0;
+ ptr.p->masterData.sendCounter++;
const BlockReference ref = numberToRef(BACKUP, nodeId);
sendSignal(ref, GSN_BACKUP_FRAGMENT_REQ, signal,
BackupFragmentReq::SignalLength, JBB);
@@ -1824,7 +1767,7 @@ Backup::execBACKUP_FRAGMENT_CONF(Signal* signal)
BackupFragmentConf * conf = (BackupFragmentConf*)signal->getDataPtr();
const Uint32 ptrI = conf->backupPtr;
- const Uint32 backupId = conf->backupId;
+ //const Uint32 backupId = conf->backupId;
const Uint32 tableId = conf->tableId;
const Uint32 fragmentNo = conf->fragmentNo;
const Uint32 nodeId = refToNode(signal->senderBlockRef());
@@ -1834,10 +1777,9 @@ Backup::execBACKUP_FRAGMENT_CONF(Signal* signal)
BackupRecordPtr ptr;
c_backupPool.getPtr(ptr, ptrI);
- masterAbortCheck(); // macro will do return if ABORTING
-
ptr.p->noOfBytes += noOfBytes;
ptr.p->noOfRecords += noOfRecords;
+ ptr.p->masterData.sendCounter--;
TablePtr tabPtr;
ndbrequire(findTable(ptr, tabPtr, tableId));
@@ -1852,17 +1794,24 @@ Backup::execBACKUP_FRAGMENT_CONF(Signal* signal)
fragPtr.p->scanned = 1;
fragPtr.p->scanning = 0;
- if(ptr.p->checkError()) {
- jam();
- masterAbort(signal, ptr, true);
- return;
- }//if
- if (ERROR_INSERTED(10028)) {
+ if (ERROR_INSERTED(10028))
+ {
ptr.p->errorCode = 328;
- masterAbort(signal, ptr, true);
- return;
- }//if
- nextFragment(signal, ptr);
+ }
+
+ if(ptr.p->checkError())
+ {
+ if(ptr.p->masterData.sendCounter.done())
+ {
+ jam();
+ masterAbort(signal, ptr);
+ return;
+ }//if
+ }
+ else
+ {
+ nextFragment(signal, ptr);
+ }
}
void
@@ -1874,15 +1823,52 @@ Backup::execBACKUP_FRAGMENT_REF(Signal* signal)
BackupFragmentRef * ref = (BackupFragmentRef*)signal->getDataPtr();
const Uint32 ptrI = ref->backupPtr;
- const Uint32 backupId = ref->backupId;
+ //const Uint32 backupId = ref->backupId;
+ const Uint32 nodeId = ref->nodeId;
BackupRecordPtr ptr;
c_backupPool.getPtr(ptr, ptrI);
- masterAbortCheck(); // macro will do return if ABORTING
+ TablePtr tabPtr;
+ ptr.p->tables.first(tabPtr);
+ for(; tabPtr.i != RNIL; ptr.p->tables.next(tabPtr)) {
+ jam();
+ FragmentPtr fragPtr;
+ Array<Fragment> & frags = tabPtr.p->fragments;
+ const Uint32 fragCount = frags.getSize();
+
+ for(Uint32 i = 0; i<fragCount; i++) {
+ jam();
+ tabPtr.p->fragments.getPtr(fragPtr, i);
+ if(fragPtr.p->scanning != 0 && nodeId == fragPtr.p->node)
+ {
+ jam();
+ ndbrequire(fragPtr.p->scanned == 0);
+ fragPtr.p->scanned = 1;
+ fragPtr.p->scanning = 0;
+ goto done;
+ }
+ }
+ }
+ ndbrequire(false);
+done:
+ ptr.p->masterData.sendCounter--;
ptr.p->setErrorCode(ref->errorCode);
- masterAbort(signal, ptr, true);
+
+ if(ptr.p->masterData.sendCounter.done())
+ {
+ jam();
+ masterAbort(signal, ptr);
+ return;
+ }//if
+
+ AbortBackupOrd *ord = (AbortBackupOrd*)signal->getDataPtrSend();
+ ord->backupId = ptr.p->backupId;
+ ord->backupPtr = ptr.i;
+ ord->requestType = AbortBackupOrd::LogBufferFull;
+ ord->senderData= ptr.i;
+ execABORT_BACKUP_ORD(signal);
}
/*****************************************************************************
@@ -1910,15 +1896,7 @@ Backup::sendDropTrig(Signal* signal, BackupRecordPtr ptr)
jam();
ptr.p->masterData.dropTrig.tableId = RNIL;
- sendAbortBackupOrd(signal, ptr, AbortBackupOrd::OkToClean);
-
- if(ptr.p->masterData.state.getState() == STOPPING) {
- jam();
- sendStopBackup(signal, ptr);
- return;
- }//if
- ndbrequire(ptr.p->masterData.state.getState() == ABORTING);
- masterSendAbortBackup(signal, ptr);
+ sendStopBackup(signal, ptr);
}//if
}
@@ -2010,7 +1988,6 @@ Backup::dropTrigReply(Signal* signal, BackupRecordPtr ptr)
return;
}//if
- ptr.p->masterData.gsn = 0;
sendDropTrig(signal, ptr); // recursive next
}
@@ -2023,14 +2000,23 @@ void
Backup::execSTOP_BACKUP_REF(Signal* signal)
{
jamEntry();
- ndbrequire(0);
+
+ StopBackupRef* ref = (StopBackupRef*)signal->getDataPtr();
+ const Uint32 ptrI = ref->backupPtr;
+ //const Uint32 backupId = ref->backupId;
+ const Uint32 nodeId = ref->nodeId;
+
+ BackupRecordPtr ptr;
+ c_backupPool.getPtr(ptr, ptrI);
+
+ ptr.p->setErrorCode(ref->errorCode);
+ stopBackupReply(signal, ptr, nodeId);
}
void
Backup::sendStopBackup(Signal* signal, BackupRecordPtr ptr)
{
jam();
- ptr.p->masterData.gsn = GSN_STOP_BACKUP_REQ;
StopBackupReq* stop = (StopBackupReq*)signal->getDataPtrSend();
stop->backupPtr = ptr.i;
@@ -2038,8 +2024,11 @@ Backup::sendStopBackup(Signal* signal, BackupRecordPtr ptr)
stop->startGCP = ptr.p->startGCP;
stop->stopGCP = ptr.p->stopGCP;
- sendSignalAllWait(ptr, GSN_STOP_BACKUP_REQ, signal,
- StopBackupReq::SignalLength);
+ ptr.p->masterData.gsn = GSN_STOP_BACKUP_REQ;
+ ptr.p->masterData.sendCounter = ptr.p->nodes;
+ NodeReceiverGroup rg(BACKUP, ptr.p->nodes);
+ sendSignal(rg, GSN_STOP_BACKUP_REQ, signal,
+ StopBackupReq::SignalLength, JBB);
}
void
@@ -2049,14 +2038,12 @@ Backup::execSTOP_BACKUP_CONF(Signal* signal)
StopBackupConf* conf = (StopBackupConf*)signal->getDataPtr();
const Uint32 ptrI = conf->backupPtr;
- const Uint32 backupId = conf->backupId;
+ //const Uint32 backupId = conf->backupId;
const Uint32 nodeId = refToNode(signal->senderBlockRef());
BackupRecordPtr ptr;
c_backupPool.getPtr(ptr, ptrI);
- masterAbortCheck(); // macro will do return if ABORTING
-
ptr.p->noOfLogBytes += conf->noOfLogBytes;
ptr.p->noOfLogRecords += conf->noOfLogRecords;
@@ -2073,35 +2060,39 @@ Backup::stopBackupReply(Signal* signal, BackupRecordPtr ptr, Uint32 nodeId)
return;
}
- // ptr.p->masterData.state.setState(INITIAL);
-
- // send backup complete first to slaves so that they know
sendAbortBackupOrd(signal, ptr, AbortBackupOrd::BackupComplete);
-
- BackupCompleteRep * rep = (BackupCompleteRep*)signal->getDataPtrSend();
- rep->backupId = ptr.p->backupId;
- rep->senderData = ptr.p->clientData;
- rep->startGCP = ptr.p->startGCP;
- rep->stopGCP = ptr.p->stopGCP;
- rep->noOfBytes = ptr.p->noOfBytes;
- rep->noOfRecords = ptr.p->noOfRecords;
- rep->noOfLogBytes = ptr.p->noOfLogBytes;
- rep->noOfLogRecords = ptr.p->noOfLogRecords;
- rep->nodes = ptr.p->nodes;
- sendSignal(ptr.p->clientRef, GSN_BACKUP_COMPLETE_REP, signal,
- BackupCompleteRep::SignalLength, JBB);
-
- signal->theData[0] = EventReport::BackupCompleted;
- signal->theData[1] = ptr.p->clientRef;
- signal->theData[2] = ptr.p->backupId;
- signal->theData[3] = ptr.p->startGCP;
- signal->theData[4] = ptr.p->stopGCP;
- signal->theData[5] = ptr.p->noOfBytes;
- signal->theData[6] = ptr.p->noOfRecords;
- signal->theData[7] = ptr.p->noOfLogBytes;
- signal->theData[8] = ptr.p->noOfLogRecords;
- ptr.p->nodes.copyto(NdbNodeBitmask::Size, signal->theData+9);
- sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 9+NdbNodeBitmask::Size, JBB);
+
+ if(!ptr.p->checkError())
+ {
+ BackupCompleteRep * rep = (BackupCompleteRep*)signal->getDataPtrSend();
+ rep->backupId = ptr.p->backupId;
+ rep->senderData = ptr.p->clientData;
+ rep->startGCP = ptr.p->startGCP;
+ rep->stopGCP = ptr.p->stopGCP;
+ rep->noOfBytes = ptr.p->noOfBytes;
+ rep->noOfRecords = ptr.p->noOfRecords;
+ rep->noOfLogBytes = ptr.p->noOfLogBytes;
+ rep->noOfLogRecords = ptr.p->noOfLogRecords;
+ rep->nodes = ptr.p->nodes;
+ sendSignal(ptr.p->clientRef, GSN_BACKUP_COMPLETE_REP, signal,
+ BackupCompleteRep::SignalLength, JBB);
+
+ signal->theData[0] = EventReport::BackupCompleted;
+ signal->theData[1] = ptr.p->clientRef;
+ signal->theData[2] = ptr.p->backupId;
+ signal->theData[3] = ptr.p->startGCP;
+ signal->theData[4] = ptr.p->stopGCP;
+ signal->theData[5] = ptr.p->noOfBytes;
+ signal->theData[6] = ptr.p->noOfRecords;
+ signal->theData[7] = ptr.p->noOfLogBytes;
+ signal->theData[8] = ptr.p->noOfLogRecords;
+ ptr.p->nodes.copyto(NdbNodeBitmask::Size, signal->theData+9);
+ sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 9+NdbNodeBitmask::Size, JBB);
+ }
+ else
+ {
+ masterAbort(signal, ptr);
+ }
}
/*****************************************************************************
@@ -2110,199 +2101,96 @@ Backup::stopBackupReply(Signal* signal, BackupRecordPtr ptr, Uint32 nodeId)
*
*****************************************************************************/
void
-Backup::masterAbort(Signal* signal, BackupRecordPtr ptr, bool controlledAbort)
+Backup::masterAbort(Signal* signal, BackupRecordPtr ptr)
{
- if(ptr.p->masterData.state.getState() == ABORTING) {
-#ifdef DEBUG_ABORT
- ndbout_c("---- Master already aborting");
-#endif
- jam();
- return;
- }
jam();
#ifdef DEBUG_ABORT
ndbout_c("************ masterAbort");
#endif
-
- sendAbortBackupOrd(signal, ptr, AbortBackupOrd::BackupFailure);
- if (!ptr.p->checkError())
- ptr.p->errorCode = AbortBackupOrd::BackupFailureDueToNodeFail;
-
- const State s = ptr.p->masterData.state.getState();
-
- ptr.p->masterData.state.setState(ABORTING);
-
- ndbrequire(s == INITIAL ||
- s == STARTED ||
- s == DEFINING ||
- s == DEFINED ||
- s == SCANNING ||
- s == STOPPING ||
- s == ABORTING);
- if(ptr.p->masterData.gsn == GSN_UTIL_SEQUENCE_REQ) {
- jam();
- DEBUG_OUT("masterAbort: gsn = GSN_UTIL_SEQUENCE_REQ");
- //-------------------------------------------------------
- // We are waiting for UTIL_SEQUENCE response. We rely on
- // this to arrive and check for ABORTING in response.
- // No slaves are involved at this point and ABORT simply
- // results in BACKUP_REF to client
- //-------------------------------------------------------
- /**
- * Waiting for Sequence Id
- * @see execUTIL_SEQUENCE_CONF
- */
- return;
- }//if
-
- if(ptr.p->masterData.gsn == GSN_UTIL_LOCK_REQ) {
+ if(ptr.p->masterData.errorCode != 0)
+ {
jam();
- DEBUG_OUT("masterAbort: gsn = GSN_UTIL_LOCK_REQ");
- //-------------------------------------------------------
- // We are waiting for UTIL_LOCK response (mutex). We rely on
- // this to arrive and check for ABORTING in response.
- // No slaves are involved at this point and ABORT simply
- // results in BACKUP_REF to client
- //-------------------------------------------------------
- /**
- * Waiting for lock
- * @see execUTIL_LOCK_CONF
- */
return;
- }//if
-
- /**
- * Unlock mutexes only at master
- */
- jam();
- Mutex mutex1(signal, c_mutexMgr, ptr.p->masterData.m_dictCommitTableMutex);
- jam();
- mutex1.unlock(); // ignore response
-
- jam();
- Mutex mutex2(signal, c_mutexMgr, ptr.p->masterData.m_defineBackupMutex);
- jam();
- mutex2.unlock(); // ignore response
-
- if (!controlledAbort) {
- jam();
- if (s == DEFINING) {
- jam();
-//-------------------------------------------------------
-// If we are in the defining phase all work is done by
-// slaves. No triggers have been allocated thus slaves
-// may free all "Master" resources, let them know...
-//-------------------------------------------------------
- sendAbortBackupOrd(signal, ptr, AbortBackupOrd::OkToClean);
- return;
- }//if
- if (s == DEFINED) {
- jam();
-//-------------------------------------------------------
-// DEFINED is the state when triggers are created. We rely
-// on that DICT will report create trigger failure in case
-// of node failure. Thus no special action is needed here.
-// We will check for errorCode != 0 when receiving
-// replies on create trigger.
-//-------------------------------------------------------
- return;
- }//if
- if(ptr.p->masterData.gsn == GSN_WAIT_GCP_REQ) {
- jam();
- DEBUG_OUT("masterAbort: gsn = GSN_WAIT_GCP_REQ");
-//-------------------------------------------------------
-// We are waiting for WAIT_GCP response. We rely on
-// this to arrive and check for ABORTING in response.
-//-------------------------------------------------------
-
- /**
- * Waiting for GCP
- * @see execWAIT_GCP_CONF
- */
- return;
- }//if
-
- if(ptr.p->masterData.gsn == GSN_ALTER_TRIG_REQ) {
- jam();
- DEBUG_OUT("masterAbort: gsn = GSN_ALTER_TRIG_REQ");
-//-------------------------------------------------------
-// We are waiting for ALTER_TRIG response. We rely on
-// this to arrive and check for ABORTING in response.
-//-------------------------------------------------------
+ }
- /**
- * All triggers haven't been created yet
- */
- return;
- }//if
+ BackupAbortRep* rep = (BackupAbortRep*)signal->getDataPtrSend();
+ rep->backupId = ptr.p->backupId;
+ rep->senderData = ptr.p->clientData;
+ rep->reason = ptr.p->errorCode;
+ sendSignal(ptr.p->clientRef, GSN_BACKUP_ABORT_REP, signal,
+ BackupAbortRep::SignalLength, JBB);
- if(ptr.p->masterData.gsn == GSN_DROP_TRIG_REQ) {
- jam();
- DEBUG_OUT("masterAbort: gsn = GSN_DROP_TRIG_REQ");
-//-------------------------------------------------------
-// We are waiting for DROP_TRIG response. We rely on
-// this to arrive and will continue dropping triggers
-// until completed.
-//-------------------------------------------------------
+ signal->theData[0] = EventReport::BackupAborted;
+ signal->theData[1] = ptr.p->clientRef;
+ signal->theData[2] = ptr.p->backupId;
+ signal->theData[3] = ptr.p->errorCode;
+ sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 4, JBB);
- /**
- * I'm currently dropping the trigger
- */
- return;
- }//if
- }//if
+ ndbrequire(ptr.p->errorCode);
+ ptr.p->masterData.errorCode = ptr.p->errorCode;
-//-------------------------------------------------------
-// If we are waiting for START_BACKUP responses we can
-// safely start dropping triggers (state == STARTED).
-// We will ignore any START_BACKUP responses after this.
-//-------------------------------------------------------
- DEBUG_OUT("masterAbort: sendDropTrig");
- sendDropTrig(signal, ptr); // dropping due to error
+ AbortBackupOrd *ord = (AbortBackupOrd*)signal->getDataPtrSend();
+ ord->backupId = ptr.p->backupId;
+ ord->backupPtr = ptr.i;
+ ord->senderData= ptr.i;
+ NodeReceiverGroup rg(BACKUP, ptr.p->nodes);
+
+ switch(ptr.p->masterData.gsn){
+ case GSN_DEFINE_BACKUP_REQ:
+ ord->requestType = AbortBackupOrd::BackupFailure;
+ sendSignal(rg, GSN_ABORT_BACKUP_ORD, signal,
+ AbortBackupOrd::SignalLength, JBB);
+ return;
+ case GSN_CREATE_TRIG_REQ:
+ case GSN_START_BACKUP_REQ:
+ case GSN_ALTER_TRIG_REQ:
+ case GSN_WAIT_GCP_REQ:
+ case GSN_BACKUP_FRAGMENT_REQ:
+ jam();
+ ptr.p->stopGCP= ptr.p->startGCP + 1;
+ sendDropTrig(signal, ptr); // dropping due to error
+ return;
+ case GSN_UTIL_SEQUENCE_REQ:
+ case GSN_UTIL_LOCK_REQ:
+ case GSN_DROP_TRIG_REQ:
+ ndbrequire(false);
+ return;
+ case GSN_STOP_BACKUP_REQ:
+ return;
+ }
}
void
-Backup::masterSendAbortBackup(Signal* signal, BackupRecordPtr ptr)
+Backup::abort_scan(Signal * signal, BackupRecordPtr ptr)
{
- if (ptr.p->masterData.state.getState() != ABORTING) {
- sendAbortBackupOrd(signal, ptr, AbortBackupOrd::BackupFailure);
- ptr.p->masterData.state.setState(ABORTING);
- }
- const State s = ptr.p->masterData.state.getAbortState();
-
- /**
- * First inform to client
- */
- if(s == DEFINING) {
- jam();
-#ifdef DEBUG_ABORT
- ndbout_c("** Abort: sending BACKUP_REF to mgmtsrvr");
-#endif
- sendBackupRef(ptr.p->clientRef, signal, ptr.p->clientData,
- ptr.p->errorCode);
+ AbortBackupOrd *ord = (AbortBackupOrd*)signal->getDataPtrSend();
+ ord->backupId = ptr.p->backupId;
+ ord->backupPtr = ptr.i;
+ ord->senderData= ptr.i;
+ ord->requestType = AbortBackupOrd::AbortScan;
- } else {
+ TablePtr tabPtr;
+ ptr.p->tables.first(tabPtr);
+ for(; tabPtr.i != RNIL; ptr.p->tables.next(tabPtr)) {
jam();
-#ifdef DEBUG_ABORT
- ndbout_c("** Abort: sending BACKUP_ABORT_REP to mgmtsrvr");
-#endif
- BackupAbortRep* rep = (BackupAbortRep*)signal->getDataPtrSend();
- rep->backupId = ptr.p->backupId;
- rep->senderData = ptr.p->clientData;
- rep->reason = ptr.p->errorCode;
- sendSignal(ptr.p->clientRef, GSN_BACKUP_ABORT_REP, signal,
- BackupAbortRep::SignalLength, JBB);
-
- signal->theData[0] = EventReport::BackupAborted;
- signal->theData[1] = ptr.p->clientRef;
- signal->theData[2] = ptr.p->backupId;
- signal->theData[3] = ptr.p->errorCode;
- sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 4, JBB);
- }//if
-
- // ptr.p->masterData.state.setState(INITIAL);
-
- sendAbortBackupOrd(signal, ptr, AbortBackupOrd::BackupFailure);
+ FragmentPtr fragPtr;
+ Array<Fragment> & frags = tabPtr.p->fragments;
+ const Uint32 fragCount = frags.getSize();
+
+ for(Uint32 i = 0; i<fragCount; i++) {
+ jam();
+ tabPtr.p->fragments.getPtr(fragPtr, i);
+ const Uint32 nodeId = fragPtr.p->node;
+ if(fragPtr.p->scanning != 0 && ptr.p->nodes.get(nodeId)) {
+ jam();
+
+ const BlockReference ref = numberToRef(BACKUP, nodeId);
+ sendSignal(ref, GSN_ABORT_BACKUP_ORD, signal,
+ AbortBackupOrd::SignalLength, JBB);
+
+ }
+ }
+ }
}
/*****************************************************************************
@@ -2313,26 +2201,17 @@ Backup::masterSendAbortBackup(Signal* signal, BackupRecordPtr ptr)
void
Backup::defineBackupRef(Signal* signal, BackupRecordPtr ptr, Uint32 errCode)
{
- if (ptr.p->slaveState.getState() == ABORTING) {
- jam();
- return;
- }
- ptr.p->slaveState.setState(ABORTING);
-
- if (errCode != 0) {
- jam();
- ptr.p->setErrorCode(errCode);
- }//if
+ ptr.p->m_gsn = GSN_DEFINE_BACKUP_REF;
+ ptr.p->setErrorCode(errCode);
ndbrequire(ptr.p->errorCode != 0);
-
+
DefineBackupRef* ref = (DefineBackupRef*)signal->getDataPtrSend();
ref->backupId = ptr.p->backupId;
ref->backupPtr = ptr.i;
ref->errorCode = ptr.p->errorCode;
+ ref->nodeId = getOwnNodeId();
sendSignal(ptr.p->masterRef, GSN_DEFINE_BACKUP_REF, signal,
DefineBackupRef::SignalLength, JBB);
-
- closeFiles(signal, ptr);
}
void
@@ -2366,6 +2245,7 @@ Backup::execDEFINE_BACKUP_REQ(Signal* signal)
CRASH_INSERTION((10014));
+ ptr.p->m_gsn = GSN_DEFINE_BACKUP_REQ;
ptr.p->slaveState.forceState(INITIAL);
ptr.p->slaveState.setState(DEFINING);
ptr.p->errorCode = 0;
@@ -2379,6 +2259,7 @@ Backup::execDEFINE_BACKUP_REQ(Signal* signal)
ptr.p->backupDataLen = req->backupDataLen;
ptr.p->masterData.dropTrig.tableId = RNIL;
ptr.p->masterData.alterTrig.tableId = RNIL;
+ ptr.p->masterData.errorCode = 0;
ptr.p->noOfBytes = 0;
ptr.p->noOfRecords = 0;
ptr.p->noOfLogBytes = 0;
@@ -2432,7 +2313,7 @@ Backup::execDEFINE_BACKUP_REQ(Signal* signal)
files[i].p->tableId = RNIL;
files[i].p->backupPtr = ptr.i;
files[i].p->filePointer = RNIL;
- files[i].p->fileDone = 0;
+ files[i].p->fileClosing = 0;
files[i].p->fileOpened = 0;
files[i].p->fileRunning = 0;
files[i].p->scanRunning = 0;
@@ -2468,17 +2349,14 @@ Backup::execDEFINE_BACKUP_REQ(Signal* signal)
ptr.p->logFilePtr = files[1].i;
ptr.p->dataFilePtr = files[2].i;
- if (!verifyNodesAlive(ptr.p->nodes)) {
+ if (!verifyNodesAlive(ptr, ptr.p->nodes)) {
jam();
defineBackupRef(signal, ptr, DefineBackupRef::Undefined);
- // sendBackupRef(signal, ptr,
- // ptr.p->errorCode?ptr.p->errorCode:BackupRef::Undefined);
return;
}//if
if (ERROR_INSERTED(10027)) {
jam();
defineBackupRef(signal, ptr, 327);
- // sendBackupRef(signal, ptr, 327);
return;
}//if
@@ -2546,8 +2424,6 @@ Backup::execLIST_TABLES_CONF(Signal* signal)
return;
}//if
- defineSlaveAbortCheck();
-
/**
* All tables fetched
*/
@@ -2679,8 +2555,6 @@ Backup::openFilesReply(Signal* signal,
}//if
}//for
- defineSlaveAbortCheck();
-
/**
* Did open succeed for all files
*/
@@ -2810,8 +2684,6 @@ Backup::execGET_TABINFOREF(Signal* signal)
BackupRecordPtr ptr;
c_backupPool.getPtr(ptr, senderData);
- defineSlaveAbortCheck();
-
defineBackupRef(signal, ptr, ref->errorCode);
}
@@ -2833,8 +2705,6 @@ Backup::execGET_TABINFO_CONF(Signal* signal)
BackupRecordPtr ptr;
c_backupPool.getPtr(ptr, senderData);
- defineSlaveAbortCheck();
-
SegmentedSectionPtr dictTabInfoPtr;
signal->getSection(dictTabInfoPtr, GetTabInfoConf::DICT_TAB_INFO);
ndbrequire(dictTabInfoPtr.sz == len);
@@ -3047,8 +2917,6 @@ Backup::execDI_FCOUNTCONF(Signal* signal)
BackupRecordPtr ptr;
c_backupPool.getPtr(ptr, senderData);
- defineSlaveAbortCheck();
-
TablePtr tabPtr;
ndbrequire(findTable(ptr, tabPtr, tableId));
@@ -3127,8 +2995,6 @@ Backup::execDIGETPRIMCONF(Signal* signal)
BackupRecordPtr ptr;
c_backupPool.getPtr(ptr, senderData);
- defineSlaveAbortCheck();
-
TablePtr tabPtr;
ndbrequire(findTable(ptr, tabPtr, tableId));
@@ -3143,9 +3009,7 @@ Backup::execDIGETPRIMCONF(Signal* signal)
void
Backup::getFragmentInfoDone(Signal* signal, BackupRecordPtr ptr)
{
- // Slave must now hold on to master data until
- // AbortBackupOrd::OkToClean signal
- ptr.p->okToCleanMaster = false;
+ ptr.p->m_gsn = GSN_DEFINE_BACKUP_CONF;
ptr.p->slaveState.setState(DEFINED);
DefineBackupConf * conf = (DefineBackupConf*)signal->getDataPtr();
conf->backupPtr = ptr.i;
@@ -3169,16 +3033,15 @@ Backup::execSTART_BACKUP_REQ(Signal* signal)
StartBackupReq* req = (StartBackupReq*)signal->getDataPtr();
const Uint32 ptrI = req->backupPtr;
- const Uint32 backupId = req->backupId;
+ //const Uint32 backupId = req->backupId;
const Uint32 signalNo = req->signalNo;
-
+
BackupRecordPtr ptr;
c_backupPool.getPtr(ptr, ptrI);
-
- slaveAbortCheck(); // macro will do return if ABORTING
ptr.p->slaveState.setState(STARTED);
-
+ ptr.p->m_gsn = GSN_START_BACKUP_REQ;
+
for(Uint32 i = 0; i<req->noOfTableTriggers; i++) {
jam();
TablePtr tabPtr;
@@ -3191,11 +3054,13 @@ Backup::execSTART_BACKUP_REQ(Signal* signal)
TriggerPtr trigPtr;
if(!ptr.p->triggers.seizeId(trigPtr, triggerId)) {
jam();
+ ptr.p->m_gsn = GSN_START_BACKUP_REF;
StartBackupRef* ref = (StartBackupRef*)signal->getDataPtrSend();
ref->backupPtr = ptr.i;
ref->backupId = ptr.p->backupId;
ref->signalNo = signalNo;
ref->errorCode = StartBackupRef::FailedToAllocateTriggerRecord;
+ ref->nodeId = getOwnNodeId();
sendSignal(ptr.p->masterRef, GSN_START_BACKUP_REF, signal,
StartBackupRef::SignalLength, JBB);
return;
@@ -3233,6 +3098,7 @@ Backup::execSTART_BACKUP_REQ(Signal* signal)
}//if
}//for
+ ptr.p->m_gsn = GSN_START_BACKUP_CONF;
StartBackupConf* conf = (StartBackupConf*)signal->getDataPtrSend();
conf->backupPtr = ptr.i;
conf->backupId = ptr.p->backupId;
@@ -3255,7 +3121,7 @@ Backup::execBACKUP_FRAGMENT_REQ(Signal* signal)
CRASH_INSERTION((10016));
const Uint32 ptrI = req->backupPtr;
- const Uint32 backupId = req->backupId;
+ //const Uint32 backupId = req->backupId;
const Uint32 tableId = req->tableId;
const Uint32 fragNo = req->fragmentNo;
const Uint32 count = req->count;
@@ -3266,10 +3132,9 @@ Backup::execBACKUP_FRAGMENT_REQ(Signal* signal)
BackupRecordPtr ptr;
c_backupPool.getPtr(ptr, ptrI);
- slaveAbortCheck(); // macro will do return if ABORTING
-
ptr.p->slaveState.setState(SCANNING);
-
+ ptr.p->m_gsn = GSN_BACKUP_FRAGMENT_REQ;
+
/**
* Get file
*/
@@ -3280,7 +3145,7 @@ Backup::execBACKUP_FRAGMENT_REQ(Signal* signal)
ndbrequire(filePtr.p->fileOpened == 1);
ndbrequire(filePtr.p->fileRunning == 1);
ndbrequire(filePtr.p->scanRunning == 0);
- ndbrequire(filePtr.p->fileDone == 0);
+ ndbrequire(filePtr.p->fileClosing == 0);
/**
* Get table
@@ -3350,7 +3215,7 @@ Backup::execBACKUP_FRAGMENT_REQ(Signal* signal)
req->transId1 = 0;
req->transId2 = (BACKUP << 20) + (getOwnNodeId() << 8);
req->clientOpPtr= filePtr.i;
- req->batch_size_rows= 16;
+ req->batch_size_rows= parallelism;
req->batch_size_bytes= 0;
sendSignal(DBLQH_REF, GSN_SCAN_FRAGREQ, signal,
ScanFragReq::SignalLength, JBB);
@@ -3572,6 +3437,13 @@ Backup::OperationRecord::newScan()
return false;
}
+bool
+Backup::OperationRecord::closeScan()
+{
+ opNoDone = opNoConf = opLen = 0;
+ return true;
+}
+
bool
Backup::OperationRecord::scanConf(Uint32 noOfOps, Uint32 total_len)
{
@@ -3600,11 +3472,9 @@ Backup::execSCAN_FRAGREF(Signal* signal)
c_backupFilePool.getPtr(filePtr, filePtrI);
filePtr.p->errorCode = ref->errorCode;
+ filePtr.p->scanRunning = 0;
- BackupRecordPtr ptr;
- c_backupPool.getPtr(ptr, filePtr.p->backupPtr);
-
- abortFile(signal, ptr, filePtr);
+ backupFragmentRef(signal, filePtr);
}
void
@@ -3639,9 +3509,11 @@ Backup::fragmentCompleted(Signal* signal, BackupFilePtr filePtr)
{
jam();
- if(filePtr.p->errorCode != 0){
+ if(filePtr.p->errorCode != 0)
+ {
jam();
- abortFileHook(signal, filePtr, true); // Scan completed
+ filePtr.p->scanRunning = 0;
+ backupFragmentRef(signal, filePtr); // Scan completed
return;
}//if
@@ -3669,20 +3541,51 @@ Backup::fragmentCompleted(Signal* signal, BackupFilePtr filePtr)
sendSignal(ptr.p->masterRef, GSN_BACKUP_FRAGMENT_CONF, signal,
BackupFragmentConf::SignalLength, JBB);
+ ptr.p->m_gsn = GSN_BACKUP_FRAGMENT_CONF;
ptr.p->slaveState.setState(STARTED);
return;
}
+
+void
+Backup::backupFragmentRef(Signal * signal, BackupFilePtr filePtr)
+{
+ BackupRecordPtr ptr;
+ c_backupPool.getPtr(ptr, filePtr.p->backupPtr);
+
+ ptr.p->m_gsn = GSN_BACKUP_FRAGMENT_REF;
+
+ BackupFragmentRef * ref = (BackupFragmentRef*)signal->getDataPtrSend();
+ ref->backupId = ptr.p->backupId;
+ ref->backupPtr = ptr.i;
+ ref->nodeId = getOwnNodeId();
+ ref->errorCode = ptr.p->errorCode;
+ sendSignal(ptr.p->masterRef, GSN_BACKUP_FRAGMENT_REF, signal,
+ BackupFragmentRef::SignalLength, JBB);
+}
void
Backup::checkScan(Signal* signal, BackupFilePtr filePtr)
{
- if(filePtr.p->errorCode != 0){
+ OperationRecord & op = filePtr.p->operation;
+
+ if(filePtr.p->errorCode != 0)
+ {
jam();
- abortFileHook(signal, filePtr, false); // Scan not completed
+
+ /**
+ * Close scan
+ */
+ op.closeScan();
+ ScanFragNextReq * req = (ScanFragNextReq *)signal->getDataPtrSend();
+ req->senderData = filePtr.i;
+ req->closeFlag = 1;
+ req->transId1 = 0;
+ req->transId2 = (BACKUP << 20) + (getOwnNodeId() << 8);
+ sendSignal(DBLQH_REF, GSN_SCAN_NEXTREQ, signal,
+ ScanFragNextReq::SignalLength, JBB);
return;
}//if
-
- OperationRecord & op = filePtr.p->operation;
+
if(op.newScan()) {
jam();
@@ -3693,8 +3596,28 @@ Backup::checkScan(Signal* signal, BackupFilePtr filePtr)
req->transId2 = (BACKUP << 20) + (getOwnNodeId() << 8);
req->batch_size_rows= 16;
req->batch_size_bytes= 0;
- sendSignal(DBLQH_REF, GSN_SCAN_NEXTREQ, signal,
- ScanFragNextReq::SignalLength, JBB);
+ if(ERROR_INSERTED(10032))
+ sendSignalWithDelay(DBLQH_REF, GSN_SCAN_NEXTREQ, signal,
+ 100, ScanFragNextReq::SignalLength);
+ else if(ERROR_INSERTED(10033))
+ {
+ SET_ERROR_INSERT_VALUE(10032);
+ sendSignalWithDelay(DBLQH_REF, GSN_SCAN_NEXTREQ, signal,
+ 10000, ScanFragNextReq::SignalLength);
+
+ BackupRecordPtr ptr;
+ c_backupPool.getPtr(ptr, filePtr.p->backupPtr);
+ AbortBackupOrd *ord = (AbortBackupOrd*)signal->getDataPtrSend();
+ ord->backupId = ptr.p->backupId;
+ ord->backupPtr = ptr.i;
+ ord->requestType = AbortBackupOrd::FileOrScanError;
+ ord->senderData= ptr.i;
+ sendSignal(ptr.p->masterRef, GSN_ABORT_BACKUP_ORD, signal,
+ AbortBackupOrd::SignalLength, JBB);
+ }
+ else
+ sendSignal(DBLQH_REF, GSN_SCAN_NEXTREQ, signal,
+ ScanFragNextReq::SignalLength, JBB);
return;
}//if
@@ -3718,11 +3641,8 @@ Backup::execFSAPPENDREF(Signal* signal)
filePtr.p->fileRunning = 0;
filePtr.p->errorCode = errCode;
-
- BackupRecordPtr ptr;
- c_backupPool.getPtr(ptr, filePtr.p->backupPtr);
-
- abortFile(signal, ptr, filePtr);
+
+ checkFile(signal, filePtr);
}
void
@@ -3738,12 +3658,6 @@ Backup::execFSAPPENDCONF(Signal* signal)
BackupFilePtr filePtr;
c_backupFilePool.getPtr(filePtr, filePtrI);
-
- if (ERROR_INSERTED(10029)) {
- BackupRecordPtr ptr;
- c_backupPool.getPtr(ptr, filePtr.p->backupPtr);
- abortFile(signal, ptr, filePtr);
- }//if
OperationRecord & op = filePtr.p->operation;
@@ -3761,30 +3675,25 @@ Backup::checkFile(Signal* signal, BackupFilePtr filePtr)
#endif
OperationRecord & op = filePtr.p->operation;
-
+
Uint32 * tmp, sz; bool eof;
- if(op.dataBuffer.getReadPtr(&tmp, &sz, &eof)) {
+ if(op.dataBuffer.getReadPtr(&tmp, &sz, &eof))
+ {
jam();
- if(filePtr.p->errorCode == 0) {
- jam();
- FsAppendReq * req = (FsAppendReq *)signal->getDataPtrSend();
- req->filePointer = filePtr.p->filePointer;
- req->userPointer = filePtr.i;
- req->userReference = reference();
- req->varIndex = 0;
- req->offset = tmp - c_startOfPages;
- req->size = sz;
-
- sendSignal(NDBFS_REF, GSN_FSAPPENDREQ, signal,
- FsAppendReq::SignalLength, JBA);
- return;
- } else {
- jam();
- if (filePtr.p->scanRunning == 1)
- eof = false;
- }//if
- }//if
+ jam();
+ FsAppendReq * req = (FsAppendReq *)signal->getDataPtrSend();
+ req->filePointer = filePtr.p->filePointer;
+ req->userPointer = filePtr.i;
+ req->userReference = reference();
+ req->varIndex = 0;
+ req->offset = tmp - c_startOfPages;
+ req->size = sz;
+
+ sendSignal(NDBFS_REF, GSN_FSAPPENDREQ, signal,
+ FsAppendReq::SignalLength, JBA);
+ return;
+ }
if(!eof) {
jam();
@@ -3794,9 +3703,7 @@ Backup::checkFile(Signal* signal, BackupFilePtr filePtr)
return;
}//if
- ndbrequire(filePtr.p->fileDone == 1);
-
- if(sz > 0 && filePtr.p->errorCode == 0) {
+ if(sz > 0) {
jam();
FsAppendReq * req = (FsAppendReq *)signal->getDataPtrSend();
req->filePointer = filePtr.p->filePointer;
@@ -3812,6 +3719,7 @@ Backup::checkFile(Signal* signal, BackupFilePtr filePtr)
}//if
filePtr.p->fileRunning = 0;
+ filePtr.p->fileClosing = 1;
FsCloseReq * req = (FsCloseReq *)signal->getDataPtrSend();
req->filePointer = filePtr.p->filePointer;
@@ -3819,64 +3727,11 @@ Backup::checkFile(Signal* signal, BackupFilePtr filePtr)
req->userReference = reference();
req->fileFlag = 0;
#ifdef DEBUG_ABORT
- ndbout_c("***** FSCLOSEREQ filePtr.i = %u", filePtr.i);
+ ndbout_c("***** a FSCLOSEREQ filePtr.i = %u", filePtr.i);
#endif
sendSignal(NDBFS_REF, GSN_FSCLOSEREQ, signal, FsCloseReq::SignalLength, JBA);
}
-void
-Backup::abortFile(Signal* signal, BackupRecordPtr ptr, BackupFilePtr filePtr)
-{
- jam();
-
- if(ptr.p->slaveState.getState() != ABORTING) {
- /**
- * Inform master of failure
- */
- jam();
- ptr.p->slaveState.setState(ABORTING);
- ptr.p->setErrorCode(AbortBackupOrd::FileOrScanError);
- sendAbortBackupOrdSlave(signal, ptr, AbortBackupOrd::FileOrScanError);
- return;
- }//if
-
-
- for(ptr.p->files.first(filePtr);
- filePtr.i!=RNIL;
- ptr.p->files.next(filePtr)){
- jam();
- filePtr.p->errorCode = 1;
- }//for
-
- closeFiles(signal, ptr);
-}
-
-void
-Backup::abortFileHook(Signal* signal, BackupFilePtr filePtr, bool scanComplete)
-{
- jam();
-
- if(!scanComplete) {
- jam();
-
- ScanFragNextReq * req = (ScanFragNextReq *)signal->getDataPtrSend();
- req->senderData = filePtr.i;
- req->closeFlag = 1;
- req->transId1 = 0;
- req->transId2 = (BACKUP << 20) + (getOwnNodeId() << 8);
- sendSignal(DBLQH_REF, GSN_SCAN_NEXTREQ, signal,
- ScanFragNextReq::SignalLength, JBB);
- return;
- }//if
-
- filePtr.p->scanRunning = 0;
-
- BackupRecordPtr ptr;
- c_backupPool.getPtr(ptr, filePtr.p->backupPtr);
-
- filePtr.i = RNIL;
- abortFile(signal, ptr, filePtr);
-}
/****************************************************************************
*
@@ -3953,27 +3808,30 @@ Backup::execTRIG_ATTRINFO(Signal* signal) {
}//if
BackupFormat::LogFile::LogEntry * logEntry = trigPtr.p->logEntry;
- if(logEntry == 0) {
+ if(logEntry == 0)
+ {
jam();
Uint32 * dst;
FsBuffer & buf = trigPtr.p->operation->dataBuffer;
ndbrequire(trigPtr.p->maxRecordSize <= buf.getMaxWrite());
- BackupRecordPtr ptr;
- c_backupPool.getPtr(ptr, trigPtr.p->backupPtr);
- if(!buf.getWritePtr(&dst, trigPtr.p->maxRecordSize)) {
- jam();
- trigPtr.p->errorCode = AbortBackupOrd::LogBufferFull;
- sendAbortBackupOrdSlave(signal, ptr, AbortBackupOrd::LogBufferFull);
- return;
- }//if
- if(trigPtr.p->operation->noOfBytes > 123 && ERROR_INSERTED(10030)) {
+ if(ERROR_INSERTED(10030) ||
+ !buf.getWritePtr(&dst, trigPtr.p->maxRecordSize))
+ {
jam();
+ BackupRecordPtr ptr;
+ c_backupPool.getPtr(ptr, trigPtr.p->backupPtr);
trigPtr.p->errorCode = AbortBackupOrd::LogBufferFull;
- sendAbortBackupOrdSlave(signal, ptr, AbortBackupOrd::LogBufferFull);
+ AbortBackupOrd *ord = (AbortBackupOrd*)signal->getDataPtrSend();
+ ord->backupId = ptr.p->backupId;
+ ord->backupPtr = ptr.i;
+ ord->requestType = AbortBackupOrd::LogBufferFull;
+ ord->senderData= ptr.i;
+ sendSignal(ptr.p->masterRef, GSN_ABORT_BACKUP_ORD, signal,
+ AbortBackupOrd::SignalLength, JBB);
return;
}//if
-
+
logEntry = (BackupFormat::LogFile::LogEntry *)dst;
trigPtr.p->logEntry = logEntry;
logEntry->Length = 0;
@@ -4015,9 +3873,10 @@ Backup::execFIRE_TRIG_ORD(Signal* signal)
BackupRecordPtr ptr;
c_backupPool.getPtr(ptr, trigPtr.p->backupPtr);
- if(gci != ptr.p->currGCP) {
+ if(gci != ptr.p->currGCP)
+ {
jam();
-
+
trigPtr.p->logEntry->TriggerEvent = htonl(trigPtr.p->event | 0x10000);
trigPtr.p->logEntry->Data[len] = htonl(gci);
len ++;
@@ -4036,20 +3895,6 @@ Backup::execFIRE_TRIG_ORD(Signal* signal)
}
void
-Backup::sendAbortBackupOrdSlave(Signal* signal, BackupRecordPtr ptr,
- Uint32 requestType)
-{
- jam();
- AbortBackupOrd *ord = (AbortBackupOrd*)signal->getDataPtrSend();
- ord->backupId = ptr.p->backupId;
- ord->backupPtr = ptr.i;
- ord->requestType = requestType;
- ord->senderData= ptr.i;
- sendSignal(ptr.p->masterRef, GSN_ABORT_BACKUP_ORD, signal,
- AbortBackupOrd::SignalLength, JBB);
-}
-
-void
Backup::sendAbortBackupOrd(Signal* signal, BackupRecordPtr ptr,
Uint32 requestType)
{
@@ -4085,7 +3930,7 @@ Backup::execSTOP_BACKUP_REQ(Signal* signal)
CRASH_INSERTION((10020));
const Uint32 ptrI = req->backupPtr;
- const Uint32 backupId = req->backupId;
+ //const Uint32 backupId = req->backupId;
const Uint32 startGCP = req->startGCP;
const Uint32 stopGCP = req->stopGCP;
@@ -4101,7 +3946,7 @@ Backup::execSTOP_BACKUP_REQ(Signal* signal)
c_backupPool.getPtr(ptr, ptrI);
ptr.p->slaveState.setState(STOPPING);
- slaveAbortCheck(); // macro will do return if ABORTING
+ ptr.p->m_gsn = GSN_STOP_BACKUP_REQ;
/**
* Insert footers
@@ -4140,12 +3985,6 @@ Backup::execSTOP_BACKUP_REQ(Signal* signal)
void
Backup::closeFiles(Signal* sig, BackupRecordPtr ptr)
{
- if (ptr.p->closingFiles) {
- jam();
- return;
- }
- ptr.p->closingFiles = true;
-
/**
* Close all files
*/
@@ -4161,12 +4000,12 @@ Backup::closeFiles(Signal* sig, BackupRecordPtr ptr)
jam();
openCount++;
- if(filePtr.p->fileDone == 1){
+ if(filePtr.p->fileClosing == 1){
jam();
continue;
}//if
- filePtr.p->fileDone = 1;
+ filePtr.p->fileClosing = 1;
if(filePtr.p->fileRunning == 1){
jam();
@@ -4183,7 +4022,7 @@ Backup::closeFiles(Signal* sig, BackupRecordPtr ptr)
req->userReference = reference();
req->fileFlag = 0;
#ifdef DEBUG_ABORT
- ndbout_c("***** FSCLOSEREQ filePtr.i = %u", filePtr.i);
+ ndbout_c("***** b FSCLOSEREQ filePtr.i = %u", filePtr.i);
#endif
sendSignal(NDBFS_REF, GSN_FSCLOSEREQ, sig,
FsCloseReq::SignalLength, JBA);
@@ -4210,11 +4049,6 @@ Backup::execFSCLOSEREF(Signal* signal)
BackupRecordPtr ptr;
c_backupPool.getPtr(ptr, filePtr.p->backupPtr);
- /**
- * This should only happen during abort of backup
- */
- ndbrequire(ptr.p->slaveState.getState() == ABORTING);
-
filePtr.p->fileOpened = 1;
FsConf * conf = (FsConf*)signal->getDataPtr();
conf->userPointer = filePtrI;
@@ -4237,7 +4071,7 @@ Backup::execFSCLOSECONF(Signal* signal)
ndbout_c("***** FSCLOSECONF filePtrI = %u", filePtrI);
#endif
- ndbrequire(filePtr.p->fileDone == 1);
+ ndbrequire(filePtr.p->fileClosing == 1);
ndbrequire(filePtr.p->fileOpened == 1);
ndbrequire(filePtr.p->fileRunning == 0);
ndbrequire(filePtr.p->scanRunning == 0);
@@ -4265,25 +4099,20 @@ Backup::closeFilesDone(Signal* signal, BackupRecordPtr ptr)
{
jam();
- if(ptr.p->slaveState.getState() == STOPPING) {
- jam();
- BackupFilePtr filePtr;
- ptr.p->files.getPtr(filePtr, ptr.p->logFilePtr);
-
- StopBackupConf* conf = (StopBackupConf*)signal->getDataPtrSend();
- conf->backupId = ptr.p->backupId;
- conf->backupPtr = ptr.i;
- conf->noOfLogBytes = filePtr.p->operation.noOfBytes;
- conf->noOfLogRecords = filePtr.p->operation.noOfRecords;
- sendSignal(ptr.p->masterRef, GSN_STOP_BACKUP_CONF, signal,
- StopBackupConf::SignalLength, JBB);
-
- ptr.p->slaveState.setState(CLEANING);
- return;
- }//if
+ jam();
+ BackupFilePtr filePtr;
+ ptr.p->files.getPtr(filePtr, ptr.p->logFilePtr);
- ndbrequire(ptr.p->slaveState.getState() == ABORTING);
- removeBackup(signal, ptr);
+ StopBackupConf* conf = (StopBackupConf*)signal->getDataPtrSend();
+ conf->backupId = ptr.p->backupId;
+ conf->backupPtr = ptr.i;
+ conf->noOfLogBytes = filePtr.p->operation.noOfBytes;
+ conf->noOfLogRecords = filePtr.p->operation.noOfRecords;
+ sendSignal(ptr.p->masterRef, GSN_STOP_BACKUP_CONF, signal,
+ StopBackupConf::SignalLength, JBB);
+
+ ptr.p->m_gsn = GSN_STOP_BACKUP_CONF;
+ ptr.p->slaveState.setState(CLEANING);
}
/*****************************************************************************
@@ -4291,57 +4120,6 @@ Backup::closeFilesDone(Signal* signal, BackupRecordPtr ptr)
* Slave functionallity: Abort backup
*
*****************************************************************************/
-void
-Backup::removeBackup(Signal* signal, BackupRecordPtr ptr)
-{
- jam();
-
- FsRemoveReq * req = (FsRemoveReq *)signal->getDataPtrSend();
- req->userReference = reference();
- req->userPointer = ptr.i;
- req->directory = 1;
- req->ownDirectory = 1;
- FsOpenReq::setVersion(req->fileNumber, 2);
- FsOpenReq::setSuffix(req->fileNumber, FsOpenReq::S_CTL);
- FsOpenReq::v2_setSequence(req->fileNumber, ptr.p->backupId);
- FsOpenReq::v2_setNodeId(req->fileNumber, getOwnNodeId());
- sendSignal(NDBFS_REF, GSN_FSREMOVEREQ, signal,
- FsRemoveReq::SignalLength, JBA);
-}
-
-void
-Backup::execFSREMOVEREF(Signal* signal)
-{
- jamEntry();
- ndbrequire(0);
-}
-
-void
-Backup::execFSREMOVECONF(Signal* signal){
- jamEntry();
-
- FsConf * conf = (FsConf*)signal->getDataPtr();
- const Uint32 ptrI = conf->userPointer;
-
- /**
- * Get backup record
- */
- BackupRecordPtr ptr;
- c_backupPool.getPtr(ptr, ptrI);
-
- ndbrequire(ptr.p->slaveState.getState() == ABORTING);
- if (ptr.p->masterRef == reference()) {
- if (ptr.p->masterData.state.getAbortState() == DEFINING) {
- jam();
- sendBackupRef(signal, ptr, ptr.p->errorCode);
- return;
- } else {
- jam();
- }//if
- }//if
- cleanupSlaveResources(ptr);
-}
-
/*****************************************************************************
*
* Slave functionallity: Abort backup
@@ -4394,8 +4172,7 @@ Backup::execABORT_BACKUP_ORD(Signal* signal)
if (c_backupPool.findId(senderData)) {
jam();
c_backupPool.getPtr(ptr, senderData);
- } else { // TODO might be abort sent to not master,
- // or master aborting too early
+ } else {
jam();
#ifdef DEBUG_ABORT
ndbout_c("Backup: abort request type=%u on id=%u,%u not found",
@@ -4405,15 +4182,15 @@ Backup::execABORT_BACKUP_ORD(Signal* signal)
}
}//if
+ ptr.p->m_gsn = GSN_ABORT_BACKUP_ORD;
const bool isCoordinator = (ptr.p->masterRef == reference());
-
+
bool ok = false;
switch(requestType){
/**
* Requests sent to master
*/
-
case AbortBackupOrd::ClientAbort:
jam();
// fall through
@@ -4422,113 +4199,61 @@ Backup::execABORT_BACKUP_ORD(Signal* signal)
// fall through
case AbortBackupOrd::FileOrScanError:
jam();
- if(ptr.p->masterData.state.getState() == ABORTING) {
-#ifdef DEBUG_ABORT
- ndbout_c("---- Already aborting");
-#endif
- jam();
- return;
- }
+ ndbrequire(isCoordinator);
ptr.p->setErrorCode(requestType);
- ndbrequire(isCoordinator); // Sent from slave to coordinator
- masterAbort(signal, ptr, false);
+ if(ptr.p->masterData.gsn == GSN_BACKUP_FRAGMENT_REQ)
+ {
+ /**
+ * Only scans are actively aborted
+ */
+ abort_scan(signal, ptr);
+ }
return;
-
+
/**
- * Info sent to slave
+ * Requests sent to slave
*/
-
- case AbortBackupOrd::OkToClean:
+ case AbortBackupOrd::AbortScan:
jam();
- cleanupMasterResources(ptr);
+ ptr.p->setErrorCode(requestType);
return;
-
- /**
- * Requests sent to slave
- */
-
+
case AbortBackupOrd::BackupComplete:
jam();
- if (ptr.p->slaveState.getState() == CLEANING) { // TODO what if state is
- // not CLEANING?
- jam();
- cleanupSlaveResources(ptr);
- }//if
+ cleanup(signal, ptr);
return;
- break;
- case AbortBackupOrd::BackupFailureDueToNodeFail:
- jam();
- ok = true;
- if (ptr.p->errorCode != 0)
- ptr.p->setErrorCode(requestType);
- break;
case AbortBackupOrd::BackupFailure:
- jam();
- ok = true;
- break;
+ case AbortBackupOrd::BackupFailureDueToNodeFail:
+ case AbortBackupOrd::OkToClean:
+ case AbortBackupOrd::IncompatibleVersions:
+#ifndef VM_TRACE
+ default:
+#endif
+ ptr.p->setErrorCode(requestType);
+ ok= true;
}
ndbrequire(ok);
- /**
- * Slave abort
- */
- slaveAbort(signal, ptr);
-}
-
-void
-Backup::slaveAbort(Signal* signal, BackupRecordPtr ptr)
-{
- if(ptr.p->slaveState.getState() == ABORTING) {
-#ifdef DEBUG_ABORT
- ndbout_c("---- Slave already aborting");
-#endif
- jam();
- return;
+ Uint32 ref= ptr.p->masterRef;
+ ptr.p->masterRef = reference();
+ ptr.p->nodes.clear();
+ ptr.p->nodes.set(getOwnNodeId());
+
+ if(ref == reference())
+ {
+ ptr.p->stopGCP= ptr.p->startGCP + 1;
+ sendDropTrig(signal, ptr);
}
-#ifdef DEBUG_ABORT
- ndbout_c("************* slaveAbort");
-#endif
-
- State slaveState = ptr.p->slaveState.getState();
- ptr.p->slaveState.setState(ABORTING);
- switch(slaveState) {
- case DEFINING:
- jam();
- return;
-//------------------------------------------
-// Will watch for the abort at various places
-// in the defining phase.
-//------------------------------------------
- case ABORTING:
- jam();
- //Fall through
- case DEFINED:
- jam();
- //Fall through
- case STOPPING:
- jam();
+ else
+ {
+ ptr.p->masterData.gsn = GSN_STOP_BACKUP_REQ;
+ ptr.p->masterData.sendCounter.clearWaitingFor();
+ ptr.p->masterData.sendCounter.setWaitingFor(getOwnNodeId());
closeFiles(signal, ptr);
- return;
- case STARTED:
- jam();
- //Fall through
- case SCANNING:
- jam();
- BackupFilePtr filePtr;
- filePtr.i = RNIL;
- abortFile(signal, ptr, filePtr);
- return;
- case CLEANING:
- jam();
- cleanupSlaveResources(ptr);
- return;
- case INITIAL:
- jam();
- ndbrequire(false);
- return;
}
}
+
void
Backup::dumpUsedResources()
{
@@ -4576,12 +4301,8 @@ Backup::dumpUsedResources()
}
void
-Backup::cleanupMasterResources(BackupRecordPtr ptr)
+Backup::cleanup(Signal* signal, BackupRecordPtr ptr)
{
-#ifdef DEBUG_ABORT
- ndbout_c("******** Cleanup Master Resources *********");
- ndbout_c("backupId = %u, errorCode = %u", ptr.p->backupId, ptr.p->errorCode);
-#endif
TablePtr tabPtr;
for(ptr.p->tables.first(tabPtr); tabPtr.i != RNIL;ptr.p->tables.next(tabPtr))
@@ -4601,20 +4322,6 @@ Backup::cleanupMasterResources(BackupRecordPtr ptr)
tabPtr.p->triggerIds[j] = ILLEGAL_TRIGGER_ID;
}//for
}//for
- ptr.p->tables.release();
- ptr.p->triggers.release();
- ptr.p->okToCleanMaster = true;
-
- cleanupFinalResources(ptr);
-}
-
-void
-Backup::cleanupSlaveResources(BackupRecordPtr ptr)
-{
-#ifdef DEBUG_ABORT
- ndbout_c("******** Clean Up Slave Resources*********");
- ndbout_c("backupId = %u, errorCode = %u", ptr.p->backupId, ptr.p->errorCode);
-#endif
BackupFilePtr filePtr;
for(ptr.p->files.first(filePtr);
@@ -4626,35 +4333,65 @@ Backup::cleanupSlaveResources(BackupRecordPtr ptr)
ndbrequire(filePtr.p->scanRunning == 0);
filePtr.p->pages.release();
}//for
+
ptr.p->files.release();
+ ptr.p->tables.release();
+ ptr.p->triggers.release();
- cleanupFinalResources(ptr);
+ ptr.p->tables.release();
+ ptr.p->triggers.release();
+ ptr.p->pages.release();
+ ptr.p->backupId = ~0;
+
+ if(ptr.p->checkError())
+ removeBackup(signal, ptr);
+ else
+ c_backups.release(ptr);
}
+
void
-Backup::cleanupFinalResources(BackupRecordPtr ptr)
+Backup::removeBackup(Signal* signal, BackupRecordPtr ptr)
{
-#ifdef DEBUG_ABORT
- ndbout_c("******** Clean Up Final Resources*********");
- ndbout_c("backupId = %u, errorCode = %u", ptr.p->backupId, ptr.p->errorCode);
-#endif
+ jam();
+
+ FsRemoveReq * req = (FsRemoveReq *)signal->getDataPtrSend();
+ req->userReference = reference();
+ req->userPointer = ptr.i;
+ req->directory = 1;
+ req->ownDirectory = 1;
+ FsOpenReq::setVersion(req->fileNumber, 2);
+ FsOpenReq::setSuffix(req->fileNumber, FsOpenReq::S_CTL);
+ FsOpenReq::v2_setSequence(req->fileNumber, ptr.p->backupId);
+ FsOpenReq::v2_setNodeId(req->fileNumber, getOwnNodeId());
+ sendSignal(NDBFS_REF, GSN_FSREMOVEREQ, signal,
+ FsRemoveReq::SignalLength, JBA);
+}
- // if (!ptr.p->tables.empty() || !ptr.p->files.empty()) {
- if (!ptr.p->okToCleanMaster || !ptr.p->files.empty()) {
- jam();
-#ifdef DEBUG_ABORT
- ndbout_c("******** Waiting to do final cleanup");
-#endif
- return;
- }
- ptr.p->pages.release();
- ptr.p->masterData.state.setState(INITIAL);
- ptr.p->slaveState.setState(INITIAL);
- ptr.p->backupId = 0;
+void
+Backup::execFSREMOVEREF(Signal* signal)
+{
+ jamEntry();
+ FsRef * ref = (FsRef*)signal->getDataPtr();
+ const Uint32 ptrI = ref->userPointer;
- ptr.p->closingFiles = false;
- ptr.p->okToCleanMaster = true;
+ FsConf * conf = (FsConf*)signal->getDataPtr();
+ conf->userPointer = ptrI;
+ execFSREMOVECONF(signal);
+}
+
+void
+Backup::execFSREMOVECONF(Signal* signal){
+ jamEntry();
+ FsConf * conf = (FsConf*)signal->getDataPtr();
+ const Uint32 ptrI = conf->userPointer;
+
+ /**
+ * Get backup record
+ */
+ BackupRecordPtr ptr;
+ c_backupPool.getPtr(ptr, ptrI);
c_backups.release(ptr);
- // ndbrequire(false);
}
+
diff --git a/ndb/src/kernel/blocks/backup/Backup.hpp b/ndb/src/kernel/blocks/backup/Backup.hpp
index 1a5d6c7a925..7bcea5655b4 100644
--- a/ndb/src/kernel/blocks/backup/Backup.hpp
+++ b/ndb/src/kernel/blocks/backup/Backup.hpp
@@ -232,6 +232,7 @@ public:
*/
bool newScan();
bool scanConf(Uint32 noOfOps, Uint32 opLen);
+ bool closeScan();
/**
* Per record
@@ -330,7 +331,7 @@ public:
Uint8 fileOpened;
Uint8 fileRunning;
- Uint8 fileDone;
+ Uint8 fileClosing;
Uint8 scanRunning;
};
typedef Ptr<BackupFile> BackupFilePtr;
@@ -403,13 +404,11 @@ public:
ArrayPool<TriggerRecord> & trp)
: slaveState(b, validSlaveTransitions, validSlaveTransitionsCount,1)
, tables(tp), triggers(trp), files(bp), pages(pp)
- , masterData(b, validMasterTransitions, validMasterTransitionsCount)
- , backup(b)
- {
- closingFiles = false;
- okToCleanMaster = true;
- }
+ , masterData(b), backup(b)
+ {
+ }
+ Uint32 m_gsn;
CompoundState slaveState;
Uint32 clientRef;
@@ -420,9 +419,6 @@ public:
Uint32 errorCode;
NdbNodeBitmask nodes;
- bool okToCleanMaster;
- bool closingFiles;
-
Uint64 noOfBytes;
Uint64 noOfRecords;
Uint64 noOfLogBytes;
@@ -444,15 +440,13 @@ public:
SimpleProperties props;// Used for (un)packing backup request
struct MasterData {
- MasterData(Backup & b, const State valid[], Uint32 count)
- : state(b, valid, count, 0)
- {
- }
+ MasterData(Backup & b)
+ {
+ }
MutexHandle2<BACKUP_DEFINE_MUTEX> m_defineBackupMutex;
MutexHandle2<DICT_COMMIT_TABLE_MUTEX> m_dictCommitTableMutex;
Uint32 gsn;
- CompoundState state;
SignalCounter sendCounter;
Uint32 errorCode;
struct {
@@ -557,7 +551,8 @@ public:
void stopBackupReply(Signal* signal, BackupRecordPtr ptr, Uint32 nodeId);
void defineBackupRef(Signal*, BackupRecordPtr, Uint32 errCode = 0);
-
+ void backupFragmentRef(Signal * signal, BackupFilePtr filePtr);
+
void nextFragment(Signal*, BackupRecordPtr);
void sendCreateTrig(Signal*, BackupRecordPtr ptr, TablePtr tabPtr);
@@ -578,14 +573,14 @@ public:
void sendAbortBackupOrd(Signal* signal, BackupRecordPtr ptr, Uint32 errCode);
void sendAbortBackupOrdSlave(Signal* signal, BackupRecordPtr ptr,
Uint32 errCode);
- void masterAbort(Signal*, BackupRecordPtr ptr, bool controlledAbort);
+ void masterAbort(Signal*, BackupRecordPtr ptr);
void masterSendAbortBackup(Signal*, BackupRecordPtr ptr);
void slaveAbort(Signal*, BackupRecordPtr ptr);
void abortFile(Signal* signal, BackupRecordPtr ptr, BackupFilePtr filePtr);
void abortFileHook(Signal* signal, BackupFilePtr filePtr, bool scanDone);
- bool verifyNodesAlive(const NdbNodeBitmask& aNodeBitMask);
+ bool verifyNodesAlive(BackupRecordPtr, const NdbNodeBitmask& aNodeBitMask);
bool checkAbort(BackupRecordPtr ptr);
void checkNodeFail(Signal* signal,
BackupRecordPtr ptr,
@@ -603,9 +598,8 @@ public:
void sendBackupRef(BlockReference ref, Signal *signal,
Uint32 senderData, Uint32 errorCode);
void dumpUsedResources();
- void cleanupMasterResources(BackupRecordPtr ptr);
- void cleanupSlaveResources(BackupRecordPtr ptr);
- void cleanupFinalResources(BackupRecordPtr ptr);
+ void cleanup(Signal*, BackupRecordPtr ptr);
+ void abort_scan(Signal*, BackupRecordPtr ptr);
void removeBackup(Signal*, BackupRecordPtr ptr);
void sendSTTORRY(Signal*);
diff --git a/ndb/src/kernel/blocks/backup/Backup.txt b/ndb/src/kernel/blocks/backup/Backup.txt
index ee5e02bb549..73942c6ebdc 100644
--- a/ndb/src/kernel/blocks/backup/Backup.txt
+++ b/ndb/src/kernel/blocks/backup/Backup.txt
@@ -341,3 +341,28 @@ start backup
(ERROR_INSERTED(10022))) {
if (ERROR_INSERTED(10029)) {
if(trigPtr.p->operation->noOfBytes > 123 && ERROR_INSERTED(10030)) {
+
+----- XXX ---
+
+DEFINE_BACKUP_REF ->
+ ABORT_BACKUP_ORD(no reply) when all DEFINE_BACKUP replies has arrived
+
+START_BACKUP_REF
+ ABORT_BACKUP_ORD(no reply) when all START_BACKUP_ replies has arrived
+
+BACKUP_FRAGMENT_REF
+ ABORT_BACKUP_ORD(reply) directly to all nodes running BACKUP_FRAGMENT
+
+ When all nodes has replied BACKUP_FRAGMENT
+ ABORT_BACKUP_ORD(no reply)
+
+STOP_BACKUP_REF
+ ABORT_BACKUP_ORD(no reply) when all STOP_BACKUP_ replies has arrived
+
+NF_COMPLETE_REP
+ slave dies
+ master sends OUTSTANDING_REF to self
+ slave does nothing
+
+ master dies
+ slave elects self as master and sets only itself as participant
diff --git a/ndb/src/kernel/blocks/backup/BackupInit.cpp b/ndb/src/kernel/blocks/backup/BackupInit.cpp
index 08fa089a9c0..eae72f43db5 100644
--- a/ndb/src/kernel/blocks/backup/BackupInit.cpp
+++ b/ndb/src/kernel/blocks/backup/BackupInit.cpp
@@ -175,7 +175,7 @@ Backup::Backup(const Configuration & conf) :
addRecSignal(GSN_START_BACKUP_CONF, &Backup::execSTART_BACKUP_CONF);
addRecSignal(GSN_BACKUP_FRAGMENT_REQ, &Backup::execBACKUP_FRAGMENT_REQ);
- //addRecSignal(GSN_BACKUP_FRAGMENT_REF, &Backup::execBACKUP_FRAGMENT_REF);
+ addRecSignal(GSN_BACKUP_FRAGMENT_REF, &Backup::execBACKUP_FRAGMENT_REF);
addRecSignal(GSN_BACKUP_FRAGMENT_CONF, &Backup::execBACKUP_FRAGMENT_CONF);
addRecSignal(GSN_STOP_BACKUP_REQ, &Backup::execSTOP_BACKUP_REQ);
diff --git a/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp b/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp
index dfae180ae71..0274ef4af3e 100644
--- a/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp
+++ b/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp
@@ -126,6 +126,7 @@ Cmvmi::Cmvmi(const Configuration & conf) :
}
setNodeInfo(getOwnNodeId()).m_connected = true;
+ setNodeInfo(getOwnNodeId()).m_version = ndbGetOwnVersion();
}
Cmvmi::~Cmvmi()
diff --git a/ndb/src/kernel/blocks/dbacc/Dbacc.hpp b/ndb/src/kernel/blocks/dbacc/Dbacc.hpp
index 64b947b5462..246afc5ceb8 100644
--- a/ndb/src/kernel/blocks/dbacc/Dbacc.hpp
+++ b/ndb/src/kernel/blocks/dbacc/Dbacc.hpp
@@ -1022,7 +1022,7 @@ private:
Uint32 placeReadInLockQueue(Signal* signal);
void placeSerialQueueRead(Signal* signal);
void checkOnlyReadEntry(Signal* signal);
- void getNoParallelTransaction(Signal* signal);
+ Uint32 getNoParallelTransaction(const Operationrec*);
void moveLastParallelQueue(Signal* signal);
void moveLastParallelQueueWrite(Signal* signal);
Uint32 placeWriteInLockQueue(Signal* signal);
@@ -1100,6 +1100,8 @@ private:
Uint32 executeNextOperation(Signal* signal);
void releaselock(Signal* signal);
void takeOutFragWaitQue(Signal* signal);
+ void check_lock_upgrade(Signal* signal, OperationrecPtr lock_owner,
+ OperationrecPtr release_op);
void allocOverflowPage(Signal* signal);
bool getrootfragmentrec(Signal* signal, RootfragmentrecPtr&, Uint32 fragId);
void insertLockOwnersList(Signal* signal, const OperationrecPtr&);
@@ -1263,7 +1265,6 @@ private:
OperationrecPtr mlpqOperPtr;
OperationrecPtr queOperPtr;
OperationrecPtr readWriteOpPtr;
- OperationrecPtr tgnptMainOpPtr;
Uint32 cfreeopRec;
Uint32 coprecsize;
/* --------------------------------------------------------------------------------- */
@@ -1514,7 +1515,6 @@ private:
Uint32 turlIndex;
Uint32 tlfrTmp1;
Uint32 tlfrTmp2;
- Uint32 tgnptNrTransaction;
Uint32 tudqeIndex;
Uint32 tscanTrid1;
Uint32 tscanTrid2;
diff --git a/ndb/src/kernel/blocks/dbacc/DbaccMain.cpp b/ndb/src/kernel/blocks/dbacc/DbaccMain.cpp
index 17c5a31cbed..44c891fc220 100644
--- a/ndb/src/kernel/blocks/dbacc/DbaccMain.cpp
+++ b/ndb/src/kernel/blocks/dbacc/DbaccMain.cpp
@@ -1936,9 +1936,7 @@ void Dbacc::insertelementLab(Signal* signal)
/* --------------------------------------------------------------------------------- */
Uint32 Dbacc::placeReadInLockQueue(Signal* signal)
{
- tgnptMainOpPtr = queOperPtr;
- getNoParallelTransaction(signal);
- if (tgnptNrTransaction == 1) {
+ if (getNoParallelTransaction(queOperPtr.p) == 1) {
if ((queOperPtr.p->transId1 == operationRecPtr.p->transId1) &&
(queOperPtr.p->transId2 == operationRecPtr.p->transId2)) {
/* --------------------------------------------------------------------------------- */
@@ -2021,9 +2019,7 @@ void Dbacc::placeSerialQueueRead(Signal* signal)
checkOnlyReadEntry(signal);
return;
}//if
- tgnptMainOpPtr = readWriteOpPtr;
- getNoParallelTransaction(signal);
- if (tgnptNrTransaction == 1) {
+ if (getNoParallelTransaction(readWriteOpPtr.p) == 1) {
jam();
/* --------------------------------------------------------------------------------- */
/* THERE WAS ONLY ONE TRANSACTION INVOLVED IN THE PARALLEL QUEUE. IF THIS IS OUR */
@@ -2104,24 +2100,23 @@ void Dbacc::checkOnlyReadEntry(Signal* signal)
/* --------------------------------------------------------------------------------- */
/* GET_NO_PARALLEL_TRANSACTION */
/* --------------------------------------------------------------------------------- */
-void Dbacc::getNoParallelTransaction(Signal* signal)
+Uint32
+Dbacc::getNoParallelTransaction(const Operationrec * op)
{
- OperationrecPtr tnptOpPtr;
-
- tgnptNrTransaction = 1;
- tnptOpPtr.i = tgnptMainOpPtr.p->nextParallelQue;
- while ((tnptOpPtr.i != RNIL) &&
- (tgnptNrTransaction == 1)) {
+ OperationrecPtr tmp;
+
+ tmp.i= op->nextParallelQue;
+ Uint32 transId[2] = { op->transId1, op->transId2 };
+ while (tmp.i != RNIL)
+ {
jam();
- ptrCheckGuard(tnptOpPtr, coprecsize, operationrec);
- if ((tnptOpPtr.p->transId1 == tgnptMainOpPtr.p->transId1) &&
- (tnptOpPtr.p->transId2 == tgnptMainOpPtr.p->transId2)) {
- tnptOpPtr.i = tnptOpPtr.p->nextParallelQue;
- } else {
- jam();
- tgnptNrTransaction++;
- }//if
- }//while
+ ptrCheckGuard(tmp, coprecsize, operationrec);
+ if (tmp.p->transId1 == transId[0] && tmp.p->transId2 == transId[1])
+ tmp.i = tmp.p->nextParallelQue;
+ else
+ return 2;
+ }
+ return 1;
}//Dbacc::getNoParallelTransaction()
void Dbacc::moveLastParallelQueue(Signal* signal)
@@ -2162,9 +2157,7 @@ void Dbacc::moveLastParallelQueueWrite(Signal* signal)
/* --------------------------------------------------------------------------------- */
Uint32 Dbacc::placeWriteInLockQueue(Signal* signal)
{
- tgnptMainOpPtr = queOperPtr;
- getNoParallelTransaction(signal);
- if (!((tgnptNrTransaction == 1) &&
+ if (!((getNoParallelTransaction(queOperPtr.p) == 1) &&
(queOperPtr.p->transId1 == operationRecPtr.p->transId1) &&
(queOperPtr.p->transId2 == operationRecPtr.p->transId2))) {
jam();
@@ -2215,9 +2208,7 @@ void Dbacc::placeSerialQueueWrite(Signal* signal)
}//if
readWriteOpPtr.i = readWriteOpPtr.p->nextSerialQue;
ptrCheckGuard(readWriteOpPtr, coprecsize, operationrec);
- tgnptMainOpPtr = readWriteOpPtr;
- getNoParallelTransaction(signal);
- if (tgnptNrTransaction == 1) {
+ if (getNoParallelTransaction(readWriteOpPtr.p) == 1) {
/* --------------------------------------------------------------------------------- */
/* THERE WAS ONLY ONE TRANSACTION INVOLVED IN THE PARALLEL QUEUE. IF THIS IS OUR */
/* TRANSACTION WE CAN STILL GET HOLD OF THE LOCK. */
@@ -5802,9 +5793,153 @@ void Dbacc::commitOperation(Signal* signal)
ptrCheckGuard(tolqTmpPtr, coprecsize, operationrec);
tolqTmpPtr.p->prevParallelQue = operationRecPtr.p->prevParallelQue;
}//if
- }//if
+
+ /**
+ * Check possible lock upgrade
+ * 1) Find lock owner
+ * 2) Count transactions in parallel que
+ * 3) If count == 1 and TRANSID(next serial) == TRANSID(lock owner)
+ * upgrade next serial
+ */
+ if(operationRecPtr.p->lockMode)
+ {
+ jam();
+ /**
+ * Committing a non shared operation can't lead to lock upgrade
+ */
+ return;
+ }
+
+ OperationrecPtr lock_owner;
+ lock_owner.i = operationRecPtr.p->prevParallelQue;
+ ptrCheckGuard(lock_owner, coprecsize, operationrec);
+ Uint32 transid[2] = { lock_owner.p->transId1,
+ lock_owner.p->transId2 };
+
+
+ while(lock_owner.p->prevParallelQue != RNIL)
+ {
+ lock_owner.i = lock_owner.p->prevParallelQue;
+ ptrCheckGuard(lock_owner, coprecsize, operationrec);
+
+ if(lock_owner.p->transId1 != transid[0] ||
+ lock_owner.p->transId2 != transid[1])
+ {
+ jam();
+ /**
+ * If more than 1 trans in lock queue -> no lock upgrade
+ */
+ return;
+ }
+ }
+
+ check_lock_upgrade(signal, lock_owner, operationRecPtr);
+ }
}//Dbacc::commitOperation()
+void
+Dbacc::check_lock_upgrade(Signal* signal,
+ OperationrecPtr lock_owner,
+ OperationrecPtr release_op)
+{
+ if((lock_owner.p->transId1 == release_op.p->transId1 &&
+ lock_owner.p->transId2 == release_op.p->transId2) ||
+ release_op.p->lockMode ||
+ lock_owner.p->nextSerialQue == RNIL)
+ {
+ jam();
+ /**
+ * No lock upgrade if same trans or lock owner has no serial queue
+ * or releasing non shared op
+ */
+ return;
+ }
+
+ OperationrecPtr next;
+ next.i = lock_owner.p->nextSerialQue;
+ ptrCheckGuard(next, coprecsize, operationrec);
+
+ if(lock_owner.p->transId1 != next.p->transId1 ||
+ lock_owner.p->transId2 != next.p->transId2)
+ {
+ jam();
+ /**
+ * No lock upgrad if !same trans in serial queue
+ */
+ return;
+ }
+
+ if (getNoParallelTransaction(lock_owner.p) > 1)
+ {
+ jam();
+ /**
+ * No lock upgrade if more than 1 transaction in parallell queue
+ */
+ return;
+ }
+
+ if (getNoParallelTransaction(next.p) > 1)
+ {
+ jam();
+ /**
+ * No lock upgrade if more than 1 transaction in next's parallell queue
+ */
+ return;
+ }
+
+ OperationrecPtr tmp;
+ tmp.i = lock_owner.p->nextSerialQue = next.p->nextSerialQue;
+ if(tmp.i != RNIL)
+ {
+ ptrCheckGuard(tmp, coprecsize, operationrec);
+ ndbassert(tmp.p->prevSerialQue == next.i);
+ tmp.p->prevSerialQue = lock_owner.i;
+ }
+ next.p->nextSerialQue = next.p->prevSerialQue = RNIL;
+
+ // Find end of parallell que
+ tmp = lock_owner;
+ Uint32 lockMode = next.p->lockMode > lock_owner.p->lockMode ?
+ next.p->lockMode : lock_owner.p->lockMode;
+ while(tmp.p->nextParallelQue != RNIL)
+ {
+ jam();
+ tmp.i = tmp.p->nextParallelQue;
+ tmp.p->lockMode = lockMode;
+ ptrCheckGuard(tmp, coprecsize, operationrec);
+ }
+ tmp.p->lockMode = lockMode;
+
+ next.p->prevParallelQue = tmp.i;
+ tmp.p->nextParallelQue = next.i;
+
+ OperationrecPtr save = operationRecPtr;
+
+ Uint32 localdata[2];
+ localdata[0] = lock_owner.p->localdata[0];
+ localdata[1] = lock_owner.p->localdata[1];
+ do {
+ next.p->localdata[0] = localdata[0];
+ next.p->localdata[1] = localdata[1];
+ next.p->lockMode = lockMode;
+
+ operationRecPtr = next;
+ executeNextOperation(signal);
+ if (next.p->nextParallelQue != RNIL)
+ {
+ jam();
+ next.i = next.p->nextParallelQue;
+ ptrCheckGuard(next, coprecsize, operationrec);
+ } else {
+ jam();
+ break;
+ }//if
+ } while (1);
+
+ operationRecPtr = save;
+
+}
+
/* ------------------------------------------------------------------------- */
/* RELEASELOCK */
/* RESETS LOCK OF AN ELEMENT. */
@@ -5841,6 +5976,8 @@ void Dbacc::releaselock(Signal* signal)
ptrCheckGuard(trlTmpOperPtr, coprecsize, operationrec);
trlTmpOperPtr.p->prevSerialQue = trlOperPtr.i;
}//if
+
+ check_lock_upgrade(signal, copyInOperPtr, operationRecPtr);
/* --------------------------------------------------------------------------------- */
/* SINCE THERE ARE STILL ITEMS IN THE PARALLEL QUEUE WE NEED NOT WORRY ABOUT */
/* STARTING QUEUED OPERATIONS. THUS WE CAN END HERE. */
@@ -8348,7 +8485,7 @@ void Dbacc::checkSendLcpConfLab(Signal* signal)
break;
}//switch
lcpConnectptr.p->noOfLcpConf++;
- ndbrequire(lcpConnectptr.p->noOfLcpConf <= 2);
+ ndbrequire(lcpConnectptr.p->noOfLcpConf <= 4);
fragrecptr.p->fragState = ACTIVEFRAG;
rlpPageptr.i = fragrecptr.p->zeroPagePtr;
ptrCheckGuard(rlpPageptr, cpagesize, page8);
@@ -8366,7 +8503,7 @@ void Dbacc::checkSendLcpConfLab(Signal* signal)
}//for
signal->theData[0] = fragrecptr.p->lcpLqhPtr;
sendSignal(lcpConnectptr.p->lcpUserblockref, GSN_ACC_LCPCONF, signal, 1, JBB);
- if (lcpConnectptr.p->noOfLcpConf == 2) {
+ if (lcpConnectptr.p->noOfLcpConf == 4) {
jam();
releaseLcpConnectRec(signal);
rootfragrecptr.i = fragrecptr.p->myroot;
@@ -8397,6 +8534,13 @@ void Dbacc::execACC_CONTOPREQ(Signal* signal)
/* LOCAL FRAG ID */
tresult = 0;
ptrCheckGuard(lcpConnectptr, clcpConnectsize, lcpConnectrec);
+ if(ERROR_INSERTED(3002) && lcpConnectptr.p->noOfLcpConf < 2)
+ {
+ sendSignalWithDelay(cownBlockref, GSN_ACC_CONTOPREQ, signal, 300,
+ signal->getLength());
+ return;
+ }
+
ndbrequire(lcpConnectptr.p->lcpstate == LCP_ACTIVE);
rootfragrecptr.i = lcpConnectptr.p->rootrecptr;
ptrCheckGuard(rootfragrecptr, crootfragmentsize, rootfragmentrec);
@@ -8430,6 +8574,15 @@ void Dbacc::execACC_CONTOPREQ(Signal* signal)
}//while
signal->theData[0] = fragrecptr.p->lcpLqhPtr;
sendSignal(lcpConnectptr.p->lcpUserblockref, GSN_ACC_CONTOPCONF, signal, 1, JBA);
+
+ lcpConnectptr.p->noOfLcpConf++;
+ if (lcpConnectptr.p->noOfLcpConf == 4) {
+ jam();
+ releaseLcpConnectRec(signal);
+ rootfragrecptr.i = fragrecptr.p->myroot;
+ ptrCheckGuard(rootfragrecptr, crootfragmentsize, rootfragmentrec);
+ rootfragrecptr.p->rootState = ACTIVEROOT;
+ }//if
return; /* ALL QUEUED OPERATION ARE RESTARTED IF NEEDED. */
}//Dbacc::execACC_CONTOPREQ()
diff --git a/ndb/src/kernel/blocks/dbdict/Dbdict.cpp b/ndb/src/kernel/blocks/dbdict/Dbdict.cpp
index 7247b7e2b9c..184db794057 100644
--- a/ndb/src/kernel/blocks/dbdict/Dbdict.cpp
+++ b/ndb/src/kernel/blocks/dbdict/Dbdict.cpp
@@ -9811,11 +9811,20 @@ Dbdict::execBUILDINDXREQ(Signal* signal)
requestType == BuildIndxReq::RT_ALTER_INDEX ||
requestType == BuildIndxReq::RT_SYSTEMRESTART) {
jam();
+
+ const bool isLocal = req->getRequestFlag() & RequestFlag::RF_LOCAL;
+ NdbNodeBitmask receiverNodes = c_aliveNodes;
+ if (isLocal) {
+ receiverNodes.clear();
+ receiverNodes.set(getOwnNodeId());
+ }
+
if (signal->getLength() == BuildIndxReq::SignalLength) {
jam();
- if (getOwnNodeId() != c_masterNodeId) {
+
+ if (!isLocal && getOwnNodeId() != c_masterNodeId) {
jam();
-
+
releaseSections(signal);
OpBuildIndex opBad;
opPtr.p = &opBad;
@@ -9828,9 +9837,9 @@ Dbdict::execBUILDINDXREQ(Signal* signal)
}
// forward initial request plus operation key to all
req->setOpKey(++c_opRecordSequence);
- NodeReceiverGroup rg(DBDICT, c_aliveNodes);
+ NodeReceiverGroup rg(DBDICT, receiverNodes);
sendSignal(rg, GSN_BUILDINDXREQ,
- signal, BuildIndxReq::SignalLength + 1, JBB);
+ signal, BuildIndxReq::SignalLength + 1, JBB);
return;
}
// seize operation record
@@ -9853,7 +9862,7 @@ Dbdict::execBUILDINDXREQ(Signal* signal)
}
c_opBuildIndex.add(opPtr);
// master expects to hear from all
- opPtr.p->m_signalCounter = c_aliveNodes;
+ opPtr.p->m_signalCounter = receiverNodes;
buildIndex_sendReply(signal, opPtr, false);
return;
}
@@ -10208,10 +10217,20 @@ Dbdict::buildIndex_sendSlaveReq(Signal* signal, OpBuildIndexPtr opPtr)
req->setConnectionPtr(opPtr.p->key);
req->setRequestType(opPtr.p->m_requestType);
req->addRequestFlag(opPtr.p->m_requestFlag);
- opPtr.p->m_signalCounter = c_aliveNodes;
- NodeReceiverGroup rg(DBDICT, c_aliveNodes);
- sendSignal(rg, GSN_BUILDINDXREQ,
- signal, BuildIndxReq::SignalLength, JBB);
+ if(opPtr.p->m_requestFlag & RequestFlag::RF_LOCAL)
+ {
+ opPtr.p->m_signalCounter.clearWaitingFor();
+ opPtr.p->m_signalCounter.setWaitingFor(getOwnNodeId());
+ sendSignal(reference(), GSN_BUILDINDXREQ,
+ signal, BuildIndxReq::SignalLength, JBB);
+ }
+ else
+ {
+ opPtr.p->m_signalCounter = c_aliveNodes;
+ NodeReceiverGroup rg(DBDICT, c_aliveNodes);
+ sendSignal(rg, GSN_BUILDINDXREQ,
+ signal, BuildIndxReq::SignalLength, JBB);
+ }
}
void
diff --git a/ndb/src/kernel/blocks/dblqh/Dblqh.hpp b/ndb/src/kernel/blocks/dblqh/Dblqh.hpp
index 0c63cb5fe17..19e055a3011 100644
--- a/ndb/src/kernel/blocks/dblqh/Dblqh.hpp
+++ b/ndb/src/kernel/blocks/dblqh/Dblqh.hpp
@@ -968,7 +968,6 @@ public:
enum LcpState {
LCP_IDLE = 0,
- LCP_STARTED = 1,
LCP_COMPLETED = 2,
LCP_WAIT_FRAGID = 3,
LCP_WAIT_TUP_PREPLCP = 4,
@@ -2266,7 +2265,7 @@ private:
void sendCopyActiveConf(Signal* signal,Uint32 tableId);
void checkLcpCompleted(Signal* signal);
void checkLcpHoldop(Signal* signal);
- void checkLcpStarted(Signal* signal);
+ bool checkLcpStarted(Signal* signal);
void checkLcpTupprep(Signal* signal);
void getNextFragForLcp(Signal* signal);
void initLcpLocAcc(Signal* signal, Uint32 fragId);
diff --git a/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp b/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp
index 3358593b150..3967098b8e9 100644
--- a/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp
+++ b/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp
@@ -10351,8 +10351,8 @@ void Dblqh::execTUP_LCPSTARTED(Signal* signal)
void Dblqh::lcpStartedLab(Signal* signal)
{
- checkLcpStarted(signal);
- if (lcpPtr.p->lcpState == LcpRecord::LCP_STARTED) {
+ if (checkLcpStarted(signal))
+ {
jam();
/* ----------------------------------------------------------------------
* THE LOCAL CHECKPOINT HAS BEEN STARTED. IT IS NOW TIME TO
@@ -10432,26 +10432,7 @@ void Dblqh::execLQH_RESTART_OP(Signal* signal)
lcpPtr.i = signal->theData[1];
ptrCheckGuard(lcpPtr, clcpFileSize, lcpRecord);
ndbrequire(fragptr.p->fragStatus == Fragrecord::BLOCKED);
- if (lcpPtr.p->lcpState == LcpRecord::LCP_STARTED) {
- jam();
- /***********************************************************************/
- /* THIS SIGNAL CAN ONLY BE RECEIVED WHEN FRAGMENT IS BLOCKED AND
- * THE LOCAL CHECKPOINT HAS BEEN STARTED. THE BLOCKING WILL BE
- * REMOVED AS SOON AS ALL OPERATIONS HAVE BEEN STARTED.
- ***********************************************************************/
- restartOperationsLab(signal);
- } else if (lcpPtr.p->lcpState == LcpRecord::LCP_BLOCKED_COMP) {
- jam();
- /*******************************************************************>
- * THE CHECKPOINT IS COMPLETED BUT HAS NOT YET STARTED UP
- * ALL OPERATIONS AGAIN.
- * WE PERFORM THIS START-UP BEFORE CONTINUING WITH THE NEXT
- * FRAGMENT OF THE LOCAL CHECKPOINT TO AVOID ANY STRANGE ERRORS.
- *******************************************************************> */
- restartOperationsLab(signal);
- } else {
- ndbrequire(false);
- }
+ restartOperationsLab(signal);
}//Dblqh::execLQH_RESTART_OP()
void Dblqh::restartOperationsLab(Signal* signal)
@@ -11000,7 +10981,8 @@ void Dblqh::checkLcpHoldop(Signal* signal)
*
* SUBROUTINE SHORT NAME = CLS
* ========================================================================== */
-void Dblqh::checkLcpStarted(Signal* signal)
+bool
+Dblqh::checkLcpStarted(Signal* signal)
{
LcpLocRecordPtr clsLcpLocptr;
@@ -11010,7 +10992,7 @@ void Dblqh::checkLcpStarted(Signal* signal)
do {
ptrCheckGuard(clsLcpLocptr, clcpLocrecFileSize, lcpLocRecord);
if (clsLcpLocptr.p->lcpLocstate == LcpLocRecord::ACC_WAIT_STARTED){
- return;
+ return false;
}//if
clsLcpLocptr.i = clsLcpLocptr.p->nextLcpLoc;
i++;
@@ -11021,12 +11003,13 @@ void Dblqh::checkLcpStarted(Signal* signal)
do {
ptrCheckGuard(clsLcpLocptr, clcpLocrecFileSize, lcpLocRecord);
if (clsLcpLocptr.p->lcpLocstate == LcpLocRecord::TUP_WAIT_STARTED){
- return;
+ return false;
}//if
clsLcpLocptr.i = clsLcpLocptr.p->nextLcpLoc;
i++;
} while (clsLcpLocptr.i != RNIL);
- lcpPtr.p->lcpState = LcpRecord::LCP_STARTED;
+
+ return true;
}//Dblqh::checkLcpStarted()
/* ==========================================================================
@@ -11187,20 +11170,12 @@ void Dblqh::sendAccContOp(Signal* signal)
do {
ptrCheckGuard(sacLcpLocptr, clcpLocrecFileSize, lcpLocRecord);
sacLcpLocptr.p->accContCounter = 0;
- if(sacLcpLocptr.p->lcpLocstate == LcpLocRecord::ACC_STARTED){
- /* ------------------------------------------------------------------- */
- /*SEND START OPERATIONS TO ACC AGAIN */
- /* ------------------------------------------------------------------- */
- signal->theData[0] = lcpPtr.p->lcpAccptr;
- signal->theData[1] = sacLcpLocptr.p->locFragid;
- sendSignal(fragptr.p->accBlockref, GSN_ACC_CONTOPREQ, signal, 2, JBA);
- count++;
- } else if(sacLcpLocptr.p->lcpLocstate == LcpLocRecord::ACC_COMPLETED){
- signal->theData[0] = sacLcpLocptr.i;
- sendSignal(reference(), GSN_ACC_CONTOPCONF, signal, 1, JBB);
- } else {
- ndbrequire(false);
- }
+ /* ------------------------------------------------------------------- */
+ /*SEND START OPERATIONS TO ACC AGAIN */
+ /* ------------------------------------------------------------------- */
+ signal->theData[0] = lcpPtr.p->lcpAccptr;
+ signal->theData[1] = sacLcpLocptr.p->locFragid;
+ sendSignal(fragptr.p->accBlockref, GSN_ACC_CONTOPREQ, signal, 2, JBA);
sacLcpLocptr.i = sacLcpLocptr.p->nextLcpLoc;
} while (sacLcpLocptr.i != RNIL);
@@ -11236,9 +11211,18 @@ void Dblqh::sendStartLcp(Signal* signal)
signal->theData[0] = stlLcpLocptr.i;
signal->theData[1] = cownref;
signal->theData[2] = stlLcpLocptr.p->tupRef;
- sendSignal(fragptr.p->tupBlockref, GSN_TUP_LCPREQ, signal, 3, JBA);
+ if(ERROR_INSERTED(5077))
+ sendSignalWithDelay(fragptr.p->tupBlockref, GSN_TUP_LCPREQ,
+ signal, 5000, 3);
+ else
+ sendSignal(fragptr.p->tupBlockref, GSN_TUP_LCPREQ, signal, 3, JBA);
stlLcpLocptr.i = stlLcpLocptr.p->nextLcpLoc;
} while (stlLcpLocptr.i != RNIL);
+
+ if(ERROR_INSERTED(5077))
+ {
+ ndbout_c("Delayed TUP_LCPREQ with 5 sec");
+ }
}//Dblqh::sendStartLcp()
/* ------------------------------------------------------------------------- */
diff --git a/ndb/src/kernel/blocks/ndbfs/OpenFiles.hpp b/ndb/src/kernel/blocks/ndbfs/OpenFiles.hpp
index b944bb5485b..0fee687f1bc 100644
--- a/ndb/src/kernel/blocks/ndbfs/OpenFiles.hpp
+++ b/ndb/src/kernel/blocks/ndbfs/OpenFiles.hpp
@@ -82,8 +82,14 @@ inline bool OpenFiles::insert(AsyncFile* file, Uint16 id){
continue;
if(strcmp(m_files[i].m_file->theFileName.c_str(),
- file->theFileName.c_str()) == 0){
- ERROR_SET(fatal, AFS_ERROR_ALLREADY_OPEN,"","OpenFiles::insert()");
+ file->theFileName.c_str()) == 0)
+ {
+ BaseString names;
+ names.assfmt("open: >%s< existing: >%s<",
+ file->theFileName.c_str(),
+ m_files[i].m_file->theFileName.c_str());
+ ERROR_SET(fatal, AFS_ERROR_ALLREADY_OPEN, names.c_str(),
+ "OpenFiles::insert()");
}
}
diff --git a/ndb/src/mgmapi/mgmapi.cpp b/ndb/src/mgmapi/mgmapi.cpp
index 68106c4689d..a8931fb32ea 100644
--- a/ndb/src/mgmapi/mgmapi.cpp
+++ b/ndb/src/mgmapi/mgmapi.cpp
@@ -1565,9 +1565,9 @@ ndb_mgm_start_backup(NdbMgmHandle handle, int wait_completed,
{ // start backup can take some time, set timeout high
Uint64 old_timeout= handle->read_timeout;
if (wait_completed == 2)
- handle->read_timeout= 30*60*1000; // 30 minutes
+ handle->read_timeout= 48*60*60*1000; // 48 hours
else if (wait_completed == 1)
- handle->read_timeout= 5*60*1000; // 5 minutes
+ handle->read_timeout= 10*60*1000; // 10 minutes
reply = ndb_mgm_call(handle, start_backup_reply, "start backup", &args);
handle->read_timeout= old_timeout;
}
diff --git a/ndb/src/mgmsrv/MgmtSrvr.cpp b/ndb/src/mgmsrv/MgmtSrvr.cpp
index fb05e57e138..ceaedc9955b 100644
--- a/ndb/src/mgmsrv/MgmtSrvr.cpp
+++ b/ndb/src/mgmsrv/MgmtSrvr.cpp
@@ -791,7 +791,7 @@ MgmtSrvr::restartNode(int processId, bool nostart,
result = sendSignal(processId, NO_WAIT, signal, true);
}
- if (result == -1) {
+ if (result == -1 && theWaitState != WAIT_NODEFAILURE) {
m_stopRec.inUse = false;
return SEND_OR_RECEIVE_FAILED;
}
@@ -1920,6 +1920,7 @@ MgmtSrvr::handleReceivedSignal(NdbApiSignal* signal)
#ifdef VM_TRACE
ndbout_c("I'm not master resending to %d", aNodeId);
#endif
+ theWaitNode= aNodeId;
NdbApiSignal aSignal(_ownReference);
BackupReq* req = CAST_PTR(BackupReq, aSignal.getDataPtrSend());
aSignal.set(TestOrd::TraceAPI, BACKUP, GSN_BACKUP_REQ,
@@ -1947,6 +1948,7 @@ MgmtSrvr::handleReceivedSignal(NdbApiSignal* signal)
event.Event = BackupEvent::BackupAborted;
event.Aborted.Reason = rep->reason;
event.Aborted.BackupId = rep->backupId;
+ event.Aborted.ErrorCode = rep->reason;
backupCallback(event);
}
break;
@@ -2076,6 +2078,13 @@ MgmtSrvr::handleStatus(NodeId nodeId, bool alive, bool nfComplete)
handleStopReply(nodeId, 0);
DBUG_VOID_RETURN;
}
+
+ if(theWaitNode == nodeId &&
+ theWaitState != NO_WAIT && theWaitState != WAIT_STOP)
+ {
+ theWaitState = WAIT_NODEFAILURE;
+ NdbCondition_Signal(theMgmtWaitForResponseCondPtr);
+ }
}
eventReport(_ownNodeId, theData);
@@ -2427,7 +2436,7 @@ MgmtSrvr::startBackup(Uint32& backupId, int waitCompleted)
int result;
if (waitCompleted == 2) {
result = sendRecSignal(nodeId, WAIT_BACKUP_COMPLETED,
- signal, true, 30*60*1000 /*30 secs*/);
+ signal, true, 48*60*60*1000 /* 48 hours */);
}
else if (waitCompleted == 1) {
result = sendRecSignal(nodeId, WAIT_BACKUP_STARTED,
@@ -2456,22 +2465,6 @@ MgmtSrvr::startBackup(Uint32& backupId, int waitCompleted)
return -1;
break;
}
- } else {
- switch(m_lastBackupEvent.Event){
- case BackupEvent::BackupCompleted:
- backupId = m_lastBackupEvent.Completed.BackupId;
- break;
- case BackupEvent::BackupStarted:
- backupId = m_lastBackupEvent.Started.BackupId;
- break;
- case BackupEvent::BackupFailedToStart:
- return m_lastBackupEvent.FailedToStart.ErrorCode;
- case BackupEvent::BackupAborted:
- return m_lastBackupEvent.Aborted.ErrorCode;
- default:
- return -1;
- break;
- }
}
return 0;
diff --git a/ndb/src/mgmsrv/MgmtSrvr.hpp b/ndb/src/mgmsrv/MgmtSrvr.hpp
index a05b29b7f31..ce78983b3c3 100644
--- a/ndb/src/mgmsrv/MgmtSrvr.hpp
+++ b/ndb/src/mgmsrv/MgmtSrvr.hpp
@@ -611,7 +611,8 @@ private:
WAIT_STOP,
WAIT_BACKUP_STARTED,
WAIT_BACKUP_COMPLETED,
- WAIT_VERSION
+ WAIT_VERSION,
+ WAIT_NODEFAILURE
};
/**
@@ -695,6 +696,7 @@ private:
NdbApiSignal* theSignalIdleList;
// List of unused signals
+ Uint32 theWaitNode;
WaitSignalType theWaitState;
// State denoting a set of signals we accept to recieve.
diff --git a/ndb/src/mgmsrv/MgmtSrvrGeneralSignalHandling.cpp b/ndb/src/mgmsrv/MgmtSrvrGeneralSignalHandling.cpp
index 2126c9d358d..f93948abc75 100644
--- a/ndb/src/mgmsrv/MgmtSrvrGeneralSignalHandling.cpp
+++ b/ndb/src/mgmsrv/MgmtSrvrGeneralSignalHandling.cpp
@@ -108,6 +108,7 @@ MgmtSrvr::sendRecSignal(Uint16 aNodeId,
return -1;
}
theWaitState = aWaitState;
+ theWaitNode = aNodeId;
return receiveOptimisedResponse(waitTime);
}
@@ -119,11 +120,12 @@ MgmtSrvr::receiveOptimisedResponse(int waitTime)
theFacade->checkForceSend(_blockNumber);
NDB_TICKS maxTime = NdbTick_CurrentMillisecond() + waitTime;
- while (theWaitState != NO_WAIT && waitTime > 0) {
+ while (theWaitState != NO_WAIT && theWaitState != WAIT_NODEFAILURE
+ && waitTime > 0) {
NdbCondition_WaitTimeout(theMgmtWaitForResponseCondPtr,
theFacade->theMutexPtr,
waitTime);
- if(theWaitState == NO_WAIT)
+ if(theWaitState == NO_WAIT || theWaitState == WAIT_NODEFAILURE)
break;
waitTime = (maxTime - NdbTick_CurrentMillisecond());
}//while
diff --git a/ndb/src/ndbapi/Ndbif.cpp b/ndb/src/ndbapi/Ndbif.cpp
index a4f233709c4..1caebe436ef 100644
--- a/ndb/src/ndbapi/Ndbif.cpp
+++ b/ndb/src/ndbapi/Ndbif.cpp
@@ -453,7 +453,7 @@ Ndb::handleReceivedSignal(NdbApiSignal* aSignal, LinearSectionPtr ptr[3])
tFirstDataPtr = int2void(tFirstData);
if(tFirstDataPtr != 0){
tOp = void2rec_op(tFirstDataPtr);
- if (tOp->checkMagicNumber() == 0) {
+ if (tOp->checkMagicNumber(false) == 0) {
tCon = tOp->theNdbCon;
if (tCon != NULL) {
if ((tCon->theSendStatus == NdbConnection::sendTC_OP) ||
@@ -466,11 +466,11 @@ Ndb::handleReceivedSignal(NdbApiSignal* aSignal, LinearSectionPtr ptr[3])
}//if
}//if
}//if
- } else {
+ }
#ifdef VM_TRACE
- ndbout_c("Recevied TCKEY_FAILREF wo/ operation");
+ ndbout_c("Recevied TCKEY_FAILREF wo/ operation");
#endif
- }
+ return;
break;
}
case GSN_TCKEYREF:
diff --git a/ndb/src/ndbapi/ndberror.c b/ndb/src/ndbapi/ndberror.c
index f052200b67d..bbc82a21324 100644
--- a/ndb/src/ndbapi/ndberror.c
+++ b/ndb/src/ndbapi/ndberror.c
@@ -140,10 +140,10 @@ ErrorBundle ErrorCodes[] = {
{ 4008, UR, "Receive from NDB failed" },
{ 4009, UR, "Cluster Failure" },
{ 4012, UR,
- "Time-out, most likely caused by simple read or cluster failure" },
+ "Request ndbd time-out, maybe due to high load or communication problems"},
{ 4024, UR,
- "Time-out, most likely caused by simple read or cluster failure" },
-
+ "Time-out, most likely caused by simple read or cluster failure" },
+
/**
* TemporaryResourceError
*/
@@ -348,7 +348,7 @@ ErrorBundle ErrorCodes[] = {
{ 1325, IE, "File or scan error" },
{ 1326, IE, "Backup abortet due to node failure" },
{ 1327, IE, "1327" },
-
+
{ 1340, IE, "Backup undefined error" },
{ 1342, AE, "Backup failed to allocate buffers (check configuration)" },
{ 1343, AE, "Backup failed to setup fs buffers (check configuration)" },
@@ -358,7 +358,8 @@ ErrorBundle ErrorCodes[] = {
{ 1347, AE, "Backup failed to allocate table memory (check configuration)" },
{ 1348, AE, "Backup failed to allocate file record (check configuration)" },
{ 1349, AE, "Backup failed to allocate attribute record (check configuration)" },
-
+ { 1329, AE, "Backup during software upgrade not supported" },
+
/**
* Still uncategorized
*/
diff --git a/ndb/test/ndbapi/testBackup.cpp b/ndb/test/ndbapi/testBackup.cpp
index 77b9d0a4baa..bea5d5307e2 100644
--- a/ndb/test/ndbapi/testBackup.cpp
+++ b/ndb/test/ndbapi/testBackup.cpp
@@ -74,20 +74,20 @@ int runAbort(NDBT_Context* ctx, NDBT_Step* step){
if (testMaster) {
if (testSlave) {
- if (backup.NFMasterAsSlave(restarter) == -1){
+ if (backup.NFMasterAsSlave(restarter) != NDBT_OK){
return NDBT_FAILED;
}
} else {
- if (backup.NFMaster(restarter) == -1){
+ if (backup.NFMaster(restarter) != NDBT_OK){
return NDBT_FAILED;
}
}
} else {
- if (backup.NFSlave(restarter) == -1){
+ if (backup.NFSlave(restarter) != NDBT_OK){
return NDBT_FAILED;
}
}
-
+
return NDBT_OK;
}
@@ -108,16 +108,16 @@ int runFail(NDBT_Context* ctx, NDBT_Step* step){
if (testMaster) {
if (testSlave) {
- if (backup.FailMasterAsSlave(restarter) == -1){
+ if (backup.FailMasterAsSlave(restarter) != NDBT_OK){
return NDBT_FAILED;
}
} else {
- if (backup.FailMaster(restarter) == -1){
+ if (backup.FailMaster(restarter) != NDBT_OK){
return NDBT_FAILED;
}
}
} else {
- if (backup.FailSlave(restarter) == -1){
+ if (backup.FailSlave(restarter) != NDBT_OK){
return NDBT_FAILED;
}
}
diff --git a/ndb/test/ndbapi/testIndex.cpp b/ndb/test/ndbapi/testIndex.cpp
index 6623ad35a7f..d359f83257f 100644
--- a/ndb/test/ndbapi/testIndex.cpp
+++ b/ndb/test/ndbapi/testIndex.cpp
@@ -1329,7 +1329,7 @@ TESTCASE("NFNR2_O",
INITIALIZER(runLoadTable);
STEP(runRestarts);
STEP(runTransactions2);
- STEP(runTransactions2);
+ //STEP(runTransactions2);
FINALIZER(runVerifyIndex);
FINALIZER(createRandomIndex_Drop);
FINALIZER(createPkIndex_Drop);
diff --git a/ndb/test/ndbapi/testOperations.cpp b/ndb/test/ndbapi/testOperations.cpp
index 9f1d5ee1191..726f35b01fb 100644
--- a/ndb/test/ndbapi/testOperations.cpp
+++ b/ndb/test/ndbapi/testOperations.cpp
@@ -547,21 +547,64 @@ runLockUpgrade1(NDBT_Context* ctx, NDBT_Step* step){
do
{
CHECK(hugoOps.startTransaction(pNdb) == 0);
- CHECK(hugoOps.pkReadRecord(pNdb, 0, 1, NdbOperation::LM_Read) == 0);
- CHECK(hugoOps.execute_NoCommit(pNdb) == 0);
+ if(ctx->getProperty("LOCK_UPGRADE", 1) == 1)
+ {
+ CHECK(hugoOps.pkReadRecord(pNdb, 0, 1, NdbOperation::LM_Read) == 0);
+ CHECK(hugoOps.execute_NoCommit(pNdb) == 0);
- ctx->setProperty("READ_DONE", 1);
- ctx->broadcast();
- ndbout_c("wait 2");
- ctx->getPropertyWait("READ_DONE", 2);
- ndbout_c("wait 2 - done");
+ ctx->setProperty("READ_DONE", 1);
+ ctx->broadcast();
+ ndbout_c("wait 2");
+ ctx->getPropertyWait("READ_DONE", 2);
+ ndbout_c("wait 2 - done");
+ }
+ else
+ {
+ ctx->setProperty("READ_DONE", 1);
+ ctx->broadcast();
+ ctx->getPropertyWait("READ_DONE", 2);
+ ndbout_c("wait 2 - done");
+ CHECK(hugoOps.pkReadRecord(pNdb, 0, 1, NdbOperation::LM_Read) == 0);
+ CHECK(hugoOps.execute_NoCommit(pNdb) == 0);
+ }
+ if(ctx->getProperty("LU_OP", o_INS) == o_INS)
+ {
+ CHECK(hugoOps.pkDeleteRecord(pNdb, 0, 1) == 0);
+ CHECK(hugoOps.pkInsertRecord(pNdb, 0, 1, 2) == 0);
+ }
+ else if(ctx->getProperty("LU_OP", o_UPD) == o_UPD)
+ {
+ CHECK(hugoOps.pkUpdateRecord(pNdb, 0, 1, 2) == 0);
+ }
+ else
+ {
+ CHECK(hugoOps.pkDeleteRecord(pNdb, 0, 1) == 0);
+ }
ctx->setProperty("READ_DONE", 3);
ctx->broadcast();
ndbout_c("before update");
- CHECK(hugoOps.pkUpdateRecord(pNdb, 0, 1, 2) == 0);
ndbout_c("wait update");
- CHECK(hugoOps.execute_NoCommit(pNdb) == 0);
- CHECK(hugoOps.closeTransaction(pNdb));
+ CHECK(hugoOps.execute_Commit(pNdb) == 0);
+ CHECK(hugoOps.closeTransaction(pNdb) == 0);
+
+ CHECK(hugoOps.startTransaction(pNdb) == 0);
+ CHECK(hugoOps.pkReadRecord(pNdb, 0, 1) == 0);
+ int res= hugoOps.execute_Commit(pNdb);
+ if(ctx->getProperty("LU_OP", o_INS) == o_INS)
+ {
+ CHECK(res == 0);
+ CHECK(hugoOps.verifyUpdatesValue(2) == 0);
+ }
+ else if(ctx->getProperty("LU_OP", o_UPD) == o_UPD)
+ {
+ CHECK(res == 0);
+ CHECK(hugoOps.verifyUpdatesValue(2) == 0);
+ }
+ else
+ {
+ CHECK(res == 626);
+ }
+
} while(0);
return result;
@@ -592,10 +635,17 @@ runLockUpgrade2(NDBT_Context* ctx, NDBT_Step* step){
ndbout_c("wait 3 - done");
NdbSleep_MilliSleep(200);
- CHECK(hugoOps.execute_Commit(pNdb) == 0);
+ if(ctx->getProperty("LU_COMMIT", (Uint32)0) == 0)
+ {
+ CHECK(hugoOps.execute_Commit(pNdb) == 0);
+ }
+ else
+ {
+ CHECK(hugoOps.execute_Rollback(pNdb) == 0);
+ }
} while(0);
- return NDBT_FAILED;
+ return result;
}
int
@@ -607,11 +657,17 @@ main(int argc, const char** argv){
NDBT_TestSuite ts("testOperations");
+ for(Uint32 i = 0; i < 12; i++)
{
BaseString name("bug_9749");
+ name.appfmt("_%d", i);
NDBT_TestCaseImpl1 *pt = new NDBT_TestCaseImpl1(&ts,
name.c_str(), "");
+ pt->setProperty("LOCK_UPGRADE", 1 + (i & 1));
+ pt->setProperty("LU_OP", 1 + ((i >> 1) % 3));
+ pt->setProperty("LU_COMMIT", i / 6);
+
pt->addInitializer(new NDBT_Initializer(pt,
"runClearTable",
runClearTable));
diff --git a/ndb/test/run-test/daily-basic-tests.txt b/ndb/test/run-test/daily-basic-tests.txt
index 453fe1ad7ae..e7753f758a1 100644
--- a/ndb/test/run-test/daily-basic-tests.txt
+++ b/ndb/test/run-test/daily-basic-tests.txt
@@ -4,6 +4,54 @@ args: --force
max-time: 600
cmd: atrt-testBackup
+args: -n NFMaster T1
+
+max-time: 600
+cmd: testBasic
+args: -n PkRead T1
+
+max-time: 600
+cmd: atrt-testBackup
+args: -n NFMasterAsSlave T1
+
+max-time: 600
+cmd: testBasic
+args: -n PkRead T1
+
+max-time: 600
+cmd: atrt-testBackup
+args: -n NFSlave T1
+
+max-time: 600
+cmd: testBasic
+args: -n PkRead T1
+
+max-time: 600
+cmd: atrt-testBackup
+args: -n FailMaster T1
+
+max-time: 600
+cmd: testBasic
+args: -n PkRead T1
+
+max-time: 600
+cmd: atrt-testBackup
+args: -n FailMasterAsSlave T1
+
+max-time: 600
+cmd: testBasic
+args: -n PkRead T1
+
+max-time: 600
+cmd: atrt-testBackup
+args: -n FailSlave T1
+
+max-time: 600
+cmd: testBasic
+args: -n PkRead T1
+
+max-time: 600
+cmd: atrt-testBackup
args: -n BackupOne T1 T6 T3 I3
# BASIC FUNCTIONALITY
diff --git a/ndb/test/src/NdbBackup.cpp b/ndb/test/src/NdbBackup.cpp
index 5e22468692e..28724323bd7 100644
--- a/ndb/test/src/NdbBackup.cpp
+++ b/ndb/test/src/NdbBackup.cpp
@@ -244,7 +244,11 @@ NdbBackup::NFSlave(NdbRestarter& _restarter){
int
NdbBackup::NF(NdbRestarter& _restarter, int *NFDuringBackup_codes, const int sz, bool onMaster){
+ int nNodes = _restarter.getNumDbNodes();
{
+ if(nNodes == 1)
+ return NDBT_OK;
+
int nodeId = _restarter.getMasterNodeId();
CHECK(_restarter.restartOneDbNode(nodeId, false, true, true) == 0,
@@ -255,15 +259,11 @@ NdbBackup::NF(NdbRestarter& _restarter, int *NFDuringBackup_codes, const int sz,
CHECK(_restarter.startNodes(&nodeId, 1) == 0,
"failed to start node");
-
- NdbSleep_SecSleep(10);
}
-
+
CHECK(_restarter.waitClusterStarted() == 0,
"waitClusterStarted failed");
-
- int nNodes = _restarter.getNumDbNodes();
-
+
myRandom48Init(NdbTick_CurrentMillisecond());
for(int i = 0; i<sz; i++){
@@ -296,6 +296,7 @@ NdbBackup::NF(NdbRestarter& _restarter, int *NFDuringBackup_codes, const int sz,
"failed to set error insert");
g_info << "error inserted" << endl;
+ NdbSleep_SecSleep(1);
g_info << "starting backup" << endl;
int r = start(backupId);
@@ -304,6 +305,7 @@ NdbBackup::NF(NdbRestarter& _restarter, int *NFDuringBackup_codes, const int sz,
if (r == 0) {
g_err << "Backup should have failed on error_insertion " << error << endl
<< "Master = " << masterNodeId << "Node = " << nodeId << endl;
+ return NDBT_FAILED;
}
CHECK(_restarter.waitNodesNoStart(&nodeId, 1) == 0,
@@ -316,8 +318,6 @@ NdbBackup::NF(NdbRestarter& _restarter, int *NFDuringBackup_codes, const int sz,
return NDBT_FAILED;
}
- NdbSleep_SecSleep(1);
-
g_info << "starting new backup" << endl;
CHECK(start(backupId) == 0,
"failed to start backup");
@@ -331,8 +331,14 @@ NdbBackup::NF(NdbRestarter& _restarter, int *NFDuringBackup_codes, const int sz,
"waitClusterStarted failed");
g_info << "node started" << endl;
+ int val2[] = { 24, 2424 };
+ CHECK(_restarter.dumpStateAllNodes(val2, 2) == 0,
+ "failed to check backup resources RestartOnErrorInsert");
+
CHECK(_restarter.insertErrorInNode(nodeId, 10099) == 0,
"failed to set error insert");
+
+ NdbSleep_SecSleep(1);
}
return NDBT_OK;
@@ -340,15 +346,8 @@ NdbBackup::NF(NdbRestarter& _restarter, int *NFDuringBackup_codes, const int sz,
int
FailS_codes[] = {
- 10023,
- 10024,
- 10025,
- 10026,
10027,
- 10028,
- 10029,
- 10030,
- 10031
+ 10033
};
int
@@ -359,9 +358,8 @@ FailM_codes[] = {
10026,
10027,
10028,
- 10029,
- 10030,
- 10031
+ 10031,
+ 10033
};
int
@@ -426,13 +424,21 @@ NdbBackup::Fail(NdbRestarter& _restarter, int *Fail_codes, const int sz, bool on
if (r == 0) {
g_err << "Backup should have failed on error_insertion " << error << endl
<< "Master = " << masterNodeId << "Node = " << nodeId << endl;
+ return NDBT_FAILED;
}
-
+
CHECK(_restarter.waitClusterStarted() == 0,
"waitClusterStarted failed");
CHECK(_restarter.insertErrorInNode(nodeId, 10099) == 0,
"failed to set error insert");
+
+ NdbSleep_SecSleep(5);
+
+ int val2[] = { 24, 2424 };
+ CHECK(_restarter.dumpStateAllNodes(val2, 2) == 0,
+ "failed to check backup resources RestartOnErrorInsert");
+
}
return NDBT_OK;
diff --git a/sql/examples/ha_archive.cc b/sql/examples/ha_archive.cc
index bc4af0c7dc7..0e1df45a70b 100644
--- a/sql/examples/ha_archive.cc
+++ b/sql/examples/ha_archive.cc
@@ -427,6 +427,30 @@ const char **ha_archive::bas_ext() const
{ static const char *ext[]= { ARZ, ARN, ARM, NullS }; return ext; }
+/*
+ Rename all files that this handler defines in bas_ext list
+
+ NOTE Don't care if the .arn file is missing
+*/
+int ha_archive::rename_table(const char * from, const char * to)
+{
+ DBUG_ENTER("ha_archive::rename_table");
+ for (const char **ext=bas_ext(); *ext ; ext++)
+ {
+ if (rename_file_ext(from,to,*ext))
+ {
+ if (my_errno == ENOENT &&
+ !my_strcasecmp(system_charset_info, *ext, ARN))
+ continue;
+
+ DBUG_RETURN(my_errno);
+ }
+
+ }
+ DBUG_RETURN(0);
+}
+
+
/*
When opening a file we:
Create/get our shared structure.
diff --git a/sql/examples/ha_archive.h b/sql/examples/ha_archive.h
index 855d756368d..1d3365aca67 100644
--- a/sql/examples/ha_archive.h
+++ b/sql/examples/ha_archive.h
@@ -124,6 +124,7 @@ public:
int optimize(THD* thd, HA_CHECK_OPT* check_opt);
THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to,
enum thr_lock_type lock_type);
+ int rename_table(const char * from, const char * to);
};
bool archive_db_init(void);
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 056c2a7ad7f..43bed35621b 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -2000,7 +2000,7 @@ static void init_signals(void)
if (test_flags & TEST_CORE_ON_SIGNAL)
{
/* Change limits so that we will get a core file */
- struct rlimit rl;
+ STRUCT_RLIMIT rl;
rl.rlim_cur = rl.rlim_max = RLIM_INFINITY;
if (setrlimit(RLIMIT_CORE, &rl) && global_system_variables.log_warnings)
sql_print_warning("setrlimit could not change the size of core files to 'infinity'; We may not be able to generate a core file on signals");