blob: 6947295e50e8952f5a1af04b56a7707833932363 [file] [log] [blame]
Jari Aaltod166f041997-06-05 14:59:13 +00001/* shell.c -- readline utility functions that are normally provided by
2 bash when readline is linked as part of the shell. */
3
Jari Aalto31859422009-01-12 13:36:28 +00004/* Copyright (C) 1997-2009 Free Software Foundation, Inc.
Jari Aaltod166f041997-06-05 14:59:13 +00005
Jari Aalto31859422009-01-12 13:36:28 +00006 This file is part of the GNU Readline Library (Readline), a library
7 for reading lines of text with interactive input and history editing.
Jari Aaltod166f041997-06-05 14:59:13 +00008
Jari Aalto31859422009-01-12 13:36:28 +00009 Readline is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
Jari Aaltod166f041997-06-05 14:59:13 +000012 (at your option) any later version.
13
Jari Aalto31859422009-01-12 13:36:28 +000014 Readline is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Jari Aaltod166f041997-06-05 14:59:13 +000017 GNU General Public License for more details.
18
Jari Aalto31859422009-01-12 13:36:28 +000019 You should have received a copy of the GNU General Public License
20 along with Readline. If not, see <http://www.gnu.org/licenses/>.
21*/
22
Jari Aaltod166f041997-06-05 14:59:13 +000023#define READLINE_LIBRARY
24
25#if defined (HAVE_CONFIG_H)
26# include <config.h>
27#endif
28
Jari Aaltob72432f1999-02-19 17:11:39 +000029#include <sys/types.h>
30
Jari Aaltod166f041997-06-05 14:59:13 +000031#if defined (HAVE_UNISTD_H)
32# include <unistd.h>
33#endif /* HAVE_UNISTD_H */
34
35#if defined (HAVE_STDLIB_H)
36# include <stdlib.h>
37#else
38# include "ansi_stdlib.h"
39#endif /* HAVE_STDLIB_H */
40
Jari Aaltocce855b1998-04-17 19:52:44 +000041#if defined (HAVE_STRING_H)
42# include <string.h>
43#else
44# include <strings.h>
45#endif /* !HAVE_STRING_H */
46
Jari Aaltof73dda02001-11-13 17:56:06 +000047#if defined (HAVE_LIMITS_H)
48# include <limits.h>
49#endif
50
Jari Aalto95732b42005-12-07 14:08:12 +000051#if defined (HAVE_FCNTL_H)
Jari Aaltobb706242000-03-17 21:46:59 +000052#include <fcntl.h>
Jari Aalto95732b42005-12-07 14:08:12 +000053#endif
54#if defined (HAVE_PWD_H)
Jari Aaltob72432f1999-02-19 17:11:39 +000055#include <pwd.h>
Jari Aalto95732b42005-12-07 14:08:12 +000056#endif
Jari Aaltod166f041997-06-05 14:59:13 +000057
Jari Aaltobb706242000-03-17 21:46:59 +000058#include <stdio.h>
59
Jari Aalto28ef6c32001-04-06 19:14:31 +000060#include "rlstdc.h"
Jari Aaltobb706242000-03-17 21:46:59 +000061#include "rlshell.h"
Chet Rameyac50fba2014-02-26 09:36:43 -050062#include "rldefs.h"
63
Jari Aaltobb706242000-03-17 21:46:59 +000064#include "xmalloc.h"
65
Jari Aalto95732b42005-12-07 14:08:12 +000066#if defined (HAVE_GETPWUID) && !defined (HAVE_GETPW_DECLS)
Jari Aaltof73dda02001-11-13 17:56:06 +000067extern struct passwd *getpwuid PARAMS((uid_t));
Jari Aalto95732b42005-12-07 14:08:12 +000068#endif /* HAVE_GETPWUID && !HAVE_GETPW_DECLS */
Jari Aaltod166f041997-06-05 14:59:13 +000069
Jari Aaltobb706242000-03-17 21:46:59 +000070#ifndef NULL
71# define NULL 0
72#endif
Jari Aaltod166f041997-06-05 14:59:13 +000073
Jari Aaltof73dda02001-11-13 17:56:06 +000074#ifndef CHAR_BIT
75# define CHAR_BIT 8
76#endif
77
78/* Nonzero if the integer type T is signed. */
79#define TYPE_SIGNED(t) (! ((t) 0 < (t) -1))
80
81/* Bound on length of the string representing an integer value of type T.
82 Subtract one for the sign bit if T is signed;
83 302 / 1000 is log10 (2) rounded up;
84 add one for integer division truncation;
85 add one more for a minus sign if t is signed. */
86#define INT_STRLEN_BOUND(t) \
87 ((sizeof (t) * CHAR_BIT - TYPE_SIGNED (t)) * 302 / 1000 \
88 + 1 + TYPE_SIGNED (t))
89
Jari Aaltob72432f1999-02-19 17:11:39 +000090/* All of these functions are resolved from bash if we are linking readline
91 as part of bash. */
Jari Aaltod166f041997-06-05 14:59:13 +000092
93/* Does shell-like quoting using single quotes. */
94char *
Jari Aalto28ef6c32001-04-06 19:14:31 +000095sh_single_quote (string)
Jari Aaltod166f041997-06-05 14:59:13 +000096 char *string;
97{
98 register int c;
99 char *result, *r, *s;
100
Jari Aaltobb706242000-03-17 21:46:59 +0000101 result = (char *)xmalloc (3 + (4 * strlen (string)));
Jari Aaltod166f041997-06-05 14:59:13 +0000102 r = result;
103 *r++ = '\'';
104
105 for (s = string; s && (c = *s); s++)
106 {
107 *r++ = c;
108
109 if (c == '\'')
110 {
111 *r++ = '\\'; /* insert escaped single quote */
112 *r++ = '\'';
113 *r++ = '\''; /* start new quoted string */
114 }
115 }
116
117 *r++ = '\'';
118 *r = '\0';
119
120 return (result);
121}
122
123/* Set the environment variables LINES and COLUMNS to lines and cols,
124 respectively. */
Chet Rameyac50fba2014-02-26 09:36:43 -0500125static char setenv_buf[INT_STRLEN_BOUND (int) + 1];
126static char putenv_buf1[INT_STRLEN_BOUND (int) + 6 + 1]; /* sizeof("LINES=") == 6 */
127static char putenv_buf2[INT_STRLEN_BOUND (int) + 8 + 1]; /* sizeof("COLUMNS=") == 8 */
128
Jari Aaltod166f041997-06-05 14:59:13 +0000129void
Jari Aalto28ef6c32001-04-06 19:14:31 +0000130sh_set_lines_and_columns (lines, cols)
Jari Aaltod166f041997-06-05 14:59:13 +0000131 int lines, cols;
132{
Jari Aalto95732b42005-12-07 14:08:12 +0000133#if defined (HAVE_SETENV)
Chet Rameyac50fba2014-02-26 09:36:43 -0500134 sprintf (setenv_buf, "%d", lines);
135 setenv ("LINES", setenv_buf, 1);
Jari Aaltob80f6442004-07-27 13:29:18 +0000136
Chet Rameyac50fba2014-02-26 09:36:43 -0500137 sprintf (setenv_buf, "%d", cols);
138 setenv ("COLUMNS", setenv_buf, 1);
Jari Aalto95732b42005-12-07 14:08:12 +0000139#else /* !HAVE_SETENV */
140# if defined (HAVE_PUTENV)
Chet Rameyac50fba2014-02-26 09:36:43 -0500141 sprintf (putenv_buf1, "LINES=%d", lines);
142 putenv (putenv_buf1);
Jari Aalto95732b42005-12-07 14:08:12 +0000143
Chet Rameyac50fba2014-02-26 09:36:43 -0500144 sprintf (putenv_buf2, "COLUMNS=%d", cols);
145 putenv (putenv_buf2);
Jari Aalto95732b42005-12-07 14:08:12 +0000146# endif /* HAVE_PUTENV */
147#endif /* !HAVE_SETENV */
Jari Aaltod166f041997-06-05 14:59:13 +0000148}
149
150char *
Jari Aalto28ef6c32001-04-06 19:14:31 +0000151sh_get_env_value (varname)
152 const char *varname;
Jari Aaltod166f041997-06-05 14:59:13 +0000153{
154 return ((char *)getenv (varname));
155}
156
Jari Aaltod166f041997-06-05 14:59:13 +0000157char *
Jari Aalto28ef6c32001-04-06 19:14:31 +0000158sh_get_home_dir ()
Jari Aaltod166f041997-06-05 14:59:13 +0000159{
Chet Rameyac50fba2014-02-26 09:36:43 -0500160 static char *home_dir = (char *)NULL;
Jari Aaltob72432f1999-02-19 17:11:39 +0000161 struct passwd *entry;
162
Chet Rameyac50fba2014-02-26 09:36:43 -0500163 if (home_dir)
164 return (home_dir);
165
Jari Aaltob72432f1999-02-19 17:11:39 +0000166 home_dir = (char *)NULL;
Jari Aalto95732b42005-12-07 14:08:12 +0000167#if defined (HAVE_GETPWUID)
Chet Rameyac50fba2014-02-26 09:36:43 -0500168# if defined (__TANDEM)
169 entry = getpwnam (getlogin ());
170# else
Jari Aaltob72432f1999-02-19 17:11:39 +0000171 entry = getpwuid (getuid ());
Chet Rameyac50fba2014-02-26 09:36:43 -0500172# endif
Jari Aaltob72432f1999-02-19 17:11:39 +0000173 if (entry)
Chet Rameyac50fba2014-02-26 09:36:43 -0500174 home_dir = savestring (entry->pw_dir);
Jari Aalto95732b42005-12-07 14:08:12 +0000175#endif
Chet Rameyac50fba2014-02-26 09:36:43 -0500176
177#if defined (HAVE_GETPWENT)
178 endpwent (); /* some systems need this */
179#endif
180
Jari Aaltob72432f1999-02-19 17:11:39 +0000181 return (home_dir);
182}
Jari Aaltobb706242000-03-17 21:46:59 +0000183
184#if !defined (O_NDELAY)
185# if defined (FNDELAY)
186# define O_NDELAY FNDELAY
187# endif
188#endif
189
190int
Jari Aalto28ef6c32001-04-06 19:14:31 +0000191sh_unset_nodelay_mode (fd)
Jari Aaltobb706242000-03-17 21:46:59 +0000192 int fd;
193{
Jari Aalto95732b42005-12-07 14:08:12 +0000194#if defined (HAVE_FCNTL)
Jari Aaltobb706242000-03-17 21:46:59 +0000195 int flags, bflags;
196
197 if ((flags = fcntl (fd, F_GETFL, 0)) < 0)
198 return -1;
199
200 bflags = 0;
201
202#ifdef O_NONBLOCK
203 bflags |= O_NONBLOCK;
204#endif
205
206#ifdef O_NDELAY
207 bflags |= O_NDELAY;
208#endif
209
210 if (flags & bflags)
211 {
212 flags &= ~bflags;
213 return (fcntl (fd, F_SETFL, flags));
214 }
Jari Aalto95732b42005-12-07 14:08:12 +0000215#endif
Jari Aaltobb706242000-03-17 21:46:59 +0000216
217 return 0;
218}