diff options
Diffstat (limited to 'lib/sh')
| -rw-r--r-- | lib/sh/Makefile.in | 29 | ||||
| -rw-r--r-- | lib/sh/eaccess.c | 222 | ||||
| -rw-r--r-- | lib/sh/netopen.c | 10 | ||||
| -rw-r--r-- | lib/sh/shmatch.c | 3 | ||||
| -rw-r--r-- | lib/sh/snprintf.c | 29 | ||||
| -rw-r--r-- | lib/sh/strtrans.c | 16 | ||||
| -rw-r--r-- | lib/sh/tmpfile.c | 5 | ||||
| -rw-r--r-- | lib/sh/wcsdup.c | 44 | ||||
| -rw-r--r-- | lib/sh/winsize.c | 1 | 
9 files changed, 349 insertions, 10 deletions
diff --git a/lib/sh/Makefile.in b/lib/sh/Makefile.in index 32e2b31..bf95d19 100644 --- a/lib/sh/Makefile.in +++ b/lib/sh/Makefile.in @@ -88,7 +88,8 @@ CSOURCES = clktck.c clock.c getcwd.c getenv.c oslib.c setlinebuf.c \  	   shquote.c strtrans.c strindex.c snprintf.c mailstat.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 winsize.c +	   mktime.c strftime.c xstrchr.c zcatfd.c winsize.c eaccess.c \ +	   wcsdup.c  # The header files for this library.  HSOURCES =  @@ -96,11 +97,12 @@ HSOURCES =  # The object files contained in $(LIBRARY_NAME)  LIBOBJS = @LIBOBJS@  OBJECTS = clktck.o clock.o getenv.o oslib.o setlinebuf.o strnlen.o \ -	  itos.o zread.o zwrite.o shtty.o shmatch.o \ +	  itos.o zread.o zwrite.o shtty.o shmatch.o eaccess.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 winsize.o ${LIBOBJS} +	  fmtullong.o fmtumax.o xstrchr.o zcatfd.o winsize.o wcsdup.o \ +	  ${LIBOBJS}  SUPPORT = Makefile @@ -134,6 +136,7 @@ ${BUILD_DIR}/version.h: ${BUILD_DIR}/config.h ${BUILD_DIR}/Makefile Makefile  # rules for losing makes, like SunOS  clktck.o: clktck.c  clock.o: clock.c +eaccess.o: eaccess.c  fmtullong.o: fmtullong.c  fmtulong.o: fmtulong.c  fmtumax.o: fmtumax.c @@ -176,6 +179,7 @@ times.o: times.c  timeval.o: timeval.c  tmpfile.o: tmpfile.c  vprint.o: vprint.c +wcsdup.o: wcsdup.c  xstrchr.o: xstrchr.c  zcatfd.o: zcatfd.c  zread.o: zread.c @@ -191,6 +195,7 @@ strtoull.o: strtol.c  # all files in the library depend on config.h  clktck.o: ${BUILD_DIR}/config.h  clock.o: ${BUILD_DIR}/config.h +eaccess.o: ${BUILD_DIR}/config.h  fmtullong.o: ${BUILD_DIR}/config.h  fmtulong.o: ${BUILD_DIR}/config.h  fmtumax.o: ${BUILD_DIR}/config.h @@ -233,6 +238,7 @@ times.o: ${BUILD_DIR}/config.h  timeval.o: ${BUILD_DIR}/config.h  tmpfile.o: ${BUILD_DIR}/config.h  vprint.o: ${BUILD_DIR}/config.h +wcsdup.o: ${BUILD_DIR}/config.h  xstrchr.o: ${BUILD_DIR}/config.h  zcatfd.o: ${BUILD_DIR}/config.h  zread.o: ${BUILD_DIR}/config.h @@ -327,6 +333,19 @@ rename.o: ${BASHINCDIR}/posixstat.h  setlinebuf.o: ${topdir}/xmalloc.h ${topdir}/bashansi.h  setlinebuf.o: ${BASHINCDIR}/ansi_stdlib.h ${BASHINCDIR}/stdc.h +eaccess.o: ${topdir}/bashtypes.h +eaccess.o: ${BASHINCDIR}/posixstat.h +eaccess.o: ${topdir}/bashansi.h ${BASHINCDIR}/ansi_stdlib.h +eaccess.o: ${BASHINCDIR}/filecntl.h +eaccess.o: ${BASHINCDIR}/stdc.h +eaccess.o: ${topdir}/shell.h ${topdir}/syntax.h ${topdir}/bashjmp.h ${BASHINCDIR}/posixjmp.h +eaccess.o: ${topdir}/command.h ${BASHINCDIR}/stdc.h ${topdir}/error.h +eaccess.o: ${topdir}/general.h ${topdir}/bashtypes.h ${topdir}/variables.h ${topdir}/conftypes.h +eaccess.o: ${topdir}/array.h ${topdir}/hashlib.h ${topdir}/quit.h +eaccess.o: ${topdir}/unwind_prot.h ${topdir}/dispose_cmd.h +eaccess.o: ${topdir}/make_cmd.h ${topdir}/subst.h ${topdir}/sig.h +eaccess.o: ${BUILD_DIR}/pathnames.h ${topdir}/externs.h ${BUILD_DIR}/version.h +  shquote.o: ${BASHINCDIR}/stdc.h ${topdir}/bashansi.h  shquote.o: ${BASHINCDIR}/ansi_stdlib.h ${topdir}/xmalloc.h @@ -450,6 +469,10 @@ fmtumax.o: ${BASHINCDIR}/stdc.h  fmtumax.o: ${BASHINCDIR}/typemax.h  fmtumax.o: ${topdir}/bashintl.h ${LIBINTL_H} ${BASHINCDIR}/gettext.h +wcsdup.o: ${topdir}/bashansi.h ${BASHINCDIR}/ansi_stdlib.h +wcsdup.o: ${BASHINCDIR}/stdc.h +wcsdup.o: ${topdir}/xmalloc.h +  xstrchr.o: ${topdir}/bashansi.h  xstrchr.o: ${BASHINCDIR}/ansi_stdlib.h  xstrchr.o: ${BASHINCDIR}/shmbutil.h diff --git a/lib/sh/eaccess.c b/lib/sh/eaccess.c new file mode 100644 index 0000000..1cff692 --- /dev/null +++ b/lib/sh/eaccess.c @@ -0,0 +1,222 @@ +/* eaccess.c - eaccess replacement for the shell, plus other access functions. */ + +/* Copyright (C) 2006 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. */ + +#if defined (HAVE_CONFIG_H) +#  include <config.h> +#endif + +#include <stdio.h> + +#include "bashtypes.h" + +#if defined (HAVE_UNISTD_H) +#  include <unistd.h> +#endif + +#include "bashansi.h" + +#include <errno.h> +#if !defined (errno) +extern int errno; +#endif /* !errno */ + +#if !defined (_POSIX_VERSION) && defined (HAVE_SYS_FILE_H) +#  include <sys/file.h> +#endif /* !_POSIX_VERSION */ +#include "posixstat.h" +#include "filecntl.h" + +#include "shell.h" + +#if !defined (R_OK) +#define R_OK 4 +#define W_OK 2 +#define X_OK 1 +#define F_OK 0 +#endif /* R_OK */ + +static int path_is_devfd __P((const char *)); +static int sh_stataccess __P((char *, int)); +#if HAVE_DECL_SETREGID +static int sh_euidaccess __P((char *, int)); +#endif + +static int +path_is_devfd (path) +     const char *path; +{ +  if (path[0] == '/' && path[1] == 'd' && strncmp (path, "/dev/fd/", 8) == 0) +    return 1; +  else if (STREQN (path, "/dev/std", 8)) +    { +      if (STREQ (path+8, "in") || STREQ (path+8, "out") || STREQ (path+8, "err")) +	return 1; +      else +	return 0; +    } +  else +    return 0; +} + +/* A wrapper for stat () which disallows pathnames that are empty strings +   and handles /dev/fd emulation on systems that don't have it. */ +int +sh_stat (path, finfo) +     const char *path; +     struct stat *finfo; +{ +  if (*path == '\0') +    { +      errno = ENOENT; +      return (-1); +    } +  if (path[0] == '/' && path[1] == 'd' && strncmp (path, "/dev/fd/", 8) == 0) +    { +#if !defined (HAVE_DEV_FD) +      intmax_t fd; +      int r; + +      if (legal_number (path + 8, &fd) && fd == (int)fd) +        { +          r = fstat ((int)fd, finfo); +          if (r == 0 || errno != EBADF) +            return (r); +        } +      errno = ENOENT; +      return (-1); +#else +  /* If HAVE_DEV_FD is defined, DEV_FD_PREFIX is defined also, and has a +     trailing slash.  Make sure /dev/fd/xx really uses DEV_FD_PREFIX/xx. +     On most systems, with the notable exception of linux, this is +     effectively a no-op. */ +      char pbuf[32]; +      strcpy (pbuf, DEV_FD_PREFIX); +      strcat (pbuf, path + 8); +      return (stat (pbuf, finfo)); +#endif /* !HAVE_DEV_FD */ +    } +#if !defined (HAVE_DEV_STDIN) +  else if (STREQN (path, "/dev/std", 8)) +    { +      if (STREQ (path+8, "in")) +	return (fstat (0, finfo)); +      else if (STREQ (path+8, "out")) +	return (fstat (1, finfo)); +      else if (STREQ (path+8, "err")) +	return (fstat (2, finfo)); +      else +	return (stat (path, finfo)); +    } +#endif /* !HAVE_DEV_STDIN */ +  return (stat (path, finfo)); +} + +/* Do the same thing access(2) does, but use the effective uid and gid, +   and don't make the mistake of telling root that any file is +   executable.  This version uses stat(2). */ +static int +sh_stataccess (path, mode) +     char *path; +     int mode; +{ +  struct stat st; + +  if (sh_stat (path, &st) < 0) +    return (-1); + +  if (current_user.euid == 0) +    { +      /* Root can read or write any file. */ +      if ((mode & X_OK) == 0) +	return (0); + +      /* Root can execute any file that has any one of the execute +	 bits set. */ +      if (st.st_mode & S_IXUGO) +	return (0); +    } + +  if (st.st_uid == current_user.euid)	/* owner */ +    mode <<= 6; +  else if (group_member (st.st_gid)) +    mode <<= 3; + +  if (st.st_mode & mode) +    return (0); + +  errno = EACCES; +  return (-1); +} + +#if HAVE_DECL_SETREGID +/* Version to call when uid != euid or gid != egid.  We temporarily swap +   the effective and real uid and gid as appropriate. */ +static int +sh_euidaccess (path, mode) +     char *path; +     int mode; +{ +  int r, e; + +  if (current_user.uid != current_user.euid) +    setreuid (current_user.euid, current_user.uid); +  if (current_user.gid != current_user.egid) +    setregid (current_user.egid, current_user.gid); + +  r = access (path, mode); +  e = errno; + +  if (current_user.uid != current_user.euid) +    setreuid (current_user.uid, current_user.euid); +  if (current_user.gid != current_user.egid) +    setregid (current_user.gid, current_user.egid); + +  errno = e; +  return r;   +} +#endif + +int +sh_eaccess (path, mode) +     char *path; +     int mode; +{ +  if (path_is_devfd (path)) +    return (sh_stataccess (path, mode)); + +#if defined (HAVE_EACCESS)		/* FreeBSD */ +  return (eaccess (path, mode)); +#elif defined (EFF_ONLY_OK)		/* SVR4(?), SVR4.2 */ +  return access (path, mode|EFF_ONLY_OK); +#else +  if (mode == F_OK) +    return (sh_stataccess (path, mode)); +     +#  if HAVE_DECL_SETREGID +  if (current_user.uid != current_user.euid || current_user.gid != current_user.egid) +    return (sh_euidaccess (path, mode)); +#  endif + +  if (current_user.uid == current_user.euid && current_user.gid == current_user.egid) +    return (access (path, mode));   + +  return (sh_stataccess (path, mode)); +#endif +} diff --git a/lib/sh/netopen.c b/lib/sh/netopen.c index aaf0c47..d8eec75 100644 --- a/lib/sh/netopen.c +++ b/lib/sh/netopen.c @@ -67,6 +67,16 @@ extern int inet_aton __P((const char *, struct in_addr *));  #endif  #ifndef HAVE_GETADDRINFO +static int _getaddr __P((char *, struct in_addr *)); +static int _getserv __P((char *, int, unsigned short *)); +static int _netopen4 __P((char *, char *, int)); +#else /* HAVE_GETADDRINFO */ +static int _netopen6 __P((char *, char *, int)); +#endif + +static int _netopen __P((char *, char *, int)); + +#ifndef HAVE_GETADDRINFO  /* Stuff the internet address corresponding to HOST into AP, in network     byte order.  Return 1 on success, 0 on failure. */ diff --git a/lib/sh/shmatch.c b/lib/sh/shmatch.c index 4508ed0..f03a2ee 100644 --- a/lib/sh/shmatch.c +++ b/lib/sh/shmatch.c @@ -57,8 +57,7 @@ sh_regmatch (string, pattern, flags)    char *subexp_str;    int subexp_len;  #endif -  int result;   - +  int result;  #if defined (ARRAY_VARS)    rematch = (SHELL_VAR *)NULL; diff --git a/lib/sh/snprintf.c b/lib/sh/snprintf.c index 114135f..4a96474 100644 --- a/lib/sh/snprintf.c +++ b/lib/sh/snprintf.c @@ -65,6 +65,7 @@  #define HAVE_PRINTF_A_FORMAT  #endif  #define HAVE_ISINF_IN_LIBC +#define HAVE_ISNAN_IN_LIBC  #define PREFER_STDARG  #define HAVE_STRINGIZE  #define HAVE_LIMITS_H @@ -370,6 +371,12 @@ static void xfree __P((void *));  	      for (; (p)->width > 0; (p)->width--) \  		 PUT_CHAR((p)->pad, p) +/* pad with zeros from decimal precision */ +#define PAD_ZERO(p) \ +	if ((p)->precision > 0) \ +	  for (; (p)->precision > 0; (p)->precision--) \ +	    PUT_CHAR('0', p) +  /* if width and prec. in the args */  #define STAR_ARGS(p) \  	do { \ @@ -651,6 +658,10 @@ number(p, d, base)    long sd;    int flags; +  /* An explicit precision turns off the zero-padding flag. */ +  if ((p->flags & PF_ZEROPAD) && p->precision >= 0 && (p->flags & PF_DOT)) +    p->flags &= ~PF_ZEROPAD; +    sd = d;	/* signed for ' ' padding in base 10 */    flags = (*p->pf == 'u' || *p->pf == 'U') ? FL_UNSIGNED : 0;    if (*p->pf == 'X') @@ -668,6 +679,12 @@ number(p, d, base)    p->width -= strlen(tmp);    PAD_RIGHT(p); +  if ((p->flags & PF_DOT) && p->precision > 0) +    { +      p->precision -= strlen(tmp); +      PAD_ZERO(p); +    } +    switch (base)      {      case 10: @@ -711,6 +728,10 @@ lnumber(p, d, base)    long long sd;    int flags; +  /* An explicit precision turns off the zero-padding flag. */ +  if ((p->flags & PF_ZEROPAD) && p->precision >= 0 && (p->flags & PF_DOT)) +    p->flags &= ~PF_ZEROPAD; +    sd = d;	/* signed for ' ' padding in base 10 */    flags = (*p->pf == 'u' || *p->pf == 'U') ? FL_UNSIGNED : 0;    if (*p->pf == 'X') @@ -728,6 +749,12 @@ lnumber(p, d, base)    p->width -= strlen(tmp);    PAD_RIGHT(p); +  if ((p->flags & PF_DOT) && p->precision > 0) +    { +      p->precision -= strlen(tmp); +      PAD_ZERO(p); +    } +    switch (base)      {      case 10: @@ -881,7 +908,9 @@ isinf(d)  #endif      return 0;  } +#endif +#ifndef HAVE_ISNAN_IN_LIBC  static int  isnan(d)       double d; diff --git a/lib/sh/strtrans.c b/lib/sh/strtrans.c index acf9d69..1f0290e 100644 --- a/lib/sh/strtrans.c +++ b/lib/sh/strtrans.c @@ -81,8 +81,18 @@ ansicstr (string, len, flags, sawc, rlen)  	    case 'n': c = '\n'; break;  	    case 'r': c = '\r'; break;  	    case 't': c = '\t'; break; -	    case '0': case '1': case '2': case '3': -	    case '4': case '5': case '6': case '7': +	    case '1': case '2': case '3': +	    case '4': case '5': case '6': +	    case '7': +#if 1 +	      if (flags & 1) +		{ +		  *r++ = '\\'; +		  break; +		} +	    /*FALLTHROUGH*/ +#endif +	    case '0':  	      /* If (FLAGS & 1), we're translating a string for echo -e (or  		 the equivalent xpg_echo option), so we obey the SUSv3/  		 POSIX-2001 requirement and accept 0-3 octal digits after @@ -166,7 +176,7 @@ ansic_quote (str, flags, rlen)       int flags, *rlen;  {    char *r, *ret, *s; -  int l, rsize, t; +  int l, rsize;    unsigned char c;    if (str == 0 || *str == 0) diff --git a/lib/sh/tmpfile.c b/lib/sh/tmpfile.c index fb7b732..5f2279d 100644 --- a/lib/sh/tmpfile.c +++ b/lib/sh/tmpfile.c @@ -47,6 +47,9 @@ extern int errno;  extern pid_t dollar_dollar_pid; +static char *get_sys_tmpdir __P((void)); +static char *get_tmpdir __P((int)); +  static char *sys_tmpdir = (char *)NULL;  static int ntmpfiles;  static int tmpnamelen = -1; @@ -55,8 +58,6 @@ static unsigned long filenum = 1L;  static char *  get_sys_tmpdir ()  { -  struct stat sb; -    if (sys_tmpdir)      return sys_tmpdir; diff --git a/lib/sh/wcsdup.c b/lib/sh/wcsdup.c new file mode 100644 index 0000000..e045307 --- /dev/null +++ b/lib/sh/wcsdup.c @@ -0,0 +1,44 @@ +/* wcsdup.c - wcsdup(3) library function */ + +/* Copyright (C) 2006 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> + +#if !defined (HAVE_WCSDUP) && defined (HANDLE_MULTIBYTE) + +#include <stdc.h> +#include <wchar.h> +#include <bashansi.h> +#include <xmalloc.h> + +wchar_t * +wcsdup (ws) +     const wchar_t *ws; +{ +  wchar_t *ret; +  size_t len; + +  len = wcslen (ws); +  ret = xmalloc ((len + 1) * sizeof (wchar_t)); +  if (ret == 0) +    return ret; +   +  return (wcscpy (ret, ws)); +} +#endif /* !HAVE_WCSDUP && HANDLE_MULTIBYTE */ diff --git a/lib/sh/winsize.c b/lib/sh/winsize.c index 8b39c99..f4696de 100644 --- a/lib/sh/winsize.c +++ b/lib/sh/winsize.c @@ -55,6 +55,7 @@ extern int shell_tty;  #if defined (READLINE)  extern void rl_set_screen_size __P((int, int));  #endif +extern void sh_set_lines_and_columns __P((int, int));  void  get_new_window_size (from_sig, rp, cp)  | 
