function __fish_umask_parse -d "Internal umask function" # Test if already a valid octal mask, and pad it with zeros if echo $argv | __fish_sgrep -E '^0?[0-7]{1,3}$' >/dev/null set -l char_count (echo $argv| wc -c) for i in (seq (math 5 - $char_count)) set argv 0$argv end echo $argv else # Test if argument really is a valid symbolic mask if not echo $argv | __fish_sgrep -E '^(((u|g|o|a|)(=|\+|-)|)(r|w|x)*)(,(((u|g|o|a|)(=|\+|-)|)(r|w|x)*))*$' >/dev/null printf (_ "%s: Invalid mask '%s'\n") umask $argv >&2 return 1 end set -l implicit_all # Insert inverted umask into res variable set -l mode set -l val set -l tmp $umask set -l res for i in 1 2 3 set tmp (echo $tmp|cut -c 2-) set -l char_count (echo $tmp|cut -c 1) set res[$i] (math 7 - $char_count) end set -l el (echo $argv|tr , \n) for i in $el switch $i case 'u*' set idx 1 set i (echo $i| cut -c 2-) case 'g*' set idx 2 set i (echo $i| cut -c 2-) case 'o*' set idx 3 set i (echo $i| cut -c 2-) case 'a*' set idx 1 2 3 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-) case '+*' set mode add set i (echo $i| cut -c 2-) case '-*' set mode remove set i (echo $i| cut -c 2-) case '*' if not count $implicit_all >/dev/null printf (_ "%s: Invalid mask '%s'\n") umask $argv >&2 return end set mode set end if not echo $perm | __fish_sgrep -E '^(r|w|x)*$' >/dev/null printf (_ "%s: Invalid mask '%s'\n") umask $argv >&2 return end set val 0 if echo $i | __fish_sgrep 'r' >/dev/null set val 4 end if echo $i | __fish_sgrep 'w' >/dev/null set val (math $val + 2) end if echo $i | __fish_sgrep 'x' >/dev/null set val (math $val + 1) 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 end for i in 1 2 3 set res[$i] (math 7 - $res[$i]) end echo 0$res[1]$res[2]$res[3] end end function __fish_umask_print_symbolic set -l res "" set -l letter a u g o for i in 2 3 4 set res $res,$letter[$i]= set val (echo $umask|cut -c $i) if contains $val 0 1 2 3 set res {$res}r end if contains $val 0 1 4 5 set res {$res}w end if contains $val 0 2 4 6 set res {$res}x end end echo $res | cut -c 2- end function umask --description "Set default file permission mask" set -l as_command 0 set -l symbolic 0 set -l options set -l shortopt pSh if not getopt -T >/dev/null # GNU getopt set longopt -l as-command,symbolic,help set options -o $shortopt $longopt -- # Verify options if not getopt -n umask $options $argv >/dev/null return 1 end else # Old getopt, used on OS X set options $shortopt # Verify options if not getopt $options $argv >/dev/null return 1 end end set -l tmp (getopt $options $argv) eval set opt $tmp while count $opt >/dev/null switch $opt[1] case -h --help __fish_print_help umask return 0 case -p --as-command set as_command 1 case -S --symbolic set symbolic 1 case -- set -e opt[1] break end set -e opt[1] end switch (count $opt) case 0 if not set -q umask set -g umask 113 end if test $as_command -eq 1 echo umask $umask else if test $symbolic -eq 1 __fish_umask_print_symbolic $umask else echo $umask end end case 1 set -l parsed (__fish_umask_parse $opt) if test (count $parsed) -eq 1 set -g umask $parsed return 0 end return 1 case '*' printf (_ '%s: Too many arguments\n') umask >&2 end end