@@ -1901,6 +1901,8 @@ static int parse_mode(const struct bfs_parser *parser, const char *mode, struct
19011901 return 0 ;
19021902 }
19031903
1904+ mode_t umask = parser -> ctx -> umask ;
1905+
19041906 expr -> file_mode = 0 ;
19051907 expr -> dir_mode = 0 ;
19061908
@@ -1938,6 +1940,7 @@ static int parse_mode(const struct bfs_parser *parser, const char *mode, struct
19381940 } op uninit (MODE_EQUALS );
19391941
19401942 mode_t who uninit (0 );
1943+ mode_t mask uninit (0 );
19411944 mode_t file_change uninit (0 );
19421945 mode_t dir_change uninit (0 );
19431946
@@ -1946,6 +1949,7 @@ static int parse_mode(const struct bfs_parser *parser, const char *mode, struct
19461949 switch (state ) {
19471950 case MODE_CLAUSE :
19481951 who = 0 ;
1952+ mask = 0777 ;
19491953 state = MODE_WHO ;
19501954 fallthru ;
19511955
@@ -1989,6 +1993,9 @@ static int parse_mode(const struct bfs_parser *parser, const char *mode, struct
19891993 case MODE_ACTION :
19901994 if (who == 0 ) {
19911995 who = 0777 ;
1996+ mask = who & ~umask ;
1997+ } else {
1998+ mask = who ;
19921999 }
19932000
19942001 switch (* i ) {
@@ -2048,27 +2055,27 @@ static int parse_mode(const struct bfs_parser *parser, const char *mode, struct
20482055 }
20492056
20502057 file_change |= (file_change << 6 ) | (file_change << 3 );
2051- file_change &= who ;
2058+ file_change &= mask ;
20522059 dir_change |= (dir_change << 6 ) | (dir_change << 3 );
2053- dir_change &= who ;
2060+ dir_change &= mask ;
20542061 state = MODE_ACTION_APPLY ;
20552062 break ;
20562063
20572064 case MODE_PERM :
20582065 switch (* i ) {
20592066 case 'r' :
2060- file_change |= who & 0444 ;
2061- dir_change |= who & 0444 ;
2067+ file_change |= mask & 0444 ;
2068+ dir_change |= mask & 0444 ;
20622069 break ;
20632070 case 'w' :
2064- file_change |= who & 0222 ;
2065- dir_change |= who & 0222 ;
2071+ file_change |= mask & 0222 ;
2072+ dir_change |= mask & 0222 ;
20662073 break ;
20672074 case 'x' :
2068- file_change |= who & 0111 ;
2075+ file_change |= mask & 0111 ;
20692076 fallthru ;
20702077 case 'X' :
2071- dir_change |= who & 0111 ;
2078+ dir_change |= mask & 0111 ;
20722079 break ;
20732080 case 's' :
20742081 if (who & 0700 ) {
0 commit comments