version 1.1.1.2, 2016/11/03 13:35:37
|
version 1.1.1.3, 2021/03/17 01:01:01
|
Line 1
|
Line 1
|
/* util.c -- readline utility functions */ |
/* util.c -- readline utility functions */ |
|
|
/* Copyright (C) 1987-2012 Free Software Foundation, Inc. | /* Copyright (C) 1987-2017 Free Software Foundation, Inc. |
|
|
This file is part of the GNU Readline Library (Readline), a library |
This file is part of the GNU Readline Library (Readline), a library |
for reading lines of text with interactive input and history editing. |
for reading lines of text with interactive input and history editing. |
Line 55
|
Line 55
|
|
|
#include "rlprivate.h" |
#include "rlprivate.h" |
#include "xmalloc.h" |
#include "xmalloc.h" |
|
#include "rlshell.h" |
|
|
/* **************************************************************** */ |
/* **************************************************************** */ |
/* */ |
/* */ |
Line 69 int _rl_allow_pathname_alphabetic_chars = 0;
|
Line 70 int _rl_allow_pathname_alphabetic_chars = 0;
|
static const char * const pathname_alphabetic_chars = "/-_=~.#$"; |
static const char * const pathname_alphabetic_chars = "/-_=~.#$"; |
|
|
int |
int |
rl_alphabetic (c) | rl_alphabetic (int c) |
int c; | |
{ |
{ |
if (ALPHABETIC (c)) |
if (ALPHABETIC (c)) |
return (1); |
return (1); |
Line 96 _rl_walphabetic (wchar_t wc)
|
Line 96 _rl_walphabetic (wchar_t wc)
|
|
|
/* How to abort things. */ |
/* How to abort things. */ |
int |
int |
_rl_abort_internal () | _rl_abort_internal (void) |
{ |
{ |
rl_ding (); |
rl_ding (); |
rl_clear_message (); |
rl_clear_message (); |
_rl_reset_argument (); |
_rl_reset_argument (); |
rl_clear_pending_input (); |
rl_clear_pending_input (); |
|
rl_deactivate_mark (); |
|
|
RL_UNSETSTATE (RL_STATE_MACRODEF); |
|
while (rl_executing_macro) |
while (rl_executing_macro) |
_rl_pop_executing_macro (); |
_rl_pop_executing_macro (); |
|
_rl_kill_kbd_macro (); |
|
|
|
RL_UNSETSTATE (RL_STATE_MULTIKEY); /* XXX */ |
|
|
rl_last_func = (rl_command_func_t *)NULL; |
rl_last_func = (rl_command_func_t *)NULL; |
#if defined (HAVE_POSIX_SIGSETJMP) | |
siglongjmp (_rl_top_level, 1); | _rl_longjmp (_rl_top_level, 1); |
#else | |
longjmp (_rl_top_level, 1); | |
#endif | |
return (0); |
return (0); |
} |
} |
|
|
int |
int |
rl_abort (count, key) | rl_abort (int count, int key) |
int count, key; | |
{ |
{ |
return (_rl_abort_internal ()); |
return (_rl_abort_internal ()); |
} |
} |
|
|
int |
int |
_rl_null_function (count, key) | _rl_null_function (int count, int key) |
int count, key; | |
{ |
{ |
return 0; |
return 0; |
} |
} |
|
|
int |
int |
rl_tty_status (count, key) | rl_tty_status (int count, int key) |
int count, key; | |
{ |
{ |
#if defined (TIOCSTAT) |
#if defined (TIOCSTAT) |
ioctl (1, TIOCSTAT, (char *)0); |
ioctl (1, TIOCSTAT, (char *)0); |
Line 146 rl_tty_status (count, key)
|
Line 143 rl_tty_status (count, key)
|
/* Return a copy of the string between FROM and TO. |
/* Return a copy of the string between FROM and TO. |
FROM is inclusive, TO is not. */ |
FROM is inclusive, TO is not. */ |
char * |
char * |
rl_copy_text (from, to) | rl_copy_text (int from, int to) |
int from, to; | |
{ |
{ |
register int length; |
register int length; |
char *copy; |
char *copy; |
Line 166 rl_copy_text (from, to)
|
Line 162 rl_copy_text (from, to)
|
/* Increase the size of RL_LINE_BUFFER until it has enough space to hold |
/* Increase the size of RL_LINE_BUFFER until it has enough space to hold |
LEN characters. */ |
LEN characters. */ |
void |
void |
rl_extend_line_buffer (len) | rl_extend_line_buffer (int len) |
int len; | |
{ |
{ |
while (len >= rl_line_buffer_len) |
while (len >= rl_line_buffer_len) |
{ |
{ |
Line 181 rl_extend_line_buffer (len)
|
Line 176 rl_extend_line_buffer (len)
|
|
|
/* A function for simple tilde expansion. */ |
/* A function for simple tilde expansion. */ |
int |
int |
rl_tilde_expand (ignore, key) | rl_tilde_expand (int ignore, int key) |
int ignore, key; | |
{ |
{ |
register int start, end; |
register int start, end; |
char *homedir, *temp; |
char *homedir, *temp; |
Line 198 rl_tilde_expand (ignore, key)
|
Line 192 rl_tilde_expand (ignore, key)
|
xfree (homedir); |
xfree (homedir); |
return (0); |
return (0); |
} |
} |
else if (rl_line_buffer[start] != '~') | else if (start >= 0 && rl_line_buffer[start] != '~') |
{ |
{ |
for (; !whitespace (rl_line_buffer[start]) && start >= 0; start--) | for (; start >= 0 && !whitespace (rl_line_buffer[start]); start--) |
; |
; |
start++; |
start++; |
} |
} |
|
else if (start < 0) |
|
start = 0; |
|
|
end = start; |
end = start; |
do |
do |
Line 322 _rl_errmsg (format, arg1, arg2)
|
Line 318 _rl_errmsg (format, arg1, arg2)
|
/* Determine if s2 occurs in s1. If so, return a pointer to the |
/* Determine if s2 occurs in s1. If so, return a pointer to the |
match in s1. The compare is case insensitive. */ |
match in s1. The compare is case insensitive. */ |
char * |
char * |
_rl_strindex (s1, s2) | _rl_strindex (const char *s1, const char *s2) |
register const char *s1, *s2; | |
{ |
{ |
register int i, l, len; |
register int i, l, len; |
|
|
Line 337 _rl_strindex (s1, s2)
|
Line 332 _rl_strindex (s1, s2)
|
/* Find the first occurrence in STRING1 of any character from STRING2. |
/* Find the first occurrence in STRING1 of any character from STRING2. |
Return a pointer to the character in STRING1. */ |
Return a pointer to the character in STRING1. */ |
char * |
char * |
_rl_strpbrk (string1, string2) | _rl_strpbrk (const char *string1, const char *string2) |
const char *string1, *string2; | |
{ |
{ |
register const char *scan; |
register const char *scan; |
#if defined (HANDLE_MULTIBYTE) |
#if defined (HANDLE_MULTIBYTE) |
Line 372 _rl_strpbrk (string1, string2)
|
Line 366 _rl_strpbrk (string1, string2)
|
/* Compare at most COUNT characters from string1 to string2. Case |
/* Compare at most COUNT characters from string1 to string2. Case |
doesn't matter (strncasecmp). */ |
doesn't matter (strncasecmp). */ |
int |
int |
_rl_strnicmp (string1, string2, count) | _rl_strnicmp (const char *string1, const char *string2, int count) |
const char *string1; | |
const char *string2; | |
int count; | |
{ |
{ |
register const char *s1; |
register const char *s1; |
register const char *s2; |
register const char *s2; |
Line 402 _rl_strnicmp (string1, string2, count)
|
Line 393 _rl_strnicmp (string1, string2, count)
|
|
|
/* strcmp (), but caseless (strcasecmp). */ |
/* strcmp (), but caseless (strcasecmp). */ |
int |
int |
_rl_stricmp (string1, string2) | _rl_stricmp (const char *string1, const char *string2) |
const char *string1; | |
const char *string2; | |
{ |
{ |
register const char *s1; |
register const char *s1; |
register const char *s2; |
register const char *s2; |
Line 429 _rl_stricmp (string1, string2)
|
Line 418 _rl_stricmp (string1, string2)
|
|
|
/* Stupid comparison routine for qsort () ing strings. */ |
/* Stupid comparison routine for qsort () ing strings. */ |
int |
int |
_rl_qsort_string_compare (s1, s2) | _rl_qsort_string_compare (char **s1, char **s2) |
char **s1, **s2; | |
{ |
{ |
#if defined (HAVE_STRCOLL) |
#if defined (HAVE_STRCOLL) |
return (strcoll (*s1, *s2)); |
return (strcoll (*s1, *s2)); |
Line 446 _rl_qsort_string_compare (s1, s2)
|
Line 434 _rl_qsort_string_compare (s1, s2)
|
} |
} |
|
|
/* Function equivalents for the macros defined in chardefs.h. */ |
/* Function equivalents for the macros defined in chardefs.h. */ |
#define FUNCTION_FOR_MACRO(f) int (f) (c) int c; { return f (c); } | #define FUNCTION_FOR_MACRO(f) int (f) (int c) { return f (c); } |
|
|
FUNCTION_FOR_MACRO (_rl_digit_p) |
FUNCTION_FOR_MACRO (_rl_digit_p) |
FUNCTION_FOR_MACRO (_rl_digit_value) |
FUNCTION_FOR_MACRO (_rl_digit_value) |
Line 459 FUNCTION_FOR_MACRO (_rl_uppercase_p)
|
Line 447 FUNCTION_FOR_MACRO (_rl_uppercase_p)
|
/* A convenience function, to force memory deallocation to be performed |
/* A convenience function, to force memory deallocation to be performed |
by readline. DLLs on Windows apparently require this. */ |
by readline. DLLs on Windows apparently require this. */ |
void |
void |
rl_free (mem) | rl_free (void *mem) |
void *mem; | |
{ |
{ |
if (mem) |
if (mem) |
free (mem); |
free (mem); |
Line 470 rl_free (mem)
|
Line 457 rl_free (mem)
|
all `public' readline header files. */ |
all `public' readline header files. */ |
#undef _rl_savestring |
#undef _rl_savestring |
char * |
char * |
_rl_savestring (s) | _rl_savestring (const char *s) |
const char *s; | |
{ |
{ |
return (strcpy ((char *)xmalloc (1 + (int)strlen (s)), (s))); |
return (strcpy ((char *)xmalloc (1 + (int)strlen (s)), (s))); |
} |
} |
Line 510 _rl_trace (va_alist)
|
Line 496 _rl_trace (va_alist)
|
} |
} |
|
|
int |
int |
_rl_tropen () | _rl_tropen (void) |
{ |
{ |
char fnbuf[128]; | char fnbuf[128], *x; |
|
|
if (_rl_tracefp) |
if (_rl_tracefp) |
fclose (_rl_tracefp); |
fclose (_rl_tracefp); |
sprintf (fnbuf, "/var/tmp/rltrace.%ld", (long)getpid()); | #if defined (_WIN32) && !defined (__CYGWIN__) |
| x = sh_get_env_value ("TEMP"); |
| if (x == 0) |
| x = "."; |
| #else |
| x = "/var/tmp"; |
| #endif |
| snprintf (fnbuf, sizeof (fnbuf), "%s/rltrace.%ld", x, (long)getpid()); |
unlink(fnbuf); |
unlink(fnbuf); |
_rl_tracefp = fopen (fnbuf, "w+"); |
_rl_tracefp = fopen (fnbuf, "w+"); |
return _rl_tracefp != 0; |
return _rl_tracefp != 0; |
} |
} |
|
|
int |
int |
_rl_trclose () | _rl_trclose (void) |
{ |
{ |
int r; |
int r; |
|
|
Line 533 _rl_trclose ()
|
Line 526 _rl_trclose ()
|
} |
} |
|
|
void |
void |
_rl_settracefp (fp) | _rl_settracefp (FILE *fp) |
FILE *fp; | |
{ |
{ |
_rl_tracefp = fp; |
_rl_tracefp = fp; |
} |
} |
Line 542 _rl_settracefp (fp)
|
Line 534 _rl_settracefp (fp)
|
#endif /* DEBUG */ |
#endif /* DEBUG */ |
|
|
|
|
#if HAVE_DECL_AUDIT_USER_TTY && defined (ENABLE_TTY_AUDIT_SUPPORT) | #if HAVE_DECL_AUDIT_USER_TTY && defined (HAVE_LIBAUDIT_H) && defined (ENABLE_TTY_AUDIT_SUPPORT) |
#include <sys/socket.h> |
#include <sys/socket.h> |
|
#include <libaudit.h> |
#include <linux/audit.h> |
#include <linux/audit.h> |
#include <linux/netlink.h> |
#include <linux/netlink.h> |
|
|
/* Report STRING to the audit system. */ |
/* Report STRING to the audit system. */ |
void |
void |
_rl_audit_tty (string) | _rl_audit_tty (char *string) |
char *string; | |
{ |
{ |
|
struct audit_message req; |
struct sockaddr_nl addr; |
struct sockaddr_nl addr; |
struct msghdr msg; |
|
struct nlmsghdr nlm; |
|
struct iovec iov[2]; |
|
size_t size; |
size_t size; |
int fd; |
int fd; |
|
|
fd = socket (AF_NETLINK, SOCK_RAW, NETLINK_AUDIT); | fd = socket (PF_NETLINK, SOCK_RAW, NETLINK_AUDIT); |
if (fd < 0) |
if (fd < 0) |
return; |
return; |
size = strlen (string) + 1; |
size = strlen (string) + 1; |
|
|
nlm.nlmsg_len = NLMSG_LENGTH (size); | if (NLMSG_SPACE (size) > MAX_AUDIT_MESSAGE_LENGTH) |
nlm.nlmsg_type = AUDIT_USER_TTY; | return; |
nlm.nlmsg_flags = NLM_F_REQUEST; | |
nlm.nlmsg_seq = 0; | |
nlm.nlmsg_pid = 0; | |
|
|
iov[0].iov_base = &nlm; | memset (&req, 0, sizeof(req)); |
iov[0].iov_len = sizeof (nlm); | req.nlh.nlmsg_len = NLMSG_SPACE (size); |
iov[1].iov_base = string; | req.nlh.nlmsg_type = AUDIT_USER_TTY; |
iov[1].iov_len = size; | req.nlh.nlmsg_flags = NLM_F_REQUEST; |
| req.nlh.nlmsg_seq = 0; |
| if (size && string) |
| memcpy (NLMSG_DATA(&req.nlh), string, size); |
| memset (&addr, 0, sizeof(addr)); |
|
|
addr.nl_family = AF_NETLINK; |
addr.nl_family = AF_NETLINK; |
addr.nl_pid = 0; |
addr.nl_pid = 0; |
addr.nl_groups = 0; |
addr.nl_groups = 0; |
|
|
msg.msg_name = &addr; | sendto (fd, &req, req.nlh.nlmsg_len, 0, (struct sockaddr*)&addr, sizeof(addr)); |
msg.msg_namelen = sizeof (addr); | |
msg.msg_iov = iov; | |
msg.msg_iovlen = 2; | |
msg.msg_control = NULL; | |
msg.msg_controllen = 0; | |
msg.msg_flags = 0; | |
| |
(void)sendmsg (fd, &msg, 0); | |
close (fd); |
close (fd); |
} |
} |
#endif |
#endif |