Import of readline 4.3.
[external/binutils.git] / readline / shell.c
1 /* shell.c -- readline utility functions that are normally provided by
2               bash when readline is linked as part of the shell. */
3
4 /* Copyright (C) 1997 Free Software Foundation, Inc.
5
6    This file is part of the GNU Readline Library, a library for
7    reading lines of text with interactive input and history editing.
8
9    The GNU Readline Library is free software; you can redistribute it
10    and/or modify it under the terms of the GNU General Public License
11    as published by the Free Software Foundation; either version 2, or
12    (at your option) any later version.
13
14    The GNU Readline Library is distributed in the hope that it will be
15    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
16    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18
19    The GNU General Public License is often shipped with GNU software, and
20    is generally kept in a file called COPYING or LICENSE.  If you do not
21    have a copy of the license, write to the Free Software Foundation,
22    59 Temple Place, Suite 330, Boston, MA 02111 USA. */
23 #define READLINE_LIBRARY
24
25 #if defined (HAVE_CONFIG_H)
26 #  include <config.h>
27 #endif
28
29 #include <sys/types.h>
30 #include <stdio.h>
31
32 #if defined (HAVE_UNISTD_H)
33 #  include <unistd.h>
34 #endif /* HAVE_UNISTD_H */
35
36 #if defined (HAVE_STDLIB_H)
37 #  include <stdlib.h>
38 #else
39 #  include "ansi_stdlib.h"
40 #endif /* HAVE_STDLIB_H */
41
42 #if defined (HAVE_STRING_H)
43 #  include <string.h>
44 #else
45 #  include <strings.h>
46 #endif /* !HAVE_STRING_H */
47
48 #if defined (HAVE_LIMITS_H)
49 #  include <limits.h>
50 #endif
51
52 #include <fcntl.h>
53 #include <pwd.h>
54
55 #include <stdio.h>
56
57 #include "rlstdc.h"
58 #include "rlshell.h"
59 #include "xmalloc.h"
60
61 #if !defined (HAVE_GETPW_DECLS)
62 extern struct passwd *getpwuid PARAMS((uid_t));
63 #endif /* !HAVE_GETPW_DECLS */
64
65 #ifndef NULL
66 #  define NULL 0
67 #endif
68
69 #ifndef CHAR_BIT
70 #  define CHAR_BIT 8
71 #endif
72
73 /* Nonzero if the integer type T is signed.  */
74 #define TYPE_SIGNED(t) (! ((t) 0 < (t) -1))
75
76 /* Bound on length of the string representing an integer value of type T.
77    Subtract one for the sign bit if T is signed;
78    302 / 1000 is log10 (2) rounded up;
79    add one for integer division truncation;
80    add one more for a minus sign if t is signed.  */
81 #define INT_STRLEN_BOUND(t) \
82   ((sizeof (t) * CHAR_BIT - TYPE_SIGNED (t)) * 302 / 1000 \
83    + 1 + TYPE_SIGNED (t))
84
85 /* All of these functions are resolved from bash if we are linking readline
86    as part of bash. */
87
88 /* Does shell-like quoting using single quotes. */
89 char *
90 sh_single_quote (string)
91      char *string;
92 {
93   register int c;
94   char *result, *r, *s;
95
96   result = (char *)xmalloc (3 + (4 * strlen (string)));
97   r = result;
98   *r++ = '\'';
99
100   for (s = string; s && (c = *s); s++)
101     {
102       *r++ = c;
103
104       if (c == '\'')
105         {
106           *r++ = '\\';  /* insert escaped single quote */
107           *r++ = '\'';
108           *r++ = '\'';  /* start new quoted string */
109         }
110     }
111
112   *r++ = '\'';
113   *r = '\0';
114
115   return (result);
116 }
117
118 /* Set the environment variables LINES and COLUMNS to lines and cols,
119    respectively. */
120 void
121 sh_set_lines_and_columns (lines, cols)
122      int lines, cols;
123 {
124   char *b;
125
126 #if defined (HAVE_PUTENV)
127   b = (char *)xmalloc (INT_STRLEN_BOUND (int) + sizeof ("LINES=") + 1);
128   sprintf (b, "LINES=%d", lines);
129   putenv (b);
130   b = (char *)xmalloc (INT_STRLEN_BOUND (int) + sizeof ("COLUMNS=") + 1);
131   sprintf (b, "COLUMNS=%d", cols);
132   putenv (b);
133 #else /* !HAVE_PUTENV */
134 #  if defined (HAVE_SETENV)
135   b = (char *)xmalloc (INT_STRLEN_BOUND (int) + 1);
136   sprintf (b, "%d", lines);
137   setenv ("LINES", b, 1);
138   b = (char *)xmalloc (INT_STRLEN_BOUND (int) + 1);
139   sprintf (b, "%d", cols);
140   setenv ("COLUMNS", b, 1);
141 #  endif /* HAVE_SETENV */
142 #endif /* !HAVE_PUTENV */
143 }
144
145 char *
146 sh_get_env_value (varname)
147      const char *varname;
148 {
149   return ((char *)getenv (varname));
150 }
151
152 char *
153 sh_get_home_dir ()
154 {
155   char *home_dir;
156   struct passwd *entry;
157
158   home_dir = (char *)NULL;
159   entry = getpwuid (getuid ());
160   if (entry)
161     home_dir = entry->pw_dir;
162   return (home_dir);
163 }
164
165 #if !defined (O_NDELAY)
166 #  if defined (FNDELAY)
167 #    define O_NDELAY FNDELAY
168 #  endif
169 #endif
170
171 int
172 sh_unset_nodelay_mode (fd)
173      int fd;
174 {
175   int flags, bflags;
176
177   if ((flags = fcntl (fd, F_GETFL, 0)) < 0)
178     return -1;
179
180   bflags = 0;
181
182 #ifdef O_NONBLOCK
183   bflags |= O_NONBLOCK;
184 #endif
185
186 #ifdef O_NDELAY
187   bflags |= O_NDELAY;
188 #endif
189
190   if (flags & bflags)
191     {
192       flags &= ~bflags;
193       return (fcntl (fd, F_SETFL, flags));
194     }
195
196   return 0;
197 }