2008-10-09 14:56:31 -07:00
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
# include "config.h"
|
|
|
|
#endif /* HAVE_CONFIG_H */
|
|
|
|
|
2012-02-17 12:48:11 -08:00
|
|
|
#include <stdlib.h>
|
2008-09-13 14:19:22 -07:00
|
|
|
#include <stdio.h>
|
2012-02-17 12:48:11 -08:00
|
|
|
#include <io.h>
|
|
|
|
#include <fcntl.h>
|
|
|
|
#include <sys/stat.h>
|
2013-03-30 08:09:37 -07:00
|
|
|
#include <sys/types.h>
|
2010-02-27 23:57:03 -08:00
|
|
|
|
2013-01-10 12:25:44 -08:00
|
|
|
#include <errno.h>
|
2008-09-13 14:19:22 -07:00
|
|
|
|
2012-02-17 12:48:11 -08:00
|
|
|
#ifndef WIN32_LEAN_AND_MEAN
|
|
|
|
# define WIN32_LEAN_AND_MEAN
|
|
|
|
#endif
|
2008-09-13 14:19:22 -07:00
|
|
|
#include <windows.h>
|
|
|
|
#undef WIN32_LEAN_AND_MEAN
|
|
|
|
|
2012-02-17 12:48:11 -08:00
|
|
|
#include "evil_macro.h"
|
|
|
|
#include "evil_stdlib.h"
|
2008-10-24 00:32:08 -07:00
|
|
|
#include "evil_private.h"
|
2008-09-13 14:19:22 -07:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Environment variable related functions
|
|
|
|
*
|
|
|
|
* char *getenv (const char *name);
|
|
|
|
* int putenv (const char *string);
|
|
|
|
* int setenv (const char *name, const char *value, int overwrite);
|
|
|
|
* void unsetenv (const char *name);
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2009-10-14 11:48:13 -07:00
|
|
|
#ifdef _WIN32_WCE
|
2008-09-13 14:19:22 -07:00
|
|
|
|
|
|
|
static char _evil_stdlib_getenv_buffer[PATH_MAX];
|
|
|
|
|
|
|
|
char *
|
|
|
|
getenv(const char *name)
|
|
|
|
{
|
|
|
|
HKEY key;
|
|
|
|
wchar_t *wname;
|
|
|
|
LONG res;
|
|
|
|
DWORD type;
|
2008-10-28 01:59:12 -07:00
|
|
|
DWORD disposition;
|
2008-09-13 14:19:22 -07:00
|
|
|
DWORD size = PATH_MAX;
|
|
|
|
|
|
|
|
if (!name || !*name)
|
|
|
|
return NULL;
|
|
|
|
|
2008-10-28 01:59:12 -07:00
|
|
|
if ((res = RegCreateKeyEx(HKEY_LOCAL_MACHINE,
|
|
|
|
TEXT("Software\\Efl\\Environment"),
|
|
|
|
0, NULL,
|
|
|
|
REG_OPTION_VOLATILE,
|
|
|
|
0, NULL,
|
|
|
|
&key, &disposition)) != ERROR_SUCCESS)
|
2008-09-13 14:19:22 -07:00
|
|
|
{
|
2008-10-28 01:59:12 -07:00
|
|
|
_evil_error_display(__FUNCTION__, res);
|
2008-09-13 14:19:22 -07:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
wname = evil_char_to_wchar(name);
|
|
|
|
if (!wname)
|
|
|
|
{
|
|
|
|
if ((res = RegCloseKey (key)) != ERROR_SUCCESS)
|
2008-10-27 01:39:13 -07:00
|
|
|
_evil_error_display(__FUNCTION__, res);
|
2008-09-13 14:19:22 -07:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((res = RegQueryValueEx(key, wname,
|
|
|
|
NULL, &type,
|
2008-10-22 14:36:55 -07:00
|
|
|
(LPBYTE)&_evil_stdlib_getenv_buffer,
|
2008-09-13 14:19:22 -07:00
|
|
|
&size)) != ERROR_SUCCESS)
|
|
|
|
{
|
|
|
|
if ((res = RegCloseKey (key)) != ERROR_SUCCESS)
|
2008-10-27 01:39:13 -07:00
|
|
|
_evil_error_display(__FUNCTION__, res);
|
2008-09-13 14:19:22 -07:00
|
|
|
free(wname);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
free(wname);
|
|
|
|
|
|
|
|
if ((res = RegCloseKey (key)) != ERROR_SUCCESS)
|
|
|
|
{
|
2008-10-27 01:39:13 -07:00
|
|
|
_evil_error_display(__FUNCTION__, res);
|
2008-09-13 14:19:22 -07:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2008-10-22 14:36:55 -07:00
|
|
|
if (_evil_stdlib_getenv_buffer[0] == '\0')
|
2008-09-13 14:19:22 -07:00
|
|
|
return NULL;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return _evil_stdlib_getenv_buffer;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-10-14 11:48:13 -07:00
|
|
|
#endif /* _WIN32_WCE */
|
2008-09-13 14:19:22 -07:00
|
|
|
|
2008-12-27 10:53:56 -08:00
|
|
|
#ifdef __MINGW32CE__
|
2008-09-13 14:19:22 -07:00
|
|
|
|
|
|
|
int
|
|
|
|
putenv(const char *string)
|
|
|
|
{
|
2008-10-13 23:52:09 -07:00
|
|
|
char *str;
|
|
|
|
char *egal;
|
|
|
|
char *name;
|
|
|
|
char *value;
|
|
|
|
|
|
|
|
str = strdup(string);
|
|
|
|
if (!str)
|
|
|
|
return -1;
|
|
|
|
egal = strchr(str, '=');
|
|
|
|
if (!egal)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
value = egal + 1;
|
|
|
|
*egal = '\0';
|
|
|
|
name = str;
|
|
|
|
setenv(name, value, 1);
|
|
|
|
free(str);
|
|
|
|
|
|
|
|
return 0;
|
2008-09-13 14:19:22 -07:00
|
|
|
}
|
|
|
|
|
2008-12-27 10:53:56 -08:00
|
|
|
#endif /* __MINGW32CE__ */
|
2008-09-13 14:19:22 -07:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
setenv(const char *name,
|
|
|
|
const char *value,
|
|
|
|
int overwrite)
|
|
|
|
{
|
2010-02-27 23:57:03 -08:00
|
|
|
#ifndef __MINGW32CE__
|
2008-09-13 14:19:22 -07:00
|
|
|
|
2009-01-11 22:03:51 -08:00
|
|
|
char *old_name;
|
|
|
|
char *str;
|
|
|
|
size_t length;
|
|
|
|
int res;
|
2008-09-13 14:19:22 -07:00
|
|
|
|
|
|
|
if (!name || !*name)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
/* if '=' is found, return EINVAL */
|
|
|
|
if (strchr (name, '='))
|
|
|
|
{
|
|
|
|
errno = EINVAL;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* if name is already set and overwrite is 0, we exit with success */
|
|
|
|
old_name = getenv(name);
|
2008-09-14 00:07:39 -07:00
|
|
|
if (!overwrite && old_name)
|
2008-09-13 14:19:22 -07:00
|
|
|
return 0;
|
|
|
|
|
2009-04-08 10:22:12 -07:00
|
|
|
length = value ? strlen(value) : 0;
|
|
|
|
length += strlen(name) + 2;
|
2008-09-13 14:19:22 -07:00
|
|
|
str = (char *)malloc(length);
|
|
|
|
if (!str)
|
|
|
|
{
|
|
|
|
errno = ENOMEM;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if (!value)
|
|
|
|
sprintf(str, "%s=", name);
|
|
|
|
else
|
|
|
|
sprintf(str, "%s=%s", name, value);
|
|
|
|
res = _putenv(str);
|
|
|
|
free(str);
|
|
|
|
|
2008-09-14 00:07:39 -07:00
|
|
|
return res;
|
|
|
|
|
2010-02-27 23:57:03 -08:00
|
|
|
#else /* __MINGW32CE__ */
|
2008-09-13 14:19:22 -07:00
|
|
|
|
|
|
|
HKEY key;
|
|
|
|
LONG res;
|
|
|
|
DWORD disposition;
|
2008-10-22 14:36:55 -07:00
|
|
|
wchar_t *wname;
|
2009-01-19 09:51:17 -08:00
|
|
|
char *data;
|
|
|
|
DWORD size;
|
2008-09-13 14:19:22 -07:00
|
|
|
|
|
|
|
if (!name || !*name)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
/* if '=' is found, return an error */
|
|
|
|
if (strchr (name, '='))
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
if ((res = RegCreateKeyEx(HKEY_LOCAL_MACHINE,
|
|
|
|
TEXT("Software\\Efl\\Environment"),
|
|
|
|
0, NULL,
|
|
|
|
REG_OPTION_VOLATILE,
|
|
|
|
0, NULL,
|
|
|
|
&key,
|
|
|
|
&disposition)) != ERROR_SUCCESS)
|
|
|
|
{
|
2008-10-27 01:39:13 -07:00
|
|
|
_evil_error_display(__FUNCTION__, res);
|
2008-09-13 14:19:22 -07:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* if name is already set and overwrite is 0, we exit with success */
|
|
|
|
if (!overwrite && (disposition == REG_OPENED_EXISTING_KEY))
|
|
|
|
return 0;
|
|
|
|
|
2008-10-22 14:36:55 -07:00
|
|
|
wname = evil_char_to_wchar(name);
|
|
|
|
if (!wname)
|
|
|
|
{
|
|
|
|
if ((res = RegCloseKey (key)) != ERROR_SUCCESS)
|
2008-10-27 01:39:13 -07:00
|
|
|
_evil_error_display(__FUNCTION__, res);
|
2008-10-22 14:36:55 -07:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2009-01-19 09:51:17 -08:00
|
|
|
if (value)
|
|
|
|
{
|
|
|
|
size = strlen(value);
|
|
|
|
data = malloc(sizeof(char) * (size + 1));
|
|
|
|
if (!data)
|
|
|
|
return -1;
|
|
|
|
memcpy((void *)data, value, size);
|
|
|
|
data[size] = '\0';
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
size = 0;
|
|
|
|
data = malloc(sizeof(char));
|
|
|
|
if (!data)
|
|
|
|
return -1;
|
|
|
|
data[0] = '\0';
|
|
|
|
}
|
|
|
|
if (!data)
|
|
|
|
return -1;
|
|
|
|
|
2008-09-14 23:56:14 -07:00
|
|
|
if ((res = RegSetValueEx(key,
|
2008-10-22 14:36:55 -07:00
|
|
|
(LPCWSTR)wname,
|
2008-09-14 23:56:14 -07:00
|
|
|
0, REG_SZ,
|
2009-01-19 09:51:17 -08:00
|
|
|
(const BYTE *)data,
|
|
|
|
size + 1)) != ERROR_SUCCESS)
|
2008-09-13 14:19:22 -07:00
|
|
|
{
|
2008-10-22 14:36:55 -07:00
|
|
|
free(wname);
|
2008-10-27 01:39:13 -07:00
|
|
|
_evil_error_display(__FUNCTION__, res);
|
2008-09-13 14:19:22 -07:00
|
|
|
if ((res = RegCloseKey (key)) != ERROR_SUCCESS)
|
2008-10-27 01:39:13 -07:00
|
|
|
_evil_error_display(__FUNCTION__, res);
|
2008-09-13 14:19:22 -07:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2009-01-19 09:51:17 -08:00
|
|
|
free(data);
|
2008-10-22 14:36:55 -07:00
|
|
|
free(wname);
|
|
|
|
|
2008-09-13 14:19:22 -07:00
|
|
|
if ((res = RegCloseKey (key)) != ERROR_SUCCESS)
|
|
|
|
{
|
2008-10-27 01:39:13 -07:00
|
|
|
_evil_error_display(__FUNCTION__, res);
|
2008-09-13 14:19:22 -07:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
2008-12-27 10:53:56 -08:00
|
|
|
|
2010-02-27 23:57:03 -08:00
|
|
|
#endif /* ! __MINGW32CE__ */
|
2008-09-13 14:19:22 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
unsetenv(const char *name)
|
|
|
|
{
|
2008-09-14 23:56:14 -07:00
|
|
|
return setenv(name, NULL, 1);
|
2008-09-13 14:19:22 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Files related functions
|
|
|
|
*
|
|
|
|
*/
|
2013-03-30 08:09:37 -07:00
|
|
|
static int
|
|
|
|
_mkstemp_init(char *__template, char **suffix, size_t *length, DWORD *val)
|
|
|
|
{
|
|
|
|
*length = strlen(__template);
|
|
|
|
if ((*length < 6) ||
|
|
|
|
(strncmp (__template + *length - 6, "XXXXXX", 6)))
|
|
|
|
{
|
|
|
|
errno = EINVAL;
|
|
|
|
return 0;
|
|
|
|
}
|
2008-09-13 14:19:22 -07:00
|
|
|
|
2013-03-30 08:09:37 -07:00
|
|
|
*suffix = __template + *length - 6;
|
|
|
|
|
|
|
|
*val = GetTickCount();
|
|
|
|
*val += GetCurrentProcessId();
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
_mkstemp(char *suffix, int val)
|
2008-09-13 14:19:22 -07:00
|
|
|
{
|
2008-10-09 14:56:31 -07:00
|
|
|
const char lookup[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
|
2013-03-30 08:09:37 -07:00
|
|
|
DWORD v = val;
|
|
|
|
|
|
|
|
suffix[0] = lookup[v % 62];
|
|
|
|
v /= 62;
|
|
|
|
suffix[1] = lookup[v % 62];
|
|
|
|
v /= 62;
|
|
|
|
suffix[2] = lookup[v % 62];
|
|
|
|
v /= 62;
|
|
|
|
suffix[3] = lookup[v % 62];
|
|
|
|
v /= 62;
|
|
|
|
suffix[4] = lookup[v % 62];
|
|
|
|
v /= 62;
|
|
|
|
suffix[5] = lookup[v % 62];
|
|
|
|
v /= 62;
|
|
|
|
|
|
|
|
val += 7777;
|
|
|
|
|
2013-06-24 20:16:36 -07:00
|
|
|
return val;
|
2013-03-30 08:09:37 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
EAPI char *
|
|
|
|
mkdtemp(char *__template)
|
|
|
|
{
|
2009-01-11 22:03:51 -08:00
|
|
|
char *suffix;
|
|
|
|
DWORD val;
|
|
|
|
size_t length;
|
|
|
|
int i;
|
2008-09-13 14:19:22 -07:00
|
|
|
|
2009-01-19 09:51:17 -08:00
|
|
|
if (!__template)
|
2008-10-09 14:56:31 -07:00
|
|
|
{
|
|
|
|
errno = EINVAL;
|
2013-03-30 08:09:37 -07:00
|
|
|
return NULL;
|
2008-10-09 14:56:31 -07:00
|
|
|
}
|
2008-09-13 14:19:22 -07:00
|
|
|
|
2013-03-30 08:09:37 -07:00
|
|
|
if (!_mkstemp_init(__template, &suffix, &length, &val))
|
|
|
|
return NULL;
|
2008-09-13 14:19:22 -07:00
|
|
|
|
2013-03-30 08:09:37 -07:00
|
|
|
for (i = 0; i < 32768; i++)
|
|
|
|
{
|
|
|
|
val = _mkstemp(suffix, val);
|
|
|
|
|
|
|
|
if (mkdir(__template))
|
|
|
|
return __template;
|
|
|
|
|
|
|
|
if (errno == EFAULT ||
|
|
|
|
errno == ENOSPC ||
|
|
|
|
errno == ENOMEM ||
|
|
|
|
errno == ENOENT ||
|
|
|
|
errno == ENOTDIR ||
|
|
|
|
errno == EPERM ||
|
|
|
|
errno == EROFS)
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
errno = EEXIST;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
mkstemp(char *__template)
|
|
|
|
{
|
|
|
|
char *suffix;
|
|
|
|
DWORD val;
|
|
|
|
size_t length;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
if (!__template)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if (!_mkstemp_init(__template, &suffix, &length, &val))
|
|
|
|
return -1;
|
2008-10-09 14:56:31 -07:00
|
|
|
|
|
|
|
for (i = 0; i < 32768; i++)
|
|
|
|
{
|
|
|
|
int fd;
|
|
|
|
|
2013-06-24 20:16:36 -07:00
|
|
|
val = _mkstemp(suffix, val);
|
2008-10-09 14:56:31 -07:00
|
|
|
|
2010-02-27 23:57:03 -08:00
|
|
|
#ifndef __MINGW32CE__
|
2011-07-16 00:14:42 -07:00
|
|
|
fd = _open(__template, _O_RDWR | _O_BINARY | _O_CREAT | _O_EXCL, _S_IREAD | _S_IWRITE);
|
2010-02-27 23:57:03 -08:00
|
|
|
#else /* ! __MINGW32CE__ */
|
2008-10-13 23:52:09 -07:00
|
|
|
{
|
2009-01-19 09:51:17 -08:00
|
|
|
FILE *f;
|
|
|
|
wchar_t *wtemplate;
|
|
|
|
|
|
|
|
wtemplate = evil_char_to_wchar(__template);
|
|
|
|
if (!wtemplate)
|
|
|
|
return -1;
|
|
|
|
f = _wfopen(wtemplate, L"rwb");
|
|
|
|
free(wtemplate);
|
2008-10-13 23:52:09 -07:00
|
|
|
if (!f)
|
|
|
|
{
|
|
|
|
errno = EEXIST;
|
|
|
|
return -1;
|
|
|
|
}
|
2010-01-29 01:34:26 -08:00
|
|
|
fd = (int)_fileno(f);
|
2008-10-13 23:52:09 -07:00
|
|
|
}
|
2010-02-27 23:57:03 -08:00
|
|
|
#endif /* __MINGW32CE__ */
|
2008-10-09 14:56:31 -07:00
|
|
|
if (fd >= 0)
|
|
|
|
return fd;
|
|
|
|
}
|
|
|
|
|
|
|
|
errno = EEXIST;
|
|
|
|
return -1;
|
|
|
|
}
|
2008-09-13 14:19:22 -07:00
|
|
|
|
|
|
|
|
|
|
|
char *
|
|
|
|
realpath(const char *file_name, char *resolved_name)
|
|
|
|
{
|
2010-02-27 23:57:03 -08:00
|
|
|
#ifndef __MINGW32CE__
|
2012-07-03 01:57:07 -07:00
|
|
|
char *retname = NULL; /* we will return this, if we fail */
|
|
|
|
|
|
|
|
/* SUSv3 says we must set `errno = EINVAL', and return NULL,
|
|
|
|
* if `name' is passed as a NULL pointer.
|
|
|
|
*/
|
|
|
|
|
|
|
|
if (file_name == NULL)
|
|
|
|
errno = EINVAL;
|
|
|
|
|
|
|
|
/* Otherwise, `name' must refer to a readable filesystem object,
|
|
|
|
* if we are going to resolve its absolute path name.
|
|
|
|
*/
|
|
|
|
|
|
|
|
else if (access(file_name, 4) == 0)
|
|
|
|
{
|
|
|
|
/* If `name' didn't point to an existing entity,
|
|
|
|
* then we don't get to here; we simply fall past this block,
|
|
|
|
* returning NULL, with `errno' appropriately set by `access'.
|
|
|
|
*
|
|
|
|
* When we _do_ get to here, then we can use `_fullpath' to
|
|
|
|
* resolve the full path for `name' into `resolved', but first,
|
|
|
|
* check that we have a suitable buffer, in which to return it.
|
|
|
|
*/
|
|
|
|
|
|
|
|
if ((retname = resolved_name) == NULL)
|
|
|
|
{
|
|
|
|
/* Caller didn't give us a buffer, so we'll exercise the
|
|
|
|
* option granted by SUSv3, and allocate one.
|
|
|
|
*
|
|
|
|
* `_fullpath' would do this for us, but it uses `malloc', and
|
|
|
|
* Microsoft's implementation doesn't set `errno' on failure.
|
|
|
|
* If we don't do this explicitly ourselves, then we will not
|
|
|
|
* know if `_fullpath' fails on `malloc' failure, or for some
|
|
|
|
* other reason, and we want to set `errno = ENOMEM' for the
|
|
|
|
* `malloc' failure case.
|
|
|
|
*/
|
|
|
|
|
|
|
|
retname = malloc(_MAX_PATH);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* By now, we should have a valid buffer.
|
|
|
|
* If we don't, then we know that `malloc' failed,
|
|
|
|
* so we can set `errno = ENOMEM' appropriately.
|
|
|
|
*/
|
|
|
|
|
|
|
|
if (retname == NULL)
|
|
|
|
errno = ENOMEM;
|
|
|
|
|
|
|
|
/* Otherwise, when we do have a valid buffer,
|
|
|
|
* `_fullpath' should only fail if the path name is too long.
|
|
|
|
*/
|
|
|
|
|
|
|
|
else if ((retname = _fullpath(retname, file_name, _MAX_PATH)) == NULL)
|
|
|
|
errno = ENAMETOOLONG;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* By the time we get to here,
|
|
|
|
* `retname' either points to the required resolved path name,
|
|
|
|
* or it is NULL, with `errno' set appropriately, either of which
|
|
|
|
* is our required return condition.
|
|
|
|
*/
|
|
|
|
|
|
|
|
return retname;
|
2008-09-13 14:19:22 -07:00
|
|
|
#else
|
2009-01-19 09:51:17 -08:00
|
|
|
char cwd[PATH_MAX];
|
|
|
|
size_t l1;
|
|
|
|
size_t l2;
|
|
|
|
size_t l;
|
|
|
|
|
|
|
|
if (!file_name || !resolved_name)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
if (!getcwd(cwd, PATH_MAX))
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
l1 = strlen(cwd);
|
|
|
|
l2 = strlen(file_name);
|
|
|
|
l = l1 + l2 + 2;
|
2008-09-13 14:19:22 -07:00
|
|
|
|
2009-01-19 09:51:17 -08:00
|
|
|
if (l > PATH_MAX)
|
|
|
|
l = PATH_MAX - 1;
|
|
|
|
memcpy(resolved_name, cwd, l1);
|
|
|
|
resolved_name[l1] = '\\';
|
|
|
|
memcpy(resolved_name + l1 + 1, file_name, l2);
|
|
|
|
resolved_name[l] = '\0';
|
2008-09-13 14:19:22 -07:00
|
|
|
|
|
|
|
return resolved_name;
|
2010-02-27 23:57:03 -08:00
|
|
|
#endif /* __MINGW32CE__ */
|
2008-09-13 14:19:22 -07:00
|
|
|
}
|