14#define dln_warning(...) rb_warning(__VA_ARGS__)
16#define dln_warning(...) fprintf(stderr, __VA_ARGS__)
24#if defined(HAVE_ALLOCA_H)
36#include "missing/file.h"
42# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
49#if !defined(_WIN32) && !HAVE_DECL_GETENV
53static char *dln_find_1(
const char *fname,
const char *path,
char *buf,
size_t size,
int exe_flag
54 DLN_FIND_EXTRA_ARG_DECL);
57dln_find_exe_r(
const char *fname,
const char *path,
char *buf,
size_t size
58 DLN_FIND_EXTRA_ARG_DECL)
64 if (path) path = envpath =
strdup(path);
75 buf = dln_find_1(fname, path, buf, size, 1 DLN_FIND_EXTRA_ARG);
81dln_find_file_r(
const char *fname,
const char *path,
char *buf,
size_t size
82 DLN_FIND_EXTRA_ARG_DECL)
84 if (!path) path =
".";
85 return dln_find_1(fname, path, buf, size, 0 DLN_FIND_EXTRA_ARG);
89dln_find_1(
const char *fname,
const char *path,
char *fbuf,
size_t size,
91 DLN_FIND_EXTRA_ARG_DECL)
93 register const char *dp;
94 register const char *ep;
97 size_t i, fnlen, fspace;
99 static const char extension[][5] = {
103 int is_abs = 0, has_path = 0;
106 const char *p = fname;
108 static const char pathname_too_long[] =
"openpath: pathname too long (ignored)\n\
109\tDirectory \"%.*s\"%s\n\tFile \"%.*s\"%s\n";
110#define PATHNAME_TOO_LONG() dln_warning(pathname_too_long, \
111 ((bp - fbuf) > 100 ? 100 : (int)(bp - fbuf)), fbuf, \
112 ((bp - fbuf) > 100 ? "..." : ""), \
113 (fnlen > 100 ? 100 : (int)fnlen), fname, \
114 (fnlen > 100 ? "..." : ""))
116#define RETURN_IF(expr) if (expr) return (char *)fname;
119 fnlen = strlen(fname);
121 dln_warning(
"openpath: pathname too long (ignored)\n\tFile \"%.*s\"%s\n",
122 (fnlen > 100 ? 100 : (int)fnlen), fname,
123 (fnlen > 100 ?
"..." :
""));
128# define CharNext(p) ((p)+1)
130# ifdef DOSISH_DRIVE_LETTER
131 if (((p[0] | 0x20) -
'a') < 26 && p[1] ==
':') {
158 for (j = 0;
STRCASECMP(ext, extension[j]); ) {
159 if (++j ==
sizeof(extension) /
sizeof(extension[0])) {
172 if (i + 1 > size)
goto toolong;
173 fspace = size - i - 1;
176 memcpy(fbuf, fname, i + 1);
177 goto needs_extension;
182 if (*p ==
'.' && *++p ==
'.') ++p;
183 RETURN_IF(*p ==
'/');
184 RETURN_IF(exe_flag && strchr(fname,
'/'));
188 for (dp = path;; dp = ++ep) {
209 if (*dp ==
'~' && (l == 1 ||
216 home = getenv(
"HOME");
247 memcpy(bp, fname, i + 1);
250 if (exe_flag && !ext) {
251 goto needs_extension;
256# define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
258 if (stat(fbuf, &st) == 0 && S_ISREG(st.st_mode)) {
259 if (exe_flag == 0)
return fbuf;
261 if (eaccess(fbuf, X_OK) == 0)
return fbuf;
276 for (j = 0; j <
sizeof(extension) /
sizeof(extension[0]); j++) {
277 if (fspace < strlen(extension[j])) {
281 strlcpy(bp + i, extension[j], fspace);
282 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.