diff options
Diffstat (limited to 'lib/sh')
-rw-r--r-- | lib/sh/Makefile.in | 14 | ||||
-rw-r--r-- | lib/sh/getenv.c | 4 | ||||
-rw-r--r-- | lib/sh/netconn.c | 6 | ||||
-rw-r--r-- | lib/sh/pathcanon.c | 3 | ||||
-rw-r--r-- | lib/sh/pathphys.c | 1 | ||||
-rw-r--r-- | lib/sh/shmatch.c | 4 | ||||
-rw-r--r-- | lib/sh/shquote.c | 38 | ||||
-rw-r--r-- | lib/sh/snprintf.c | 74 | ||||
-rw-r--r-- | lib/sh/strftime.c | 17 | ||||
-rw-r--r-- | lib/sh/strnlen.c | 45 | ||||
-rw-r--r-- | lib/sh/strtoimax.c | 6 | ||||
-rw-r--r-- | lib/sh/strtoumax.c | 6 | ||||
-rw-r--r-- | lib/sh/strtrans.c | 8 | ||||
-rw-r--r-- | lib/sh/winsize.c | 82 | ||||
-rw-r--r-- | lib/sh/zread.c | 8 |
15 files changed, 279 insertions, 37 deletions
diff --git a/lib/sh/Makefile.in b/lib/sh/Makefile.in index c375c1d..32e2b31 100644 --- a/lib/sh/Makefile.in +++ b/lib/sh/Makefile.in @@ -2,7 +2,7 @@ # Makefile for the Bash library # # -# Copyright (C) 1998-2002 Free Software Foundation, Inc. +# Copyright (C) 1998-2005 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -86,21 +86,21 @@ CSOURCES = clktck.c clock.c getcwd.c getenv.c oslib.c setlinebuf.c \ inet_aton.c netconn.c netopen.c strpbrk.c timeval.c makepath.c \ pathcanon.c pathphys.c tmpfile.c stringlist.c stringvec.c spell.c \ shquote.c strtrans.c strindex.c snprintf.c mailstat.c \ - fmtulong.c fmtullong.c fmtumax.c shmatch.c \ + fmtulong.c fmtullong.c fmtumax.c shmatch.c strnlen.c \ strtoll.c strtoull.c strtoimax.c strtoumax.c memset.c strstr.c \ - mktime.c strftime.c xstrchr.c zcatfd.c + mktime.c strftime.c xstrchr.c zcatfd.c winsize.c # The header files for this library. HSOURCES = # The object files contained in $(LIBRARY_NAME) LIBOBJS = @LIBOBJS@ -OBJECTS = clktck.o clock.o getenv.o oslib.o setlinebuf.o \ +OBJECTS = clktck.o clock.o getenv.o oslib.o setlinebuf.o strnlen.o \ itos.o zread.o zwrite.o shtty.o shmatch.o \ netconn.o netopen.o timeval.o makepath.o pathcanon.o \ pathphys.o tmpfile.o stringlist.o stringvec.o spell.o shquote.o \ strtrans.o strindex.o snprintf.o mailstat.o fmtulong.o \ - fmtullong.o fmtumax.o xstrchr.o zcatfd.o ${LIBOBJS} + fmtullong.o fmtumax.o xstrchr.o zcatfd.o winsize.o ${LIBOBJS} SUPPORT = Makefile @@ -162,6 +162,7 @@ strftime.o: strftime.c strindex.o: strindex.c stringlist.o: stringlist.c stringvec.o: stringvec.c +strnlen.o: strnlen.c strpbrk.o: strpbrk.c strtod.o: strtod.c strtoimax.o: strtoimax.c @@ -218,6 +219,7 @@ strftime.o: ${BUILD_DIR}/config.h strindex.o: ${BUILD_DIR}/config.h stringlist.o: ${BUILD_DIR}/config.h stringvec.o: ${BUILD_DIR}/config.h +strnlen.o: ${BUILD_DIR}/config.h strpbrk.o: ${BUILD_DIR}/config.h strtod.o: ${BUILD_DIR}/config.h strtoimax.o: ${BUILD_DIR}/config.h @@ -372,6 +374,8 @@ stringvec.o: ${topdir}/unwind_prot.h ${topdir}/dispose_cmd.h stringvec.o: ${topdir}/make_cmd.h ${topdir}/subst.h ${topdir}/sig.h stringvec.o: ${BUILD_DIR}/pathnames.h ${topdir}/externs.h ${BUILD_DIR}/version.h +strnlen.o: ${BASHINCDIR}/stdc.h + strpbrk.o: ${BASHINCDIR}/stdc.h strtod.o: ${topdir}/bashansi.h diff --git a/lib/sh/getenv.c b/lib/sh/getenv.c index a7dfb18..c3fbf75 100644 --- a/lib/sh/getenv.c +++ b/lib/sh/getenv.c @@ -127,7 +127,7 @@ putenv (str) value = name + offset + 1; /* XXX - should we worry about readonly here? */ - var = bind_variable (name, value); + var = bind_variable (name, value, 0); if (var == 0) { errno = EINVAL; @@ -175,7 +175,7 @@ setenv (name, value, rewrite) var = find_variable (name); if (var == 0) - var = bind_variable (name, v); + var = bind_variable (name, v, 0); if (var == 0) return -1; diff --git a/lib/sh/netconn.c b/lib/sh/netconn.c index d05aef5..ae7c249 100644 --- a/lib/sh/netconn.c +++ b/lib/sh/netconn.c @@ -1,6 +1,6 @@ /* netconn.c -- is a particular file descriptor a network connection?. */ -/* Copyright (C) 2002 Free Software Foundation, Inc. +/* Copyright (C) 2002-2005 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. @@ -52,8 +52,8 @@ isnetconn (fd) l = sizeof(sa); rv = getpeername(fd, &sa, &l); - /* Solaris 2.5 getpeername() returns EINVAL if the fd is not a socket. */ - return ((rv < 0 && (errno == ENOTSOCK || errno == EINVAL)) ? 0 : 1); + /* Posix.2 says getpeername can return these errors. */ + return ((rv < 0 && (errno == ENOTSOCK || errno == ENOTCONN || errno == EINVAL)) ? 0 : 1); #else /* !HAVE_GETPEERNAME || SVR4_2 || __BEOS__ */ # if defined (SVR4) || defined (SVR4_2) /* Sockets on SVR4 and SVR4.2 are character special (streams) devices. */ diff --git a/lib/sh/pathcanon.c b/lib/sh/pathcanon.c index 8892954..3b427a8 100644 --- a/lib/sh/pathcanon.c +++ b/lib/sh/pathcanon.c @@ -75,10 +75,11 @@ static int _path_isdir (path) char *path; { - int l, x; + int l; struct stat sb; /* This should leave errno set to the correct value. */ + errno = 0; l = stat (path, &sb) == 0 && S_ISDIR (sb.st_mode); #if defined (__CYGWIN__) if (l == 0) diff --git a/lib/sh/pathphys.c b/lib/sh/pathphys.c index 4d6304c..1f73944 100644 --- a/lib/sh/pathphys.c +++ b/lib/sh/pathphys.c @@ -285,6 +285,7 @@ sh_realpath (pathname, resolved) { strncpy (resolved, wd, PATH_MAX - 1); resolved[PATH_MAX - 1] = '\0'; + free (wd); return resolved; } else diff --git a/lib/sh/shmatch.c b/lib/sh/shmatch.c index 18292ae..4508ed0 100644 --- a/lib/sh/shmatch.c +++ b/lib/sh/shmatch.c @@ -39,7 +39,7 @@ #include "variables.h" #include "externs.h" -extern int glob_ignore_case; +extern int glob_ignore_case, match_ignore_case; int sh_regmatch (string, pattern, flags) @@ -65,7 +65,7 @@ sh_regmatch (string, pattern, flags) #endif rflags = REG_EXTENDED; - if (glob_ignore_case) + if (glob_ignore_case || match_ignore_case) rflags |= REG_ICASE; #if !defined (ARRAY_VARS) rflags |= REG_NOSUB; diff --git a/lib/sh/shquote.c b/lib/sh/shquote.c index aac2d34..e992a66 100644 --- a/lib/sh/shquote.c +++ b/lib/sh/shquote.c @@ -81,7 +81,8 @@ sh_double_quote (string) for (s = string; s && (c = *s); s++) { - if (sh_syntaxtab[c] & CBSDQUOTE) + /* Backslash-newline disappears within double quotes, so don't add one. */ + if ((sh_syntaxtab[c] & CBSDQUOTE) && c != '\n') *r++ = '\\'; else if (c == CTLESC || c == CTLNUL) *r++ = CTLESC; /* could be '\\'? */ @@ -95,6 +96,32 @@ sh_double_quote (string) return (result); } +/* Turn S into a simple double-quoted string. If FLAGS is non-zero, quote + double quote characters in S with backslashes. */ +char * +sh_mkdoublequoted (s, slen, flags) + const char *s; + int slen, flags; +{ + char *r, *ret; + int rlen; + + rlen = (flags == 0) ? slen + 3 : (2 * slen) + 1; + ret = r = (char *)xmalloc (rlen); + + *r++ = '"'; + while (*s) + { + if (flags && *s == '"') + *r++ = '\\'; + *r++ = *s++; + } + *r++ = '"'; + *r = '\0'; + + return ret; +} + /* Remove backslashes that are quoting characters that are special between double quotes. Return a new string. XXX - should this handle CTLESC and CTLNUL? */ @@ -128,7 +155,11 @@ sh_un_double_quote (string) } /* Quote special characters in STRING using backslashes. Return a new - string. */ + string. NOTE: if the string is to be further expanded, we need a + way to protect the CTLESC and CTLNUL characters. As I write this, + the current callers will never cause the string to be expanded without + going through the shell parser, which will protect the internal + quoting characters. */ char * sh_backslash_quote (string) char *string; @@ -160,11 +191,12 @@ sh_backslash_quote (string) *r++ = '\\'; *r++ = c; break; -#endif + case CTLESC: case CTLNUL: /* internal quoting characters */ *r++ = CTLESC; /* could be '\\'? */ *r++ = c; break; +#endif case '#': /* comment char */ if (s == string) diff --git a/lib/sh/snprintf.c b/lib/sh/snprintf.c index b79b41f..114135f 100644 --- a/lib/sh/snprintf.c +++ b/lib/sh/snprintf.c @@ -372,10 +372,27 @@ static void xfree __P((void *)); /* if width and prec. in the args */ #define STAR_ARGS(p) \ + do { \ if ((p)->flags & PF_STAR_W) \ - (p)->width = GETARG (int); \ + { \ + (p)->width = GETARG (int); \ + if ((p)->width < 0) \ + { \ + (p)->flags |= PF_LADJUST; \ + (p)->justify = LEFT; \ + (p)->width = -(p)->width; \ + } \ + } \ if ((p)->flags & PF_STAR_P) \ - (p)->precision = GETARG (int) + { \ + (p)->precision = GETARG (int); \ + if ((p)->precision < 0) \ + { \ + (p)->flags &= ~PF_STAR_P; \ + (p)->precision = NOT_FOUND; \ + } \ + } \ + } while (0) #if defined (HAVE_LOCALE_H) # define GETLOCALEDATA(d, t, g) \ @@ -915,7 +932,7 @@ floating(p, d) char *tmp, *tmp2, *t; int i; - if (chkinfnan(p, d, 1) || chkinfnan(p, d, 2)) + if (d != 0 && (chkinfnan(p, d, 1) || chkinfnan(p, d, 2))) return; /* already printed nan or inf */ GETLOCALEDATA(decpoint, thoussep, grouping); @@ -936,8 +953,8 @@ floating(p, d) PUT_SPACE(d, p, 0.); while (*tmp) - { /* the integral */ - PUT_CHAR(*tmp, p); + { + PUT_CHAR(*tmp, p); /* the integral */ tmp++; } FREE (t); @@ -1010,7 +1027,7 @@ exponent(p, d) PUT_CHAR('E', p); /* the sign of the exp */ - if (j > 0) + if (j >= 0) PUT_CHAR('+', p); else { @@ -1150,6 +1167,7 @@ vsnprintf_internal(data, string, length, format, args) wint_t wc; #endif const char *convstart; + int negprec; /* Sanity check, the string length must be >= 0. C99 actually says that LENGTH can be zero here, in the case of snprintf/vsnprintf (it's never @@ -1165,6 +1183,7 @@ vsnprintf_internal(data, string, length, format, args) decpoint = thoussep = 0; grouping = 0; + negprec = 0; for (; c = *(data->pf); data->pf++) { if (c != '%') @@ -1221,16 +1240,24 @@ vsnprintf_internal(data, string, length, format, args) data->flags |= PF_STAR_W; continue; case '-': - data->flags |= PF_LADJUST; - data->justify = LEFT; + if ((data->flags & PF_DOT) == 0) + { + data->flags |= PF_LADJUST; + data->justify = LEFT; + } + else + negprec = 1; continue; case ' ': if ((data->flags & PF_PLUS) == 0) data->flags |= PF_SPACE; continue; case '+': - data->flags |= PF_PLUS; - data->justify = RIGHT; + if ((data->flags & PF_DOT) == 0) + { + data->flags |= PF_PLUS; + data->justify = RIGHT; + } continue; case '\'': data->flags |= PF_THOUSANDS; @@ -1250,7 +1277,7 @@ vsnprintf_internal(data, string, length, format, args) if (n < 0) n = 0; if (data->flags & PF_DOT) - data->precision = n; + data->precision = negprec ? NOT_FOUND : n; else data->width = n; continue; @@ -1507,11 +1534,21 @@ ldfallback (data, fs, fe, ld) char fmtbuf[FALLBACK_FMTSIZE], *obuf; int fl; - obuf = (char *)xmalloc(LFALLBACK_BASE + (data->precision < 6 ? 6 : data->precision) + 2); + fl = LFALLBACK_BASE + (data->precision < 6 ? 6 : data->precision) + 2; + obuf = (char *)xmalloc (fl); fl = fe - fs + 1; strncpy (fmtbuf, fs, fl); fmtbuf[fl] = '\0'; - sprintf (obuf, fmtbuf, ld); + + if ((data->flags & PF_STAR_W) && (data->flags & PF_STAR_P)) + sprintf (obuf, fmtbuf, data->width, data->precision, ld); + else if (data->flags & PF_STAR_W) + sprintf (obuf, fmtbuf, data->width, ld); + else if (data->flags & PF_STAR_P) + sprintf (obuf, fmtbuf, data->precision, ld); + else + sprintf (obuf, fmtbuf, ld); + for (x = obuf; *x; x++) PUT_CHAR (*x, data); xfree (obuf); @@ -1533,7 +1570,16 @@ dfallback (data, fs, fe, d) fl = fe - fs + 1; strncpy (fmtbuf, fs, fl); fmtbuf[fl] = '\0'; - sprintf (obuf, fmtbuf, d); + + if ((data->flags & PF_STAR_W) && (data->flags & PF_STAR_P)) + sprintf (obuf, fmtbuf, data->width, data->precision, d); + else if (data->flags & PF_STAR_W) + sprintf (obuf, fmtbuf, data->width, d); + else if (data->flags & PF_STAR_P) + sprintf (obuf, fmtbuf, data->precision, d); + else + sprintf (obuf, fmtbuf, d); + for (x = obuf; *x; x++) PUT_CHAR (*x, data); } diff --git a/lib/sh/strftime.c b/lib/sh/strftime.c index 4cb542f..0783d28 100644 --- a/lib/sh/strftime.c +++ b/lib/sh/strftime.c @@ -80,15 +80,21 @@ #undef strchr /* avoid AIX weirdness */ +#if defined (SHELL) +extern char *get_string_value (const char *); +#endif + extern void tzset(void); static int weeknumber(const struct tm *timeptr, int firstweekday); static int iso8601wknum(const struct tm *timeptr); +#ifndef inline #ifdef __GNUC__ #define inline __inline__ #else #define inline /**/ #endif +#endif #define range(low, item, hi) max(low, min(item, hi)) @@ -98,8 +104,12 @@ extern int daylight; #if defined(SOLARIS) || defined(mips) || defined (M_UNIX) extern long int timezone, altzone; #else +# if defined (HPUX) +extern long int timezone; +# else extern int timezone, altzone; -#endif +# endif /* !HPUX */ +#endif /* !SOLARIS && !mips && !M_UNIX */ #endif #undef min /* just in case */ @@ -480,8 +490,13 @@ strftime(char *s, size_t maxsize, const char *format, const struct tm *timeptr) * Systems with tzname[] probably have timezone as * secs west of GMT. Convert to mins east of GMT. */ +# ifdef HPUX + off = -timezone / 60; +# else off = -(daylight ? timezone : altzone) / 60; +# endif /* !HPUX */ #else /* !HAVE_TZNAME */ + gettimeofday(& tv, & zone); off = -zone.tz_minuteswest; #endif /* !HAVE_TZNAME */ #endif /* !HAVE_TM_ZONE */ diff --git a/lib/sh/strnlen.c b/lib/sh/strnlen.c new file mode 100644 index 0000000..da8feec --- /dev/null +++ b/lib/sh/strnlen.c @@ -0,0 +1,45 @@ +/* Copyright (C) 2004 Free Software Foundation, Inc. + + This program 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 2, or (at your option) any + later version. + + This program 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 this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#if !defined (HAVE_STRNLEN) + +#include <sys/types.h> + +#if defined (HAVE_UNISTD_H) +# include <unistd.h> +#endif + +#include <stdc.h> + +/* Find the length of S, but scan at most MAXLEN characters. If no '\0' + terminator is found within the first MAXLEN characters, return MAXLEN. */ +size_t +strnlen (s, maxlen) + register const char *s; + size_t maxlen; +{ + register const char *e; + size_t n; + + for (e = s, n = 0; *e && n < maxlen; e++, n++) + ; + return n; +} +#endif diff --git a/lib/sh/strtoimax.c b/lib/sh/strtoimax.c index 30075ce..e20c4cc 100644 --- a/lib/sh/strtoimax.c +++ b/lib/sh/strtoimax.c @@ -1,5 +1,5 @@ /* Convert string representation of a number into an intmax_t value. - Copyright 1999, 2001 Free Software Foundation, Inc. + Copyright 1999-2005 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -48,6 +48,10 @@ extern long strtol __P((const char *, char **, int)); extern long long strtoll __P((const char *, char **, int)); #endif +#ifdef strtoimax +#undef strtoimax +#endif + intmax_t strtoimax (ptr, endptr, base) const char *ptr; diff --git a/lib/sh/strtoumax.c b/lib/sh/strtoumax.c index c35461a..e723d49 100644 --- a/lib/sh/strtoumax.c +++ b/lib/sh/strtoumax.c @@ -1,5 +1,5 @@ /* Convert string representation of a number into an uintmax_t value. - Copyright 1999, 2001 Free Software Foundation, Inc. + Copyright 1999-2005 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -48,6 +48,10 @@ extern unsigned long strtoul __P((const char *, char **, int)); extern unsigned long long strtoull __P((const char *, char **, int)); #endif +#ifdef strtoumax +#undef strtoumax +#endif + uintmax_t strtoumax (ptr, endptr, base) const char *ptr; diff --git a/lib/sh/strtrans.c b/lib/sh/strtrans.c index e264e3d..acf9d69 100644 --- a/lib/sh/strtrans.c +++ b/lib/sh/strtrans.c @@ -44,7 +44,8 @@ that we're translating a string for `echo -e', and therefore should not treat a single quote as a character that may be escaped with a backslash. If (FLAGS&2) is non-zero, we're expanding for the parser and want to - quote CTLESC and CTLNUL with CTLESC */ + quote CTLESC and CTLNUL with CTLESC. If (flags&4) is non-zero, we want + to remove the backslash before any unrecognized escape sequence. */ char * ansicstr (string, len, flags, sawc, rlen) char *string; @@ -141,7 +142,10 @@ ansicstr (string, len, flags, sawc, rlen) break; } /*FALLTHROUGH*/ - default: *r++ = '\\'; break; + default: + if ((flags & 4) == 0) + *r++ = '\\'; + break; } if ((flags & 2) && (c == CTLESC || c == CTLNUL)) *r++ = CTLESC; diff --git a/lib/sh/winsize.c b/lib/sh/winsize.c new file mode 100644 index 0000000..8b39c99 --- /dev/null +++ b/lib/sh/winsize.c @@ -0,0 +1,82 @@ +/* Handle window size changes and information. */ + +/* Copyright (C) 2005 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash 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 2, or (at your option) any later + version. + + Bash 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 Bash; see the file COPYING. If not, write to the Free Software + Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ + +#include "config.h" + +#include <stdc.h> + +#include "bashtypes.h" + +#if defined (HAVE_UNISTD_H) +# include <unistd.h> +#endif + +#include <sys/ioctl.h> + +#if !defined (STRUCT_WINSIZE_IN_SYS_IOCTL) +/* For struct winsize on SCO */ +/* sys/ptem.h has winsize but needs mblk_t from sys/stream.h */ +# if defined (HAVE_SYS_PTEM_H) && defined (TIOCGWINSZ) && defined (SIGWINCH) +# if defined (HAVE_SYS_STREAM_H) +# include <sys/stream.h> +# endif +# include <sys/ptem.h> +# endif /* HAVE_SYS_PTEM_H && TIOCGWINSZ && SIGWINCH */ +#endif /* !STRUCT_WINSIZE_IN_SYS_IOCTL */ + +#include <stdio.h> + +/* Return the fd from which we are actually getting input. */ +#define input_tty() (shell_tty != -1) ? shell_tty : fileno (stderr) + +#if !defined (errno) +extern int errno; +#endif /* !errno */ + +extern int shell_tty; + +#if defined (READLINE) +extern void rl_set_screen_size __P((int, int)); +#endif + +void +get_new_window_size (from_sig, rp, cp) + int from_sig; + int *rp, *cp; +{ +#if defined (TIOCGWINSZ) + struct winsize win; + int tty; + + tty = input_tty (); + if (tty >= 0 && (ioctl (tty, TIOCGWINSZ, &win) == 0) && + win.ws_row > 0 && win.ws_col > 0) + { + sh_set_lines_and_columns (win.ws_row, win.ws_col); +#if defined (READLINE) + rl_set_screen_size (win.ws_row, win.ws_col); + if (rp) + *rp = win.ws_row; + if (cp) + *cp = win.ws_col; +#endif + } +#endif +} diff --git a/lib/sh/zread.c b/lib/sh/zread.c index b515548..460234b 100644 --- a/lib/sh/zread.c +++ b/lib/sh/zread.c @@ -124,9 +124,13 @@ zsyncfd (fd) int fd; { off_t off; + int r; off = lused - lind; + r = 0; if (off > 0) - lseek (fd, -off, SEEK_CUR); - lused = lind = 0; + r = lseek (fd, -off, SEEK_CUR); + + if (r >= 0) + lused = lind = 0; } |