From 2f795d8fc50d81641d95723d9ddd92795886bed3 Mon Sep 17 00:00:00 2001 From: Jacques Germishuys Date: Sat, 12 Jul 2014 14:45:56 +0200 Subject: [PATCH] Cleanup portability/compatibility layer * Removes mingw-compat.h * Cleans up separation of compiler/platform idiosyncrasies * Unifies mingw/msvc stat structures and functions * (Tries to) hide more compiler specific implementation details (even in our internal API) --- src/path.h | 1 + src/posix.h | 74 +++++++++++++++++++++++++--------------- src/unix/posix.h | 23 ++++++++++++- src/win32/mingw-compat.h | 17 +++------ src/win32/msvc-compat.h | 28 ++------------- src/win32/posix.h | 38 +++++++-------------- src/win32/posix_w32.c | 17 +++++++++ 7 files changed, 107 insertions(+), 91 deletions(-) diff --git a/src/path.h b/src/path.h index 3e6efe3de..e10aeb0c9 100644 --- a/src/path.h +++ b/src/path.h @@ -8,6 +8,7 @@ #define INCLUDE_path_h__ #include "common.h" +#include "posix.h" #include "buffer.h" #include "vector.h" diff --git a/src/posix.h b/src/posix.h index 965cd98d5..9ef348739 100644 --- a/src/posix.h +++ b/src/posix.h @@ -12,23 +12,61 @@ #include #include "fnmatch.h" +/* stat: file mode type testing macros */ #ifndef S_IFGITLINK #define S_IFGITLINK 0160000 #define S_ISGITLINK(m) (((m) & S_IFMT) == S_IFGITLINK) #endif +#ifndef S_IFLNK +#define S_IFLNK 0120000 +#undef _S_IFLNK +#define _S_IFLNK S_IFLNK +#endif + +#ifndef S_IXUSR +#define S_IXUSR 00100 +#endif + +#ifndef S_ISLNK +#define S_ISLNK(m) (((m) & _S_IFMT) == _S_IFLNK) +#endif + +#ifndef S_ISDIR +#define S_ISDIR(m) (((m) & _S_IFMT) == _S_IFDIR) +#endif + +#ifndef S_ISREG +#define S_ISREG(m) (((m) & _S_IFMT) == _S_IFREG) +#endif + +#ifndef S_ISFIFO +#define S_ISFIFO(m) (((m) & _S_IFMT) == _S_IFIFO) +#endif + /* if S_ISGID is not defined, then don't try to set it */ #ifndef S_ISGID #define S_ISGID 0 #endif -#if !defined(O_BINARY) +#ifndef O_BINARY #define O_BINARY 0 #endif -#if !defined(O_CLOEXEC) +#ifndef O_CLOEXEC #define O_CLOEXEC 0 #endif +/* access() mode parameter #defines */ +#ifndef F_OK +#define F_OK 0 /* existence check */ +#endif +#ifndef W_OK +#define W_OK 2 /* write mode check */ +#endif +#ifndef R_OK +#define R_OK 4 /* read mode check */ +#endif + /* Determine whether an errno value indicates that a read or write failed * because the descriptor is blocked. */ @@ -38,6 +76,12 @@ #define GIT_ISBLOCKED(e) ((e) == EAGAIN) #endif +/* define some standard errnos that the runtime may be missing. for example, + * mingw lacks EAFNOSUPPORT. */ +#ifndef EAFNOSUPPORT +#define EAFNOSUPPORT (INT_MAX-1) +#endif + typedef int git_file; /** @@ -56,8 +100,6 @@ typedef int git_file; extern int p_read(git_file fd, void *buf, size_t cnt); extern int p_write(git_file fd, const void *buf, size_t cnt); -#define p_fstat(f,b) fstat(f, b) -#define p_lseek(f,n,w) lseek(f, n, w) #define p_close(fd) close(fd) #define p_umask(m) umask(m) @@ -66,30 +108,6 @@ extern int p_creat(const char *path, mode_t mode); extern int p_getcwd(char *buffer_out, size_t size); extern int p_rename(const char *from, const char *to); -#ifndef GIT_WIN32 - -#define p_stat(p,b) stat(p, b) -#define p_chdir(p) chdir(p) -#define p_rmdir(p) rmdir(p) -#define p_chmod(p,m) chmod(p, m) -#define p_access(p,m) access(p,m) -#define p_ftruncate(fd, sz) ftruncate(fd, sz) -#define p_recv(s,b,l,f) recv(s,b,l,f) -#define p_send(s,b,l,f) send(s,b,l,f) -typedef int GIT_SOCKET; -#define INVALID_SOCKET -1 - -#define p_localtime_r localtime_r -#define p_gmtime_r gmtime_r - -#else - -typedef SOCKET GIT_SOCKET; -extern struct tm * p_localtime_r (const time_t *timer, struct tm *result); -extern struct tm * p_gmtime_r (const time_t *timer, struct tm *result); - -#endif - /** * Platform-dependent methods */ diff --git a/src/unix/posix.h b/src/unix/posix.h index ccdc7536e..0c8732aff 100644 --- a/src/unix/posix.h +++ b/src/unix/posix.h @@ -10,7 +10,16 @@ #include #include +typedef int GIT_SOCKET; +#define INVALID_SOCKET -1 + +#define p_strcasecmp(s1, s2) strcasecmp(s1, s2) +#define p_strncasecmp(s1, s2, c) strncasecmp(s1, s2, c) + +#define p_lseek(f,n,w) lseek(f, n, w) +#define p_fstat(f,b) fstat(f, b) #define p_lstat(p,b) lstat(p,b) + #define p_readlink(a, b, c) readlink(a, b, c) #define p_symlink(o,n) symlink(o, n) #define p_link(o,n) link(o, n) @@ -18,6 +27,10 @@ #define p_mkdir(p,m) mkdir(p, m) #define p_fsync(fd) fsync(fd) +#define p_recv(s,b,l,f) recv(s,b,l,f) +#define p_send(s,b,l,f) send(s,b,l,f) +#define p_inet_pton(a, b, c) inet_pton(a, b, c) + /* The OpenBSD realpath function behaves differently */ #if !defined(__OpenBSD__) # define p_realpath(p, po) realpath(p, po) @@ -28,9 +41,17 @@ char *p_realpath(const char *, char *); #define p_vsnprintf(b, c, f, a) vsnprintf(b, c, f, a) #define p_snprintf(b, c, f, ...) snprintf(b, c, f, __VA_ARGS__) #define p_mkstemp(p) mkstemp(p) -#define p_inet_pton(a, b, c) inet_pton(a, b, c) +#define p_stat(p,b) stat(p, b) +#define p_chdir(p) chdir(p) +#define p_chmod(p,m) chmod(p, m) +#define p_rmdir(p) rmdir(p) +#define p_access(p,m) access(p,m) +#define p_ftruncate(fd, sz) ftruncate(fd, sz) /* see win32/posix.h for explanation about why this exists */ #define p_lstat_posixly(p,b) lstat(p,b) +#define p_localtime_r(c, r) localtime_r(c, r) +#define p_gmtime_r(c, r) gmtime_r(c, r) + #endif diff --git a/src/win32/mingw-compat.h b/src/win32/mingw-compat.h index 059e39cbc..83ee28765 100644 --- a/src/win32/mingw-compat.h +++ b/src/win32/mingw-compat.h @@ -9,18 +9,11 @@ #if defined(__MINGW32__) -/* use a 64-bit file offset type */ -# undef lseek -# define lseek _lseeki64 -# undef stat -# define stat _stati64 -# undef fstat -# define fstat _fstati64 - -/* stat: file mode type testing macros */ -# define _S_IFLNK 0120000 -# define S_IFLNK _S_IFLNK -# define S_ISLNK(m) (((m) & _S_IFMT) == _S_IFLNK) +#if _WIN32_WINNT >= 0x0601 +#define stat __stat64 +#else +#define stat _stati64 +#endif #endif diff --git a/src/win32/msvc-compat.h b/src/win32/msvc-compat.h index fa4e2912c..efbc8ee37 100644 --- a/src/win32/msvc-compat.h +++ b/src/win32/msvc-compat.h @@ -9,32 +9,10 @@ #if defined(_MSC_VER) -/* access() mode parameter #defines */ -# define F_OK 0 /* existence check */ -# define W_OK 2 /* write mode check */ -# define R_OK 4 /* read mode check */ +/* 64-bit stat information, regardless of USE_32BIT_TIME_T define */ +#define stat __stat64 -# define lseek _lseeki64 -# define stat __stat64 -# define fstat _fstat64 - -/* stat: file mode type testing macros */ -# define _S_IFLNK 0120000 -# define S_IFLNK _S_IFLNK -# define S_IXUSR 00100 - -# define S_ISDIR(m) (((m) & _S_IFMT) == _S_IFDIR) -# define S_ISREG(m) (((m) & _S_IFMT) == _S_IFREG) -# define S_ISFIFO(m) (((m) & _S_IFMT) == _S_IFIFO) -# define S_ISLNK(m) (((m) & _S_IFMT) == _S_IFLNK) - -# define mode_t unsigned short - -/* case-insensitive string comparison */ -# define strcasecmp _stricmp -# define strncasecmp _strnicmp - -/* MSVC doesn't define ssize_t at all */ +typedef unsigned short mode_t; typedef SSIZE_T ssize_t; /* define snprintf using variadic macro support if available */ diff --git a/src/win32/posix.h b/src/win32/posix.h index 22ea6a531..847283719 100644 --- a/src/win32/posix.h +++ b/src/win32/posix.h @@ -12,30 +12,18 @@ #include "utf-conv.h" #include "dir.h" -/* define some standard errnos that the runtime may be missing. for example, - * mingw lacks EAFNOSUPPORT. */ +typedef SOCKET GIT_SOCKET; -#ifndef EAFNOSUPPORT -# define EAFNOSUPPORT (INT_MAX-1) -#endif +#define p_strcasecmp(s1, s2) _stricmp(s1, s2) +#define p_strncasecmp(s1, s2, c) _strnicmp(s1, s2, c) -#if defined(_MSC_VER) && _MSC_VER >= 1500 -# define p_ftruncate(fd, sz) _chsize_s(fd, sz) -#else /* MinGW */ -# define p_ftruncate(fd, sz) _chsize(fd, sz) -#endif - -GIT_INLINE(int) p_link(const char *old, const char *new) -{ - GIT_UNUSED(old); - GIT_UNUSED(new); - errno = ENOSYS; - return -1; -} - -extern int p_mkdir(const char *path, mode_t mode); -extern int p_unlink(const char *path); +#define p_lseek(f,n,w) _lseeki64(f, n, w) +#define p_fstat(f,b) _fstat64(f, b) extern int p_lstat(const char *file_name, struct stat *buf); + +extern int p_link(const char *old, const char *new); +extern int p_unlink(const char *path); +extern int p_mkdir(const char *path, mode_t mode); extern int p_readlink(const char *path, char *buf, size_t bufsiz); extern int p_symlink(const char *old, const char *new); extern char *p_realpath(const char *orig_path, char *buffer); @@ -47,15 +35,15 @@ extern int p_chdir(const char* path); extern int p_chmod(const char* path, mode_t mode); extern int p_rmdir(const char* path); extern int p_access(const char* path, mode_t mode); +extern int p_ftruncate(int fd, long size); extern int p_fsync(int fd); -extern int p_open(const char *path, int flags, ...); -extern int p_creat(const char *path, mode_t mode); -extern int p_getcwd(char *buffer_out, size_t size); -extern int p_rename(const char *from, const char *to); extern int p_recv(GIT_SOCKET socket, void *buffer, size_t length, int flags); extern int p_send(GIT_SOCKET socket, const void *buffer, size_t length, int flags); extern int p_inet_pton(int af, const char* src, void* dst); +extern struct tm * p_localtime_r (const time_t *timer, struct tm *result); +extern struct tm * p_gmtime_r (const time_t *timer, struct tm *result); + /* p_lstat is almost but not quite POSIX correct. Specifically, the use of * ENOTDIR is wrong, in that it does not mean precisely that a non-directory * entry was encountered. Making it correct is potentially expensive, diff --git a/src/win32/posix_w32.c b/src/win32/posix_w32.c index a74fcaad1..7df8100ca 100644 --- a/src/win32/posix_w32.c +++ b/src/win32/posix_w32.c @@ -51,6 +51,15 @@ static int utf8_to_16_with_errno(git_win32_path dest, const char *src) return len; } +int p_ftruncate(int fd, long size) +{ +#if defined(_MSC_VER) && _MSC_VER >= 1500 + return _chsize_s(fd, size); +#else + return _chsize(fd, size); +#endif +} + int p_mkdir(const char *path, mode_t mode) { git_win32_path buf; @@ -63,6 +72,14 @@ int p_mkdir(const char *path, mode_t mode) return _wmkdir(buf); } +int p_link(const char *old, const char *new) +{ + GIT_UNUSED(old); + GIT_UNUSED(new); + errno = ENOSYS; + return -1; +} + int p_unlink(const char *path) { git_win32_path buf;