mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-07-16 10:03:04 -07:00
Add SKIPREADLINE support to make and cmake
It's mostly for headless support. At the moment, for interactive uage without readline, some commands will exit the client prematurely if they use kbd_enter_pressed().
This commit is contained in:
parent
4372a728f7
commit
def475e747
5 changed files with 109 additions and 27 deletions
|
@ -49,6 +49,21 @@ if (NOT SKIPPYTHON EQUAL 1)
|
||||||
pkg_search_module(PYTHON3EMBED QUIET python3-embed)
|
pkg_search_module(PYTHON3EMBED QUIET python3-embed)
|
||||||
endif (NOT SKIPPYTHON EQUAL 1)
|
endif (NOT SKIPPYTHON EQUAL 1)
|
||||||
|
|
||||||
|
if (NOT SKIPREADLINE EQUAL 1)
|
||||||
|
if (APPLE)
|
||||||
|
find_path(READLINE_INCLUDE_DIRS readline/readline.h /usr/local/opt/readline/include /opt/local/include /opt/include /usr/local/include /usr/include NO_DEFAULT_PATH)
|
||||||
|
endif (APPLE)
|
||||||
|
find_path(READLINE_INCLUDE_DIRS readline/readline.h)
|
||||||
|
|
||||||
|
if (APPLE)
|
||||||
|
find_library(READLINE_LIBRARIES readline /usr/local/opt/readline/lib /opt/local/lib /opt/lib /usr/local/lib /usr/lib NO_DEFAULT_PATH)
|
||||||
|
endif (APPLE)
|
||||||
|
find_library(READLINE_LIBRARIES readline)
|
||||||
|
if (READLINE_INCLUDE_DIRS AND READLINE_LIBRARIES)
|
||||||
|
set(READLINE_FOUND ON)
|
||||||
|
endif (READLINE_INCLUDE_DIRS AND READLINE_LIBRARIES)
|
||||||
|
endif (NOT SKIPREADLINE EQUAL 1)
|
||||||
|
|
||||||
add_subdirectory(${PM3_ROOT}/client/deps deps)
|
add_subdirectory(${PM3_ROOT}/client/deps deps)
|
||||||
|
|
||||||
set (TARGET_SOURCES
|
set (TARGET_SOURCES
|
||||||
|
@ -246,6 +261,14 @@ if (NOT SKIPPYTHON EQUAL 1)
|
||||||
endif (PYTHON3EMBED_FOUND)
|
endif (PYTHON3EMBED_FOUND)
|
||||||
endif (NOT SKIPPYTHON EQUAL 1)
|
endif (NOT SKIPPYTHON EQUAL 1)
|
||||||
|
|
||||||
|
if (NOT SKIPREADLINE EQUAL 1)
|
||||||
|
if (READLINE_FOUND)
|
||||||
|
add_definitions("-DHAVE_READLINE")
|
||||||
|
set(ADDITIONAL_DIRS ${READLINE_INCLUDE_DIRS} ${ADDITIONAL_DIRS})
|
||||||
|
set(ADDITIONAL_LNK ${READLINE_LIBRARIES} ${ADDITIONAL_LNK})
|
||||||
|
endif (READLINE_FOUND)
|
||||||
|
endif(NOT SKIPREADLINE EQUAL 1)
|
||||||
|
|
||||||
message("===================================================================")
|
message("===================================================================")
|
||||||
if (SKIPQT EQUAL 1)
|
if (SKIPQT EQUAL 1)
|
||||||
message("GUI support: skipped")
|
message("GUI support: skipped")
|
||||||
|
@ -278,6 +301,16 @@ else (SKIPPYTHON EQUAL 1)
|
||||||
message("Python3 library: Python3 not found, disabled")
|
message("Python3 library: Python3 not found, disabled")
|
||||||
endif (PYTHON3EMBED_FOUND)
|
endif (PYTHON3EMBED_FOUND)
|
||||||
endif(SKIPPYTHON EQUAL 1)
|
endif(SKIPPYTHON EQUAL 1)
|
||||||
|
|
||||||
|
if (SKIPREADLINE EQUAL 1)
|
||||||
|
message("Readline library: skipped")
|
||||||
|
else (SKIPREADLINE EQUAL 1)
|
||||||
|
if (READLINE_FOUND)
|
||||||
|
message("Readline library: enabled")
|
||||||
|
else (READLINE_FOUND)
|
||||||
|
message("Readline library: Readline not found, disabled")
|
||||||
|
endif (READLINE_FOUND)
|
||||||
|
endif(SKIPREADLINE EQUAL 1)
|
||||||
message("===================================================================")
|
message("===================================================================")
|
||||||
|
|
||||||
add_executable(proxmark3
|
add_executable(proxmark3
|
||||||
|
@ -308,13 +341,10 @@ target_include_directories(proxmark3 PRIVATE
|
||||||
${ADDITIONAL_DIRS}
|
${ADDITIONAL_DIRS}
|
||||||
)
|
)
|
||||||
|
|
||||||
if (APPLE)
|
if (NOT APPLE)
|
||||||
set_target_properties(proxmark3 PROPERTIES LINK_FLAGS "-Wl,-F/Library/Frameworks, -L/usr/local/opt/readline/lib")
|
|
||||||
set_target_properties(proxmark3 PROPERTIES COMPILE_FLAGS "-I/usr/local/opt/readline/include")
|
|
||||||
else (APPLE)
|
|
||||||
# required for Raspberry Pi, but breaks with clang (OSX). Need to be at the end of the linker line.
|
# required for Raspberry Pi, but breaks with clang (OSX). Need to be at the end of the linker line.
|
||||||
set(ADDITIONAL_LNK ${ADDITIONAL_LNK} -Wl,--as-needed -latomic -Wl,--no-as-needed)
|
set(ADDITIONAL_LNK ${ADDITIONAL_LNK} -Wl,--as-needed -latomic -Wl,--no-as-needed)
|
||||||
endif (APPLE)
|
endif (NOT APPLE)
|
||||||
|
|
||||||
|
|
||||||
find_library(pm3rrg_rdv4_cliparser REQUIRED)
|
find_library(pm3rrg_rdv4_cliparser REQUIRED)
|
||||||
|
@ -328,7 +358,6 @@ find_library(pm3rrg_rdv4_whereami REQUIRED)
|
||||||
|
|
||||||
target_link_libraries(proxmark3 PRIVATE
|
target_link_libraries(proxmark3 PRIVATE
|
||||||
bz2
|
bz2
|
||||||
readline
|
|
||||||
m
|
m
|
||||||
pm3rrg_rdv4_mbedtls
|
pm3rrg_rdv4_mbedtls
|
||||||
pm3rrg_rdv4_cliparser
|
pm3rrg_rdv4_cliparser
|
||||||
|
|
|
@ -256,11 +256,14 @@ LDLIBS += $(QTLDLIBS)
|
||||||
CXXINCLUDES += $(QTINCLUDES)
|
CXXINCLUDES += $(QTINCLUDES)
|
||||||
|
|
||||||
## Readline
|
## Readline
|
||||||
ifeq ($(platform),Darwin)
|
ifneq ($(SKIPREADLINE),1)
|
||||||
LDLIBS += -L/usr/local/opt/readline/lib
|
ifeq ($(platform),Darwin)
|
||||||
INCLUDES += -I/usr/local/opt/readline/include
|
LDLIBS += -L/usr/local/opt/readline/lib
|
||||||
|
INCLUDES += -I/usr/local/opt/readline/include
|
||||||
|
endif
|
||||||
|
LDLIBS += -lreadline
|
||||||
|
READLINE_FOUND = 1
|
||||||
endif
|
endif
|
||||||
LDLIBS += -lreadline
|
|
||||||
|
|
||||||
#######################################################################################################
|
#######################################################################################################
|
||||||
CFLAGS ?= $(DEFCFLAGS)
|
CFLAGS ?= $(DEFCFLAGS)
|
||||||
|
@ -280,6 +283,10 @@ ifneq (,$(findstring MINGW,$(platform)))
|
||||||
PM3CFLAGS += -mno-ms-bitfields -fexec-charset=cp850
|
PM3CFLAGS += -mno-ms-bitfields -fexec-charset=cp850
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq ($(READLINE_FOUND),1)
|
||||||
|
PM3CFLAGS += -DHAVE_READLINE
|
||||||
|
endif
|
||||||
|
|
||||||
ifeq ($(BT_FOUND),1)
|
ifeq ($(BT_FOUND),1)
|
||||||
PM3CFLAGS += -DHAVE_BLUEZ
|
PM3CFLAGS += -DHAVE_BLUEZ
|
||||||
endif
|
endif
|
||||||
|
@ -366,6 +373,16 @@ else
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq ($(SKIPREADLINE),1)
|
||||||
|
$(info Readline library: skipped)
|
||||||
|
else
|
||||||
|
ifeq ($(READLINE_FOUND),1)
|
||||||
|
$(info Readline library: enabled)
|
||||||
|
else
|
||||||
|
$(info Readline library: Readline not found, disabled)
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
ifeq ($(SKIPWHEREAMISYSTEM),1)
|
ifeq ($(SKIPWHEREAMISYSTEM),1)
|
||||||
$(info Whereami library: local library forced)
|
$(info Whereami library: local library forced)
|
||||||
else
|
else
|
||||||
|
|
|
@ -73,12 +73,13 @@ static int usage_legic_sim(void) {
|
||||||
}
|
}
|
||||||
static int usage_legic_wrbl(void) {
|
static int usage_legic_wrbl(void) {
|
||||||
PrintAndLogEx(NORMAL, "Write data to a LEGIC Prime tag. It autodetects tagsize to make sure size\n");
|
PrintAndLogEx(NORMAL, "Write data to a LEGIC Prime tag. It autodetects tagsize to make sure size\n");
|
||||||
PrintAndLogEx(NORMAL, "Usage: hf legic wrbl [h] [o <offset>] [d <data (hex symbols)>]\n");
|
PrintAndLogEx(NORMAL, "Usage: hf legic wrbl [h] [o <offset>] [d <data (hex symbols)>] [y]\n");
|
||||||
PrintAndLogEx(NORMAL, "Options:");
|
PrintAndLogEx(NORMAL, "Options:");
|
||||||
PrintAndLogEx(NORMAL, " h : this help");
|
PrintAndLogEx(NORMAL, " h : this help");
|
||||||
PrintAndLogEx(NORMAL, " o <offset> : (hex) offset in data array to start writing");
|
PrintAndLogEx(NORMAL, " o <offset> : (hex) offset in data array to start writing");
|
||||||
//PrintAndLogEx(NORMAL, " <IV> : (optional) Initialization vector to use (ODD and 7bits)");
|
//PrintAndLogEx(NORMAL, " <IV> : (optional) Initialization vector to use (ODD and 7bits)");
|
||||||
PrintAndLogEx(NORMAL, " d <data> : (hex symbols) bytes to write ");
|
PrintAndLogEx(NORMAL, " d <data> : (hex symbols) bytes to write ");
|
||||||
|
PrintAndLogEx(NORMAL, " y : Auto-confirm dangerous operations ");
|
||||||
PrintAndLogEx(NORMAL, "");
|
PrintAndLogEx(NORMAL, "");
|
||||||
PrintAndLogEx(NORMAL, "Examples:");
|
PrintAndLogEx(NORMAL, "Examples:");
|
||||||
PrintAndLogEx(NORMAL, _YELLOW_(" hf legic wrbl o 10 d 11223344 - Write 0x11223344 starting from offset 0x10"));
|
PrintAndLogEx(NORMAL, _YELLOW_(" hf legic wrbl o 10 d 11223344 - Write 0x11223344 starting from offset 0x10"));
|
||||||
|
@ -596,6 +597,7 @@ static int CmdLegicWrbl(const char *Cmd) {
|
||||||
uint8_t *data = NULL;
|
uint8_t *data = NULL;
|
||||||
uint8_t cmdp = 0;
|
uint8_t cmdp = 0;
|
||||||
bool errors = false;
|
bool errors = false;
|
||||||
|
bool autoconfirm = false;
|
||||||
int len = 0, bg, en;
|
int len = 0, bg, en;
|
||||||
uint32_t offset = 0, IV = 0x55;
|
uint32_t offset = 0, IV = 0x55;
|
||||||
|
|
||||||
|
@ -655,6 +657,10 @@ static int CmdLegicWrbl(const char *Cmd) {
|
||||||
errors = true;
|
errors = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case 'y': {
|
||||||
|
autoconfirm = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
default: {
|
default: {
|
||||||
PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp));
|
PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp));
|
||||||
errors = true;
|
errors = true;
|
||||||
|
@ -693,23 +699,28 @@ static int CmdLegicWrbl(const char *Cmd) {
|
||||||
return PM3_EOUTOFBOUND;
|
return PM3_EOUTOFBOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (offset == 5 || offset == 6) {
|
if ((offset == 5 || offset == 6) && (! autoconfirm)) {
|
||||||
PrintAndLogEx(NORMAL, "############# DANGER ################");
|
PrintAndLogEx(NORMAL, "############# DANGER ################");
|
||||||
PrintAndLogEx(NORMAL, "# changing the DCF is irreversible #");
|
PrintAndLogEx(NORMAL, "# changing the DCF is irreversible #");
|
||||||
PrintAndLogEx(NORMAL, "#####################################");
|
PrintAndLogEx(NORMAL, "#####################################");
|
||||||
|
const char *confirm = "Do you really want to continue? y(es)/n(o) : ";
|
||||||
#ifndef ANDROID
|
bool overwrite = false;
|
||||||
char *answer = readline("do you really want to continue? y(es) n(o) : ");
|
#ifdef HAVE_READLINE
|
||||||
bool overwrite = (answer[0] == 'y' || answer[0] == 'Y');
|
char *answer = readline(confirm);
|
||||||
|
overwrite = (answer[0] == 'y' || answer[0] == 'Y');
|
||||||
|
#else
|
||||||
|
printf("%s", confirm);
|
||||||
|
char *answer = NULL;
|
||||||
|
size_t anslen = 0;
|
||||||
|
if (getline(&answer, &anslen, stdin) > 0) {
|
||||||
|
overwrite = (answer[0] == 'y' || answer[0] == 'Y');
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
free(answer);
|
||||||
if (!overwrite) {
|
if (!overwrite) {
|
||||||
PrintAndLogEx(NORMAL, "command cancelled");
|
PrintAndLogEx(NORMAL, "command cancelled");
|
||||||
return PM3_EOPABORTED;
|
return PM3_EOPABORTED;
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
PrintAndLogEx(NORMAL, "\n No interactive support on Android. ");
|
|
||||||
PrintAndLogEx(NORMAL, " So no confirmation asked, beware! ");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
legic_chk_iv(&IV);
|
legic_chk_iv(&IV);
|
||||||
|
|
|
@ -15,8 +15,11 @@
|
||||||
#include <stdio.h> // for Mingw readline
|
#include <stdio.h> // for Mingw readline
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#ifdef HAVE_READLINE
|
||||||
#include <readline/readline.h>
|
#include <readline/readline.h>
|
||||||
#include <readline/history.h>
|
#include <readline/history.h>
|
||||||
|
#endif
|
||||||
|
#include <ctype.h>
|
||||||
#include "usart_defs.h"
|
#include "usart_defs.h"
|
||||||
#include "util_posix.h"
|
#include "util_posix.h"
|
||||||
#include "proxgui.h"
|
#include "proxgui.h"
|
||||||
|
@ -117,6 +120,7 @@ static void prompt_compose(char *buf, size_t buflen, const char *promptctx, cons
|
||||||
snprintf(buf, buflen - 1, PROXPROMPT_COMPOSE, promptdev, promptctx);
|
snprintf(buf, buflen - 1, PROXPROMPT_COMPOSE, promptdev, promptctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_READLINE
|
||||||
static int check_comm(void) {
|
static int check_comm(void) {
|
||||||
// If communications thread goes down. Device disconnected then this should hook up PM3 again.
|
// If communications thread goes down. Device disconnected then this should hook up PM3 again.
|
||||||
if (IsCommunicationThreadDead() && session.pm3_present) {
|
if (IsCommunicationThreadDead() && session.pm3_present) {
|
||||||
|
@ -132,6 +136,7 @@ static int check_comm(void) {
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// first slot is always NULL, indicating absence of script when idx=0
|
// first slot is always NULL, indicating absence of script when idx=0
|
||||||
static FILE *cmdscriptfile[MAX_NESTED_CMDSCRIPT + 1] = {0};
|
static FILE *cmdscriptfile[MAX_NESTED_CMDSCRIPT + 1] = {0};
|
||||||
|
@ -208,6 +213,7 @@ main_loop(char *script_cmds_file, char *script_cmd, bool stayInCommandLoop) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_READLINE
|
||||||
char *my_history_path = NULL;
|
char *my_history_path = NULL;
|
||||||
if (searchHomeFilePath(&my_history_path, NULL, PROXHISTORY, true) != PM3_SUCCESS) {
|
if (searchHomeFilePath(&my_history_path, NULL, PROXHISTORY, true) != PM3_SUCCESS) {
|
||||||
PrintAndLogEx(ERR, "No history will be recorded");
|
PrintAndLogEx(ERR, "No history will be recorded");
|
||||||
|
@ -215,6 +221,7 @@ main_loop(char *script_cmds_file, char *script_cmd, bool stayInCommandLoop) {
|
||||||
} else {
|
} else {
|
||||||
read_history(my_history_path);
|
read_history(my_history_path);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
// loops every time enter is pressed...
|
// loops every time enter is pressed...
|
||||||
while (1) {
|
while (1) {
|
||||||
bool printprompt = false;
|
bool printprompt = false;
|
||||||
|
@ -290,12 +297,25 @@ check_script:
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
prompt_ctx = PROXPROMPT_CTX_INTERACTIVE;
|
prompt_ctx = PROXPROMPT_CTX_INTERACTIVE;
|
||||||
rl_event_hook = check_comm;
|
|
||||||
char prompt[PROXPROMPT_MAX_SIZE] = {0};
|
char prompt[PROXPROMPT_MAX_SIZE] = {0};
|
||||||
prompt_compose(prompt, sizeof(prompt), prompt_ctx, prompt_dev);
|
prompt_compose(prompt, sizeof(prompt), prompt_ctx, prompt_dev);
|
||||||
char prompt_filtered[PROXPROMPT_MAX_SIZE] = {0};
|
char prompt_filtered[PROXPROMPT_MAX_SIZE] = {0};
|
||||||
memcpy_filter_ansi(prompt_filtered, prompt, sizeof(prompt_filtered), !session.supports_colors);
|
memcpy_filter_ansi(prompt_filtered, prompt, sizeof(prompt_filtered), !session.supports_colors);
|
||||||
|
#ifdef HAVE_READLINE
|
||||||
|
rl_event_hook = check_comm;
|
||||||
cmd = readline(prompt_filtered);
|
cmd = readline(prompt_filtered);
|
||||||
|
#else
|
||||||
|
printf("%s", prompt_filtered);
|
||||||
|
cmd = NULL;
|
||||||
|
size_t len = 0;
|
||||||
|
int ret;
|
||||||
|
if ((ret = getline(&cmd, &len, stdin)) < 0) {
|
||||||
|
// TODO this happens also when kbd_enter_pressed() is used, with a key pressed or not
|
||||||
|
printf("GETLINE ERR %i", ret);
|
||||||
|
free(cmd);
|
||||||
|
cmd = NULL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
fflush(NULL);
|
fflush(NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -333,6 +353,7 @@ check_script:
|
||||||
PrintAndLogEx(NORMAL, "%s%s", prompt_filtered, cmd);
|
PrintAndLogEx(NORMAL, "%s%s", prompt_filtered, cmd);
|
||||||
g_printAndLog = PRINTANDLOG_PRINT | PRINTANDLOG_LOG;
|
g_printAndLog = PRINTANDLOG_PRINT | PRINTANDLOG_LOG;
|
||||||
|
|
||||||
|
#ifdef HAVE_READLINE
|
||||||
// add to history if not from a script
|
// add to history if not from a script
|
||||||
if (!current_cmdscriptfile()) {
|
if (!current_cmdscriptfile()) {
|
||||||
HIST_ENTRY *entry = history_get(history_length);
|
HIST_ENTRY *entry = history_get(history_length);
|
||||||
|
@ -341,6 +362,7 @@ check_script:
|
||||||
add_history(cmd);
|
add_history(cmd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
// process cmd
|
// process cmd
|
||||||
int ret = CommandReceived(cmd);
|
int ret = CommandReceived(cmd);
|
||||||
// exit or quit
|
// exit or quit
|
||||||
|
@ -367,11 +389,12 @@ check_script:
|
||||||
while (current_cmdscriptfile())
|
while (current_cmdscriptfile())
|
||||||
pop_cmdscriptfile();
|
pop_cmdscriptfile();
|
||||||
|
|
||||||
|
#ifdef HAVE_READLINE
|
||||||
if (my_history_path) {
|
if (my_history_path) {
|
||||||
write_history(my_history_path);
|
write_history(my_history_path);
|
||||||
free(my_history_path);
|
free(my_history_path);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
if (cmd) {
|
if (cmd) {
|
||||||
free(cmd);
|
free(cmd);
|
||||||
cmd = NULL;
|
cmd = NULL;
|
||||||
|
@ -681,12 +704,14 @@ int main(int argc, char *argv[]) {
|
||||||
char *port = NULL;
|
char *port = NULL;
|
||||||
uint32_t speed = 0;
|
uint32_t speed = 0;
|
||||||
|
|
||||||
|
#ifdef HAVE_READLINE
|
||||||
/* initialize history */
|
/* initialize history */
|
||||||
using_history();
|
using_history();
|
||||||
|
|
||||||
#ifdef RL_STATE_READCMD
|
#ifdef RL_STATE_READCMD
|
||||||
rl_extend_line_buffer(1024);
|
rl_extend_line_buffer(1024);
|
||||||
#endif
|
#endif // RL_STATE_READCMD
|
||||||
|
#endif // HAVE_READLINE
|
||||||
|
|
||||||
char *exec_name = argv[0];
|
char *exec_name = argv[0];
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#ifndef ANDROID
|
#ifdef HAVE_READLINE
|
||||||
#include <readline/readline.h>
|
#include <readline/readline.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -297,8 +297,6 @@ void PrintAndLogEx(logLevel_t level, const char *fmt, ...) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void fPrintAndLog(FILE *stream, const char *fmt, ...) {
|
static void fPrintAndLog(FILE *stream, const char *fmt, ...) {
|
||||||
char *saved_line;
|
|
||||||
int saved_point;
|
|
||||||
va_list argptr;
|
va_list argptr;
|
||||||
static FILE *logfile = NULL;
|
static FILE *logfile = NULL;
|
||||||
static int logging = 1;
|
static int logging = 1;
|
||||||
|
@ -344,6 +342,8 @@ static void fPrintAndLog(FILE *stream, const char *fmt, ...) {
|
||||||
#ifdef RL_STATE_READCMD
|
#ifdef RL_STATE_READCMD
|
||||||
// We are using GNU readline. libedit (OSX) doesn't support this flag.
|
// We are using GNU readline. libedit (OSX) doesn't support this flag.
|
||||||
int need_hack = (rl_readline_state & RL_STATE_READCMD) > 0;
|
int need_hack = (rl_readline_state & RL_STATE_READCMD) > 0;
|
||||||
|
char *saved_line;
|
||||||
|
int saved_point;
|
||||||
|
|
||||||
if (need_hack) {
|
if (need_hack) {
|
||||||
saved_point = rl_point;
|
saved_point = rl_point;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue