5836a818ec
This reverts commitb558ff043d
. This reverts commit4a11f20659
. The initial import commit failed to retain local changes made to readline's configure.in (and the commit message erroneously stated that there were no local changes that needed to be reapplied). Also the import caused a couple of build errors and a scattering of testsuite regressions throughout many arches. It's probably better to start over with this import, hopefully more carefully next time.
209 lines
4.4 KiB
C
209 lines
4.4 KiB
C
/* shell.c -- readline utility functions that are normally provided by
|
|
bash when readline is linked as part of the shell. */
|
|
|
|
/* Copyright (C) 1997-2009 Free Software Foundation, Inc.
|
|
|
|
This file is part of the GNU Readline Library (Readline), a library
|
|
for reading lines of text with interactive input and history editing.
|
|
|
|
Readline is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
Readline is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with Readline. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#define READLINE_LIBRARY
|
|
|
|
#if defined (HAVE_CONFIG_H)
|
|
# include <config.h>
|
|
#endif
|
|
|
|
#include <sys/types.h>
|
|
|
|
#if defined (HAVE_UNISTD_H)
|
|
# include <unistd.h>
|
|
#endif /* HAVE_UNISTD_H */
|
|
|
|
#if defined (HAVE_STDLIB_H)
|
|
# include <stdlib.h>
|
|
#else
|
|
# include "ansi_stdlib.h"
|
|
#endif /* HAVE_STDLIB_H */
|
|
|
|
#if defined (HAVE_STRING_H)
|
|
# include <string.h>
|
|
#else
|
|
# include <strings.h>
|
|
#endif /* !HAVE_STRING_H */
|
|
|
|
#if defined (HAVE_LIMITS_H)
|
|
# include <limits.h>
|
|
#endif
|
|
|
|
#if defined (HAVE_FCNTL_H)
|
|
#include <fcntl.h>
|
|
#endif
|
|
#if defined (HAVE_PWD_H)
|
|
#include <pwd.h>
|
|
#endif
|
|
|
|
#include <stdio.h>
|
|
|
|
#include "rlstdc.h"
|
|
#include "rlshell.h"
|
|
#include "xmalloc.h"
|
|
|
|
#if defined (HAVE_GETPWUID) && !defined (HAVE_GETPW_DECLS)
|
|
extern struct passwd *getpwuid PARAMS((uid_t));
|
|
#endif /* HAVE_GETPWUID && !HAVE_GETPW_DECLS */
|
|
|
|
#ifndef NULL
|
|
# define NULL 0
|
|
#endif
|
|
|
|
#ifndef CHAR_BIT
|
|
# define CHAR_BIT 8
|
|
#endif
|
|
|
|
/* Nonzero if the integer type T is signed. */
|
|
#define TYPE_SIGNED(t) (! ((t) 0 < (t) -1))
|
|
|
|
/* Bound on length of the string representing an integer value of type T.
|
|
Subtract one for the sign bit if T is signed;
|
|
302 / 1000 is log10 (2) rounded up;
|
|
add one for integer division truncation;
|
|
add one more for a minus sign if t is signed. */
|
|
#define INT_STRLEN_BOUND(t) \
|
|
((sizeof (t) * CHAR_BIT - TYPE_SIGNED (t)) * 302 / 1000 \
|
|
+ 1 + TYPE_SIGNED (t))
|
|
|
|
/* All of these functions are resolved from bash if we are linking readline
|
|
as part of bash. */
|
|
|
|
/* Does shell-like quoting using single quotes. */
|
|
char *
|
|
sh_single_quote (string)
|
|
char *string;
|
|
{
|
|
register int c;
|
|
char *result, *r, *s;
|
|
|
|
result = (char *)xmalloc (3 + (4 * strlen (string)));
|
|
r = result;
|
|
*r++ = '\'';
|
|
|
|
for (s = string; s && (c = *s); s++)
|
|
{
|
|
*r++ = c;
|
|
|
|
if (c == '\'')
|
|
{
|
|
*r++ = '\\'; /* insert escaped single quote */
|
|
*r++ = '\'';
|
|
*r++ = '\''; /* start new quoted string */
|
|
}
|
|
}
|
|
|
|
*r++ = '\'';
|
|
*r = '\0';
|
|
|
|
return (result);
|
|
}
|
|
|
|
/* Set the environment variables LINES and COLUMNS to lines and cols,
|
|
respectively. */
|
|
void
|
|
sh_set_lines_and_columns (lines, cols)
|
|
int lines, cols;
|
|
{
|
|
char *b;
|
|
|
|
#if defined (HAVE_SETENV)
|
|
b = (char *)xmalloc (INT_STRLEN_BOUND (int) + 1);
|
|
sprintf (b, "%d", lines);
|
|
setenv ("LINES", b, 1);
|
|
xfree (b);
|
|
|
|
b = (char *)xmalloc (INT_STRLEN_BOUND (int) + 1);
|
|
sprintf (b, "%d", cols);
|
|
setenv ("COLUMNS", b, 1);
|
|
xfree (b);
|
|
#else /* !HAVE_SETENV */
|
|
# if defined (HAVE_PUTENV)
|
|
b = (char *)xmalloc (INT_STRLEN_BOUND (int) + sizeof ("LINES=") + 1);
|
|
sprintf (b, "LINES=%d", lines);
|
|
putenv (b);
|
|
|
|
b = (char *)xmalloc (INT_STRLEN_BOUND (int) + sizeof ("COLUMNS=") + 1);
|
|
sprintf (b, "COLUMNS=%d", cols);
|
|
putenv (b);
|
|
# endif /* HAVE_PUTENV */
|
|
#endif /* !HAVE_SETENV */
|
|
}
|
|
|
|
char *
|
|
sh_get_env_value (varname)
|
|
const char *varname;
|
|
{
|
|
return ((char *)getenv (varname));
|
|
}
|
|
|
|
char *
|
|
sh_get_home_dir ()
|
|
{
|
|
char *home_dir;
|
|
struct passwd *entry;
|
|
|
|
home_dir = (char *)NULL;
|
|
#if defined (HAVE_GETPWUID)
|
|
entry = getpwuid (getuid ());
|
|
if (entry)
|
|
home_dir = entry->pw_dir;
|
|
#endif
|
|
return (home_dir);
|
|
}
|
|
|
|
#if !defined (O_NDELAY)
|
|
# if defined (FNDELAY)
|
|
# define O_NDELAY FNDELAY
|
|
# endif
|
|
#endif
|
|
|
|
int
|
|
sh_unset_nodelay_mode (fd)
|
|
int fd;
|
|
{
|
|
#if defined (HAVE_FCNTL)
|
|
int flags, bflags;
|
|
|
|
if ((flags = fcntl (fd, F_GETFL, 0)) < 0)
|
|
return -1;
|
|
|
|
bflags = 0;
|
|
|
|
#ifdef O_NONBLOCK
|
|
bflags |= O_NONBLOCK;
|
|
#endif
|
|
|
|
#ifdef O_NDELAY
|
|
bflags |= O_NDELAY;
|
|
#endif
|
|
|
|
if (flags & bflags)
|
|
{
|
|
flags &= ~bflags;
|
|
return (fcntl (fd, F_SETFL, flags));
|
|
}
|
|
#endif
|
|
|
|
return 0;
|
|
}
|