Imported from ../bash-2.03.tar.gz.
This commit is contained in:
parent
bc4cd23ce9
commit
b72432fdcc
191 changed files with 10113 additions and 3553 deletions
|
|
@ -1,10 +1,11 @@
|
|||
# This Makefile for building libbuiltins.a is in -*- text -*- for Emacs.
|
||||
#
|
||||
SHELL = /bin/sh
|
||||
SHELL = @MAKE_SHELL@
|
||||
RANLIB = @RANLIB@
|
||||
CC = @CC@
|
||||
CC_FOR_BUILD = @CC_FOR_BUILD@
|
||||
AR = @AR@
|
||||
ARFLAGS = @ARFLAGS@
|
||||
RM = rm -f
|
||||
CP = cp
|
||||
|
||||
|
|
@ -24,7 +25,7 @@ LDFLAGS = @LDFLAGS@ $(LOCAL_LDFLAGS) $(CFLAGS)
|
|||
LOCAL_LDFLAGS = @LOCAL_LDFLAGS@
|
||||
LIBS = @LIBS@
|
||||
|
||||
INCLUDES = -I. -I.. -I$(topdir) -I$(topdir)/lib -I$(srcdir)
|
||||
INCLUDES = -I. -I.. @RL_INCLUDE@ -I$(topdir) -I$(topdir)/lib -I$(srcdir)
|
||||
|
||||
CCFLAGS = ${PROFILE_FLAGS} $(DEFS) $(LOCAL_DEFS) $(SYSTEM_FLAGS) $(CPPFLAGS) \
|
||||
${INCLUDES} $(LOCAL_CFLAGS) $(CFLAGS)
|
||||
|
|
@ -87,7 +88,7 @@ all: $(MKBUILTINS) libbuiltins.a
|
|||
|
||||
libbuiltins.a: $(MKBUILTINS) $(OFILES) builtins.o
|
||||
$(RM) $@
|
||||
$(AR) cr $@ $(OFILES)
|
||||
$(AR) $(ARFLAGS) $@ $(OFILES)
|
||||
-$(RANLIB) $@
|
||||
|
||||
builtext.h builtins.c: $(MKBUILTINS) $(DEFSRC)
|
||||
|
|
@ -95,12 +96,12 @@ builtext.h builtins.c: $(MKBUILTINS) $(DEFSRC)
|
|||
@-if test -f builtext.h; then mv -f builtext.h old-builtext.h; fi
|
||||
./$(MKBUILTINS) -externfile builtext.h -structfile builtins.c \
|
||||
-noproduction $(DIRECTDEFINE) $(DEFSRC)
|
||||
@-if cmp -s old-builtext.h builtext.h; then \
|
||||
@-if cmp -s old-builtext.h builtext.h 2>/dev/null; then \
|
||||
mv old-builtext.h builtext.h; \
|
||||
else \
|
||||
$(RM) old-builtext.h; \
|
||||
fi
|
||||
@-if cmp -s old-builtins.c builtins.c; then \
|
||||
@-if cmp -s old-builtins.c builtins.c 2>/dev/null; then \
|
||||
mv old-builtins.c builtins.c; \
|
||||
else \
|
||||
$(RM) old-builtins.c; \
|
||||
|
|
@ -112,7 +113,7 @@ mkbuiltins.o: mkbuiltins.c
|
|||
$(CC_FOR_BUILD) -c $(CCFLAGS) $<
|
||||
|
||||
mkbuiltins: mkbuiltins.o
|
||||
$(CC_FOR_BUILD) $(LDFLAGS) -o $(MKBUILTINS) mkbuiltins.o $(LIBS)
|
||||
$(CC_FOR_BUILD) $(PROFILE_FLAGS) $(LDFLAGS) -o $(MKBUILTINS) mkbuiltins.o $(LIBS)
|
||||
|
||||
# rules for deficient makes, like SunOS
|
||||
mkbuiltins.o: mkbuiltins.c
|
||||
|
|
@ -126,7 +127,7 @@ evalfile.o: evalfile.c
|
|||
ulimit.o: pipesize.h
|
||||
|
||||
pipesize.h: psize.aux
|
||||
$(SHELL) $(srcdir)/psize.sh > pipesize.h
|
||||
$(SHELL) $(srcdir)/psize.sh > $@
|
||||
|
||||
psize.aux: psize.c
|
||||
$(CC_FOR_BUILD) $(CCFLAGS) -o $@ $(srcdir)/psize.c
|
||||
|
|
@ -139,7 +140,7 @@ builtins.texi: $(MKBUILTINS)
|
|||
./$(MKBUILTINS) -documentonly $(DEFSRC)
|
||||
|
||||
clean:
|
||||
$(RM) $(OFILES) $(CREATED_FILES) $(MKBUILTINS) libbuiltins.a
|
||||
$(RM) $(OFILES) $(CREATED_FILES) $(MKBUILTINS) mkbuiltins.o libbuiltins.a
|
||||
|
||||
mostlyclean:
|
||||
$(RM) $(OFILES) libbuiltins.a
|
||||
|
|
|
|||
|
|
@ -140,22 +140,20 @@ bindpwd (no_symlinks)
|
|||
else
|
||||
dirname = get_working_directory ("cd");
|
||||
|
||||
bind_variable ("OLDPWD", get_string_value ("PWD"));
|
||||
|
||||
old_anm = array_needs_making;
|
||||
tvar = bind_variable ("PWD", dirname);
|
||||
/* This is an efficiency hack. If PWD is exported, we will need to
|
||||
remake the exported environment every time we change directories.
|
||||
If there is no other reason to make the exported environment, just
|
||||
update PWD in place and mark the exported environment as no longer
|
||||
needing a remake. */
|
||||
pwdvar = get_string_value ("PWD");
|
||||
|
||||
tvar = bind_variable ("OLDPWD", pwdvar);
|
||||
if (old_anm == 0 && array_needs_making && exported_p (tvar))
|
||||
{
|
||||
pwdvar = xmalloc (STRLEN (dirname) + 5); /* 5 = "PWD" + '=' + '\0' */
|
||||
strcpy (pwdvar, "PWD=");
|
||||
if (dirname)
|
||||
strcpy (pwdvar + 4, dirname);
|
||||
add_or_supercede_exported_var (pwdvar, 0);
|
||||
update_export_env_inplace ("OLDPWD=", 7, pwdvar);
|
||||
array_needs_making = 0;
|
||||
}
|
||||
|
||||
tvar = bind_variable ("PWD", dirname);
|
||||
if (old_anm == 0 && array_needs_making && exported_p (tvar))
|
||||
{
|
||||
update_export_env_inplace ("PWD=", 4, dirname);
|
||||
array_needs_making = 0;
|
||||
}
|
||||
|
||||
|
|
@ -243,7 +241,7 @@ cd_builtin (list)
|
|||
{
|
||||
/* Find directory in $CDPATH. */
|
||||
path_index = 0;
|
||||
while ((path = extract_colon_unit (cdpath, &path_index)))
|
||||
while (path = extract_colon_unit (cdpath, &path_index))
|
||||
{
|
||||
/* OPT is 1 if the path element is non-empty */
|
||||
opt = path[0] != '\0';
|
||||
|
|
|
|||
|
|
@ -26,17 +26,17 @@ $FUNCTION enable_builtin
|
|||
$SHORT_DOC enable [-pnds] [-a] [-f filename] [name ...]
|
||||
Enable and disable builtin shell commands. This allows
|
||||
you to use a disk command which has the same name as a shell
|
||||
builtin. If -n is used, the NAMEs become disabled; otherwise
|
||||
NAMEs are enabled. For example, to use the `test' found on your
|
||||
path instead of the shell builtin version, type `enable -n test'.
|
||||
On systems supporting dynamic loading, the -f option may be used
|
||||
to load new builtins from the shared object FILENAME. The -d
|
||||
option will delete a builtin previously loaded with -f. If no
|
||||
non-option names are given, or the -p option is supplied, a list
|
||||
of builtins is printed. The -a option means to print every builtin
|
||||
with an indication of whether or not it is enabled. The -s option
|
||||
restricts the output to the Posix.2 `special' builtins. The -n
|
||||
option displays a list of all disabled builtins.
|
||||
builtin without specifying a full pathname. If -n is used, the
|
||||
NAMEs become disabled; otherwise NAMEs are enabled. For example,
|
||||
to use the `test' found in $PATH instead of the shell builtin
|
||||
version, type `enable -n test'. On systems supporting dynamic
|
||||
loading, the -f option may be used to load new builtins from the
|
||||
shared object FILENAME. The -d option will delete a builtin
|
||||
previously loaded with -f. If no non-option names are given, or
|
||||
the -p option is supplied, a list of builtins is printed. The
|
||||
-a option means to print every builtin with an indication of whether
|
||||
or not it is enabled. The -s option restricts the output to the POSIX.2
|
||||
`special' builtins. The -n option displays a list of all disabled builtins.
|
||||
$END
|
||||
|
||||
#include <config.h>
|
||||
|
|
@ -391,6 +391,20 @@ delete_builtin (b)
|
|||
shell_builtins = new_shell_builtins;
|
||||
}
|
||||
|
||||
/* Tenon's MachTen has a dlclose that doesn't return a value, so we
|
||||
finesse it with a local wrapper. */
|
||||
static int
|
||||
local_dlclose (handle)
|
||||
void *handle;
|
||||
{
|
||||
#if !defined (__MACHTEN__)
|
||||
return (dlclose (handle));
|
||||
#else /* __MACHTEN__ */
|
||||
dlclose (handle);
|
||||
return ((dlerror () != NULL) ? -1 : 0);
|
||||
#endif /* __MACHTEN__ */
|
||||
}
|
||||
|
||||
static int
|
||||
dyn_unload_builtin (name)
|
||||
char *name;
|
||||
|
|
@ -398,6 +412,7 @@ dyn_unload_builtin (name)
|
|||
struct builtin *b;
|
||||
void *handle;
|
||||
int ref, i;
|
||||
char *uerror;
|
||||
|
||||
b = builtin_address_internal (name, 1);
|
||||
if (b == 0)
|
||||
|
|
@ -420,7 +435,7 @@ dyn_unload_builtin (name)
|
|||
|
||||
/* Don't remove the shared object unless the reference count of builtins
|
||||
using it drops to zero. */
|
||||
if (ref == 1 && dlclose (handle) != 0)
|
||||
if (ref == 1 && local_dlclose (handle) != 0)
|
||||
{
|
||||
builtin_error ("cannot delete %s: %s", name, dlerror ());
|
||||
return (EXECUTION_FAILURE);
|
||||
|
|
|
|||
|
|
@ -51,6 +51,8 @@
|
|||
extern int errno;
|
||||
#endif
|
||||
|
||||
#define IS_BUILTIN(s) (builtin_address_internal(s, 0) != (struct builtin *)NULL)
|
||||
|
||||
extern void run_trap_cleanup ();
|
||||
|
||||
extern int interactive, interactive_shell;
|
||||
|
|
@ -181,7 +183,7 @@ parse_and_execute (string, from_file, flags)
|
|||
}
|
||||
|
||||
default:
|
||||
programming_error ("parse_and_execute: bad jump: code %d", code);
|
||||
command_error ("parse_and_execute", CMDERR_BADJUMP, code, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -206,9 +208,20 @@ parse_and_execute (string, from_file, flags)
|
|||
global_command = (COMMAND *)NULL;
|
||||
|
||||
#if defined (ONESHOT)
|
||||
if (startup_state == 2 && *bash_input.location.string == '\0' &&
|
||||
command->type == cm_simple && !command->redirects &&
|
||||
!command->value.Simple->redirects &&
|
||||
/*
|
||||
* IF
|
||||
* we were invoked as `bash -c' (startup_state == 2) AND
|
||||
* parse_and_execute has not been called recursively AND
|
||||
* we have parsed the full command (string == '\0') AND
|
||||
* we have a simple command without redirections AND
|
||||
* the command is not being timed
|
||||
* THEN
|
||||
* tell the execution code that we don't need to fork
|
||||
*/
|
||||
if (startup_state == 2 && parse_and_execute_level == 1 &&
|
||||
*bash_input.location.string == '\0' &&
|
||||
command->type == cm_simple &&
|
||||
!command->redirects && !command->value.Simple->redirects &&
|
||||
((command->flags & CMD_TIME_PIPELINE) == 0))
|
||||
{
|
||||
command->flags |= CMD_NO_FORK;
|
||||
|
|
|
|||
|
|
@ -26,13 +26,13 @@ $FUNCTION fc_builtin
|
|||
$DEPENDS_ON HISTORY
|
||||
$SHORT_DOC fc [-e ename] [-nlr] [first] [last] or fc -s [pat=rep] [cmd]
|
||||
|
||||
fc is used to list or edit and re-execute commands from the history list.
|
||||
FIRST and LAST can be numbers specifying the range, or FIRST can be a
|
||||
string, which means the most recent command beginning with that
|
||||
string.
|
||||
|
||||
-e ENAME selects which editor to use. Default is FCEDIT, then EDITOR,
|
||||
then the editor which corresponds to the current readline editing
|
||||
mode, then vi.
|
||||
then vi.
|
||||
|
||||
-l means list lines instead of editing.
|
||||
-n means no line numbers listed.
|
||||
|
|
@ -156,7 +156,7 @@ fc_builtin (list)
|
|||
register int i;
|
||||
register char *sep;
|
||||
int numbering, reverse, listing, execute;
|
||||
int histbeg, histend, last_hist, retval, first, opt;
|
||||
int histbeg, histend, last_hist, retval, opt;
|
||||
FILE *stream;
|
||||
REPL *rlist, *rl;
|
||||
char *ename, *command, *newcom, *line;
|
||||
|
|
@ -372,64 +372,11 @@ fc_builtin (list)
|
|||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
|
||||
/* Now reopen the file and execute the edited commands. */
|
||||
|
||||
stream = fopen (fn, "r");
|
||||
|
||||
if (stream == NULL)
|
||||
{
|
||||
builtin_error ("cannot reopen temp file %s", fn);
|
||||
unlink (fn);
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
|
||||
retval = EXECUTION_SUCCESS;
|
||||
first = 1;
|
||||
|
||||
#if 1
|
||||
/* Make sure parse_and_execute doesn't turn this off, even though a
|
||||
call to parse_and_execute farther up the function call stack (e.g.,
|
||||
if this is called by vi_edit_and_execute_command) may have already
|
||||
called bash_history_disable. */
|
||||
remember_on_history = 1;
|
||||
#else
|
||||
/* First, write the commands to the history file. This will not happen
|
||||
when we call parse_and_execute, since parse_and_execute disables
|
||||
the command line history while it executes. */
|
||||
|
||||
opt = current_command_line_count;
|
||||
while ((line = fc_readline (stream)) != NULL)
|
||||
{
|
||||
if (line[0] == '\n')
|
||||
{
|
||||
free (line);
|
||||
continue; /* Skip blank lines. */
|
||||
}
|
||||
|
||||
if (first)
|
||||
{
|
||||
first = 0;
|
||||
/* If we retrieved only one command from the history file, but we
|
||||
read multiple lines from the edited file, and literal_history
|
||||
has been set by `shopt', we assume that it was a compound
|
||||
command stored with embedded newlines. In this case, we want
|
||||
the history code to store it as one command again. */
|
||||
if (literal_history && histbeg == histend)
|
||||
current_command_line_count = 1;
|
||||
fc_replhist (line);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (literal_history && histbeg == histend)
|
||||
current_command_line_count++;
|
||||
fc_addhist (line);
|
||||
}
|
||||
|
||||
free (line);
|
||||
}
|
||||
fclose (stream);
|
||||
current_command_line_count = opt;
|
||||
#endif
|
||||
|
||||
/* Turn on the `v' flag while fc_execute_file runs so the commands
|
||||
will be echoed as they are read by the parser. */
|
||||
|
|
|
|||
|
|
@ -232,6 +232,19 @@ sh_getopt_restore_state (argv)
|
|||
nextchar = argv[sh_curopt] + sh_charindex;
|
||||
}
|
||||
|
||||
#if 0
|
||||
void
|
||||
sh_getopt_debug_restore_state (argv)
|
||||
char **argv;
|
||||
{
|
||||
if (nextchar && nextchar != argv[sh_curopt] + sh_charindex)
|
||||
{
|
||||
itrace("sh_getopt_debug_restore_state: resetting nextchar");
|
||||
nextchar = argv[sh_curopt] + sh_charindex;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef TEST
|
||||
|
||||
/* Compile with -DTEST to make an executable for use in testing
|
||||
|
|
|
|||
|
|
@ -181,6 +181,8 @@ dogetopts (argc, argv)
|
|||
{
|
||||
for (i = 0; i < 10 && dollar_vars[i]; i++)
|
||||
;
|
||||
|
||||
sh_getopt_restore_state (dollar_vars);
|
||||
ret = sh_getopt (i, dollar_vars, optstr);
|
||||
}
|
||||
else
|
||||
|
|
@ -198,6 +200,7 @@ dogetopts (argc, argv)
|
|||
for (words = rest_of_args; words; words = words->next, i++)
|
||||
v[i] = words->word->word;
|
||||
v[i] = (char *)NULL;
|
||||
sh_getopt_restore_state (v);
|
||||
ret = sh_getopt (i, v, optstr);
|
||||
free (v);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -130,6 +130,10 @@ char *assignment_builtins[] =
|
|||
static int is_special_builtin ();
|
||||
static int is_assignment_builtin ();
|
||||
|
||||
#if !defined (HAVE_RENAME)
|
||||
static int rename ();
|
||||
#endif
|
||||
|
||||
void extract_info ();
|
||||
|
||||
void file_error ();
|
||||
|
|
@ -265,8 +269,7 @@ main (argc, argv)
|
|||
{
|
||||
write_longdocs (structfile, saved_builtins);
|
||||
fclose (structfile);
|
||||
link (temp_struct_filename, struct_filename);
|
||||
unlink (temp_struct_filename);
|
||||
rename (temp_struct_filename, struct_filename);
|
||||
}
|
||||
|
||||
if (externfile)
|
||||
|
|
@ -457,6 +460,10 @@ extract_info (filename, structfile, externfile)
|
|||
if ((nr = read (fd, buffer, file_size)) < 0)
|
||||
file_error (filename);
|
||||
|
||||
/* This is needed on WIN32, and does not hurt on Unix. */
|
||||
if (nr < file_size)
|
||||
file_size = nr;
|
||||
|
||||
close (fd);
|
||||
|
||||
if (nr == 0)
|
||||
|
|
@ -1395,3 +1402,16 @@ is_assignment_builtin (name)
|
|||
{
|
||||
return (_find_in_table (name, assignment_builtins));
|
||||
}
|
||||
|
||||
#if !defined (HAVE_RENAME)
|
||||
static int
|
||||
rename (from, to)
|
||||
char *from, *to;
|
||||
{
|
||||
unlink (to);
|
||||
if (link (from, to) < 0)
|
||||
return (-1);
|
||||
unlink (from);
|
||||
return (0);
|
||||
}
|
||||
#endif /* !HAVE_RENAME */
|
||||
|
|
|
|||
|
|
@ -99,7 +99,7 @@ int
|
|||
printf_builtin (list)
|
||||
WORD_LIST *list;
|
||||
{
|
||||
int ch, end, fieldwidth, precision, foundmod;
|
||||
int ch, end, fieldwidth, precision, foundmod, fmtlen;
|
||||
char convch, nextch, *format, *fmt, *start;
|
||||
|
||||
retval = EXECUTION_SUCCESS;
|
||||
|
|
@ -125,12 +125,12 @@ printf_builtin (list)
|
|||
if (list->word->word == 0 || list->word->word[0] == '\0')
|
||||
return (EXECUTION_SUCCESS);
|
||||
|
||||
format = ansicstr (list->word->word, strlen (list->word->word), (int *)NULL, (int *)NULL);
|
||||
format = ansicstr (list->word->word, strlen (list->word->word), (int *)NULL, &fmtlen);
|
||||
|
||||
garglist = list->next;
|
||||
|
||||
/* If the format string is empty after preprocessing, return immediately. */
|
||||
if (format == 0 || *format == 0)
|
||||
if ((format == 0 || *format == 0) && fmtlen == 0)
|
||||
return (EXECUTION_SUCCESS);
|
||||
|
||||
/* Basic algorithm is to scan the format string for conversion
|
||||
|
|
@ -139,11 +139,12 @@ printf_builtin (list)
|
|||
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. */
|
||||
#define FMTIND (fmt - format)
|
||||
|
||||
do
|
||||
{
|
||||
/* find next format specification */
|
||||
for (fmt = format; *fmt; fmt++)
|
||||
for (fmt = format; FMTIND < fmtlen; fmt++)
|
||||
{
|
||||
precision = fieldwidth = foundmod = 0;
|
||||
|
||||
|
|
@ -179,11 +180,6 @@ printf_builtin (list)
|
|||
/* skip to conversion char */
|
||||
for (; *fmt && strchr(SKIP2, *fmt); ++fmt)
|
||||
;
|
||||
if (*fmt == 0)
|
||||
{
|
||||
builtin_error ("`%s': missing format character", start);
|
||||
PRETURN (EXECUTION_FAILURE);
|
||||
}
|
||||
|
||||
/* skip possible format modifiers */
|
||||
if (*fmt == 'l' || *fmt == 'L' || *fmt == 'h')
|
||||
|
|
@ -192,6 +188,12 @@ printf_builtin (list)
|
|||
foundmod = 1;
|
||||
}
|
||||
|
||||
if (*fmt == 0)
|
||||
{
|
||||
builtin_error ("`%s': missing format character", start);
|
||||
PRETURN (EXECUTION_FAILURE);
|
||||
}
|
||||
|
||||
convch = *fmt;
|
||||
nextch = fmt[1];
|
||||
fmt[1] = '\0';
|
||||
|
|
|
|||
|
|
@ -117,6 +117,10 @@ $END
|
|||
#include "common.h"
|
||||
#include "builtext.h"
|
||||
|
||||
#ifdef LOADABLE_BUILTIN
|
||||
# include "builtins.h"
|
||||
#endif
|
||||
|
||||
#if !defined (errno)
|
||||
extern int errno;
|
||||
#endif /* !errno */
|
||||
|
|
@ -642,4 +646,98 @@ get_directory_stack ()
|
|||
free (d);
|
||||
return ret; /* was (REVERSE_LIST (ret, (WORD_LIST *)); */
|
||||
}
|
||||
|
||||
#ifdef LOADABLE_BUILTIN
|
||||
static char *dirs_doc[] = {
|
||||
"Display the list of currently remembered directories. Directories",
|
||||
"find their way onto the list with the `pushd' command; you can get",
|
||||
"back up through the list with the `popd' command.",
|
||||
"",
|
||||
"The -l flag specifies that `dirs' should not print shorthand versions",
|
||||
"of directories which are relative to your home directory. This means",
|
||||
"that `~/bin' might be displayed as `/homes/bfox/bin'. The -v flag",
|
||||
"causes `dirs' to print the directory stack with one entry per line,",
|
||||
"prepending the directory name with its position in the stack. The -p",
|
||||
"flag does the same thing, but the stack position is not prepended.",
|
||||
"The -c flag clears the directory stack by deleting all of the elements.",
|
||||
"",
|
||||
"+N displays the Nth entry counting from the left of the list shown by",
|
||||
" dirs when invoked without options, starting with zero.",
|
||||
"",
|
||||
"-N displays the Nth entry counting from the right of the list shown by",
|
||||
" dirs when invoked without options, starting with zero.",
|
||||
(char *)NULL
|
||||
};
|
||||
|
||||
static char *pushd_doc[] = {
|
||||
"Adds a directory to the top of the directory stack, or rotates",
|
||||
"the stack, making the new top of the stack the current working",
|
||||
"directory. With no arguments, exchanges the top two directories.",
|
||||
"",
|
||||
"+N Rotates the stack so that the Nth directory (counting",
|
||||
" from the left of the list shown by `dirs', starting with",
|
||||
" zero) is at the top.",
|
||||
"",
|
||||
"-N Rotates the stack so that the Nth directory (counting",
|
||||
" from the right of the list shown by `dirs', starting with",
|
||||
" zero) is at the top.",
|
||||
"",
|
||||
"-n suppress the normal change of directory when adding directories",
|
||||
" to the stack, so only the stack is manipulated.",
|
||||
"",
|
||||
"dir adds DIR to the directory stack at the top, making it the",
|
||||
" new current working directory.",
|
||||
"",
|
||||
"You can see the directory stack with the `dirs' command.",
|
||||
(char *)NULL
|
||||
};
|
||||
|
||||
static char *popd_doc[] = {
|
||||
"Removes entries from the directory stack. With no arguments,",
|
||||
"removes the top directory from the stack, and cd's to the new",
|
||||
"top directory.",
|
||||
"",
|
||||
"+N removes the Nth entry counting from the left of the list",
|
||||
" shown by `dirs', starting with zero. For example: `popd +0'",
|
||||
" removes the first directory, `popd +1' the second.",
|
||||
"",
|
||||
"-N removes the Nth entry counting from the right of the list",
|
||||
" shown by `dirs', starting with zero. For example: `popd -0'",
|
||||
" removes the last directory, `popd -1' the next to last.",
|
||||
"",
|
||||
"-n suppress the normal change of directory when removing directories",
|
||||
" from the stack, so only the stack is manipulated.",
|
||||
"",
|
||||
"You can see the directory stack with the `dirs' command.",
|
||||
(char *)NULL
|
||||
};
|
||||
|
||||
struct builtin pushd_struct = {
|
||||
"pushd",
|
||||
pushd_builtin,
|
||||
BUILTIN_ENABLED,
|
||||
pushd_doc,
|
||||
"pushd [+N | -N] [-n] [dir]",
|
||||
0
|
||||
};
|
||||
|
||||
struct builtin popd_struct = {
|
||||
"popd",
|
||||
popd_builtin,
|
||||
BUILTIN_ENABLED,
|
||||
popd_doc,
|
||||
"popd [+N | -N] [-n]",
|
||||
0
|
||||
};
|
||||
|
||||
struct builtin dirs_struct = {
|
||||
"dirs",
|
||||
dirs_builtin,
|
||||
BUILTIN_ENABLED,
|
||||
dirs_doc,
|
||||
"dirs [-clpv] [+N] [-N]",
|
||||
0
|
||||
};
|
||||
#endif /* LOADABLE_BUILTIN */
|
||||
|
||||
#endif /* PUSHD_AND_POPD */
|
||||
|
|
|
|||
|
|
@ -189,6 +189,7 @@ read_builtin (list)
|
|||
c = rlbuf[rlind++];
|
||||
}
|
||||
else
|
||||
{
|
||||
#endif
|
||||
|
||||
while (((retval = read (0, &c, 1)) < 0) && errno == EINTR)
|
||||
|
|
@ -199,6 +200,10 @@ read_builtin (list)
|
|||
break;
|
||||
}
|
||||
|
||||
#if defined (READLINE)
|
||||
}
|
||||
#endif
|
||||
|
||||
if (i + 2 >= size)
|
||||
input_string = xrealloc (input_string, size += 128);
|
||||
|
||||
|
|
|
|||
|
|
@ -89,7 +89,7 @@ $END
|
|||
|
||||
$BUILTIN { ... }
|
||||
$DOCNAME grouping_braces
|
||||
$SHORT_DOC { COMMANDS }
|
||||
$SHORT_DOC { COMMANDS ; }
|
||||
Run a set of commands in a group. This is one way to redirect an
|
||||
entire set of commands.
|
||||
$END
|
||||
|
|
|
|||
|
|
@ -92,7 +92,7 @@ $SHORT_DOC set [--abefhkmnptuvxBCHP] [-o option] [arg ...]
|
|||
noclobber same as -C
|
||||
noexec same as -n
|
||||
noglob same as -f
|
||||
notify save as -b
|
||||
notify same as -b
|
||||
nounset same as -u
|
||||
onecmd same as -t
|
||||
physical same as -P
|
||||
|
|
|
|||
|
|
@ -79,10 +79,19 @@ extern int hist_verify, history_reediting, perform_hostname_completion;
|
|||
extern void enable_hostname_completion ();
|
||||
#endif
|
||||
|
||||
#if defined (RESTRICTED_SHELL)
|
||||
extern int restricted_shell;
|
||||
extern char *shell_name;
|
||||
#endif
|
||||
|
||||
extern void set_shellopts ();
|
||||
|
||||
static int set_interactive_comments ();
|
||||
|
||||
#if defined (RESTRICTED_SHELL)
|
||||
static int set_restricted_shell ();
|
||||
#endif
|
||||
|
||||
static struct {
|
||||
char *name;
|
||||
int *value;
|
||||
|
|
@ -120,6 +129,9 @@ static struct {
|
|||
{ "nocaseglob", &glob_ignore_case, (Function *)NULL },
|
||||
{ "nullglob", &allow_null_glob_expansion, (Function *)NULL },
|
||||
{ "promptvars", &promptvars, (Function *)NULL },
|
||||
#if defined (RESTRICTED_SHELL)
|
||||
{ "restricted_shell", &restricted_shell, set_restricted_shell },
|
||||
#endif
|
||||
{ "shift_verbose", &print_shift_error, (Function *)NULL },
|
||||
{ "sourcepath", &source_uses_path, (Function *)NULL },
|
||||
{ (char *)0, (int *)0, (Function *)NULL }
|
||||
|
|
@ -262,7 +274,7 @@ toggle_shopts (mode, list, quiet)
|
|||
return (rval);
|
||||
}
|
||||
|
||||
static int
|
||||
static void
|
||||
print_shopt (name, val, flags)
|
||||
char *name;
|
||||
int val, flags;
|
||||
|
|
@ -400,3 +412,20 @@ set_interactive_comments (mode)
|
|||
set_shellopts ();
|
||||
return (0);
|
||||
}
|
||||
|
||||
#if defined (RESTRICTED_SHELL)
|
||||
/* Don't allow the value of restricted_shell to be modified. */
|
||||
|
||||
static int
|
||||
set_restricted_shell (mode)
|
||||
int mode;
|
||||
{
|
||||
static int save_restricted = -1;
|
||||
|
||||
if (save_restricted == -1)
|
||||
save_restricted = shell_is_restricted (shell_name);
|
||||
|
||||
restricted_shell = save_restricted;
|
||||
return (0);
|
||||
}
|
||||
#endif /* RESTRICTED_SHELL */
|
||||
|
|
|
|||
|
|
@ -129,7 +129,10 @@ test_builtin (list)
|
|||
if (list == 0)
|
||||
{
|
||||
if (this_command_name[0] == '[' && !this_command_name[1])
|
||||
builtin_error ("missing `]'");
|
||||
{
|
||||
builtin_error ("missing `]'");
|
||||
return (EX_BADUSAGE);
|
||||
}
|
||||
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -62,6 +62,7 @@ $END
|
|||
#endif /* ALIAS */
|
||||
|
||||
#include "common.h"
|
||||
#include "bashgetopt.h"
|
||||
|
||||
extern int find_reserved_word ();
|
||||
|
||||
|
|
@ -69,14 +70,14 @@ extern int find_reserved_word ();
|
|||
it as a simple command. i.e., which file would this shell use to
|
||||
execve, or if it is a builtin command, or an alias. Possible flag
|
||||
arguments:
|
||||
-type Returns the "type" of the object, one of
|
||||
-t Returns the "type" of the object, one of
|
||||
`alias', `keyword', `function', `builtin',
|
||||
or `file'.
|
||||
|
||||
-path Returns the pathname of the file if -type is
|
||||
-p Returns the pathname of the file if -type is
|
||||
a file.
|
||||
|
||||
-all Returns all occurrences of words, whether they
|
||||
-a Returns all occurrences of words, whether they
|
||||
be a filename in the path, alias, function,
|
||||
or builtin.
|
||||
Order of evaluation:
|
||||
|
|
@ -86,12 +87,14 @@ extern int find_reserved_word ();
|
|||
builtin
|
||||
file
|
||||
*/
|
||||
|
||||
int
|
||||
type_builtin (list)
|
||||
WORD_LIST *list;
|
||||
{
|
||||
int path_only, type_only, all, verbose;
|
||||
int successful_finds;
|
||||
int successful_finds, opt;
|
||||
WORD_LIST *prev, *this;
|
||||
|
||||
if (list == 0)
|
||||
return (EXECUTION_SUCCESS);
|
||||
|
|
@ -99,32 +102,69 @@ type_builtin (list)
|
|||
path_only = type_only = all = 0;
|
||||
successful_finds = 0;
|
||||
|
||||
while (list && *(list->word->word) == '-')
|
||||
/* Handle the obsolescent `-type', `-path', and `-all' by prescanning
|
||||
the arguments and removing those options from the list before calling
|
||||
internal_getopt. Recognize `--type', `--path', and `--all' also.
|
||||
THIS SHOULD REALLY GO AWAY. */
|
||||
for (this = list; this && this->word->word[0] == '-'; )
|
||||
{
|
||||
char *flag = &(list->word->word[1]);
|
||||
char *flag = &(this->word->word[1]);
|
||||
|
||||
if (flag[0] == 't' && (!flag[1] || strcmp (flag + 1, "ype") == 0))
|
||||
if (STREQ (flag, "type") || STREQ (flag, "-type"))
|
||||
{
|
||||
type_only = 1;
|
||||
path_only = 0;
|
||||
}
|
||||
else if (flag[0] == 'p' && (!flag[1] || strcmp (flag + 1, "ath") == 0))
|
||||
else if (STREQ (flag, "path") || STREQ (flag, "-path"))
|
||||
{
|
||||
path_only = 1;
|
||||
type_only = 0;
|
||||
}
|
||||
else if (flag[0] == 'a' && (!flag[1] || strcmp (flag + 1, "ll") == 0))
|
||||
{
|
||||
all = 1;
|
||||
}
|
||||
else if (STREQ (flag, "all") || STREQ (flag, "-all"))
|
||||
all = 1;
|
||||
else
|
||||
{
|
||||
bad_option (flag);
|
||||
prev = this;
|
||||
this = this->next;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* We found a long option; remove it from the argument list. Don't
|
||||
free it if it's the head of the argument list, though -- the
|
||||
argument list will be freed by the caller. */
|
||||
if (this == list)
|
||||
this = list = list->next;
|
||||
else
|
||||
{
|
||||
prev->next = this->next;
|
||||
this->next = (WORD_LIST *)NULL;
|
||||
dispose_words (this);
|
||||
this = prev->next;
|
||||
}
|
||||
}
|
||||
|
||||
reset_internal_getopt ();
|
||||
while ((opt = internal_getopt (list, "apt")) != -1)
|
||||
{
|
||||
switch (opt)
|
||||
{
|
||||
case 't':
|
||||
type_only = 1;
|
||||
path_only = 0;
|
||||
break;
|
||||
case 'p':
|
||||
path_only = 1;
|
||||
type_only = 0;
|
||||
break;
|
||||
case 'a':
|
||||
all = 1;
|
||||
break;
|
||||
default:
|
||||
builtin_usage ();
|
||||
return (EX_USAGE);
|
||||
}
|
||||
list = list->next;
|
||||
}
|
||||
list = loptend;
|
||||
|
||||
if (type_only)
|
||||
verbose = 1;
|
||||
|
|
@ -150,10 +190,7 @@ type_builtin (list)
|
|||
|
||||
fflush (stdout);
|
||||
|
||||
if (successful_finds != 0)
|
||||
return (EXECUTION_SUCCESS);
|
||||
else
|
||||
return (EXECUTION_FAILURE);
|
||||
return ((successful_finds != 0) ? EXECUTION_SUCCESS : EXECUTION_FAILURE);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -202,7 +239,7 @@ describe_command (command, verbose, all)
|
|||
|
||||
found = 1;
|
||||
|
||||
if (!all)
|
||||
if (all == 0)
|
||||
return (1);
|
||||
}
|
||||
#endif /* ALIAS */
|
||||
|
|
@ -220,7 +257,7 @@ describe_command (command, verbose, all)
|
|||
|
||||
found = 1;
|
||||
|
||||
if (!all)
|
||||
if (all == 0)
|
||||
return (1);
|
||||
}
|
||||
|
||||
|
|
@ -251,7 +288,7 @@ describe_command (command, verbose, all)
|
|||
|
||||
found = 1;
|
||||
|
||||
if (!all)
|
||||
if (all == 0)
|
||||
return (1);
|
||||
}
|
||||
|
||||
|
|
@ -267,7 +304,7 @@ describe_command (command, verbose, all)
|
|||
|
||||
found = 1;
|
||||
|
||||
if (!all)
|
||||
if (all == 0)
|
||||
return (1);
|
||||
}
|
||||
|
||||
|
|
@ -293,9 +330,9 @@ describe_command (command, verbose, all)
|
|||
}
|
||||
}
|
||||
|
||||
/* If the user isn't doing "-all", then we might care about
|
||||
/* If the user isn't doing "-a", then we might care about
|
||||
whether the file is present in our hash table. */
|
||||
if (!all)
|
||||
if (all == 0)
|
||||
{
|
||||
if ((full_path = find_hashed_filename (command)) != (char *)NULL)
|
||||
{
|
||||
|
|
@ -314,7 +351,7 @@ describe_command (command, verbose, all)
|
|||
/* Now search through $PATH. */
|
||||
while (1)
|
||||
{
|
||||
if (!all)
|
||||
if (all == 0)
|
||||
full_path = find_user_command (command);
|
||||
else
|
||||
full_path =
|
||||
|
|
@ -337,7 +374,7 @@ describe_command (command, verbose, all)
|
|||
free (full_path);
|
||||
full_path = (char *)NULL;
|
||||
|
||||
if (!all)
|
||||
if (all == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -154,24 +154,20 @@ extern int errno;
|
|||
# define RLIM_INFINITY 0x7fffffff
|
||||
#endif
|
||||
|
||||
#if !defined (RLIM_INVALID)
|
||||
# define RLIM_INVALID (RLIMTYPE)-1
|
||||
#endif
|
||||
|
||||
#define LIMIT_HARD 0x01
|
||||
#define LIMIT_SOFT 0x02
|
||||
|
||||
static int ulimit_internal ();
|
||||
static void printone ();
|
||||
static void print_all_limits ();
|
||||
static int ulimit_internal __P((int, char *, int, int));
|
||||
static void printone __P((int, RLIMTYPE, int));
|
||||
static void print_all_limits __P((int));
|
||||
|
||||
static int get_limit ();
|
||||
static int set_limit ();
|
||||
static int get_limit __P((int, int, RLIMTYPE *));
|
||||
static int set_limit __P((int, RLIMTYPE, int));
|
||||
|
||||
static RLIMTYPE filesize ();
|
||||
static RLIMTYPE pipesize ();
|
||||
static RLIMTYPE getmaxuprc ();
|
||||
static RLIMTYPE getmaxvm ();
|
||||
static int filesize __P((RLIMTYPE *));
|
||||
static int pipesize __P((RLIMTYPE *));
|
||||
static int getmaxuprc __P((int, RLIMTYPE *));
|
||||
static int getmaxvm __P((int, RLIMTYPE *));
|
||||
|
||||
typedef struct {
|
||||
int option; /* The ulimit option for this limit. */
|
||||
|
|
@ -351,7 +347,6 @@ ulimit_internal (cmd, cmdarg, mode, multiple)
|
|||
long block_factor;
|
||||
RLIMTYPE current_limit, real_limit, limit;
|
||||
|
||||
limit = RLIM_INVALID;
|
||||
setting = cmdarg != 0;
|
||||
limind = _findlim (cmd);
|
||||
if (mode == 0)
|
||||
|
|
@ -412,26 +407,30 @@ get_limit (ind, mode, limptr)
|
|||
switch (limits[ind].parameter)
|
||||
{
|
||||
case RLIMIT_FILESIZE:
|
||||
value = filesize ();
|
||||
if (filesize (&value) < 0)
|
||||
return -1;
|
||||
break;
|
||||
case RLIMIT_PIPESIZE:
|
||||
value = pipesize ();
|
||||
if (pipesize (&value) < 0)
|
||||
return -1;
|
||||
break;
|
||||
case RLIMIT_OPENFILES:
|
||||
value = (RLIMTYPE)getdtablesize ();
|
||||
break;
|
||||
case RLIMIT_VIRTMEM:
|
||||
value = getmaxvm (mode);
|
||||
if (getmaxvm (mode, &value) < 0)
|
||||
return -1;
|
||||
break;
|
||||
case RLIMIT_MAXUPROC:
|
||||
value = getmaxuprc (mode);
|
||||
if (getmaxuprc (mode, &value) < 0)
|
||||
return -1;
|
||||
break;
|
||||
default:
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
*limptr = value;
|
||||
return ((value == RLIM_INVALID) ? -1 : 0);
|
||||
return (0);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -439,6 +438,11 @@ get_limit (ind, mode, limptr)
|
|||
if (getrlimit (limits[ind].parameter, &limit) < 0)
|
||||
return -1;
|
||||
value = (mode & LIMIT_SOFT) ? limit.rlim_cur : limit.rlim_max;
|
||||
# if defined (HPUX9)
|
||||
if (limits[ind].parameter == RLIMIT_FILESIZE)
|
||||
*limptr = value * 512; /* Ugh. */
|
||||
else
|
||||
# endif /* HPUX9 */
|
||||
*limptr = value;
|
||||
return 0;
|
||||
#else
|
||||
|
|
@ -486,6 +490,10 @@ set_limit (ind, newlim, mode)
|
|||
#if defined (HAVE_RESOURCE)
|
||||
if (getrlimit (limits[ind].parameter, &limit) < 0)
|
||||
return -1;
|
||||
# if defined (HPUX9)
|
||||
if (limits[ind].parameter == RLIMIT_FILESIZE)
|
||||
newlim /= 512; /* Ugh. */
|
||||
# endif /* HPUX9 */
|
||||
val = (current_user.euid != 0 && newlim == RLIM_INFINITY &&
|
||||
(limit.rlim_cur <= limit.rlim_max))
|
||||
? limit.rlim_max : newlim;
|
||||
|
|
@ -502,72 +510,91 @@ set_limit (ind, newlim, mode)
|
|||
}
|
||||
}
|
||||
|
||||
static RLIMTYPE
|
||||
getmaxvm (mode)
|
||||
static int
|
||||
getmaxvm (mode, valuep)
|
||||
int mode;
|
||||
RLIMTYPE *valuep;
|
||||
{
|
||||
#if defined (HAVE_RESOURCE)
|
||||
struct rlimit rl;
|
||||
RLIMTYPE maxdata, maxstack;
|
||||
|
||||
if (getrlimit (RLIMIT_DATA, &rl) < 0)
|
||||
return (RLIM_INVALID);
|
||||
return -1;
|
||||
else
|
||||
maxdata = (mode & LIMIT_SOFT) ? rl.rlim_cur : rl.rlim_max;
|
||||
|
||||
if (getrlimit (RLIMIT_STACK, &rl) < 0)
|
||||
return (RLIM_INVALID);
|
||||
return -1;
|
||||
else
|
||||
maxstack = (mode & LIMIT_SOFT) ? rl.rlim_cur : rl.rlim_max;
|
||||
|
||||
/* Protect against overflow. */
|
||||
return ((maxdata / 1024L) + (maxstack / 1024L));
|
||||
*valuep = (maxdata / 1024L) + (maxstack / 1024L);
|
||||
return 0;
|
||||
#else
|
||||
errno = EINVAL;
|
||||
return RLIM_INVALID;
|
||||
return -1;
|
||||
#endif /* HAVE_RESOURCE */
|
||||
}
|
||||
|
||||
static RLIMTYPE
|
||||
filesize()
|
||||
static int
|
||||
filesize(valuep)
|
||||
RLIMTYPE *valuep;
|
||||
{
|
||||
#if !defined (HAVE_RESOURCE)
|
||||
return ((RLIMTYPE)ulimit (1, 0L));
|
||||
long result;
|
||||
if ((result = ulimit (1, 0L)) < 0)
|
||||
return -1;
|
||||
else
|
||||
*valuep = (RLIMTYPE) result;
|
||||
return 0;
|
||||
#else
|
||||
errno = EINVAL;
|
||||
return RLIM_INVALID;
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
static RLIMTYPE
|
||||
pipesize ()
|
||||
static int
|
||||
pipesize (valuep)
|
||||
RLIMTYPE *valuep;
|
||||
{
|
||||
#if defined (PIPE_BUF)
|
||||
/* This is defined on Posix systems. */
|
||||
return ((RLIMTYPE) PIPE_BUF);
|
||||
*valuep = (RLIMTYPE) PIPE_BUF;
|
||||
return 0;
|
||||
#else
|
||||
# if defined (PIPESIZE)
|
||||
/* This is defined by running a program from the Makefile. */
|
||||
return ((RLIMTYPE) PIPESIZE);
|
||||
*valuep = (RLIMTYPE) PIPESIZE;
|
||||
return 0;
|
||||
# else
|
||||
errno = EINVAL;
|
||||
return RLIM_INVALID;
|
||||
return -1;
|
||||
# endif /* PIPESIZE */
|
||||
#endif /* PIPE_BUF */
|
||||
}
|
||||
|
||||
static RLIMTYPE
|
||||
getmaxuprc (mode)
|
||||
static int
|
||||
getmaxuprc (mode, valuep)
|
||||
int mode;
|
||||
RLIMTYPE *valuep;
|
||||
{
|
||||
# if defined (HAVE_SYSCONF) && defined (_SC_CHILD_MAX)
|
||||
return ((RLIMTYPE)sysconf (_SC_CHILD_MAX));
|
||||
long maxchild;
|
||||
maxchild = sysconf (_SC_CHILD_MAX);
|
||||
if (maxchild < 0)
|
||||
return -1;
|
||||
else
|
||||
*valuep = (RLIMTYPE) maxchild;
|
||||
return 0;
|
||||
# else /* !HAVE_SYSCONF || !_SC_CHILD_MAX */
|
||||
# if defined (MAXUPRC)
|
||||
return ((RLIMTYPE)MAXUPRC);
|
||||
*valuep = (RLIMTYPE) MAXUPRC;
|
||||
return 0;
|
||||
# else /* MAXUPRC */
|
||||
errno = EINVAL;
|
||||
return RLIM_INVALID;
|
||||
return -1;
|
||||
# endif /* !MAXUPRC */
|
||||
# endif /* !HAVE_SYSCONF || !_SC_CHILD_MAX */
|
||||
}
|
||||
|
|
@ -585,8 +612,12 @@ print_all_limits (mode)
|
|||
for (i = 0; limits[i].option > 0; i++)
|
||||
{
|
||||
if (get_limit (i, mode, &value) < 0)
|
||||
value = RLIM_INVALID;
|
||||
printone (i, value, 1);
|
||||
{
|
||||
fprintf (stderr, DESCFMT, limits[i].description);
|
||||
builtin_error ("cannot get limit: %s", strerror (errno));
|
||||
}
|
||||
else
|
||||
printone (i, value, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -600,8 +631,6 @@ printone (limind, curlim, pdesc)
|
|||
printf (DESCFMT, limits[limind].description);
|
||||
if (curlim == RLIM_INFINITY)
|
||||
puts ("unlimited");
|
||||
else if (curlim == RLIM_INVALID)
|
||||
builtin_error ("cannot get limit: %s\n", strerror (errno));
|
||||
else
|
||||
print_rlimtype ((curlim / limits[limind].block_factor), 1);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -174,29 +174,15 @@ print_symbolic_umask (um)
|
|||
printf ("u=%s,g=%s,o=%s\n", ubits, gbits, obits);
|
||||
}
|
||||
|
||||
/* Set the umask from a symbolic mode string similar to that accepted
|
||||
by chmod. If the -S argument is given, then print the umask in a
|
||||
symbolic form. */
|
||||
static int
|
||||
symbolic_umask (list)
|
||||
WORD_LIST *list;
|
||||
int
|
||||
parse_symbolic_mode (mode, initial_bits)
|
||||
char *mode;
|
||||
int initial_bits;
|
||||
{
|
||||
int um, umc, c;
|
||||
int who, op, perm, mask;
|
||||
int who, op, perm, mask, bits, c;
|
||||
char *s;
|
||||
|
||||
/* Get the initial umask. Don't change it yet. */
|
||||
um = umask (022);
|
||||
umask (um);
|
||||
|
||||
/* All work below is done with the complement of the umask -- it's
|
||||
more intuitive and easier to deal with. It is complemented
|
||||
again before being returned. */
|
||||
umc = ~um;
|
||||
|
||||
s = list->word->word;
|
||||
|
||||
for (;;)
|
||||
for (s = mode, bits = initial_bits;;)
|
||||
{
|
||||
who = op = perm = mask = 0;
|
||||
|
||||
|
|
@ -205,20 +191,20 @@ symbolic_umask (list)
|
|||
{
|
||||
switch (c = *s++)
|
||||
{
|
||||
case 'u':
|
||||
who |= S_IRWXU;
|
||||
continue;
|
||||
case 'g':
|
||||
who |= S_IRWXG;
|
||||
continue;
|
||||
case 'o':
|
||||
who |= S_IRWXO;
|
||||
continue;
|
||||
case 'a':
|
||||
who |= S_IRWXU | S_IRWXG | S_IRWXO;
|
||||
continue;
|
||||
default:
|
||||
break;
|
||||
case 'u':
|
||||
who |= S_IRWXU;
|
||||
continue;
|
||||
case 'g':
|
||||
who |= S_IRWXG;
|
||||
continue;
|
||||
case 'o':
|
||||
who |= S_IRWXO;
|
||||
continue;
|
||||
case 'a':
|
||||
who |= S_IRWXU | S_IRWXG | S_IRWXO;
|
||||
continue;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -226,13 +212,13 @@ symbolic_umask (list)
|
|||
op = *s++;
|
||||
switch (op)
|
||||
{
|
||||
case '+':
|
||||
case '-':
|
||||
case '=':
|
||||
break;
|
||||
default:
|
||||
builtin_error ("bad symbolic mode operator: %c", op);
|
||||
return (-1);
|
||||
case '+':
|
||||
case '-':
|
||||
case '=':
|
||||
break;
|
||||
default:
|
||||
builtin_error ("bad symbolic mode operator: %c", op);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/* Parse out the `perm' section of the symbolic mode clause. */
|
||||
|
|
@ -242,17 +228,15 @@ symbolic_umask (list)
|
|||
|
||||
switch (c)
|
||||
{
|
||||
case 'r':
|
||||
perm |= S_IRUGO;
|
||||
break;
|
||||
|
||||
case 'w':
|
||||
perm |= S_IWUGO;
|
||||
break;
|
||||
|
||||
case 'x':
|
||||
perm |= S_IXUGO;
|
||||
break;
|
||||
case 'r':
|
||||
perm |= S_IRUGO;
|
||||
break;
|
||||
case 'w':
|
||||
perm |= S_IWUGO;
|
||||
break;
|
||||
case 'x':
|
||||
perm |= S_IXUGO;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -265,32 +249,22 @@ symbolic_umask (list)
|
|||
|
||||
switch (op)
|
||||
{
|
||||
case '+':
|
||||
umc |= perm;
|
||||
break;
|
||||
|
||||
case '-':
|
||||
umc &= ~perm;
|
||||
break;
|
||||
|
||||
case '=':
|
||||
umc &= ~who;
|
||||
umc |= perm;
|
||||
break;
|
||||
|
||||
#if 0
|
||||
/* No other values are possible. */
|
||||
default:
|
||||
builtin_error ("bad symbolic mode operator: %c", op);
|
||||
return (-1);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!*s)
|
||||
{
|
||||
um = ~umc & 0777;
|
||||
case '+':
|
||||
bits |= perm;
|
||||
break;
|
||||
case '-':
|
||||
bits &= ~perm;
|
||||
break;
|
||||
case '=':
|
||||
bits &= ~who;
|
||||
bits |= perm;
|
||||
break;
|
||||
|
||||
/* No other values are possible. */
|
||||
}
|
||||
|
||||
if (*s == '\0')
|
||||
break;
|
||||
else
|
||||
s++; /* skip past ',' */
|
||||
}
|
||||
|
|
@ -300,5 +274,28 @@ symbolic_umask (list)
|
|||
return (-1);
|
||||
}
|
||||
}
|
||||
|
||||
return (bits);
|
||||
}
|
||||
|
||||
/* Set the umask from a symbolic mode string similar to that accepted
|
||||
by chmod. If the -S argument is given, then print the umask in a
|
||||
symbolic form. */
|
||||
static int
|
||||
symbolic_umask (list)
|
||||
WORD_LIST *list;
|
||||
{
|
||||
int um, bits;
|
||||
|
||||
/* Get the initial umask. Don't change it yet. */
|
||||
um = umask (022);
|
||||
umask (um);
|
||||
|
||||
/* All work is done with the complement of the umask -- it's
|
||||
more intuitive and easier to deal with. It is complemented
|
||||
again before being returned. */
|
||||
bits = parse_symbolic_mode (list->word->word, ~um);
|
||||
|
||||
um = ~bits & 0777;
|
||||
return (um);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue