Fix broken umask, add completions, documentation cleanups, etc

darcs-hash:20051022100605-ac50b-9b6ece502b203bf7690583d57b5b0713de30890c.gz
This commit is contained in:
axel 2005-10-22 20:06:05 +10:00
parent 6139df926b
commit fc5e0ab367
6 changed files with 124 additions and 69 deletions

View file

@ -104,8 +104,9 @@ BUILTIN_DOC_HDR := $(BUILTIN_DOC_SRC:.txt=.doxygen)
CMD_DOC_SRC := doc_src/count.txt doc_src/dirh.txt doc_src/dirs.txt \ CMD_DOC_SRC := doc_src/count.txt doc_src/dirh.txt doc_src/dirs.txt \
doc_src/fishd.txt doc_src/help.txt doc_src/mimedb.txt \ doc_src/fishd.txt doc_src/help.txt doc_src/mimedb.txt \
doc_src/nextd.txt doc_src/open.txt doc_src/popd.txt \ doc_src/nextd.txt doc_src/open.txt doc_src/popd.txt \
doc_src/prevd.txt doc_src/pushd.txt doc_src/set_color.txt \ doc_src/prevd.txt doc_src/psub.txt doc_src/pushd.txt \
doc_src/tokenize.txt doc_src/type.txt doc_src/set_color.txt doc_src/tokenize.txt doc_src/type.txt \
doc_src/umask.txt
# #
# Files generated by running doxygen on the files in $(CMD_DOC_SRC) # Files generated by running doxygen on the files in $(CMD_DOC_SRC)

View file

@ -7,15 +7,23 @@
\subsection umask-description Description \subsection umask-description Description
With no argument, the current file-creation mask is printed, if an With no argument, the current file-creation mask is printed, if an
argument is specified, it is the new file creation mask. argument is specified, it is the new file creation mask. The mask may
be specified as an octal number, in which case it is interpreted as
the rights that should be masked away, i.e. it is the inverse of the
file permissions any new files will have. If a synbolic mask is
specified, the actual file permission bits, and not the inverse, are
specified.
- <code>-h</code> or <code>--help</code> print this message - <code>-h</code> or <code>--help</code> print this message
- <code>-S</code> or <code>--symbolic</code> prints the file-creation mask in symbolic form instead of octal form. Use <code>man chmod</code> for more information. - <code>-S</code> or <code>--symbolic</code> prints the file-creation mask in symbolic form instead of octal form. Use <code>man chmod</code> for more information.
- <code>-p</code> or <code>--as-command</code> prints any output in a form that may be reused as input - <code>-p</code> or <code>--as-command</code> prints any output in a form that may be reused as input
The umask implementation in fish should behave identically to the one in bash. The umask implementation in fish should behave identically to the one
in bash.
\subsection umask-example Example \subsection umask-example Example
<code>umask 600</code> sets the file creation mask to read and write for the owner and no permissions at all for any other users. <code>umask 177</code> or <code>umask u=rw</code>sets the file
creation mask to read and write for the owner and no permissions at
all for any other users.

20
env.c
View file

@ -15,7 +15,6 @@
#include <sys/stat.h> #include <sys/stat.h>
#include <pwd.h> #include <pwd.h>
#if HAVE_NCURSES_H #if HAVE_NCURSES_H
#include <ncurses.h> #include <ncurses.h>
#else #else
@ -27,6 +26,7 @@
#endif #endif
#include <term.h> #include <term.h>
#include <errno.h>
#include "util.h" #include "util.h"
#include "wutil.h" #include "wutil.h"
@ -385,6 +385,24 @@ void env_set( const wchar_t *key,
fish_setlocale(LC_ALL,val); fish_setlocale(LC_ALL,val);
} }
if( wcscmp( key, L"umask" ) == 0)
{
wchar_t *end;
int mask;
if( val && wcslen(val) )
{
errno=0;
mask = wcstol( val, &end, 8 );
if( !errno && !*end )
{
umask( mask );
}
}
}
/* /*
Zero element arrays are internaly not coded as null but as this placeholder string Zero element arrays are internaly not coded as null but as this placeholder string
*/ */

42
exec.c
View file

@ -58,10 +58,6 @@ pid_t getpgid( pid_t pid );
*/ */
#define FORK_ERROR L"Could not create child process - exiting" #define FORK_ERROR L"Could not create child process - exiting"
/**
Default value for the umask
*/
#define UMASK_DEFAULT 0664
/** /**
List of all pipes used by internal pipes. These must be closed in List of all pipes used by internal pipes. These must be closed in
@ -70,36 +66,6 @@ pid_t getpgid( pid_t pid );
*/ */
static array_list_t *open_fds=0; static array_list_t *open_fds=0;
/**
The umask. Recalculated every time exec is run. by calling get_umask().
*/
static int umask_val;
/**
Calculate the current value of the umask. Should be done once at
the beginning of each call to exec. Uses the $umask environment
variable, if available, defaults to the constant UMASK_DEFAULT.
*/
static int get_umask()
{
wchar_t *m = env_get( L"umask" );
wchar_t *end;
int mask;
if( !m || !wcslen(m) )
return UMASK_DEFAULT;
errno=0;
mask = wcstol( m, &end, 8 );
if( errno || *end )
{
return UMASK_DEFAULT;
}
return mask;
}
void exec_close( int fd ) void exec_close( int fd )
{ {
@ -313,7 +279,7 @@ static void handle_child_io( io_data_t *io )
break; break;
case IO_FILE: case IO_FILE:
if( (tmp=wopen( io->param1.filename, if( (tmp=wopen( io->param1.filename,
io->param2.flags, umask_val ))==-1 ) io->param2.flags, 0777 ) )==-1 )
{ {
debug( 1, debug( 1,
FILE_ERROR, FILE_ERROR,
@ -516,7 +482,7 @@ static io_data_t *io_transmogrify( io_data_t * in )
{ {
int fd; int fd;
if( (fd=wopen( in->param1.filename, in->param2.flags, umask_val ))==-1 ) if( (fd=wopen( in->param1.filename, in->param2.flags, 0777 ) )==-1 )
{ {
debug( 1, debug( 1,
FILE_ERROR, FILE_ERROR,
@ -678,8 +644,6 @@ void exec( job_t *j )
int exec_error=0; int exec_error=0;
umask_val = get_umask();
debug( 4, L"Exec job %ls with id %d", j->command, j->job_id ); debug( 4, L"Exec job %ls with id %d", j->command, j->job_id );
if( j->first_process->type==INTERNAL_EXEC ) if( j->first_process->type==INTERNAL_EXEC )
@ -890,7 +854,7 @@ void exec( job_t *j )
in->filename); in->filename);
*/ */
builtin_stdin=wopen( in->param1.filename, builtin_stdin=wopen( in->param1.filename,
in->param2.flags, umask_val ); in->param2.flags, 0777 );
if( builtin_stdin == -1 ) if( builtin_stdin == -1 )
{ {
debug( 1, debug( 1,

View file

@ -6,6 +6,10 @@ for i in (builtin -n)
complete -c help -x -a $i -d 'Help for the '$i' builtin' complete -c help -x -a $i -d 'Help for the '$i' builtin'
end end
for i in count dirh dirs help mimedb nextd open popd prevd pushd set_color tokenize psub umask type
complete -c help -x -a $i -d 'Help for the '$i' command'
end
for i in syntax todo bugs history; for i in syntax todo bugs history;
complete -c help -x -a $i -d 'Help section on '$i complete -c help -x -a $i -d 'Help section on '$i
end end

View file

@ -154,7 +154,7 @@ function help -d "Show help for the fish shell"
set fish_help_page "builtins.html\#"$fish_help_item set fish_help_page "builtins.html\#"$fish_help_item
end end
if contains -- $fish_help_item count dirh dirs help mimedb nextd open popd prevd pushd set_color tokenize if contains -- $fish_help_item count dirh dirs help mimedb nextd open popd prevd pushd set_color tokenize psub umask type
set fish_help_page "commands.html\#"$fish_help_item set fish_help_page "commands.html\#"$fish_help_item
end end
@ -755,48 +755,82 @@ echo
end end
function __fish_umask_parse -d "Parses a file permission specification as into an octal version" function __fish_umask_parse -d "Parses a file permission specification as into an octal version"
# Test if already a valid octal mask # Test if already a valid octal mask, and pad it with zeros
if echo $argv | grep -E '^[0-7]{1,4}$' >/dev/null if echo $argv | grep -E '^(0|)[0-7]{1,3}$' >/dev/null
for i in (seq (echo 5-(echo $argv|wc -c)|bc)); set -- argv 0$argv; end
echo $argv echo $argv
else else
set res 0 0 0 # Test if argument really is a valid symbolic mask
set el (echo $argv|tr , \n) if not echo $argv | grep -E '^(((u|g|o|a|)(=|\+|-)|)(r|w|x)*)(,(((u|g|o|a|)(=|\+|-)|)(r|w|x)*))*$' >/dev/null
echo umask: Invalid mask $argv >&2
return 1
end
set -e implicit_all
# Make sure the current umask is defined
if not set -q umask
set umask 0000
end
# If umask is invalid, reset it
if not echo $umask | grep -E '^(0|)[0-7]{1,3}$' >/dev/null
set umask 0000
end
# Pad umask with zeros
for i in (seq (echo 5-(echo $umask|wc -c)|bc)); set -- argv 0$umask; end
# Insert inverted umask into res variable
set tmp $umask
for i in 1 2 3
set -- tmp (echo $tmp|cut -c 2-)
set -- res[$i] (echo 7-(echo $tmp|cut -c 1)|bc)
end
set -- el (echo $argv|tr , \n)
for i in $el for i in $el
switch $i switch $i
case 'u*' case 'u*'
set idx 1 set idx 1
set i (echo $i| cut -c 2-) set -- i (echo $i| cut -c 2-)
case 'g*' case 'g*'
set idx 2 set idx 2
set i (echo $i| cut -c 2-) set -- i (echo $i| cut -c 2-)
case 'o*' case 'o*'
set idx 3 set idx 3
set i (echo $i| cut -c 2-) set -- i (echo $i| cut -c 2-)
case 'a*' case 'a*'
set idx 1 2 3 set idx 1 2 3
set i (echo $i| cut -c 2-) set -- i (echo $i| cut -c 2-)
case '*' case '*'
set implicit_all 1
set idx 1 2 3 set idx 1 2 3
end end
switch $i switch $i
case '=*' case '=*'
set mode set set mode set
set i (echo $i| cut -c 2-) set -- i (echo $i| cut -c 2-)
case '+*' case '+*'
set mode add set mode add
set i (echo $i| cut -c 2-) set -- i (echo $i| cut -c 2-)
case '-*' case '-*'
set mode remove set mode remove
set i (echo $i| cut -c 2-) set -- i (echo $i| cut -c 2-)
case '*' case '*'
if not set -q implicit_all
echo umask: Invalid mask $argv >&2
return
end
set mode set set mode set
end end
@ -806,41 +840,67 @@ function __fish_umask_parse -d "Parses a file permission specification as into a
end end
set val 0 set val 0
if echo $perm |grep 'r' >/dev/null if echo $i |grep 'r' >/dev/null
set val 4 set val 4
end end
if echo $perm |grep 'w' >/dev/null if echo $i |grep 'w' >/dev/null
set val (echo $val + 2|bc) set val (echo $val + 2|bc)
end end
if echo $perm |grep 'x' >/dev/null if echo $i |grep 'x' >/dev/null
set val (echo $val + 1|bc) set val (echo $val + 1|bc)
end end
for j in $idx for j in $idx
set res[$j] $val switch $mode
case set
set res[$j] $val
case add
set res[$j] (perl -e 'print( ( '$res[$j]'|'$val[$j]' )."\n" )')
case remove
set res[$j] (perl -e 'print( ( (7-'$res[$j]')&'$val[$j]' )."\n" )')
end
end end
end end
echo $res[1]$res[2]$res[3]
for i in 1 2 3
set res[$i] (echo 7-$res[$i]|bc)
end
echo 0$res[1]$res[2]$res[3]
end end
end end
function __fish_umask_print_symbolic function __fish_umask_print_symbolic
set -l res "" set -l res ""
set -l letter u g o set -l letter a u g o
for i in 1 2 3 # Make sure the current umask is defined
if not set -q umask
set umask 0000
end
# If umask is invalid, reset it
if not echo $umask | grep -E '^(0|)[0-7]{1,3}$' >/dev/null
set umask 0000
end
# Pad umask with zeros
for i in (seq (echo 5-(echo $umask|wc -c)|bc)); set -- argv 0$umask; end
for i in 2 3 4
set res $res,$letter[$i]= set res $res,$letter[$i]=
set val (echo $umask|cut -c $i) set val (echo $umask|cut -c $i)
if contains $val 4 5 6 7 if contains $val 0 1 2 3
set res {$res}r set res {$res}r
end end
if contains $val 2 3 6 7 if contains $val 0 1 4 5
set res {$res}w set res {$res}w
end end
if contains $val 1 3 5 7 if contains $val 0 2 4 6
set res {$res}x set res {$res}x
end end
@ -896,7 +956,7 @@ function umask -d "Set default file permission mask"
case 0 case 0
if not set -q umask if not set -q umask
set -g umask 664 set -g umask 113
end end
if test $as_command -eq 1 if test $as_command -eq 1
echo umask $umask echo umask $umask