xref: /openbsd/gnu/lib/libreadline/shell.c (revision af70c2df)
11acd27e7Smillert /* shell.c -- readline utility functions that are normally provided by
21acd27e7Smillert 	      bash when readline is linked as part of the shell. */
31acd27e7Smillert 
41acd27e7Smillert /* Copyright (C) 1997 Free Software Foundation, Inc.
51acd27e7Smillert 
61acd27e7Smillert    This file is part of the GNU Readline Library, a library for
71acd27e7Smillert    reading lines of text with interactive input and history editing.
81acd27e7Smillert 
91acd27e7Smillert    The GNU Readline Library is free software; you can redistribute it
101acd27e7Smillert    and/or modify it under the terms of the GNU General Public License
111acd27e7Smillert    as published by the Free Software Foundation; either version 2, or
121acd27e7Smillert    (at your option) any later version.
131acd27e7Smillert 
141acd27e7Smillert    The GNU Readline Library is distributed in the hope that it will be
151acd27e7Smillert    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
161acd27e7Smillert    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
171acd27e7Smillert    GNU General Public License for more details.
181acd27e7Smillert 
191acd27e7Smillert    The GNU General Public License is often shipped with GNU software, and
201acd27e7Smillert    is generally kept in a file called COPYING or LICENSE.  If you do not
211acd27e7Smillert    have a copy of the license, write to the Free Software Foundation,
221acd27e7Smillert    59 Temple Place, Suite 330, Boston, MA 02111 USA. */
231acd27e7Smillert #define READLINE_LIBRARY
241acd27e7Smillert 
251acd27e7Smillert #if defined (HAVE_CONFIG_H)
261acd27e7Smillert #  include <config.h>
271acd27e7Smillert #endif
281acd27e7Smillert 
291acd27e7Smillert #include <sys/types.h>
301acd27e7Smillert 
311acd27e7Smillert #if defined (HAVE_UNISTD_H)
321acd27e7Smillert #  include <unistd.h>
331acd27e7Smillert #endif /* HAVE_UNISTD_H */
341acd27e7Smillert 
351acd27e7Smillert #if defined (HAVE_STDLIB_H)
361acd27e7Smillert #  include <stdlib.h>
371acd27e7Smillert #else
381acd27e7Smillert #  include "ansi_stdlib.h"
391acd27e7Smillert #endif /* HAVE_STDLIB_H */
401acd27e7Smillert 
411acd27e7Smillert #if defined (HAVE_STRING_H)
421acd27e7Smillert #  include <string.h>
431acd27e7Smillert #else
441acd27e7Smillert #  include <strings.h>
451acd27e7Smillert #endif /* !HAVE_STRING_H */
461acd27e7Smillert 
47*af70c2dfSkettenis #if defined (HAVE_LIMITS_H)
48*af70c2dfSkettenis #  include <limits.h>
49*af70c2dfSkettenis #endif
50*af70c2dfSkettenis 
511acd27e7Smillert #include <fcntl.h>
521acd27e7Smillert #include <pwd.h>
531acd27e7Smillert 
541acd27e7Smillert #include <stdio.h>
551acd27e7Smillert 
56*af70c2dfSkettenis #include "rlstdc.h"
571acd27e7Smillert #include "rlshell.h"
581acd27e7Smillert #include "xmalloc.h"
591acd27e7Smillert 
601acd27e7Smillert #if !defined (HAVE_GETPW_DECLS)
61*af70c2dfSkettenis extern struct passwd *getpwuid PARAMS((uid_t));
621acd27e7Smillert #endif /* !HAVE_GETPW_DECLS */
631acd27e7Smillert 
641acd27e7Smillert #ifndef NULL
651acd27e7Smillert #  define NULL 0
661acd27e7Smillert #endif
671acd27e7Smillert 
68*af70c2dfSkettenis #ifndef CHAR_BIT
69*af70c2dfSkettenis #  define CHAR_BIT 8
70*af70c2dfSkettenis #endif
71*af70c2dfSkettenis 
72*af70c2dfSkettenis /* Nonzero if the integer type T is signed.  */
73*af70c2dfSkettenis #define TYPE_SIGNED(t) (! ((t) 0 < (t) -1))
74*af70c2dfSkettenis 
75*af70c2dfSkettenis /* Bound on length of the string representing an integer value of type T.
76*af70c2dfSkettenis    Subtract one for the sign bit if T is signed;
77*af70c2dfSkettenis    302 / 1000 is log10 (2) rounded up;
78*af70c2dfSkettenis    add one for integer division truncation;
79*af70c2dfSkettenis    add one more for a minus sign if t is signed.  */
80*af70c2dfSkettenis #define INT_STRLEN_BOUND(t) \
81*af70c2dfSkettenis   ((sizeof (t) * CHAR_BIT - TYPE_SIGNED (t)) * 302 / 1000 \
82*af70c2dfSkettenis    + 1 + TYPE_SIGNED (t))
83*af70c2dfSkettenis 
841acd27e7Smillert /* All of these functions are resolved from bash if we are linking readline
851acd27e7Smillert    as part of bash. */
861acd27e7Smillert 
871acd27e7Smillert /* Does shell-like quoting using single quotes. */
881acd27e7Smillert char *
sh_single_quote(string)89*af70c2dfSkettenis sh_single_quote (string)
901acd27e7Smillert      char *string;
911acd27e7Smillert {
921acd27e7Smillert   register int c;
931acd27e7Smillert   char *result, *r, *s;
941acd27e7Smillert 
951acd27e7Smillert   result = (char *)xmalloc (3 + (4 * strlen (string)));
961acd27e7Smillert   r = result;
971acd27e7Smillert   *r++ = '\'';
981acd27e7Smillert 
991acd27e7Smillert   for (s = string; s && (c = *s); s++)
1001acd27e7Smillert     {
1011acd27e7Smillert       *r++ = c;
1021acd27e7Smillert 
1031acd27e7Smillert       if (c == '\'')
1041acd27e7Smillert 	{
1051acd27e7Smillert 	  *r++ = '\\';	/* insert escaped single quote */
1061acd27e7Smillert 	  *r++ = '\'';
1071acd27e7Smillert 	  *r++ = '\'';	/* start new quoted string */
1081acd27e7Smillert 	}
1091acd27e7Smillert     }
1101acd27e7Smillert 
1111acd27e7Smillert   *r++ = '\'';
1121acd27e7Smillert   *r = '\0';
1131acd27e7Smillert 
1141acd27e7Smillert   return (result);
1151acd27e7Smillert }
1161acd27e7Smillert 
1171acd27e7Smillert /* Set the environment variables LINES and COLUMNS to lines and cols,
1181acd27e7Smillert    respectively. */
1191acd27e7Smillert void
sh_set_lines_and_columns(lines,cols)120*af70c2dfSkettenis sh_set_lines_and_columns (lines, cols)
1211acd27e7Smillert      int lines, cols;
1221acd27e7Smillert {
1231acd27e7Smillert   char *b;
1241acd27e7Smillert 
1251acd27e7Smillert #if defined (HAVE_PUTENV)
12663bef317Sbeck   if (asprintf (&b, "LINES=%d", lines) == -1)
12763bef317Sbeck 	  memory_error_and_abort("asprintf");
1281acd27e7Smillert   putenv (b);
12963bef317Sbeck   if (asprintf (&b, "COLUMNS=%d", cols) == -1)
13063bef317Sbeck 	  memory_error_and_abort("asprintf");
1311acd27e7Smillert   putenv (b);
1321acd27e7Smillert #else /* !HAVE_PUTENV */
1331acd27e7Smillert #  if defined (HAVE_SETENV)
13463bef317Sbeck   if (asprintf(&b, "%d", lines) == -1)
13563bef317Sbeck 	  memory_error_and_abort("asprintf");
1361acd27e7Smillert   setenv ("LINES", b, 1);
13763bef317Sbeck   if (asprintf (&b, "%d", cols) == -1)
13863bef317Sbeck 	  memory_error_and_abort("asprintf");
1391acd27e7Smillert   setenv ("COLUMNS", b, 1);
1401acd27e7Smillert #  endif /* HAVE_SETENV */
1411acd27e7Smillert #endif /* !HAVE_PUTENV */
1421acd27e7Smillert }
1431acd27e7Smillert 
1441acd27e7Smillert char *
sh_get_env_value(varname)145*af70c2dfSkettenis sh_get_env_value (varname)
146*af70c2dfSkettenis      const char *varname;
1471acd27e7Smillert {
1481acd27e7Smillert   return ((char *)getenv (varname));
1491acd27e7Smillert }
1501acd27e7Smillert 
1511acd27e7Smillert char *
sh_get_home_dir()152*af70c2dfSkettenis sh_get_home_dir ()
1531acd27e7Smillert {
1541acd27e7Smillert   char *home_dir;
1551acd27e7Smillert   struct passwd *entry;
1561acd27e7Smillert 
1571acd27e7Smillert   home_dir = (char *)NULL;
1581acd27e7Smillert   entry = getpwuid (getuid ());
1591acd27e7Smillert   if (entry)
1601acd27e7Smillert     home_dir = entry->pw_dir;
1611acd27e7Smillert   return (home_dir);
1621acd27e7Smillert }
1631acd27e7Smillert 
1641acd27e7Smillert #if !defined (O_NDELAY)
1651acd27e7Smillert #  if defined (FNDELAY)
1661acd27e7Smillert #    define O_NDELAY FNDELAY
1671acd27e7Smillert #  endif
1681acd27e7Smillert #endif
1691acd27e7Smillert 
1701acd27e7Smillert int
sh_unset_nodelay_mode(fd)171*af70c2dfSkettenis sh_unset_nodelay_mode (fd)
1721acd27e7Smillert      int fd;
1731acd27e7Smillert {
1741acd27e7Smillert   int flags, bflags;
1751acd27e7Smillert 
1761acd27e7Smillert   if ((flags = fcntl (fd, F_GETFL, 0)) < 0)
1771acd27e7Smillert     return -1;
1781acd27e7Smillert 
1791acd27e7Smillert   bflags = 0;
1801acd27e7Smillert 
1811acd27e7Smillert #ifdef O_NONBLOCK
1821acd27e7Smillert   bflags |= O_NONBLOCK;
1831acd27e7Smillert #endif
1841acd27e7Smillert 
1851acd27e7Smillert #ifdef O_NDELAY
1861acd27e7Smillert   bflags |= O_NDELAY;
1871acd27e7Smillert #endif
1881acd27e7Smillert 
1891acd27e7Smillert   if (flags & bflags)
1901acd27e7Smillert     {
1911acd27e7Smillert       flags &= ~bflags;
1921acd27e7Smillert       return (fcntl (fd, F_SETFL, flags));
1931acd27e7Smillert     }
1941acd27e7Smillert 
1951acd27e7Smillert   return 0;
1961acd27e7Smillert }
197