YAP should not try to control cwd, that's the OS task
This commit is contained in:
parent
6c9c410283
commit
666b68c1fb
703
C/sysbits.c
703
C/sysbits.c
@ -35,9 +35,13 @@ static char SccsId[] = "%W% %G%";
|
|||||||
|
|
||||||
/* windows.h does not like absmi.h, this
|
/* windows.h does not like absmi.h, this
|
||||||
should fix it for now */
|
should fix it for now */
|
||||||
|
#if _WIN32 || __MINGW32__
|
||||||
|
#include <winsock2.h>
|
||||||
|
#endif
|
||||||
#include "absmi.h"
|
#include "absmi.h"
|
||||||
#include "yapio.h"
|
#include "yapio.h"
|
||||||
#include "alloc.h"
|
#include "alloc.h"
|
||||||
|
#include "pl-incl.h"
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#if STDC_HEADERS
|
#if STDC_HEADERS
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -83,6 +87,7 @@ static char SccsId[] = "%W% %G%";
|
|||||||
#include <direct.h>
|
#include <direct.h>
|
||||||
#endif
|
#endif
|
||||||
#include <io.h>
|
#include <io.h>
|
||||||
|
#include <shlwapi.h>
|
||||||
#else
|
#else
|
||||||
#if HAVE_SYS_PARAM_H
|
#if HAVE_SYS_PARAM_H
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
@ -92,10 +97,31 @@ static char SccsId[] = "%W% %G%";
|
|||||||
#if HAVE_FENV_H && !defined(__CYGWIN__)
|
#if HAVE_FENV_H && !defined(__CYGWIN__)
|
||||||
#include <fenv.h>
|
#include <fenv.h>
|
||||||
#endif
|
#endif
|
||||||
|
#if HAVE_WORDEXP_H
|
||||||
|
#include <wordexp.h>
|
||||||
|
#endif
|
||||||
|
#if HAVE_LIBGEN_H
|
||||||
|
#include <libgen.h>
|
||||||
|
#endif
|
||||||
#if HAVE_READLINE_READLINE_H
|
#if HAVE_READLINE_READLINE_H
|
||||||
#include <readline/readline.h>
|
#include <readline/readline.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static void
|
||||||
|
Yap_FileError(yap_error_number type, Term where, const char *format,...)
|
||||||
|
{
|
||||||
|
GET_LD
|
||||||
|
if ( truePrologFlag(PLFLAG_FILEERRORS) ) {
|
||||||
|
va_list ap;
|
||||||
|
|
||||||
|
va_start (ap, format);
|
||||||
|
/* now build the error string */
|
||||||
|
Yap_Error(type, TermNil, format, ap);
|
||||||
|
va_end (ap);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void InitTime(int);
|
static void InitTime(int);
|
||||||
static void InitWTime(void);
|
static void InitWTime(void);
|
||||||
@ -146,7 +172,7 @@ Yap_WinError(char *yap_error)
|
|||||||
NULL, GetLastError(),
|
NULL, GetLastError(),
|
||||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), msg, 256,
|
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), msg, 256,
|
||||||
NULL);
|
NULL);
|
||||||
Yap_Error(OPERATING_SYSTEM_ERROR, TermNil, "%s at %s", msg, yap_error);
|
Yap_Error(OPERATING_SYSTEM_ERROR, TermNil, "%s at %s", msg, yap_error);
|
||||||
}
|
}
|
||||||
#endif /* __WINDOWS__ */
|
#endif /* __WINDOWS__ */
|
||||||
|
|
||||||
@ -155,65 +181,57 @@ Yap_WinError(char *yap_error)
|
|||||||
(C) <= 'Z') || (C) == '_' )
|
(C) <= 'Z') || (C) == '_' )
|
||||||
|
|
||||||
|
|
||||||
static int
|
/// is_directory: verifies whether an expanded file name
|
||||||
|
/// points at a readable directory
|
||||||
|
static bool
|
||||||
is_directory(const char *FileName)
|
is_directory(const char *FileName)
|
||||||
{
|
{
|
||||||
#ifdef __WINDOWS__
|
#ifdef __WINDOWS__
|
||||||
char s[YAP_FILENAME_MAX+1];
|
DWORD dwAtts = GetFileAttributes( FileName );
|
||||||
char *s0 = (char *)FileName;
|
|
||||||
char *s1 = s;
|
|
||||||
int ch;
|
|
||||||
|
|
||||||
// win32 syntax
|
|
||||||
if (s0[0] == '/' && s0[1] == '/' && isalpha(s0[2]) && s0[3] == '/')
|
|
||||||
{
|
|
||||||
s1[0] = s0[2];
|
|
||||||
s1[1] = ':';
|
|
||||||
s1[2] = '\\';
|
|
||||||
s0+=4;
|
|
||||||
s1+=3;
|
|
||||||
}
|
|
||||||
while ((ch = *s1++ = *s0++)) {
|
|
||||||
if (ch == '$') {
|
|
||||||
s1[-1] = '%';
|
|
||||||
ch = *s0;
|
|
||||||
// handle $(....)
|
|
||||||
if (ch == '{') {
|
|
||||||
s0++;
|
|
||||||
while ((ch = *s0++) != '}') {
|
|
||||||
*s1++ = ch;
|
|
||||||
if (ch == '\0') return FALSE;
|
|
||||||
}
|
|
||||||
*s1++ = '%';
|
|
||||||
} else {
|
|
||||||
while (((ch = *s1++ = *s0++) >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || (ch == '-') || (ch >= '0' && ch <= '9') || (ch == '_'));
|
|
||||||
s1[-1] = '%';
|
|
||||||
*s1++ = ch;
|
|
||||||
if (ch == '\0') { s1--; s0--; }
|
|
||||||
}
|
|
||||||
} else if (ch == '/')
|
|
||||||
s1[-1] = '\\';
|
|
||||||
}
|
|
||||||
if (ExpandEnvironmentStrings(s, (LPSTR)FileName, YAP_FILENAME_MAX) == 0)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
DWORD dwAtts = GetFileAttributes( FileName );
|
|
||||||
if (dwAtts == INVALID_FILE_ATTRIBUTES)
|
if (dwAtts == INVALID_FILE_ATTRIBUTES)
|
||||||
return FALSE;
|
return false;
|
||||||
return (dwAtts & FILE_ATTRIBUTE_DIRECTORY);
|
return (dwAtts & FILE_ATTRIBUTE_DIRECTORY);
|
||||||
#elif HAVE_LSTAT
|
#elif HAVE_LSTAT
|
||||||
struct stat buf;
|
struct stat buf;
|
||||||
|
|
||||||
if (lstat(FileName, &buf) == -1) {
|
if (lstat(FileName, &buf) == -1) {
|
||||||
/* return an error number */
|
/* return an error number */
|
||||||
return FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
return S_ISDIR(buf.st_mode);
|
return S_ISDIR(buf.st_mode);
|
||||||
#else
|
#else
|
||||||
return FALSE;
|
Yap_Error(SYSTEM_ERROR, TermNil,
|
||||||
|
"stat not available in this configuration");
|
||||||
|
return false;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// has_access just calls access
|
||||||
|
/// it uses F_OK, R_OK and friend
|
||||||
|
static bool
|
||||||
|
has_access(const char *FileName, int mode)
|
||||||
|
{
|
||||||
|
#if HAS_ACCESS
|
||||||
|
if (access( FileName, mode ) == 0)
|
||||||
|
return true;
|
||||||
|
if (errno == EINVAL) {
|
||||||
|
Yap_Error(SYSTEM_ERROR, TermNil,
|
||||||
|
"bad flags to access");
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
#else
|
||||||
|
Yap_Error(SYSTEM_ERROR, TermNil,
|
||||||
|
"access not available in this configuration");
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
exists( const char *f)
|
||||||
|
{
|
||||||
|
return has_access( f, F_OK );
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
dir_separator (int ch)
|
dir_separator (int ch)
|
||||||
{
|
{
|
||||||
@ -240,7 +258,327 @@ is_directory(const char *FileName)
|
|||||||
char *libdir = NULL;
|
char *libdir = NULL;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static Int
|
|
||||||
|
int
|
||||||
|
IsAbsolutePath(const char *p)
|
||||||
|
{
|
||||||
|
#if _WIN32 || __MINGW32__
|
||||||
|
return !PathIsRelative(p);
|
||||||
|
#else
|
||||||
|
return p[0] == '/';
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
expandVars(const char *pattern, char *expanded, int maxlen)
|
||||||
|
{
|
||||||
|
#if __WIN32 || __MINGW32__
|
||||||
|
DWORD retval=0;
|
||||||
|
// notice that the file does not need to exist1
|
||||||
|
retval = ExpandEnvironmentStrings(pattern,
|
||||||
|
expanded,
|
||||||
|
maxlen);
|
||||||
|
|
||||||
|
if (retval == 0)
|
||||||
|
{
|
||||||
|
Yap_WinError("Generating a full path name for a file" );
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return expanded;
|
||||||
|
#elif HAVE_WORDEXP
|
||||||
|
wordexp_t result;
|
||||||
|
|
||||||
|
/* Expand the string for the program to run. */
|
||||||
|
switch (wordexp (pattern, &result, 0))
|
||||||
|
{
|
||||||
|
case 0: /* Successful. */
|
||||||
|
if (result.we_wordv[1]) {
|
||||||
|
wordfree (&result);
|
||||||
|
return NULL;
|
||||||
|
} else {
|
||||||
|
char *w = result.we_wordv[0];
|
||||||
|
strncpy( expanded, w, maxlen );
|
||||||
|
wordfree (&result);
|
||||||
|
return expanded;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case WRDE_NOSPACE:
|
||||||
|
/* If the error was WRDE_NOSPACE,
|
||||||
|
then perhaps part of the result was allocated. */
|
||||||
|
wordfree (&result);
|
||||||
|
default: /* Some other error. */
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if _WIN32 || defined(__MINGW32__)
|
||||||
|
// straightforward conversion from Unix style to WIN style
|
||||||
|
// check cygwin path.cc for possible improvements
|
||||||
|
static char *
|
||||||
|
unix2win( const char *source, char *target, int max)
|
||||||
|
{
|
||||||
|
char *s = target;
|
||||||
|
const char *s0 = source;
|
||||||
|
char *s1;
|
||||||
|
int ch;
|
||||||
|
|
||||||
|
if (s == NULL)
|
||||||
|
s = malloc(YAP_FILENAME_MAX+1);
|
||||||
|
s1 = s;
|
||||||
|
// win32 syntax
|
||||||
|
// handle drive notation, eg //a/
|
||||||
|
if (s0[0] == '\0') {
|
||||||
|
s[0] = '.';
|
||||||
|
s[1] = '\0';
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
if (s0[0] == '/' && s0[1] == '/' && isalpha(s0[2]) && s0[3] == '/')
|
||||||
|
{
|
||||||
|
s1[0] = s0[2];
|
||||||
|
s1[1] = ':';
|
||||||
|
s1[2] = '\\';
|
||||||
|
s0+=4;
|
||||||
|
s1+=3;
|
||||||
|
}
|
||||||
|
while ((ch = *s1++ = *s0++)) {
|
||||||
|
if (ch == '$') {
|
||||||
|
s1[-1] = '%';
|
||||||
|
ch = *s0;
|
||||||
|
// handle $(....)
|
||||||
|
if (ch == '{') {
|
||||||
|
s0++;
|
||||||
|
while ((ch = *s0++) != '}') {
|
||||||
|
*s1++ = ch;
|
||||||
|
if (ch == '\0') return FALSE;
|
||||||
|
}
|
||||||
|
*s1++ = '%';
|
||||||
|
} else {
|
||||||
|
while (((ch = *s1++ = *s0++) >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || (ch == '-') || (ch >= '0' && ch <= '9') || (ch == '_'));
|
||||||
|
s1[-1] = '%';
|
||||||
|
*s1++ = ch;
|
||||||
|
if (ch == '\0') { s1--; s0--; }
|
||||||
|
}
|
||||||
|
} else if (ch == '/')
|
||||||
|
s1[-1] = '\\';
|
||||||
|
}
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if O_XOS
|
||||||
|
char *
|
||||||
|
PrologPath(const char *p, char *buf, size_t len)
|
||||||
|
{ GET_LD
|
||||||
|
int flags = (truePrologFlag(PLFLAG_FILE_CASE) ? 0 : XOS_DOWNCASE);
|
||||||
|
|
||||||
|
return _xos_canonical_filename(p, buf, len, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
OsPath(const char *p, char *buf)
|
||||||
|
{ strcpy(buf, p);
|
||||||
|
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
char *
|
||||||
|
OsPath(const char *X, char *Y) {
|
||||||
|
if (X!=Y && Y) strcpy(Y,X);
|
||||||
|
return Y;
|
||||||
|
}
|
||||||
|
#endif /* O_XOS */
|
||||||
|
|
||||||
|
#if _WIN32
|
||||||
|
#define HAVE_BASENAME 1
|
||||||
|
#define HAVE_REALPATH 1
|
||||||
|
#define HAVE_WORDEXP 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
bool ChDir(const char *path) {
|
||||||
|
bool rc = false;
|
||||||
|
char *qpath = AbsoluteFile(path, NULL);
|
||||||
|
|
||||||
|
#if _WIN32 || defined(__MINGW32__)
|
||||||
|
GET_LD
|
||||||
|
if ((rc = (SetCurrentDirectory(qpath) != 0)) == 0)
|
||||||
|
{
|
||||||
|
Yap_WinError("SetCurrentDirectory failed" );
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
rc = (chdir(qpath) == 0);
|
||||||
|
#endif
|
||||||
|
free( qpath );
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
#if _WIN32 || defined(__MINGW32__)
|
||||||
|
char *
|
||||||
|
BaseName(const char *X) {
|
||||||
|
char *qpath = unix2win(X, NULL, YAP_FILENAME_MAX);
|
||||||
|
char base[YAP_FILENAME_MAX], ext[YAP_FILENAME_MAX];
|
||||||
|
_splitpath(qpath, NULL, NULL, base, ext);
|
||||||
|
strcpy(qpath, base);
|
||||||
|
strcat(qpath, ext);
|
||||||
|
return qpath;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
DirName(const char *X) {
|
||||||
|
char dir[YAP_FILENAME_MAX];
|
||||||
|
char drive[YAP_FILENAME_MAX];
|
||||||
|
char *o = unix2win(X, NULL, YAP_FILENAME_MAX);
|
||||||
|
int err;
|
||||||
|
if (!o)
|
||||||
|
return NULL;
|
||||||
|
if (( err = _splitpath_s(o, drive, YAP_FILENAME_MAX-1, dir, YAP_FILENAME_MAX-1,NULL, 0, NULL, 0) ) != 0) {
|
||||||
|
Yap_FileError(OPERATING_SYSTEM_ERROR, TermNil, "could not perform _splitpath %s: %s", X, strerror(errno));
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
}
|
||||||
|
strncpy(o, drive, YAP_FILENAME_MAX-1);
|
||||||
|
strncat(o, dir, YAP_FILENAME_MAX-1);
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static char *myrealpath( const char *path, char *out)
|
||||||
|
{
|
||||||
|
#if _WIN32 || defined(__MINGW32__)
|
||||||
|
DWORD retval=0;
|
||||||
|
// notice that the file does not need to exist
|
||||||
|
retval = GetFullPathName(path,
|
||||||
|
YAP_FILENAME_MAX,
|
||||||
|
out,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
if (retval == 0)
|
||||||
|
{
|
||||||
|
Yap_WinError("Generating a full path name for a file" );
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
#elif HAVE_REALPATH
|
||||||
|
{
|
||||||
|
char *rc = realpath(path,out);
|
||||||
|
char *s0;
|
||||||
|
|
||||||
|
if (rc == NULL && (errno == ENOENT|| errno == EACCES)) {
|
||||||
|
char *s = basename((char *)path);
|
||||||
|
s0 = malloc(strlen(s)+1);
|
||||||
|
strcpy(s0, s);
|
||||||
|
if ((rc = myrealpath(dirname((char *)path), out))==NULL) {
|
||||||
|
Yap_FileError(OPERATING_SYSTEM_ERROR, TermNil, "could not find file %s: %s", path, strerror(errno));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if(rc[strlen(rc)-1] != '/' )
|
||||||
|
strcat(rc, "/");
|
||||||
|
strcat(rc, s0);
|
||||||
|
free(s0);
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
return NULL;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
AbsoluteFile(const char *spec, char *tmp)
|
||||||
|
{
|
||||||
|
GET_LD
|
||||||
|
char *rc;
|
||||||
|
char *qpath0;
|
||||||
|
|
||||||
|
#if _WIN32 || defined(__MINGW32__)
|
||||||
|
char *o = malloc(YAP_FILENAME_MAX+1);
|
||||||
|
if (!o)
|
||||||
|
return NULL;
|
||||||
|
// first pass, remove Unix style stuff
|
||||||
|
if (unix2win(spec, o, YAP_FILENAME_MAX) == NULL)
|
||||||
|
return NULL;
|
||||||
|
spec = (const char *)o;
|
||||||
|
#endif
|
||||||
|
if (tmp == NULL) {
|
||||||
|
tmp = malloc(YAP_FILENAME_MAX+1);
|
||||||
|
if (tmp == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( truePrologFlag(PLFLAG_FILEVARS) )
|
||||||
|
{
|
||||||
|
qpath0 = malloc(YAP_FILENAME_MAX+1);
|
||||||
|
#if HAVE_WORDEXP
|
||||||
|
qpath0=expandVars(spec,qpath0,YAP_FILENAME_MAX);
|
||||||
|
#endif
|
||||||
|
#if _WIN32 || defined(__MINGW32__)
|
||||||
|
free((char *)spec);
|
||||||
|
#endif
|
||||||
|
spec = qpath0;
|
||||||
|
}
|
||||||
|
#if HAVE_REALPATH
|
||||||
|
rc = myrealpath(spec, tmp);
|
||||||
|
#endif
|
||||||
|
if (spec == qpath0
|
||||||
|
#if _WIN32 || defined(__MINGW32__)
|
||||||
|
|| true
|
||||||
|
#endif
|
||||||
|
)
|
||||||
|
free((char *)spec);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *canoniseFileName( char *path) {
|
||||||
|
#if HAVE_REALPATH && HAVE_BASENAME
|
||||||
|
#if _WIN32 || defined(__MINGW32__)
|
||||||
|
char *o = malloc(YAP_FILENAME_MAX+1);
|
||||||
|
if (!o)
|
||||||
|
return NULL;
|
||||||
|
// first pass, remove Unix style stuff
|
||||||
|
if (unix2win(path, o, YAP_FILENAME_MAX) == NULL)
|
||||||
|
return NULL;
|
||||||
|
path = o;
|
||||||
|
#endif
|
||||||
|
char *rc, *tmp = malloc(PATH_MAX);
|
||||||
|
if (tmp == NULL) return NULL;
|
||||||
|
rc = myrealpath(path, tmp);
|
||||||
|
if (rc != tmp)
|
||||||
|
free(tmp);
|
||||||
|
#if _WIN32 || defined(__MINGW32__)
|
||||||
|
free(o);
|
||||||
|
#endif
|
||||||
|
return rc;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
atom_t TemporaryFile( const char *prefix, int *fd) {
|
||||||
|
#if HAVE_MKSTEMP
|
||||||
|
char *tmp = malloc(PATH_MAX);
|
||||||
|
int n;
|
||||||
|
int f;
|
||||||
|
if (tmp == NULL) return (atom_t)0;
|
||||||
|
strncpy(tmp, prefix, PATH_MAX-1);
|
||||||
|
n = strlen( tmp );
|
||||||
|
if (n >= 6 &&
|
||||||
|
tmp[n-1] == 'X' &&
|
||||||
|
tmp[n-2] == 'X' &&
|
||||||
|
tmp[n-3] == 'X' &&
|
||||||
|
tmp[n-4] == 'X' &&
|
||||||
|
tmp[n-5] == 'X' &&
|
||||||
|
tmp[n-6] == 'X')
|
||||||
|
f = mkstemp(tmp);
|
||||||
|
else {
|
||||||
|
strncat(tmp, "XXXXXX", PATH_MAX-1);
|
||||||
|
f = mkstemp(tmp);
|
||||||
|
}
|
||||||
|
if (fd) *fd = f;
|
||||||
|
return YAP_SWIAtomFromAtom(Yap_LookupAtom(tmp));
|
||||||
|
#else
|
||||||
|
return ATOM_nil;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
initSysPath(Term tlib, Term tcommons, bool dir_done, bool commons_done) {
|
initSysPath(Term tlib, Term tcommons, bool dir_done, bool commons_done) {
|
||||||
CACHE_REGS
|
CACHE_REGS
|
||||||
int len;
|
int len;
|
||||||
@ -309,7 +647,7 @@ initSysPath(Term tlib, Term tcommons, bool dir_done, bool commons_done) {
|
|||||||
while (*--pt != '\\') {
|
while (*--pt != '\\') {
|
||||||
/* skip executable */
|
/* skip executable */
|
||||||
if (pt == LOCAL_FileNameBuf) {
|
if (pt == LOCAL_FileNameBuf) {
|
||||||
Yap_Error(OPERATING_SYSTEM_ERROR, TermNil, "could not find executable name");
|
Yap_FileError(OPERATING_SYSTEM_ERROR, TermNil, "could not find executable name");
|
||||||
/* do nothing */
|
/* do nothing */
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@ -317,7 +655,7 @@ initSysPath(Term tlib, Term tcommons, bool dir_done, bool commons_done) {
|
|||||||
while (*--pt != '\\') {
|
while (*--pt != '\\') {
|
||||||
/* skip parent directory "bin\\" */
|
/* skip parent directory "bin\\" */
|
||||||
if (pt == LOCAL_FileNameBuf) {
|
if (pt == LOCAL_FileNameBuf) {
|
||||||
Yap_Error(OPERATING_SYSTEM_ERROR, TermNil, "could not find executable name");
|
Yap_FileError(OPERATING_SYSTEM_ERROR, TermNil, "could not find executable name");
|
||||||
/* do nothing */
|
/* do nothing */
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@ -1154,8 +1492,8 @@ Yap_random (void)
|
|||||||
#elif HAVE_RAND
|
#elif HAVE_RAND
|
||||||
return (((double) (rand ()) / RAND_MAX));
|
return (((double) (rand ()) / RAND_MAX));
|
||||||
#else
|
#else
|
||||||
Yap_Error(SYSTEM_ERROR, TermNil,
|
Yap_Error(SYSTEM_ERROR, TermNil,
|
||||||
"random not available in this configuration");
|
"random not available in this configuration");
|
||||||
return (0.0);
|
return (0.0);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -1697,6 +2035,7 @@ MSCHandleSignal(DWORD dwCtrlType) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* SIGINT can cause problems, if caught before full initialization */
|
/* SIGINT can cause problems, if caught before full initialization */
|
||||||
static void
|
static void
|
||||||
InitSignals (void)
|
InitSignals (void)
|
||||||
@ -1762,211 +2101,87 @@ Yap_volume_header(char *file)
|
|||||||
return volume_header(file);
|
return volume_header(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char * PL_cwd(char *cwd, size_t cwdlen)
|
||||||
|
{
|
||||||
|
return Yap_getcwd( cwd, cwdlen );
|
||||||
|
}
|
||||||
|
|
||||||
char * Yap_getcwd(const char *cwd, size_t cwdlen)
|
char * Yap_getcwd(const char *cwd, size_t cwdlen)
|
||||||
{
|
{
|
||||||
return PL_cwd((char *)cwd, cwdlen);
|
#if _WIN32 || defined(__MINGW32__)
|
||||||
}
|
if (GetCurrentDirectory(cwdlen, (char *)cwd) == 0)
|
||||||
|
{
|
||||||
|
Yap_WinError("GetCurrentDirectory failed" );
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return (char *)cwd;
|
||||||
|
#else
|
||||||
|
return getcwd(cwd, cwdlen);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
/******
|
|
||||||
TODO: rewrite to use wordexp
|
static char *
|
||||||
****/
|
expandWithPrefix(const char *source, const char *root, char *result)
|
||||||
static int
|
{
|
||||||
TrueFileName (char *source, char *root, char *result, int in_lib, int expand_root)
|
char *work;
|
||||||
|
char ares1[YAP_FILENAME_MAX+1];
|
||||||
|
|
||||||
|
work = expandVars( source, ares1, YAP_FILENAME_MAX);
|
||||||
|
// expand names first
|
||||||
|
if (root && !IsAbsolutePath( source ) ) {
|
||||||
|
char ares2[YAP_FILENAME_MAX+1];
|
||||||
|
strncpy( ares2, root, YAP_FILENAME_MAX );
|
||||||
|
strncat( ares2, "/", YAP_FILENAME_MAX );
|
||||||
|
strncat( ares2, work, YAP_FILENAME_MAX );
|
||||||
|
return AbsoluteFile( ares2, result );
|
||||||
|
} else {
|
||||||
|
// expand path
|
||||||
|
return myrealpath( work, result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static bool
|
||||||
|
TrueFileName (char *isource, char *root, char *result, int in_lib, int expand_root)
|
||||||
{
|
{
|
||||||
CACHE_REGS
|
CACHE_REGS
|
||||||
char *work;
|
|
||||||
char ares1[YAP_FILENAME_MAX+1];
|
char *work;
|
||||||
|
const char *source = isource;
|
||||||
result[0] = '\0';
|
|
||||||
if (strlen(source) >= YAP_FILENAME_MAX) {
|
// expand names in case you have
|
||||||
Yap_Error(OPERATING_SYSTEM_ERROR, TermNil, "%s in true_file-name is larger than the buffer size (%d bytes)", source, strlen(source));
|
// to add a prefix
|
||||||
}
|
if (!expand_root)
|
||||||
#if defined(__MINGW32__) || _MSC_VER
|
root = NULL;
|
||||||
/* step 0: replace / by \ */
|
if (exists((work = expandWithPrefix( source, root, result ))))
|
||||||
strncpy(ares1, source, YAP_FILENAME_MAX);
|
return true; // done
|
||||||
{
|
if (in_lib) {
|
||||||
char *p = ares1, ch = p[0];
|
if (Yap_LibDir != NULL) {
|
||||||
while (ch != '\0') {
|
strncpy(LOCAL_FileNameBuf, Yap_LibDir, YAP_FILENAME_MAX);
|
||||||
if (ch == '/') p[0] = '\\';
|
|
||||||
p++;
|
|
||||||
ch = p[0];
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
source = ares1;
|
|
||||||
#endif
|
|
||||||
/* step 1: eating home information */
|
|
||||||
if (source[0] == '~') {
|
|
||||||
if (dir_separator(source[1]) || source[1] == '\0')
|
|
||||||
{
|
|
||||||
char *s;
|
|
||||||
source++;
|
|
||||||
#if defined(_WIN32)
|
|
||||||
s = getenv("HOMEDRIVE");
|
|
||||||
if (s != NULL)
|
|
||||||
strncpy (result, getenv ("HOMEDRIVE"), YAP_FILENAME_MAX);
|
|
||||||
s = getenv("HOMEPATH");
|
|
||||||
if (s != NULL)
|
|
||||||
strncpy (result, s, YAP_FILENAME_MAX);
|
|
||||||
#else
|
|
||||||
s = getenv ("HOME");
|
|
||||||
if (s != NULL)
|
|
||||||
strncpy (result, s, YAP_FILENAME_MAX);
|
|
||||||
#endif
|
|
||||||
} else {
|
|
||||||
#if HAVE_GETPWNAM
|
|
||||||
struct passwd *user_passwd;
|
|
||||||
char *res0 = result;
|
|
||||||
|
|
||||||
source++;
|
|
||||||
while (!dir_separator((*res0 = *source)) && *res0 != '\0')
|
|
||||||
res0++, source++;
|
|
||||||
*res0++ = '\0';
|
|
||||||
if ((user_passwd = getpwnam (result)) == NULL) {
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
strncpy (result, user_passwd->pw_dir, YAP_FILENAME_MAX);
|
|
||||||
#else
|
|
||||||
return FALSE;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
strncat (result, source, YAP_FILENAME_MAX);
|
|
||||||
} else if (source[0] == '$') {
|
|
||||||
/* follow SICStus expansion rules */
|
|
||||||
int ch;
|
|
||||||
char *s;
|
|
||||||
char *res0 = source+1;
|
|
||||||
if (*res0 == '{') {
|
|
||||||
res0++;
|
|
||||||
while ((ch = *res0) && is_valid_env_char (ch) && ch != '}') {
|
|
||||||
res0++;
|
|
||||||
}
|
|
||||||
*res0++ = '\0';
|
|
||||||
if (ch == '}') {
|
|
||||||
// {...}
|
|
||||||
source++;
|
|
||||||
ch = *res0;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
while ((ch = *res0) && is_valid_env_char (ch)) {
|
|
||||||
res0++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!(s = (char *) getenv (source+1))) {
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
*res0 = ch;
|
|
||||||
strncpy (result, s, YAP_FILENAME_MAX);
|
|
||||||
strncat (result, res0, YAP_FILENAME_MAX);
|
|
||||||
} else {
|
|
||||||
strncpy (result, source, YAP_FILENAME_MAX);
|
|
||||||
}
|
|
||||||
/* step 3: get the full file name */
|
|
||||||
if (expand_root && !dir_separator(result[0]) && !volume_header(result)) {
|
|
||||||
if (!Yap_getcwd(ares1, YAP_FILENAME_MAX))
|
|
||||||
return FALSE;
|
|
||||||
#if _MSC_VER || defined(__MINGW32__)
|
|
||||||
strncat (ares1, "\\", YAP_FILENAME_MAX-1);
|
|
||||||
#else
|
|
||||||
strncat (ares1, "/", YAP_FILENAME_MAX-1);
|
|
||||||
#endif
|
|
||||||
if (root) {
|
|
||||||
if (!dir_separator(root[0]) && !volume_header(root)) {
|
|
||||||
strncat(ares1, root, YAP_FILENAME_MAX-1);
|
|
||||||
} else {
|
|
||||||
strncpy(ares1, root, YAP_FILENAME_MAX-1);
|
|
||||||
}
|
|
||||||
#if _MSC_VER || defined(__MINGW32__)
|
|
||||||
strncat (ares1, "\\", YAP_FILENAME_MAX-1);
|
|
||||||
#else
|
|
||||||
strncat (ares1, "/", YAP_FILENAME_MAX-1);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
strncat (ares1, result, YAP_FILENAME_MAX-1);
|
|
||||||
if (in_lib) {
|
|
||||||
int tmpf;
|
|
||||||
if ((tmpf = open(ares1, O_RDONLY)) < 0) {
|
|
||||||
/* not in current directory, let us try the library */
|
|
||||||
if (Yap_LibDir != NULL) {
|
|
||||||
strncpy(LOCAL_FileNameBuf, Yap_LibDir, YAP_FILENAME_MAX);
|
|
||||||
#if HAVE_GETENV
|
#if HAVE_GETENV
|
||||||
} else {
|
|
||||||
char *yap_env = getenv("YAPLIBDIR");
|
|
||||||
if (yap_env != NULL) {
|
|
||||||
strncpy(ares1, yap_env, YAP_FILENAME_MAX);
|
|
||||||
#endif
|
|
||||||
} else {
|
|
||||||
#if __WINDOWS__
|
|
||||||
if (Yap_LibDir)
|
|
||||||
strncpy(ares1, Yap_LibDir, YAP_FILENAME_MAX);
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
strncpy(ares1, YAP_LIBDIR, YAP_FILENAME_MAX);
|
|
||||||
}
|
|
||||||
#if HAVE_GETENV
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#if _MSC_VER || defined(__MINGW32__)
|
|
||||||
strncat(ares1,"\\", YAP_FILENAME_MAX-1);
|
|
||||||
#else
|
|
||||||
strncat(ares1,"/", YAP_FILENAME_MAX-1);
|
|
||||||
#endif
|
|
||||||
strncat(ares1,result, YAP_FILENAME_MAX-1);
|
|
||||||
if ((tmpf = open(ares1, O_RDONLY)) >= 0) {
|
|
||||||
close(tmpf);
|
|
||||||
strncpy (result, ares1, YAP_FILENAME_MAX);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
strncpy (result, ares1, YAP_FILENAME_MAX);
|
|
||||||
close(tmpf);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
strncpy (result, ares1, YAP_FILENAME_MAX);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* step 4: simplifying the file name */
|
|
||||||
work = result;
|
|
||||||
while (*work != '\0')
|
|
||||||
{
|
{
|
||||||
char *new_work, *next_work;
|
char *yap_env = getenv("YAPLIBDIR");
|
||||||
if (*work++ != '.')
|
if (yap_env &&
|
||||||
continue;
|
exists((work = expandWithPrefix( source, yap_env, result ))))
|
||||||
if (*work != '.')
|
return true; // done
|
||||||
{
|
|
||||||
if (!dir_separator(*work) || !dir_separator(work[-2]))
|
|
||||||
continue;
|
|
||||||
next_work = work + 1;
|
|
||||||
new_work = --work;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!dir_separator(work[1]) || !dir_separator(work[-2]))
|
|
||||||
continue;
|
|
||||||
next_work = work + 2;
|
|
||||||
work -= 2;
|
|
||||||
if (work == result)
|
|
||||||
return (FALSE);
|
|
||||||
while (!dir_separator(*--work) && work != result);
|
|
||||||
if (work == result && !dir_separator(work[0]))
|
|
||||||
return (FALSE);
|
|
||||||
new_work = ++work;
|
|
||||||
}
|
|
||||||
while ((*new_work++ = *next_work++)!=0);
|
|
||||||
}
|
}
|
||||||
if (work != result && dir_separator(work[-1])) {
|
#endif
|
||||||
/* should only do this on result being a directory */
|
#if __WINDOWS__
|
||||||
int ch0 = work[-1];
|
{
|
||||||
work--;
|
if (Yap_LibDir &&
|
||||||
work[0] = '\0';
|
exists((work = expandWithPrefix( source, Yap_LibDir, result ))))
|
||||||
if (!is_directory(result)) {
|
return true; // done
|
||||||
/* put it back: */
|
|
||||||
work[0] = ch0;
|
|
||||||
work++;
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
if (YAP_LIBDIR &&
|
||||||
|
exists((work = expandWithPrefix( source, YAP_LIBDIR, result ))))
|
||||||
|
return true; // done
|
||||||
}
|
}
|
||||||
return TRUE;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
Yap_TrueFileName (char *source, char *result, int in_lib)
|
Yap_TrueFileName (char *source, char *result, int in_lib)
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user