diff options
Diffstat (limited to 'parse.c')
-rw-r--r-- | parse.c | 48 |
1 files changed, 41 insertions, 7 deletions
@@ -149,6 +149,21 @@ struct parser_state { }; /** + * Invoke stat() on an argument. + */ +static int stat_arg(const struct parser_state *state, struct expr *expr, struct stat *sb) { + bool follow = state->cl->flags & BFTW_FOLLOW; + int flags = follow ? 0 : AT_SYMLINK_NOFOLLOW; + + int ret = fstatat(AT_FDCWD, expr->sdata, sb, flags); + if (ret != 0) { + print_error(NULL, expr->sdata, errno); + free_expr(expr); + } + return ret; +} + +/** * Parse the expression specified on the command line. */ static struct expr *parse_expr(struct parser_state *state); @@ -344,13 +359,7 @@ static struct expr *parse_acnewer(struct parser_state *state, const char *option } struct stat sb; - - bool follow = state->cl->flags & BFTW_FOLLOW; - int flags = follow ? 0 : AT_SYMLINK_NOFOLLOW; - - if (fstatat(AT_FDCWD, expr->sdata, &sb, flags) != 0) { - print_error(NULL, expr->sdata, errno); - free_expr(expr); + if (stat_arg(state, expr, &sb) != 0) { return NULL; } @@ -409,6 +418,26 @@ static struct expr *parse_depth(struct parser_state *state, const char *option, } /** + * Parse -samefile FILE. + */ +static struct expr *parse_samefile(struct parser_state *state, const char *option) { + struct expr *expr = parse_test_sdata(state, option, eval_samefile); + if (!expr) { + return NULL; + } + + struct stat sb; + if (stat_arg(state, expr, &sb) != 0) { + return NULL; + } + + expr->dev = sb.st_dev; + expr->ino = sb.st_ino; + + return expr; +} + +/** * Parse -type [bcdpfls]. */ static struct expr *parse_type(struct parser_state *state) { @@ -619,6 +648,11 @@ static struct expr *parse_literal(struct parser_state *state) { } break; + case 's': + if (strcmp(arg, "-samefile") == 0) { + return parse_samefile(state, arg); + } + case 't': if (strcmp(arg, "-true") == 0) { return &expr_true; |