commit bash-20080410 snapshot

This commit is contained in:
Chet Ramey
2011-12-07 09:21:48 -05:00
parent 1d0e1a34e0
commit 6a8fd0ed50
220 changed files with 27343 additions and 10005 deletions
+2
View File
@@ -91,6 +91,8 @@ basename_builtin (list)
}
char *basename_doc[] = {
"Return non-directory portion of pathname.",
"",
"The STRING is converted to a filename corresponding to the last",
"pathname component in STRING. If the suffix string SUFFIX is",
"supplied, it is removed.",
+1
View File
@@ -11,6 +11,7 @@
#include <stdio.h>
#include "builtins.h"
#include "shell.h"
#include "common.h"
basename_builtin (list)
WORD_LIST *list;
+2
View File
@@ -84,6 +84,8 @@ WORD_LIST *list;
}
char *cat_doc[] = {
"Display files.",
"",
"Read each FILE and display it on the standard output. If any",
"FILE is `-' or if no FILE argument is given, the standard input",
"is read.",
+100
View File
@@ -0,0 +1,100 @@
/*
* cat replacement
*
* no options - the way cat was intended
*/
#include <fcntl.h>
#include <errno.h>
#include "builtins.h"
#include "shell.h"
#ifndef errno
extern int errno;
#endif
extern char *strerror ();
extern char **make_builtin_argv ();
static int
fcopy(fd)
int fd;
{
char buf[1024], *s;
int n, w, e;
while (n = read(fd, buf, sizeof (buf))) {
w = write(1, buf, n);
if (w != n) {
e = errno;
write(2, "cat: write error: ", 18);
s = strerror(e);
write(2, s, strlen(s));
write(2, "\n", 1);
return 1;
}
}
return 0;
}
cat_main (argc, argv)
int argc;
char **argv;
{
int i, fd, r;
char *s;
if (argc == 1)
return (fcopy(0));
for (i = r = 1; i < argc; i++) {
if (argv[i][0] == '-' && argv[i][1] == '\0')
fd = 0;
else {
fd = open(argv[i], O_RDONLY, 0666);
if (fd < 0) {
s = strerror(errno);
write(2, "cat: cannot open ", 17);
write(2, argv[i], strlen(argv[i]));
write(2, ": ", 2);
write(2, s, strlen(s));
write(2, "\n", 1);
continue;
}
}
r = fcopy(fd);
if (fd != 0)
close(fd);
}
return (r);
}
cat_builtin(list)
WORD_LIST *list;
{
char **v;
int c, r;
v = make_builtin_argv(list, &c);
r = cat_main(c, v);
free(v);
return r;
}
char *cat_doc[] = {
"Read each FILE and display it on the standard output. If any",
"FILE is `-' or if no FILE argument is given, the standard input",
"is read.",
(char *)0
};
struct builtin cat_struct = {
"cat",
cat_builtin,
BUILTIN_ENABLED,
cat_doc,
"cat [-] [file ...]",
0
};
+2
View File
@@ -360,6 +360,8 @@ _cut_strsep(stringp, delim)
}
static char *cut_doc[] = {
"Select portions of lines.",
"",
"Select portions of each line (as specified by LIST) from each FILE",
"(by default, the standard input), and write them to the standard output.",
"Items specified by LIST are either column positions or fields delimited",
+1
View File
@@ -63,6 +63,7 @@ static const char sccsid[] = "@(#)cut.c 8.3 (Berkeley) 5/4/95";
#include "builtins.h"
#include "shell.h"
#include "bashgetopt.h"
#include "common.h"
#if !defined (errno)
extern int errno;
+2
View File
@@ -79,6 +79,8 @@ dirname_builtin (list)
}
char *dirname_doc[] = {
"Display directory portion of pathname.",
"",
"The STRING is converted to the name of the directory containing",
"the filename corresponding to the last pathname component in STRING.",
(char *)NULL
+1
View File
@@ -11,6 +11,7 @@
#include <stdio.h>
#include "builtins.h"
#include "shell.h"
#include "common.h"
dirname_builtin (list)
WORD_LIST *list;
+2
View File
@@ -376,6 +376,8 @@ finfo_builtin(list)
}
static char *finfo_doc[] = {
"Display information about file attributes.",
"",
"Display information about each FILE. Only single operators should",
"be supplied. If no options are supplied, a summary of the info",
"available about each FILE is printed. If FILE is of the form",
+1
View File
@@ -12,6 +12,7 @@
#include <pwd.h>
#include <grp.h>
#include <errno.h>
#include "posixtime.h"
#include "bashansi.h"
#include "shell.h"
+2
View File
@@ -1343,6 +1343,8 @@ getconf_one(list)
}
static char *getconf_doc[] = {
"Display values of system limits and options.",
"",
"getconf writes the current value of a configurable system limit or",
"option variable to the standard output.",
(char *)NULL
File diff suppressed because it is too large Load Diff
+2
View File
@@ -128,6 +128,8 @@ head_builtin (list)
}
char *head_doc[] = {
"Display lines from beginning of file.",
"",
"Copy the first N lines from the input files to the standard output.",
"N is supplied as an argument to the `-n' option. If N is not given,",
"the first ten lines are copied.",
+1
View File
@@ -21,6 +21,7 @@
#include "builtins.h"
#include "shell.h"
#include "bashgetopt.h"
#include "common.h"
#if !defined (errno)
extern int errno;
+4 -1
View File
@@ -41,8 +41,11 @@ hello_builtin (list)
}
/* An array of strings forming the `long' documentation for a builtin xxx,
which is printed by `help xxx'. It must end with a NULL. */
which is printed by `help xxx'. It must end with a NULL. By convention,
the first line is a short description. */
char *hello_doc[] = {
"Sample builtin.",
"",
"this is the long doc for the sample hello builtin",
(char *)NULL
};
+61
View File
@@ -0,0 +1,61 @@
/* Sample builtin to be dynamically loaded with enable -f and create a new
builtin. */
/* See Makefile for compilation details. */
#include <config.h>
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif
#include <stdio.h>
#include "builtins.h"
#include "shell.h"
#include "bashgetopt.h"
/* A builtin `xxx' is normally implemented with an `xxx_builtin' function.
If you're converting a command that uses the normal Unix argc/argv
calling convention, use argv = make_builtin_argv (list, &argc) and call
the original `main' something like `xxx_main'. Look at cat.c for an
example.
Builtins should use internal_getopt to parse options. It is the same as
getopt(3), but it takes a WORD_LIST *. Look at print.c for an example
of its use.
If the builtin takes no options, call no_options(list) before doing
anything else. If it returns a non-zero value, your builtin should
immediately return EX_USAGE. Look at logname.c for an example.
A builtin command returns EXECUTION_SUCCESS for success and
EXECUTION_FAILURE to indicate failure. */
int
hello_builtin (list)
WORD_LIST *list;
{
printf("hello world\n");
fflush (stdout);
return (EXECUTION_SUCCESS);
}
/* An array of strings forming the `long' documentation for a builtin xxx,
which is printed by `help xxx'. It must end with a NULL. */
char *hello_doc[] = {
"this is the long doc for the sample hello builtin",
(char *)NULL
};
/* The standard structure describing a builtin command. bash keeps an array
of these structures. The flags must include BUILTIN_ENABLED so the
builtin can be used. */
struct builtin hello_struct = {
"hello", /* builtin name */
hello_builtin, /* function implementing the builtin */
BUILTIN_ENABLED, /* initial flags for builtin */
hello_doc, /* array of long documentation strings. */
"hello", /* usage synopsis; becomes short_doc */
0 /* reserved for internal use */
};
+3 -1
View File
@@ -294,7 +294,9 @@ id_prall (uname)
}
char *id_doc[] = {
"return information about user identity",
"Display information about user."
"",
"Return information about user identity",
(char *)NULL
};
+308
View File
@@ -0,0 +1,308 @@
/*
* id - POSIX.2 user identity
*
* (INCOMPLETE -- supplementary groups for other users not yet done)
*
* usage: id [-Ggu] [-nr] [user]
*
* The default output format looks something like:
* uid=xxx(chet) gid=xx groups=aa(aname), bb(bname), cc(cname)
*/
#include <config.h>
#include <stdio.h>
#include "bashtypes.h"
#include <pwd.h>
#include <grp.h>
#include "bashansi.h"
#ifdef HAVE_LIMITS_H
# include <limits.h>
#else
# include <sys/param.h>
#endif
#if !defined (HAVE_GETPW_DECLS)
extern struct passwd *getpwuid ();
#endif
extern struct group *getgrgid ();
#include "shell.h"
#include "builtins.h"
#include "stdc.h"
#include "common.h"
#include "bashgetopt.h"
#define ID_ALLGROUPS 0x001 /* -G */
#define ID_GIDONLY 0x002 /* -g */
#define ID_USENAME 0x004 /* -n */
#define ID_USEREAL 0x008 /* -r */
#define ID_USERONLY 0x010 /* -u */
#define ID_FLAGSET(s) ((id_flags & (s)) != 0)
static int id_flags;
static uid_t ruid, euid;
static gid_t rgid, egid;
static char *id_user;
static int inituser ();
static int id_pruser ();
static int id_prgrp ();
static int id_prgroups ();
static int id_prall ();
int
id_builtin (list)
WORD_LIST *list;
{
int opt;
char *user;
id_flags = 0;
reset_internal_getopt ();
while ((opt = internal_getopt (list, "Ggnru")) != -1)
{
switch (opt)
{
case 'G': id_flags |= ID_ALLGROUPS; break;
case 'g': id_flags |= ID_GIDONLY; break;
case 'n': id_flags |= ID_USENAME; break;
case 'r': id_flags |= ID_USEREAL; break;
case 'u': id_flags |= ID_USERONLY; break;
default:
builtin_usage ();
return (EX_USAGE);
}
}
list = loptend;
user = list ? list->word->word : (char *)NULL;
/* Check for some invalid option combinations */
opt = ID_FLAGSET (ID_ALLGROUPS) + ID_FLAGSET (ID_GIDONLY) + ID_FLAGSET (ID_USERONLY);
if (opt > 1 || (opt == 0 && ((id_flags & (ID_USEREAL|ID_USENAME)) != 0)))
{
builtin_usage ();
return (EX_USAGE);
}
if (list && list->next)
{
builtin_usage ();
return (EX_USAGE);
}
if (inituser (user) < 0)
return (EXECUTION_FAILURE);
opt = 0;
if (id_flags & ID_USERONLY)
opt += id_pruser ((id_flags & ID_USEREAL) ? ruid : euid);
else if (id_flags & ID_GIDONLY)
opt += id_prgrp ((id_flags & ID_USEREAL) ? rgid : egid);
else if (id_flags & ID_ALLGROUPS)
opt += id_prgroups (user);
else
opt += id_prall (user);
putchar ('\n');
fflush (stdout);
return (opt == 0 ? EXECUTION_SUCCESS : EXECUTION_FAILURE);
}
static int
inituser (uname)
char *uname;
{
struct passwd *pwd;
if (uname)
{
pwd = getpwnam (uname);
if (pwd == 0)
{
builtin_error ("%s: no such user", uname);
return -1;
}
ruid = euid = pwd->pw_uid;
rgid = egid = pwd->pw_gid;
}
else
{
ruid = current_user.uid;
euid = current_user.euid;
rgid = current_user.gid;
egid = current_user.egid;
}
return 0;
}
/* Print the name or value of user ID UID. */
static int
id_pruser (uid)
int uid;
{
struct passwd *pwd = NULL;
int r;
r = 0;
if (id_flags & ID_USENAME)
{
pwd = getpwuid (uid);
if (pwd == NULL)
r = 1;
}
if (pwd)
printf ("%s", pwd->pw_name);
else
printf ("%u", (unsigned) uid);
return r;
}
/* Print the name or value of group ID GID. */
static int
id_prgrp (gid)
int gid;
{
struct group *grp = NULL;
int r;
r = 0;
if (id_flags & ID_USENAME)
{
grp = getgrgid (gid);
if (grp == NULL)
r = 1;
}
if (grp)
printf ("%s", grp->gr_name);
else
printf ("%u", (unsigned) gid);
return r;
}
static int
id_prgroups (uname)
char *uname;
{
int *glist, ng, i, r;
r = 0;
id_prgrp (rgid);
if (egid != rgid)
{
putchar (' ');
id_prgrp (egid);
}
if (uname)
{
builtin_error ("supplementary groups for other users not yet implemented");
glist = (int *)NULL;
ng = 0;
r = 1;
}
else
glist = get_group_array (&ng);
for (i = 0; i < ng; i++)
if (glist[i] != rgid && glist[i] != egid)
{
putchar (' ');
id_prgrp (glist[i]);
}
return r;
}
static int
id_prall (uname)
char *uname;
{
int r, i, ng, *glist;
struct passwd *pwd;
struct group *grp;
r = 0;
printf ("uid=%u", (unsigned) ruid);
pwd = getpwuid (ruid);
if (pwd == NULL)
r = 1;
else
printf ("(%s)", pwd->pw_name);
printf (" gid=%u", (unsigned) rgid);
grp = getgrgid (rgid);
if (grp == NULL)
r = 1;
else
printf ("(%s)", grp->gr_name);
if (euid != ruid)
{
printf (" euid=%u", (unsigned) euid);
pwd = getpwuid (euid);
if (pwd == NULL)
r = 1;
else
printf ("(%s)", pwd->pw_name);
}
if (egid != rgid)
{
printf (" egid=%u", (unsigned) egid);
grp = getgrgid (egid);
if (grp == NULL)
r = 1;
else
printf ("(%s)", grp->gr_name);
}
if (uname)
{
builtin_error ("supplementary groups for other users not yet implemented");
glist = (int *)NULL;
ng = 0;
r = 1;
}
else
glist = get_group_array (&ng);
if (ng > 0)
printf (" groups=");
for (i = 0; i < ng; i++)
{
if (i > 0)
printf (", ");
printf ("%u", (unsigned) glist[i]);
grp = getgrgid (glist[i]);
if (grp == NULL)
r = 1;
else
printf ("(%s)", grp->gr_name);
}
return r;
}
char *id_doc[] = {
"return information about user identity",
(char *)NULL
};
struct builtin id_struct = {
"id",
id_builtin,
BUILTIN_ENABLED,
id_doc,
"id [user]\n\tid -G [-n] [user]\n\tid -g [-nr] [user]\n\tid -u [-nr] [user]",
0
};
+2
View File
@@ -187,6 +187,8 @@ dolink (src, dst, flags)
}
char *ln_doc[] = {
"Link files.",
"",
"Create a new directory entry with the same modes as the original",
"file. The -f option means to unlink any existing file, permitting",
"the link to occur. The -s option means to create a symbolic link.",
+1
View File
@@ -18,6 +18,7 @@
#include "builtins.h"
#include "shell.h"
#include "bashgetopt.h"
#include "common.h"
#if !defined (errno)
extern int errno;
+3 -1
View File
@@ -36,7 +36,9 @@ logname_builtin (list)
}
char *logname_doc[] = {
"write the current user's login name to the standard output",
"Display user login name.",
"",
"Write the current user's login name to the standard output",
"and exit. logname ignores the LOGNAME and USER variables.",
"logname ignores any non-option arguments.",
(char *)NULL
+1
View File
@@ -11,6 +11,7 @@
#include "builtins.h"
#include "shell.h"
#include "common.h"
#if !defined (errno)
extern int errno;
+2
View File
@@ -192,6 +192,8 @@ make_path (path, nmode, parent_mode)
}
char *mkdir_doc[] = {
"Create directories.",
"",
"Make directories. Create the directories named as arguments, in",
"the order specified, using mode rwxrwxrwx as modified by the current",
"umask (see `help umask'). The -m option causes the file permission",
+1
View File
@@ -16,6 +16,7 @@
#include "builtins.h"
#include "shell.h"
#include "bashgetopt.h"
#include "common.h"
#if !defined (errno)
extern int errno;
+2
View File
@@ -56,6 +56,8 @@ enable_mypid_builtin(WORD_LIST *list)
}
char const *enable_mypid_doc[] = {
"Enable $MYPID.",
"",
"Enables use of the ${MYPID} dynamic variable. ",
"It will yield the current pid of a subshell.",
(char *)0
+71
View File
@@ -0,0 +1,71 @@
/* This module should be dynamically loaded with enable -f
* which would create a new builtin named mypid. You'll need
* the source code for GNU bash to recompile this module.
*
* Then, from within bash, enable -f ./mypid enable_mypid, where ./mypid
* is the binary obtained from running make. Hereafter, `${MYPID}'
* is a shell builtin variable.
*/
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include "builtins.h"
#include "shell.h"
#define INIT_DYNAMIC_VAR(var, val, gfunc, afunc) \
do \
{ SHELL_VAR *v = bind_variable (var, (val), 0); \
v->dynamic_value = gfunc; \
v->assign_func = afunc; \
} \
while (0)
static SHELL_VAR *
assign_mypid (
SHELL_VAR *self,
char *value,
arrayind_t unused )
{
return (self);
}
static SHELL_VAR *
get_mypid (SHELL_VAR *var)
{
int rv;
char *p;
rv = getpid();
p = itos (rv);
FREE (value_cell (var));
VSETATTR (var, att_integer);
var_setvalue (var, p);
return (var);
}
int
enable_mypid_builtin(WORD_LIST *list)
{
INIT_DYNAMIC_VAR ("MYPID", (char *)NULL, get_mypid, assign_mypid);
return 0;
}
char const *enable_mypid_doc[] = {
"Enables use of the ${MYPID} dynamic variable. ",
"It will yield the current pid of a subshell.",
(char *)0
};
struct builtin enable_mypid_struct = {
"enable_mypid",
enable_mypid_builtin,
BUILTIN_ENABLED,
(char**)(void*)enable_mypid_doc,
"enable_mypid N",
0
};
+2
View File
@@ -17,6 +17,8 @@ WORD_LIST *list;
}
char *necho_doc[] = {
"Display arguments.",
"",
"Print the arguments to the standard ouput separated",
"by space characters and terminated with a newline.",
(char *)NULL
+33
View File
@@ -0,0 +1,33 @@
/* necho - echo without options or argument interpretation */
/* Sample builtin to be dynamically loaded with enable -f and replace an
existing builtin. */
#include <stdio.h>
#include "builtins.h"
#include "shell.h"
necho_builtin (list)
WORD_LIST *list;
{
print_word_list (list, " ");
printf("\n");
fflush (stdout);
return (EXECUTION_SUCCESS);
}
char *necho_doc[] = {
"Print the arguments to the standard ouput separated",
"by space characters and terminated with a newline.",
(char *)NULL
};
struct builtin necho_struct = {
"echo",
necho_builtin,
BUILTIN_ENABLED,
necho_doc,
"echo [args]",
0
};
+2
View File
@@ -113,6 +113,8 @@ pathchk_builtin (list)
}
char *pathchk_doc[] = {
"Check pathnames for validity.",
"",
"Check each pathname argument for validity (i.e., it may be used to",
"create or access a file without casuing syntax errors) and portability",
"(i.e., no filename truncation will result). If the `-p' option is",
+1
View File
@@ -45,6 +45,7 @@
#include "stdc.h"
#include "bashgetopt.h"
#include "maxpath.h"
#include "common.h"
#if !defined (errno)
extern int errno;
+2
View File
@@ -32,6 +32,8 @@ static FILE *ofp;
extern char *this_command_name;
static char *print_doc[] = {
"Display arguments.",
"",
"Output the arguments. The -f option means to use the argument as a",
"format string as would be supplied to printf(1). The rest of the",
"options are as in ksh.",
+2
View File
@@ -17,6 +17,8 @@
#include "builtins.h"
#include "stdc.h"
#include "bashgetopt.h"
#include "builtext.h"
#include "common.h"
#if !defined (errno)
extern int errno;
+3 -1
View File
@@ -58,7 +58,9 @@ printenv_builtin (list)
}
char *printenv_doc[] = {
"print values of environment variables",
"Display environment.",
"",
"Print names and values of environment variables",
(char *)NULL
};
+1
View File
@@ -11,6 +11,7 @@
#include "builtins.h"
#include "shell.h"
#include "bashgetopt.h"
#include "common.h"
extern char **export_env;
+2
View File
@@ -79,6 +79,8 @@ push_builtin (list)
}
char *push_doc[] = {
"Create child shell.",
"",
"Create a child that is an exact duplicate of the running shell",
"and wait for it to exit. The $SHLVL, $!, $$, and $PPID variables",
"are adjusted in the child. The return value is the exit status",
+1
View File
@@ -11,6 +11,7 @@
#include "shell.h"
#include "jobs.h"
#include "bashgetopt.h"
#include "common.h"
#ifndef errno
extern int errno;
+2
View File
@@ -102,6 +102,8 @@ WORD_LIST *list;
}
char *realpath_doc[] = {
"Display pathname in canonical form.",
"",
"Display the canonicalized version of each PATHNAME argument, resolving",
"symbolic links. The -c option checks whether or not each resolved name",
"exists. The -s option produces no output; the exit status determines the",
+3 -2
View File
@@ -34,6 +34,7 @@
#include "builtins.h"
#include "shell.h"
#include "bashgetopt.h"
#include "common.h"
#ifndef errno
extern int errno;
@@ -67,14 +68,14 @@ WORD_LIST *list;
vflag = 1;
break;
default:
usage();
builtin_usage();
}
}
list = loptend;
if (list == 0)
usage();
builtin_usage();
for (es = EXECUTION_SUCCESS; list; list = list->next) {
p = list->word->word;
+2
View File
@@ -34,6 +34,8 @@ rmdir_builtin (list)
}
char *rmdir_doc[] = {
"Remove directory.",
"",
"rmdir removes the directory entry specified by each argument,",
"provided the directory is empty.",
(char *)NULL
+1
View File
@@ -8,6 +8,7 @@
#include <errno.h>
#include "builtins.h"
#include "shell.h"
#include "common.h"
#if !defined (errno)
extern int errno;
+2
View File
@@ -133,6 +133,8 @@ WORD_LIST *list;
}
static char *sleep_doc[] = {
"Suspend execution for specified period.",
""
"sleep suspends execution for a minimum of SECONDS[.FRACTION] seconds.",
(char *)NULL
};
+1
View File
@@ -27,6 +27,7 @@
#include "shell.h"
#include "builtins.h"
#include "common.h"
#define RETURN(x) \
do { \
+2
View File
@@ -102,6 +102,8 @@ extern char *single_quote ();
extern char **make_builtin_argv ();
static char *sprintf_doc[] = {
"Format arguments and assign result to variable.",
"",
"sprintf formats and outputs its arguments, after the second, under control",
"of the format and assigns the result to the variable named by its first",
"argument. The format is a character string which contains three types",
+514
View File
@@ -0,0 +1,514 @@
/*
* Copyright (c) 1989, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#if !defined(BUILTIN) && !defined(SHELL)
#ifndef lint
static char copyright[] =
"@(#) Copyright (c) 1989, 1993\n\
The Regents of the University of California. All rights reserved.\n";
#endif /* not lint */
#endif
#ifndef lint
static char sccsid[] = "@(#)printf.c 8.1 (Berkeley) 7/20/93";
#endif /* not lint */
#include <sys/types.h>
#include <errno.h>
#include <limits.h>
#include <stdio.h>
#include "bashansi.h"
#include "shell.h"
#include "builtins.h"
#include "stdc.h"
#if !defined (errno)
extern int errno;
#endif
static char sbuf[1024];
static int sblen;
/* Gee, I wish sprintf could be reliably counted upon to return the
number of characters written :-( */
#define PF(f, func) \
do { \
if (fieldwidth) \
if (precision) \
sprintf(sbuf, f, fieldwidth, precision, func); \
else \
sprintf(sbuf, f, fieldwidth, func); \
else if (precision) \
sprintf(sbuf, f, precision, func); \
else \
sprintf(sbuf, f, func); \
spaddstr (sbuf, strlen (sbuf)); \
} while (0)
static int asciicode __P((void));
static void escape __P((char *));
static int getchr __P((void));
static double getdouble __P((void));
static int getint __P((int *));
static int getlong __P((long *));
static char *getstr __P((void));
static char *mklong __P((char *, int));
static void usage __P((void));
static char **gargv;
static char *outstr;
static int outsize;
static int outind;
int sprintf_builtin ();
static int sprintf_main ();
static void spaddstr ();
extern char *this_command_name;
extern char *single_quote ();
extern char **make_builtin_argv ();
static char *sprintf_doc[] = {
"sprintf formats and outputs its arguments, after the second, under control",
"of the format and assigns the result to the variable named by its first",
"argument. The format is a character string which contains three types",
"of objects: plain characters, which are simply copied to the output string,",
"character escape sequences which are converted and copied to the output",
"string, and format specifications, each of which causes printing of the",
"next successive argument. In addition to the standard sprintf(3) formats,",
"%b means to expand escapes in the corresponding argument, and %q means",
"to quote the argument in a way that can be reused as shell input. Each",
"one of the format specifications must not expand to more than 1024",
"characters, though there is no limit on the total size of the output",
"string.",
(char *)NULL
};
struct builtin sprintf_struct = {
"sprintf",
sprintf_builtin,
BUILTIN_ENABLED,
sprintf_doc,
"sprintf var format [arguments]",
(char *)0
};
int
sprintf_builtin (list)
WORD_LIST *list;
{
int c, r;
char **v, *varname;
WORD_LIST *l;
SHELL_VAR *var;
if (list == 0)
{
builtin_usage ();
return (EXECUTION_FAILURE);
}
varname = list->word->word;
list = list->next;
if (legal_identifier (varname) == 0)
{
builtin_error ("%s: not a legal variable name", varname);
return (EXECUTION_FAILURE);
}
outind = 0;
if (outstr == 0)
outstr = xmalloc (outsize = 64);
outstr[0] = '\0';
v = make_builtin_argv (list, &c);
r = sprintf_main (c, v);
free (v);
var = bind_variable (varname, outstr, 0);
if (readonly_p (var))
{
builtin_error ("%s: readonly variable", varname);
return (EXECUTION_FAILURE);
}
return r;
}
static void
spaddstr(str, len)
char *str;
int len;
{
RESIZE_MALLOCED_BUFFER (outstr, outind, len, outsize, 64);
strcpy (outstr + outind, str);
outind += len;
}
static int
sprintf_main(argc, argv)
int argc;
char *argv[];
{
extern int optind;
static char *skip1, *skip2;
int ch, end, fieldwidth, precision;
char convch, nextch, *format, *fmt, *start;
while ((ch = getopt(argc, argv, "")) != EOF)
switch (ch) {
case '?':
default:
usage();
return (1);
}
argc -= optind;
argv += optind;
if (argc < 1) {
usage();
return (1);
}
/*
* Basic algorithm is to scan the format string for conversion
* specifications -- once one is found, find out if the field
* width or precision is a '*'; if it is, gather up value. Note,
* format strings are reused as necessary to use up the provided
* arguments, arguments of zero/null string are provided to use
* up the format string.
*/
skip1 = "#-+ 0";
skip2 = "*0123456789";
escape(fmt = format = *argv); /* backslash interpretation */
gargv = ++argv;
for (;;) {
end = 0;
/* find next format specification */
next: for (start = fmt;; ++fmt) {
if (!*fmt) {
/* avoid infinite loop */
if (end == 1) {
warnx("missing format character",
NULL, NULL);
return (1);
}
end = 1;
if (fmt > start)
(void)printf("%s", start);
if (!*gargv)
return (0);
fmt = format;
goto next;
}
/* %% prints a % */
if (*fmt == '%') {
if (*++fmt != '%')
break;
*fmt++ = '\0';
(void)printf("%s", start);
goto next;
}
}
/* skip to field width */
for (; strchr(skip1, *fmt); ++fmt);
if (*fmt == '*') {
if (getint(&fieldwidth))
return (1);
} else
fieldwidth = 0;
/* skip to possible '.', get following precision */
for (; strchr(skip2, *fmt); ++fmt);
if (*fmt == '.')
++fmt;
if (*fmt == '*') {
if (getint(&precision))
return (1);
} else
precision = 0;
/* skip to conversion char */
for (; strchr(skip2, *fmt); ++fmt);
if (!*fmt) {
warnx("missing format character", NULL, NULL);
return (1);
}
convch = *fmt;
nextch = *++fmt;
*fmt = '\0';
switch(convch) {
case 'c': {
char p;
p = getchr();
PF(start, p);
break;
}
case 's': {
char *p;
p = getstr();
PF(start, p);
break;
}
case 'b': { /* expand escapes in argument */
char *p;
p = getstr();
escape(p);
PF("%s", p);
break;
}
case 'q': { /* print with shell single quoting */
char *p, *p2;
p = getstr();
p2 = single_quote(p);
PF("%s", p2);
free(p2);
break;
}
case 'd': case 'i': case 'o': case 'u': case 'x': case 'X': {
long p;
char *f;
if ((f = mklong(start, convch)) == NULL)
return (1);
if (getlong(&p))
return (1);
PF(f, p);
break;
}
case 'e': case 'E': case 'f': case 'g': case 'G': {
double p;
p = getdouble();
PF(start, p);
break;
}
default:
warnx("illegal format character", NULL, NULL);
return (1);
}
*fmt = nextch;
}
/* NOTREACHED */
}
static char *
mklong(str, ch)
char *str;
int ch;
{
static char copy[64];
int len;
len = strlen(str) + 2;
memmove(copy, str, len - 3);
copy[len - 3] = 'l';
copy[len - 2] = ch;
copy[len - 1] = '\0';
return (copy);
}
static void
escape(fmt)
register char *fmt;
{
register char *store;
register int value, c;
for (store = fmt; c = *fmt; ++fmt, ++store) {
if (c != '\\') {
*store = c;
continue;
}
switch (*++fmt) {
case '\0': /* EOS, user error */
*store = '\\';
*++store = '\0';
return;
case '\\': /* backslash */
case '\'': /* single quote */
*store = *fmt;
break;
case 'a': /* bell/alert */
*store = '\7';
break;
case 'b': /* backspace */
*store = '\b';
break;
case 'c':
return;
case 'e':
case 'E':
*store = '\033';
break;
case 'f': /* form-feed */
*store = '\f';
break;
case 'n': /* newline */
*store = '\n';
break;
case 'r': /* carriage-return */
*store = '\r';
break;
case 't': /* horizontal tab */
*store = '\t';
break;
case 'v': /* vertical tab */
*store = '\13';
break;
/* octal constant */
case '0': case '1': case '2': case '3':
case '4': case '5': case '6': case '7':
for (c = 3, value = 0;
c-- && *fmt >= '0' && *fmt <= '7'; ++fmt) {
value <<= 3;
value += *fmt - '0';
}
--fmt;
*store = value;
break;
default:
*store = *fmt;
break;
}
}
*store = '\0';
}
static int
getchr()
{
if (!*gargv)
return ('\0');
return ((int)**gargv++);
}
static char *
getstr()
{
if (!*gargv)
return ("");
return (*gargv++);
}
static char *Number = "+-.0123456789";
static int
getint(ip)
int *ip;
{
long val;
if (getlong(&val))
return (1);
if (val > INT_MAX) {
warnx("%s: %s", *gargv, strerror(ERANGE));
return (1);
}
*ip = val;
return (0);
}
static int
getlong(lp)
long *lp;
{
long val;
char *ep;
if (!*gargv) {
*lp = 0;
return (0);
}
if (strchr(Number, **gargv)) {
errno = 0;
val = strtol(*gargv, &ep, 0);
if (*ep != '\0') {
warnx("%s: illegal number", *gargv, NULL);
return (1);
}
if (errno == ERANGE)
if (val == LONG_MAX) {
warnx("%s: %s", *gargv, strerror(ERANGE));
return (1);
}
if (val == LONG_MIN) {
warnx("%s: %s", *gargv, strerror(ERANGE));
return (1);
}
*lp = val;
++gargv;
return (0);
}
*lp = (long)asciicode();
return (0);
}
static double
getdouble()
{
if (!*gargv)
return ((double)0);
if (strchr(Number, **gargv))
return (atof(*gargv++));
return ((double)asciicode());
}
static int
asciicode()
{
register int ch;
ch = **gargv;
if (ch == '\'' || ch == '"')
ch = (*gargv)[1];
++gargv;
return (ch);
}
static void
usage()
{
(void)fprintf(stderr, "usage: printf format [arg ...]\n");
}
+2
View File
@@ -85,6 +85,8 @@ strftime_builtin (list)
/* An array of strings forming the `long' documentation for a builtin xxx,
which is printed by `help xxx'. It must end with a NULL. */
char *strftime_doc[] = {
"Display formatted time.",
"",
"Converts date and time format to a string and displays it on the",
"standard output. If the optional second argument is supplied, it",
"is used as the number of seconds since the epoch to use in the",
+105
View File
@@ -0,0 +1,105 @@
/* strftime - loadable builtin interface to strftime(3) */
/* See Makefile for compilation details. */
#include <config.h>
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif
#include "bashtypes.h"
#include "posixtime.h"
#include <stdio.h>
#include "builtins.h"
#include "shell.h"
#include "common.h"
int
strftime_builtin (list)
WORD_LIST *list;
{
char *format, *tbuf;
size_t tbsize, tsize;
time_t secs;
struct tm *t;
int n;
intmax_t i;
if (list == 0)
{
builtin_usage ();
return (EX_USAGE);
}
if (no_options (list))
return (EX_USAGE);
format = list->word->word;
if (format == 0 || *format == 0)
{
printf ("\n");
return (EXECUTION_SUCCESS);
}
list = list->next;
if (list && list->word->word)
{
n = legal_number (list->word->word, &i);
if (n == 0 || i < 0 || i != (time_t)i)
{
sh_invalidnum (list->word->word);
return (EXECUTION_FAILURE);
}
else
secs = i;
}
else
secs = NOW;
t = localtime (&secs);
tbsize = strlen (format) * 4;
tbuf = 0;
/* Now try to figure out how big the buffer should really be. strftime(3)
will return the number of bytes placed in the buffer unless it's greater
than MAXSIZE, in which case it returns 0. */
for (n = 1; n < 4; n++)
{
tbuf = xrealloc (tbuf, tbsize * n);
tsize = strftime (tbuf, tbsize * n, format, t);
if (tsize)
break;
}
printf ("%s\n", tbuf);
free (tbuf);
return (EXECUTION_SUCCESS);
}
/* An array of strings forming the `long' documentation for a builtin xxx,
which is printed by `help xxx'. It must end with a NULL. */
char *strftime_doc[] = {
"Converts date and time format to a string and displays it on the",
"standard output. If the optional second argument is supplied, it",
"is used as the number of seconds since the epoch to use in the",
"conversion, otherwise the current time is used.",
(char *)NULL
};
/* The standard structure describing a builtin command. bash keeps an array
of these structures. The flags must include BUILTIN_ENABLED so the
builtin can be used. */
struct builtin strftime_struct = {
"strftime", /* builtin name */
strftime_builtin, /* function implementing the builtin */
BUILTIN_ENABLED, /* initial flags for builtin */
strftime_doc, /* array of long documentation strings. */
"strftime format [seconds]", /* usage synopsis; becomes short_doc */
0 /* reserved for internal use */
};
+3 -1
View File
@@ -18,7 +18,9 @@ sync_builtin (list)
}
char *sync_doc[] = {
"force completion of pending disk writes",
"Sync disks.",
""
"Force completion of pending disk writes",
(char *)NULL
};
+32
View File
@@ -0,0 +1,32 @@
/* sync - sync the disks by forcing pending filesystem writes to complete */
#include <config.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include "builtins.h"
#include "shell.h"
#include "bashgetopt.h"
sync_builtin (list)
WORD_LIST *list;
{
sync();
return (EXECUTION_SUCCESS);
}
char *sync_doc[] = {
"force completion of pending disk writes",
(char *)NULL
};
struct builtin sync_struct = {
"sync", /* builtin name */
sync_builtin, /* function implementing the builtin */
BUILTIN_ENABLED, /* initial flags for builtin */
sync_doc, /* array of long documentation strings. */
"sync", /* usage synopsis; becomes short_doc */
0 /* reserved for internal use */
};
+2
View File
@@ -141,6 +141,8 @@ tee_builtin (list)
}
char *tee_doc[] = {
"Duplicate standard output.",
"",
"Copy standard input to standard output, making a copy in each",
"filename argument. If the `-a' option is gived, the specified",
"files are appended to, otherwise they are overwritten. If the",
+1
View File
@@ -22,6 +22,7 @@
#include "builtins.h"
#include "shell.h"
#include "bashgetopt.h"
#include "common.h"
#if !defined (errno)
extern int errno;
+3
View File
@@ -43,6 +43,9 @@ template_builtin (list)
}
char *template_doc[] = {
"Short description.",
""
"Longer description of builtin and usage.",
(char *)NULL
};
+56
View File
@@ -0,0 +1,56 @@
/* template - example template for loadable builtin */
/* See Makefile for compilation details. */
#include <config.h>
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif
#include "bashansi.h"
#include <stdio.h>
#include <errno.h>
#include "builtins.h"
#include "shell.h"
#include "bashgetopt.h"
#if !defined (errno)
extern int errno;
#endif
extern char *strerror ();
template_builtin (list)
WORD_LIST *list;
{
int opt, rval;
rval = EXECUTION_SUCCESS;
reset_internal_getopt ();
while ((opt = internal_getopt (list, "")) != -1)
{
switch (opt)
{
default:
builtin_usage ();
return (EX_USAGE);
}
}
list = loptend;
return (rval);
}
char *template_doc[] = {
(char *)NULL
};
struct builtin template_struct = {
"template", /* builtin name */
template_builtin, /* function implementing the builtin */
BUILTIN_ENABLED, /* initial flags for builtin */
template_doc, /* array of long documentation strings. */
"template", /* usage synopsis; becomes short_doc */
0 /* reserved for internal use */
};
+4
View File
@@ -19,11 +19,15 @@ false_builtin (list)
}
static char *true_doc[] = {
"Exit successfully.",
"",
"Return a successful result.",
(char *)NULL
};
static char *false_doc[] = {
"Exit unsuccessfully.",
"",
"Return an unsuccessful result.",
(char *)NULL
};
+1
View File
@@ -4,6 +4,7 @@
#include "bashtypes.h"
#include "shell.h"
#include "builtins.h"
#include "common.h"
true_builtin (list)
WORD_LIST *list;
+2
View File
@@ -41,6 +41,8 @@ tty_builtin (list)
}
char *tty_doc[] = {
"Display terminal name.",
"",
"tty writes the name of the terminal that is opened for standard",
"input to standard output. If the `-s' option is supplied, nothing",
"is written; the exit status determines whether or not the standard",
+1
View File
@@ -8,6 +8,7 @@
#include "builtins.h"
#include "shell.h"
#include "bashgetopt.h"
#include "common.h"
extern char *ttyname ();
+3 -1
View File
@@ -126,7 +126,9 @@ uprint (flag, info)
}
char *uname_doc[] = {
"display information about the system",
"Display system information.",
"",
"Display information about the system hardware and OS.",
(char *)NULL
};
+1
View File
@@ -27,6 +27,7 @@ struct utsname {
#include "builtins.h"
#include "shell.h"
#include "bashgetopt.h"
#include "common.h"
#define FLAG_SYSNAME 0x01 /* -s */
#define FLAG_NODENAME 0x02 /* -n */
+2
View File
@@ -40,6 +40,8 @@ unlink_builtin (list)
char *unlink_doc[] = {
"Remove a directory entry.",
"",
"Forcibly remove a directory entry, even if it's a directory.",
(char *)NULL
};
+1
View File
@@ -14,6 +14,7 @@
#include "builtins.h"
#include "shell.h"
#include "common.h"
#ifndef errno
extern int errno;
+3 -1
View File
@@ -39,7 +39,9 @@ whoami_builtin (list)
}
char *whoami_doc[] = {
"display name of current user",
"Print user name",
"",
"Display name of current user.",
(char *)NULL
};
+1
View File
@@ -8,6 +8,7 @@
#include "builtins.h"
#include "shell.h"
#include "bashgetopt.h"
#include "common.h"
whoami_builtin (list)
WORD_LIST *list;
+2
View File
@@ -164,6 +164,8 @@ int main(int argc, char *argv[])
#ifdef BASH_BUILTIN
static char *xtitle_doc[] = {
"Set xterm window title.",
"",
"Either set or read the title of the current xterm window. With the",
"-q option, writes the current xterm title to standard output. Without",
"the -q option, sets the xterm title to be the arguments given,",
+183
View File
@@ -0,0 +1,183 @@
/*
* Originally from
* http://www.excessus.demon.co.uk/misc-hacks/index.html#xtitle
*/
/*
* Made into a loadable builtin by chet@po.cwru.edu.
*/
#if defined (HAVE_CONFIG_H)
# include <config.h>
#endif
#include <stdio.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <termios.h>
#ifdef BASH_BUILTIN
#include "shell.h"
#include "builtins.h"
#include "bashgetopt.h"
#endif
#ifdef BASH_BUILTIN
int xtitle_builtin(WORD_LIST *list)
#else
int main(int argc, char *argv[])
#endif
{
int query = 0;
int fd;
int openned = 0;
#ifdef BASH_BUILTIN
reset_internal_getopt();
#endif
for (;;) {
#ifdef BASH_BUILTIN
int i;
i = internal_getopt(list, "q");
#else
int i = getopt(argc, argv, "q");
#endif
if (i < 0)
break;
switch (i) {
case 'q':
query = 1;
break;
default:
#ifdef BASH_BUILTIN
builtin_usage();
#else
fprintf(stderr, "usage: xtitle [-q] [string]\n");
#endif
return (1);
}
}
#ifdef BASH_BUILTIN
if (!query && loptend == 0) {
#else
if (!query && optind == argc) {
#endif
fprintf(stderr, "xtitle: no string to set\n");
return (1);
}
{
char *t = getenv("TERM");
if (!t || strncmp(t, "xterm", 5))
return (0);
}
if (isatty(0))
fd = 0;
else {
fd = open("/dev/tty", O_RDWR);
if (fd < 0) {
fprintf(stderr, "xtitle: couldn't open terminal: %s", strerror(errno));
return (1);
}
openned = 1;
}
if (!query) {
#ifdef BASH_BUILTIN
WORD_LIST *l = loptend;
char sp = ' ';
write(fd, "\33]0;", 4);
while (l) {
write(fd, l->word->word, strlen(l->word->word));
if (l->next)
write(fd, &sp, 1);
l = l->next;
}
write(fd, "\33\\", 2);
#else
int i;
char sp = ' ';
write(fd, "\33]0;", 4);
for (i = optind; i < argc; i++) {
write(fd, argv[i], strlen(argv[i]));
if (i < argc - 1)
write(fd, &sp, 1);
}
write(fd, "\33\\", 2);
#endif
} else {
struct termios o, n;
char hack;
int state = 0;
tcgetattr(fd, &o);
n = o;
n.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
|INLCR|IGNCR|ICRNL|IXON);
n.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
n.c_cflag &= ~(CSIZE|PARENB);
n.c_cflag |= CS8;
tcsetattr(fd, TCSAFLUSH, &n);
write(fd, "\33[21t", 5);
while (state != -1) {
if (read(fd, &hack, 1) < 1)
break;
switch (state) {
case 0:
if (hack == '\33') state = 1;
break;
case 1:
if (hack == ']') state = 2; else state = 0;
break;
case 2:
if (hack == 'l') state = 3; else state = 0;
break;
case 3:
if (hack == '\33') state = 4; else putchar(hack);
break;
case 4:
if (hack == '\\') { state = -1; putchar('\n'); }
else { putchar('\33'); putchar(hack); state = 3; }
break;
}
}
tcsetattr(fd, TCSAFLUSH, &o);
}
if (openned)
close(fd);
return (0);
}
#ifdef BASH_BUILTIN
static char *xtitle_doc[] = {
"Either set or read the title of the current xterm window. With the",
"-q option, writes the current xterm title to standard output. Without",
"the -q option, sets the xterm title to be the arguments given,",
"separated by space characters. [By Mark Wooding, mdw@nsict.org]",
0
};
struct builtin xtitle_struct = {
"xtitle",
xtitle_builtin,
BUILTIN_ENABLED,
xtitle_doc,
"xtitle [-q] [arguments]",
0
};
#endif