158314Sache/* $FreeBSD$ */
226497Sache/* shell.c -- readline utility functions that are normally provided by
326497Sache	      bash when readline is linked as part of the shell. */
426497Sache
526497Sache/* Copyright (C) 1997 Free Software Foundation, Inc.
626497Sache
726497Sache   This file is part of the GNU Readline Library, a library for
826497Sache   reading lines of text with interactive input and history editing.
926497Sache
1026497Sache   The GNU Readline Library is free software; you can redistribute it
1126497Sache   and/or modify it under the terms of the GNU General Public License
1258314Sache   as published by the Free Software Foundation; either version 2, or
1326497Sache   (at your option) any later version.
1426497Sache
1526497Sache   The GNU Readline Library is distributed in the hope that it will be
1626497Sache   useful, but WITHOUT ANY WARRANTY; without even the implied warranty
1726497Sache   of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1826497Sache   GNU General Public License for more details.
1926497Sache
2026497Sache   The GNU General Public License is often shipped with GNU software, and
2126497Sache   is generally kept in a file called COPYING or LICENSE.  If you do not
2226497Sache   have a copy of the license, write to the Free Software Foundation,
2358314Sache   59 Temple Place, Suite 330, Boston, MA 02111 USA. */
2426497Sache#define READLINE_LIBRARY
2526497Sache
2626497Sache#if defined (HAVE_CONFIG_H)
2726497Sache#  include <config.h>
2826497Sache#endif
2926497Sache
3047563Sache#include <sys/types.h>
3147563Sache
3226497Sache#if defined (HAVE_UNISTD_H)
3326497Sache#  include <unistd.h>
3426497Sache#endif /* HAVE_UNISTD_H */
3526497Sache
3626497Sache#if defined (HAVE_STDLIB_H)
3726497Sache#  include <stdlib.h>
3826497Sache#else
3926497Sache#  include "ansi_stdlib.h"
4026497Sache#endif /* HAVE_STDLIB_H */
4126497Sache
4235489Sache#if defined (HAVE_STRING_H)
4335489Sache#  include <string.h>
4435489Sache#else
4535489Sache#  include <strings.h>
4635489Sache#endif /* !HAVE_STRING_H */
4735489Sache
48119614Sache#if defined (HAVE_LIMITS_H)
49119614Sache#  include <limits.h>
50119614Sache#endif
51119614Sache
52157188Sache#if defined (HAVE_FCNTL_H)
5358314Sache#include <fcntl.h>
54157188Sache#endif
55157188Sache#if defined (HAVE_PWD_H)
5647563Sache#include <pwd.h>
57157188Sache#endif
5826497Sache
5958314Sache#include <stdio.h>
6058314Sache
6175409Sache#include "rlstdc.h"
6258314Sache#include "rlshell.h"
6358314Sache#include "xmalloc.h"
6458314Sache
65157188Sache#if defined (HAVE_GETPWUID) && !defined (HAVE_GETPW_DECLS)
66119614Sacheextern struct passwd *getpwuid PARAMS((uid_t));
67157188Sache#endif /* HAVE_GETPWUID && !HAVE_GETPW_DECLS */
6826497Sache
6958314Sache#ifndef NULL
7058314Sache#  define NULL 0
7158314Sache#endif
7226497Sache
73119614Sache#ifndef CHAR_BIT
74119614Sache#  define CHAR_BIT 8
75119614Sache#endif
76119614Sache
77119614Sache/* Nonzero if the integer type T is signed.  */
78119614Sache#define TYPE_SIGNED(t) (! ((t) 0 < (t) -1))
79119614Sache
80119614Sache/* Bound on length of the string representing an integer value of type T.
81119614Sache   Subtract one for the sign bit if T is signed;
82119614Sache   302 / 1000 is log10 (2) rounded up;
83119614Sache   add one for integer division truncation;
84119614Sache   add one more for a minus sign if t is signed.  */
85119614Sache#define INT_STRLEN_BOUND(t) \
86119614Sache  ((sizeof (t) * CHAR_BIT - TYPE_SIGNED (t)) * 302 / 1000 \
87119614Sache   + 1 + TYPE_SIGNED (t))
88119614Sache
8947563Sache/* All of these functions are resolved from bash if we are linking readline
9047563Sache   as part of bash. */
9126497Sache
9226497Sache/* Does shell-like quoting using single quotes. */
9326497Sachechar *
9475409Sachesh_single_quote (string)
9526497Sache     char *string;
9626497Sache{
9726497Sache  register int c;
9826497Sache  char *result, *r, *s;
9926497Sache
10058314Sache  result = (char *)xmalloc (3 + (4 * strlen (string)));
10126497Sache  r = result;
10226497Sache  *r++ = '\'';
10326497Sache
10426497Sache  for (s = string; s && (c = *s); s++)
10526497Sache    {
10626497Sache      *r++ = c;
10726497Sache
10826497Sache      if (c == '\'')
10926497Sache	{
11026497Sache	  *r++ = '\\';	/* insert escaped single quote */
11126497Sache	  *r++ = '\'';
11226497Sache	  *r++ = '\'';	/* start new quoted string */
11326497Sache	}
11426497Sache    }
11526497Sache
11626497Sache  *r++ = '\'';
11726497Sache  *r = '\0';
11826497Sache
11926497Sache  return (result);
12026497Sache}
12126497Sache
12226497Sache/* Set the environment variables LINES and COLUMNS to lines and cols,
12326497Sache   respectively. */
12426497Sachevoid
12575409Sachesh_set_lines_and_columns (lines, cols)
12626497Sache     int lines, cols;
12726497Sache{
12826497Sache  char *b;
12926497Sache
130157188Sache#if defined (HAVE_SETENV)
131119614Sache  b = (char *)xmalloc (INT_STRLEN_BOUND (int) + 1);
13226497Sache  sprintf (b, "%d", lines);
13326497Sache  setenv ("LINES", b, 1);
134136758Speter  free (b);
135136758Speter
136119614Sache  b = (char *)xmalloc (INT_STRLEN_BOUND (int) + 1);
13726497Sache  sprintf (b, "%d", cols);
13826497Sache  setenv ("COLUMNS", b, 1);
139136758Speter  free (b);
140157188Sache#else /* !HAVE_SETENV */
141157188Sache#  if defined (HAVE_PUTENV)
142157188Sache  b = (char *)xmalloc (INT_STRLEN_BOUND (int) + sizeof ("LINES=") + 1);
143157188Sache  sprintf (b, "LINES=%d", lines);
144157188Sache  putenv (b);
145157188Sache
146157188Sache  b = (char *)xmalloc (INT_STRLEN_BOUND (int) + sizeof ("COLUMNS=") + 1);
147157188Sache  sprintf (b, "COLUMNS=%d", cols);
148157188Sache  putenv (b);
149157188Sache#  endif /* HAVE_PUTENV */
150157188Sache#endif /* !HAVE_SETENV */
15126497Sache}
15226497Sache
15326497Sachechar *
15475409Sachesh_get_env_value (varname)
15575409Sache     const char *varname;
15626497Sache{
15726497Sache  return ((char *)getenv (varname));
15826497Sache}
15926497Sache
16026497Sachechar *
16175409Sachesh_get_home_dir ()
16226497Sache{
16347563Sache  char *home_dir;
16447563Sache  struct passwd *entry;
16547563Sache
16647563Sache  home_dir = (char *)NULL;
167157188Sache#if defined (HAVE_GETPWUID)
16847563Sache  entry = getpwuid (getuid ());
16947563Sache  if (entry)
17047563Sache    home_dir = entry->pw_dir;
171157188Sache#endif
17247563Sache  return (home_dir);
17347563Sache}
17458314Sache
17558314Sache#if !defined (O_NDELAY)
17658314Sache#  if defined (FNDELAY)
17758314Sache#    define O_NDELAY FNDELAY
17858314Sache#  endif
17958314Sache#endif
18058314Sache
18158314Sacheint
18275409Sachesh_unset_nodelay_mode (fd)
18358314Sache     int fd;
18458314Sache{
185157188Sache#if defined (HAVE_FCNTL)
18658314Sache  int flags, bflags;
18758314Sache
18858314Sache  if ((flags = fcntl (fd, F_GETFL, 0)) < 0)
18958314Sache    return -1;
19058314Sache
19158314Sache  bflags = 0;
19258314Sache
19358314Sache#ifdef O_NONBLOCK
19458314Sache  bflags |= O_NONBLOCK;
19558314Sache#endif
19658314Sache
19758314Sache#ifdef O_NDELAY
19858314Sache  bflags |= O_NDELAY;
19958314Sache#endif
20058314Sache
20158314Sache  if (flags & bflags)
20258314Sache    {
20358314Sache      flags &= ~bflags;
20458314Sache      return (fcntl (fd, F_SETFL, flags));
20558314Sache    }
206157188Sache#endif
20758314Sache
20858314Sache  return 0;
20958314Sache}
210