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 \
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/prevd.txt doc_src/pushd.txt doc_src/set_color.txt \
doc_src/tokenize.txt doc_src/type.txt
doc_src/prevd.txt doc_src/psub.txt doc_src/pushd.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)

View File

@ -7,15 +7,23 @@
\subsection umask-description Description
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>-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
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
<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 <pwd.h>
#if HAVE_NCURSES_H
#include <ncurses.h>
#else
@ -27,6 +26,7 @@
#endif
#include <term.h>
#include <errno.h>
#include "util.h"
#include "wutil.h"
@ -385,6 +385,24 @@ void env_set( const wchar_t *key,
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
*/

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"
/**
Default value for the umask
*/
#define UMASK_DEFAULT 0664
/**
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;
/**
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 )
{
@ -313,7 +279,7 @@ static void handle_child_io( io_data_t *io )
break;
case IO_FILE:
if( (tmp=wopen( io->param1.filename,
io->param2.flags, umask_val ))==-1 )
io->param2.flags, 0777 ) )==-1 )
{
debug( 1,
FILE_ERROR,
@ -516,7 +482,7 @@ static io_data_t *io_transmogrify( io_data_t * in )
{
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,
FILE_ERROR,
@ -678,8 +644,6 @@ void exec( job_t *j )
int exec_error=0;
umask_val = get_umask();
debug( 4, L"Exec job %ls with id %d", j->command, j->job_id );
if( j->first_process->type==INTERNAL_EXEC )
@ -890,7 +854,7 @@ void exec( job_t *j )
in->filename);
*/
builtin_stdin=wopen( in->param1.filename,
in->param2.flags, umask_val );
in->param2.flags, 0777 );
if( builtin_stdin == -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'
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;
complete -c help -x -a $i -d 'Help section on '$i
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
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
end
@ -755,48 +755,82 @@ echo
end
function __fish_umask_parse -d "Parses a file permission specification as into an octal version"
# Test if already a valid octal mask
if echo $argv | grep -E '^[0-7]{1,4}$' >/dev/null
# Test if already a valid octal mask, and pad it with zeros
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
else
set res 0 0 0
set el (echo $argv|tr , \n)
# Test if argument really is a valid symbolic mask
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
switch $i
case 'u*'
set idx 1
set i (echo $i| cut -c 2-)
set -- i (echo $i| cut -c 2-)
case 'g*'
set idx 2
set i (echo $i| cut -c 2-)
set -- i (echo $i| cut -c 2-)
case 'o*'
set idx 3
set i (echo $i| cut -c 2-)
set -- i (echo $i| cut -c 2-)
case 'a*'
set idx 1 2 3
set i (echo $i| cut -c 2-)
set -- i (echo $i| cut -c 2-)
case '*'
set implicit_all 1
set idx 1 2 3
end
switch $i
case '=*'
set mode set
set i (echo $i| cut -c 2-)
set -- i (echo $i| cut -c 2-)
case '+*'
set mode add
set i (echo $i| cut -c 2-)
set -- i (echo $i| cut -c 2-)
case '-*'
set mode remove
set i (echo $i| cut -c 2-)
set -- i (echo $i| cut -c 2-)
case '*'
if not set -q implicit_all
echo umask: Invalid mask $argv >&2
return
end
set mode set
end
@ -806,41 +840,67 @@ function __fish_umask_parse -d "Parses a file permission specification as into a
end
set val 0
if echo $perm |grep 'r' >/dev/null
if echo $i |grep 'r' >/dev/null
set val 4
end
if echo $perm |grep 'w' >/dev/null
if echo $i |grep 'w' >/dev/null
set val (echo $val + 2|bc)
end
if echo $perm |grep 'x' >/dev/null
if echo $i |grep 'x' >/dev/null
set val (echo $val + 1|bc)
end
for j in $idx
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
echo $res[1]$res[2]$res[3]
end
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
function __fish_umask_print_symbolic
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 val (echo $umask|cut -c $i)
if contains $val 4 5 6 7
if contains $val 0 1 2 3
set res {$res}r
end
if contains $val 2 3 6 7
if contains $val 0 1 4 5
set res {$res}w
end
if contains $val 1 3 5 7
if contains $val 0 2 4 6
set res {$res}x
end
@ -896,7 +956,7 @@ function umask -d "Set default file permission mask"
case 0
if not set -q umask
set -g umask 664
set -g umask 113
end
if test $as_command -eq 1
echo umask $umask