14#define dln_warning rb_warning
15#define dln_warning_arg
17#define dln_warning fprintf
18#define dln_warning_arg stderr,
26#if defined(HAVE_ALLOCA_H)
38#include "missing/file.h"
44# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
51#if !defined(_WIN32) && !HAVE_DECL_GETENV
55static char *dln_find_1(
const char *fname,
const char *path,
char *buf,
size_t size,
int exe_flag
56 DLN_FIND_EXTRA_ARG_DECL);
59dln_find_exe_r(
const char *fname,
const char *path,
char *buf,
size_t size
60 DLN_FIND_EXTRA_ARG_DECL)
66 if (path) path = envpath =
strdup(path);
77 buf = dln_find_1(fname, path, buf, size, 1 DLN_FIND_EXTRA_ARG);
83dln_find_file_r(
const char *fname,
const char *path,
char *buf,
size_t size
84 DLN_FIND_EXTRA_ARG_DECL)
86 if (!path) path =
".";
87 return dln_find_1(fname, path, buf, size, 0 DLN_FIND_EXTRA_ARG);
91dln_find_1(
const char *fname,
const char *path,
char *fbuf,
size_t size,
93 DLN_FIND_EXTRA_ARG_DECL)
95 register const char *dp;
96 register const char *ep;
99 size_t i, fnlen, fspace;
101 static const char extension[][5] = {
105 int is_abs = 0, has_path = 0;
108 const char *p = fname;
110 static const char pathname_too_long[] =
"openpath: pathname too long (ignored)\n\
111\tDirectory \"%.*s\"%s\n\tFile \"%.*s\"%s\n";
112#define PATHNAME_TOO_LONG() dln_warning(dln_warning_arg pathname_too_long, \
113 ((bp - fbuf) > 100 ? 100 : (int)(bp - fbuf)), fbuf, \
114 ((bp - fbuf) > 100 ? "..." : ""), \
115 (fnlen > 100 ? 100 : (int)fnlen), fname, \
116 (fnlen > 100 ? "..." : ""))
118#define RETURN_IF(expr) if (expr) return (char *)fname;
121 fnlen = strlen(fname);
123 dln_warning(dln_warning_arg
124 "openpath: pathname too long (ignored)\n\tFile \"%.*s\"%s\n",
125 (fnlen > 100 ? 100 : (int)fnlen), fname,
126 (fnlen > 100 ?
"..." :
""));
131# define CharNext(p) ((p)+1)
133# ifdef DOSISH_DRIVE_LETTER
134 if (((p[0] | 0x20) -
'a') < 26 && p[1] ==
':') {
161 for (j = 0;
STRCASECMP(ext, extension[j]); ) {
162 if (++j ==
sizeof(extension) /
sizeof(extension[0])) {
175 if (i + 1 > size)
goto toolong;
176 fspace = size - i - 1;
179 memcpy(fbuf, fname, i + 1);
180 goto needs_extension;
185 if (*p ==
'.' && *++p ==
'.') ++p;
186 RETURN_IF(*p ==
'/');
187 RETURN_IF(exe_flag && strchr(fname,
'/'));
191 for (dp = path;; dp = ++ep) {
212 if (*dp ==
'~' && (l == 1 ||
219 home = getenv(
"HOME");
250 memcpy(bp, fname, i + 1);
253 if (exe_flag && !ext) {
254 goto needs_extension;
259# define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
261 if (stat(fbuf, &st) == 0 && S_ISREG(st.st_mode)) {
262 if (exe_flag == 0)
return fbuf;
264 if (eaccess(fbuf, X_OK) == 0)
return fbuf;
279 for (j = 0; j <
sizeof(extension) /
sizeof(extension[0]); j++) {
280 if (fspace < strlen(extension[j])) {
284 strlcpy(bp + i, extension[j], fspace);
285 if (stat(fbuf, &st) == 0)
#define PATH_SEP
The delimiter of PATH environment variable.
#define STRCASECMP
Old name of st_locale_insensitive_strcasecmp.
#define strdup(s)
Just another name of ruby_strdup.