mirror of
https://github.com/git/git.git
synced 2025-03-27 04:46:47 +00:00
Windows's rename() is based on the MoveFile() API, which fails if the destination exists. Here we work around the problem by using MoveFileEx(). Furthermore, the posixly correct error is returned if the destination is a directory. The implementation is still slightly incomplete, however, because of the missing error code translation: We assume that the failure is due to permissions. Signed-off-by: Johannes Sixt <johannes.sixt@telecom.at>
124 lines
2.5 KiB
C
124 lines
2.5 KiB
C
#include "../git-compat-util.h"
|
|
|
|
unsigned int _CRT_fmode = _O_BINARY;
|
|
|
|
#undef open
|
|
int mingw_open (const char *filename, int oflags, ...)
|
|
{
|
|
va_list args;
|
|
unsigned mode;
|
|
va_start(args, oflags);
|
|
mode = va_arg(args, int);
|
|
va_end(args);
|
|
|
|
if (!strcmp(filename, "/dev/null"))
|
|
filename = "nul";
|
|
int fd = open(filename, oflags, mode);
|
|
if (fd < 0 && (oflags & O_CREAT) && errno == EACCES) {
|
|
DWORD attrs = GetFileAttributes(filename);
|
|
if (attrs != INVALID_FILE_ATTRIBUTES && (attrs & FILE_ATTRIBUTE_DIRECTORY))
|
|
errno = EISDIR;
|
|
}
|
|
return fd;
|
|
}
|
|
|
|
unsigned int sleep (unsigned int seconds)
|
|
{
|
|
Sleep(seconds*1000);
|
|
return 0;
|
|
}
|
|
|
|
int mkstemp(char *template)
|
|
{
|
|
char *filename = mktemp(template);
|
|
if (filename == NULL)
|
|
return -1;
|
|
return open(filename, O_RDWR | O_CREAT, 0600);
|
|
}
|
|
|
|
int gettimeofday(struct timeval *tv, void *tz)
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
int poll(struct pollfd *ufds, unsigned int nfds, int timeout)
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
struct tm *gmtime_r(const time_t *timep, struct tm *result)
|
|
{
|
|
/* gmtime() in MSVCRT.DLL is thread-safe, but not reentrant */
|
|
memcpy(result, gmtime(timep), sizeof(struct tm));
|
|
return result;
|
|
}
|
|
|
|
struct tm *localtime_r(const time_t *timep, struct tm *result)
|
|
{
|
|
/* localtime() in MSVCRT.DLL is thread-safe, but not reentrant */
|
|
memcpy(result, localtime(timep), sizeof(struct tm));
|
|
return result;
|
|
}
|
|
|
|
#undef getcwd
|
|
char *mingw_getcwd(char *pointer, int len)
|
|
{
|
|
int i;
|
|
char *ret = getcwd(pointer, len);
|
|
if (!ret)
|
|
return ret;
|
|
for (i = 0; pointer[i]; i++)
|
|
if (pointer[i] == '\\')
|
|
pointer[i] = '/';
|
|
return ret;
|
|
}
|
|
|
|
#undef rename
|
|
int mingw_rename(const char *pold, const char *pnew)
|
|
{
|
|
/*
|
|
* Try native rename() first to get errno right.
|
|
* It is based on MoveFile(), which cannot overwrite existing files.
|
|
*/
|
|
if (!rename(pold, pnew))
|
|
return 0;
|
|
if (errno != EEXIST)
|
|
return -1;
|
|
if (MoveFileEx(pold, pnew, MOVEFILE_REPLACE_EXISTING))
|
|
return 0;
|
|
/* TODO: translate more errors */
|
|
if (GetLastError() == ERROR_ACCESS_DENIED) {
|
|
DWORD attrs = GetFileAttributes(pnew);
|
|
if (attrs != INVALID_FILE_ATTRIBUTES && (attrs & FILE_ATTRIBUTE_DIRECTORY)) {
|
|
errno = EISDIR;
|
|
return -1;
|
|
}
|
|
}
|
|
errno = EACCES;
|
|
return -1;
|
|
}
|
|
|
|
struct passwd *getpwuid(int uid)
|
|
{
|
|
static char user_name[100];
|
|
static struct passwd p;
|
|
|
|
DWORD len = sizeof(user_name);
|
|
if (!GetUserName(user_name, &len))
|
|
return NULL;
|
|
p.pw_name = user_name;
|
|
p.pw_gecos = "unknown";
|
|
p.pw_dir = NULL;
|
|
return &p;
|
|
}
|
|
|
|
int setitimer(int type, struct itimerval *in, struct itimerval *out)
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
int sigaction(int sig, struct sigaction *in, struct sigaction *out)
|
|
{
|
|
return -1;
|
|
}
|