Skip to content

Commit

Permalink
merge revision(s) 58146,58150,58156: [Backport #13276]
Browse files Browse the repository at this point in the history
	error.c: refactor warning messages

	* error.c (with_warning_string): extract building warning message
	  string from variadic arguments.

	* error.c (syserr_warning): write warning message with the system
	  error message.

	error.c: warning functions

	* error.c: define warning functions in all combinations of
	  * no errno, system errno, argument
	  * without/with encoding
	  * enabled/disabled by default

	dir.c: err at glob failure

	* dir.c (glob_helper): raise a SystemCallError exception when
	  opendir() failed, except for ENOENT, ENOTDIR, and EACCES.  this
	  behavior predates 1.0; the comments in glob.c claimed that
	  glob() returned -1 on error but actualy the pointer to a global
	  variable, then dir_glob() did check only -1 as the comments, and
	  ignored actual errors.  [ruby-core:80226] [Bug #13276]

	dir.c: ruby_glob_funcs_t

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_4@61367 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
  • Loading branch information
nagachika committed Dec 20, 2017
1 parent 83b2ba3 commit b20e9eb
Show file tree
Hide file tree
Showing 5 changed files with 241 additions and 84 deletions.
119 changes: 100 additions & 19 deletions dir.c
Expand Up @@ -1248,6 +1248,12 @@ to_be_ignored(int e)
#define STAT(p, s) stat((p), (s))
#endif

typedef int ruby_glob_errfunc(const char*, VALUE, const void*, int);
typedef struct {
ruby_glob_func *match;
ruby_glob_errfunc *error;
} ruby_glob_funcs_t;

/* System call with warning */
static int
do_stat(const char *path, struct stat *pst, int flags, rb_encoding *enc)
Expand All @@ -1274,7 +1280,8 @@ do_lstat(const char *path, struct stat *pst, int flags, rb_encoding *enc)
#endif

static DIR *
do_opendir(const char *path, int flags, rb_encoding *enc)
do_opendir(const char *path, int flags, rb_encoding *enc,
ruby_glob_errfunc *errfunc, VALUE arg, int *status)
{
DIR *dirp;
#ifdef _WIN32
Expand All @@ -1295,7 +1302,12 @@ do_opendir(const char *path, int flags, rb_encoding *enc)
e = errno;
/* fallback */
case 0:
*status = 0;
if (to_be_ignored(e)) break;
if (errfunc) {
*status = (*errfunc)(path, arg, enc, e);
break;
}
sys_warning(path, enc);
}
}
Expand Down Expand Up @@ -1705,6 +1717,61 @@ glob_func_caller(VALUE val)
return Qnil;
}

struct glob_error_args {
const char *path;
rb_encoding *enc;
int error;
};

static VALUE
glob_func_warning(VALUE val)
{
struct glob_error_args *arg = (struct glob_error_args *)val;
rb_syserr_enc_warning(arg->error, arg->enc, "%s", arg->path);
return Qnil;
}

#if 0
static int
rb_glob_warning(const char *path, VALUE a, const void *enc, int error)
{
int status;
struct glob_error_args args;

args.path = path;
args.enc = enc;
args.error = error;
rb_protect(glob_func_warning, (VALUE)&args, &status);
return status;
}
#endif

static VALUE
glob_func_error(VALUE val)
{
struct glob_error_args *arg = (struct glob_error_args *)val;
VALUE path = rb_enc_str_new_cstr(arg->path, arg->enc);
rb_syserr_fail_str(arg->error, path);
return Qnil;
}

static int
rb_glob_error(const char *path, VALUE a, const void *enc, int error)
{
int status;
struct glob_error_args args;
VALUE (*errfunc)(VALUE) = glob_func_error;

if (error == EACCES) {
errfunc = glob_func_warning;
}
args.path = path;
args.enc = enc;
args.error = error;
rb_protect(errfunc, (VALUE)&args, &status);
return status;
}

static inline int
dirent_match(const char *pat, rb_encoding *enc, const char *name, const struct dirent *dp, int flags)
{
Expand All @@ -1726,7 +1793,7 @@ glob_helper(
struct glob_pattern **beg,
struct glob_pattern **end,
int flags,
ruby_glob_func *func,
const ruby_glob_funcs_t *funcs,
VALUE arg,
rb_encoding *enc)
{
Expand Down Expand Up @@ -1785,13 +1852,13 @@ glob_helper(
}
}
if (match_all && pathtype > path_noent) {
status = glob_call_func(func, path, arg, enc);
status = glob_call_func(funcs->match, path, arg, enc);
if (status) return status;
}
if (match_dir && pathtype == path_directory) {
char *tmp = join_path(path, pathlen, dirsep, "", 0);
if (!tmp) return -1;
status = glob_call_func(func, tmp, arg, enc);
status = glob_call_func(funcs->match, tmp, arg, enc);
GLOB_FREE(tmp);
if (status) return status;
}
Expand All @@ -1810,20 +1877,22 @@ glob_helper(
if (cur + 1 == end && (*cur)->type <= ALPHA) {
plainname = join_path(path, pathlen, dirsep, (*cur)->str, strlen((*cur)->str));
if (!plainname) return -1;
dirp = do_opendir(plainname, flags, enc);
dirp = do_opendir(plainname, flags, enc, funcs->error, arg, &status);
GLOB_FREE(plainname);
}
else
# else
;
# endif
dirp = do_opendir(*path ? path : ".", flags, enc);
dirp = do_opendir(*path ? path : ".", flags, enc, funcs->error, arg, &status);
if (dirp == NULL) {
# if FNM_SYSCASE || NORMALIZE_UTF8PATH
if ((magical < 2) && !recursive && (errno == EACCES)) {
/* no read permission, fallback */
goto literally;
}
# endif
return 0;
return status;
}
IF_NORMALIZE_UTF8PATH(norm_p = need_normalization(dirp, *path ? path : "."));

Expand Down Expand Up @@ -1923,7 +1992,7 @@ glob_helper(

status = glob_helper(buf, name - buf + namlen, 1,
new_pathtype, new_beg, new_end,
flags, func, arg, enc);
flags, funcs, arg, enc);
GLOB_FREE(buf);
GLOB_FREE(new_beg);
if (status) break;
Expand Down Expand Up @@ -1983,11 +2052,12 @@ glob_helper(
long base = pathlen + (dirsep != 0);
buf = replace_real_basename(buf, base, enc, IF_NORMALIZE_UTF8PATH(1)+0,
flags, &new_pathtype);
if (!buf) break;
}
#endif
status = glob_helper(buf, pathlen + strlen(buf + pathlen), 1,
new_pathtype, new_beg, new_end,
flags, func, arg, enc);
flags, funcs, arg, enc);
GLOB_FREE(buf);
GLOB_FREE(new_beg);
if (status) break;
Expand All @@ -2001,7 +2071,9 @@ glob_helper(
}

static int
ruby_glob0(const char *path, int flags, ruby_glob_func *func, VALUE arg, rb_encoding *enc)
ruby_glob0(const char *path, int flags,
const ruby_glob_funcs_t *funcs, VALUE arg,
rb_encoding *enc)
{
struct glob_pattern *list;
const char *root, *start;
Expand Down Expand Up @@ -2029,7 +2101,7 @@ ruby_glob0(const char *path, int flags, ruby_glob_func *func, VALUE arg, rb_enco
return -1;
}
status = glob_helper(buf, n, 0, path_unknown, &list, &list + 1,
flags, func, arg, enc);
flags, funcs, arg, enc);
glob_free_pattern(list);
GLOB_FREE(buf);

Expand All @@ -2039,8 +2111,11 @@ ruby_glob0(const char *path, int flags, ruby_glob_func *func, VALUE arg, rb_enco
int
ruby_glob(const char *path, int flags, ruby_glob_func *func, VALUE arg)
{
return ruby_glob0(path, flags & ~GLOB_VERBOSE, func, arg,
rb_ascii8bit_encoding());
ruby_glob_funcs_t funcs;
funcs.match = func;
funcs.error = NULL;
return ruby_glob0(path, flags & ~GLOB_VERBOSE,
&funcs, arg, rb_ascii8bit_encoding());
}

static int
Expand All @@ -2054,6 +2129,10 @@ rb_glob_caller(const char *path, VALUE a, void *enc)
return status;
}

static const ruby_glob_funcs_t rb_glob_funcs = {
rb_glob_caller, rb_glob_error,
};

void
rb_glob(const char *path, void (*func)(const char *, VALUE, void *), VALUE arg)
{
Expand All @@ -2064,8 +2143,8 @@ rb_glob(const char *path, void (*func)(const char *, VALUE, void *), VALUE arg)
args.value = arg;
args.enc = rb_ascii8bit_encoding();

status = ruby_glob0(path, GLOB_VERBOSE, rb_glob_caller, (VALUE)&args,
args.enc);
status = ruby_glob0(path, GLOB_VERBOSE, &rb_glob_funcs,
(VALUE)&args, args.enc);
if (status) GLOB_JUMP_TAG(status);
}

Expand Down Expand Up @@ -2143,7 +2222,7 @@ ruby_brace_expand(const char *str, int flags, ruby_glob_func *func, VALUE arg,
}

struct brace_args {
ruby_glob_func *func;
ruby_glob_funcs_t funcs;
VALUE value;
int flags;
};
Expand All @@ -2153,7 +2232,7 @@ glob_brace(const char *path, VALUE val, void *enc)
{
struct brace_args *arg = (struct brace_args *)val;

return ruby_glob0(path, arg->flags, arg->func, arg->value, enc);
return ruby_glob0(path, arg->flags, &arg->funcs, arg->value, enc);
}

int
Expand All @@ -2162,7 +2241,8 @@ ruby_brace_glob_with_enc(const char *str, int flags, ruby_glob_func *func, VALUE
struct brace_args args;

flags &= ~GLOB_VERBOSE;
args.func = func;
args.funcs.match = func;
args.funcs.error = NULL;
args.value = arg;
args.flags = flags;
return ruby_brace_expand(str, flags, glob_brace, (VALUE)&args, enc);
Expand All @@ -2184,7 +2264,8 @@ push_caller(const char *path, VALUE val, void *enc)
{
struct push_glob_args *arg = (struct push_glob_args *)val;

return ruby_glob0(path, arg->flags, rb_glob_caller, (VALUE)&arg->glob, enc);
return ruby_glob0(path, arg->flags, &rb_glob_funcs,
(VALUE)&arg->glob, enc);
}

static int
Expand Down

0 comments on commit b20e9eb

Please sign in to comment.