Try to append executable suffixes if not having extension on OS/2
This commit is contained in:
parent
8f633da789
commit
5ed2481df2
1
Build.sh
1
Build.sh
@ -833,6 +833,7 @@ OpenBSD)
|
||||
OS/2)
|
||||
: ${CC=gcc}
|
||||
: ${SIZE=echo ignore size}
|
||||
SRCS="$SRCS os2.c"
|
||||
;;
|
||||
OSF1)
|
||||
HAVE_SIG_T=0 # incompatible
|
||||
|
13
exec.c
13
exec.c
@ -1239,6 +1239,13 @@ search_access(const char *fn, int mode)
|
||||
return (0);
|
||||
}
|
||||
|
||||
#ifdef __OS2__
|
||||
/* check if path is something we want to find, adding executable extensions */
|
||||
#define search_access(fn, mode) access_ex((search_access), (fn), (mode))
|
||||
#else
|
||||
#define search_access(fn, mode) (search_access)((fn), (mode))
|
||||
#endif
|
||||
|
||||
/*
|
||||
* search for command with PATH
|
||||
*/
|
||||
@ -1260,7 +1267,11 @@ search_path(const char *name, const char *lpath,
|
||||
search_path_ok:
|
||||
if (errnop)
|
||||
*errnop = 0;
|
||||
return (name);
|
||||
#ifndef __OS2__
|
||||
return name;
|
||||
#else
|
||||
return real_exec_name(name);
|
||||
#endif
|
||||
}
|
||||
goto search_path_err;
|
||||
}
|
||||
|
134
os2.c
Normal file
134
os2.c
Normal file
@ -0,0 +1,134 @@
|
||||
/*-
|
||||
* Copyright (c) 2015
|
||||
* KO Myung-Hun <komh@chollian.net>
|
||||
*
|
||||
* Provided that these terms and disclaimer and all copyright notices
|
||||
* are retained or reproduced in an accompanying document, permission
|
||||
* is granted to deal in this work without restriction, including un-
|
||||
* limited rights to use, publicly perform, distribute, sell, modify,
|
||||
* merge, give away, or sublicence.
|
||||
*
|
||||
* This work is provided "AS IS" and WITHOUT WARRANTY of any kind, to
|
||||
* the utmost extent permitted by applicable law, neither express nor
|
||||
* implied; without malicious intent or gross negligence. In no event
|
||||
* may a licensor, author or contributor be held liable for indirect,
|
||||
* direct, other damage, loss, or other issues arising in any way out
|
||||
* of dealing in the work, even if advised of the possibility of such
|
||||
* damage or existence of a defect, except proven that it results out
|
||||
* of said person's immediate fault when using the work as intended.
|
||||
*/
|
||||
|
||||
#include "sh.h"
|
||||
|
||||
static char *remove_trailing_dots(char *);
|
||||
static int access_stat_ex(int (*)(), const char *, void *);
|
||||
static int test_exec_exist(const char *, char *);
|
||||
|
||||
/* Remove trailing dots. */
|
||||
static char *
|
||||
remove_trailing_dots(char *name)
|
||||
{
|
||||
char *p;
|
||||
|
||||
for (p = name + strlen(name); --p > name && *p == '.'; )
|
||||
/* nothing */;
|
||||
|
||||
if (*p != '.' && *p != '/' && *p != '\\' && *p != ':')
|
||||
p[1] = '\0';
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
#define REMOVE_TRAILING_DOTS(name) \
|
||||
remove_trailing_dots(strcpy(alloca(strlen(name) + 1), name))
|
||||
|
||||
/* Alias of stat() */
|
||||
int _std_stat(const char *, struct stat *);
|
||||
|
||||
/* Replacement for stat() of kLIBC which fails if there are trailing dots */
|
||||
int
|
||||
stat(const char *name, struct stat *buffer)
|
||||
{
|
||||
return _std_stat(REMOVE_TRAILING_DOTS(name), buffer);
|
||||
}
|
||||
|
||||
/* Alias of access() */
|
||||
int _std_access(const char *, int);
|
||||
|
||||
/* Replacement for access() of kLIBC which fails if there are trailing dots */
|
||||
int
|
||||
access(const char *name, int mode)
|
||||
{
|
||||
/*
|
||||
* On OS/2 kLIBC, X_OK is set only for executable files. This prevent
|
||||
* scripts from being executed.
|
||||
*/
|
||||
if (mode & X_OK)
|
||||
mode = (mode & ~X_OK) | R_OK;
|
||||
|
||||
return _std_access(REMOVE_TRAILING_DOTS(name), mode);
|
||||
}
|
||||
|
||||
#define MAX_X_SUFFIX_LEN 4
|
||||
|
||||
static const char *x_suffix_list[] =
|
||||
{"", ".ksh", ".exe", ".sh", ".cmd", ".com", ".bat", NULL};
|
||||
|
||||
/* Call fn() by appending executable extensions. */
|
||||
static int
|
||||
access_stat_ex(int (*fn)(), const char *name, void *arg)
|
||||
{
|
||||
char *x_name;
|
||||
const char **x_suffix;
|
||||
int rc = -1;
|
||||
|
||||
/* Have an extension ? */
|
||||
if (_getext(name))
|
||||
return fn(name, arg);
|
||||
|
||||
/* Otherwise, try to append executable suffixes */
|
||||
x_name = alloc(strlen(name) + MAX_X_SUFFIX_LEN + 1, ATEMP);
|
||||
|
||||
for (x_suffix = x_suffix_list; rc && *x_suffix; x_suffix++) {
|
||||
strcpy(x_name, name);
|
||||
strcat(x_name, *x_suffix);
|
||||
|
||||
rc = fn(x_name, arg);
|
||||
}
|
||||
|
||||
afree(x_name, ATEMP);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* access()/search_access() version */
|
||||
int
|
||||
access_ex(int (*fn)(const char *, int), const char *name, int mode)
|
||||
{
|
||||
return access_stat_ex(fn, name, (void *)mode);
|
||||
}
|
||||
|
||||
static int
|
||||
test_exec_exist(const char *name, char *real_name)
|
||||
{
|
||||
struct stat sb;
|
||||
|
||||
if (stat(name, &sb) < 0 || !S_ISREG(sb.st_mode))
|
||||
return -1;
|
||||
|
||||
strcpy(real_name, name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *
|
||||
real_exec_name(const char *name)
|
||||
{
|
||||
char x_name[strlen(name) + MAX_X_SUFFIX_LEN + 1];
|
||||
const char *real_name = name;
|
||||
|
||||
if (access_stat_ex(test_exec_exist, real_name, x_name) != -1)
|
||||
strdupx(real_name, x_name, ATEMP);
|
||||
|
||||
return real_name;
|
||||
}
|
5
sh.h
5
sh.h
@ -1920,6 +1920,11 @@ char *strdup_i(const char *, Area *);
|
||||
char *strndup_i(const char *, size_t, Area *);
|
||||
#endif
|
||||
int unbksl(bool, int (*)(void), void (*)(int));
|
||||
#ifdef __OS2__
|
||||
/* os2.c */
|
||||
int access_ex(int (*)(const char *, int), const char *, int);
|
||||
const char *real_exec_name(const char *);
|
||||
#endif
|
||||
/* shf.c */
|
||||
struct shf *shf_open(const char *, int, int, int);
|
||||
struct shf *shf_fdopen(int, int, struct shf *);
|
||||
|
Loading…
Reference in New Issue
Block a user