| 1 | #ifndef COMPAT_MINGW_POSIX_H |
| 2 | #define COMPAT_MINGW_POSIX_H |
| 3 | |
| 4 | #ifdef __MINGW64_VERSION_MAJOR |
| 5 | #include <stdint.h> |
| 6 | #include <wchar.h> |
| 7 | typedef _sigset_t sigset_t; |
| 8 | #endif |
| 9 | #include <winsock2.h> |
| 10 | #include <ws2tcpip.h> |
| 11 | |
| 12 | /* MinGW-w64 reports to have flockfile, but it does not actually have it. */ |
| 13 | #ifdef __MINGW64_VERSION_MAJOR |
| 14 | #undef _POSIX_THREAD_SAFE_FUNCTIONS |
| 15 | #endif |
| 16 | |
| 17 | /* |
| 18 | * things that are not available in header files |
| 19 | */ |
| 20 | |
| 21 | typedef int uid_t; |
| 22 | typedef int socklen_t; |
| 23 | #ifndef __MINGW64_VERSION_MAJOR |
| 24 | typedef int pid_t; |
| 25 | #define hstrerror strerror |
| 26 | #endif |
| 27 | |
| 28 | #define S_IFLNK 0120000 /* Symbolic link */ |
| 29 | #define S_ISLNK(x) (((x) & S_IFMT) == S_IFLNK) |
| 30 | #define S_ISSOCK(x) 0 |
| 31 | |
| 32 | #ifndef S_IRWXG |
| 33 | #define S_IRGRP 0 |
| 34 | #define S_IWGRP 0 |
| 35 | #define S_IXGRP 0 |
| 36 | #define S_IRWXG (S_IRGRP | S_IWGRP | S_IXGRP) |
| 37 | #endif |
| 38 | #ifndef S_IRWXO |
| 39 | #define S_IROTH 0 |
| 40 | #define S_IWOTH 0 |
| 41 | #define S_IXOTH 0 |
| 42 | #define S_IRWXO (S_IROTH | S_IWOTH | S_IXOTH) |
| 43 | #endif |
| 44 | |
| 45 | #define S_ISUID 0004000 |
| 46 | #define S_ISGID 0002000 |
| 47 | #define S_ISVTX 0001000 |
| 48 | |
| 49 | #define WIFEXITED(x) 1 |
| 50 | #define WIFSIGNALED(x) 0 |
| 51 | #define WEXITSTATUS(x) ((x) & 0xff) |
| 52 | #define WTERMSIG(x) SIGTERM |
| 53 | |
| 54 | #ifndef EWOULDBLOCK |
| 55 | #define EWOULDBLOCK EAGAIN |
| 56 | #endif |
| 57 | #ifndef ELOOP |
| 58 | #define ELOOP EMLINK |
| 59 | #endif |
| 60 | #define SHUT_WR SD_SEND |
| 61 | |
| 62 | #define SIGHUP 1 |
| 63 | #define SIGQUIT 3 |
| 64 | #define SIGKILL 9 |
| 65 | #define SIGPIPE 13 |
| 66 | #define SIGALRM 14 |
| 67 | #define SIGCHLD 17 |
| 68 | |
| 69 | #define F_GETFD 1 |
| 70 | #define F_SETFD 2 |
| 71 | #define FD_CLOEXEC 0x1 |
| 72 | |
| 73 | #if !defined O_CLOEXEC && defined O_NOINHERIT |
| 74 | #define O_CLOEXEC O_NOINHERIT |
| 75 | #endif |
| 76 | |
| 77 | #ifndef EAFNOSUPPORT |
| 78 | #define EAFNOSUPPORT WSAEAFNOSUPPORT |
| 79 | #endif |
| 80 | #ifndef ECONNABORTED |
| 81 | #define ECONNABORTED WSAECONNABORTED |
| 82 | #endif |
| 83 | #ifndef ENOTSOCK |
| 84 | #define ENOTSOCK WSAENOTSOCK |
| 85 | #endif |
| 86 | |
| 87 | struct passwd { |
| 88 | char *pw_name; |
| 89 | char *pw_gecos; |
| 90 | char *pw_dir; |
| 91 | }; |
| 92 | |
| 93 | typedef void (__cdecl *sig_handler_t)(int); |
| 94 | struct sigaction { |
| 95 | sig_handler_t sa_handler; |
| 96 | unsigned sa_flags; |
| 97 | }; |
| 98 | #define SA_RESTART 0 |
| 99 | #define SA_NOCLDSTOP 1 |
| 100 | |
| 101 | struct itimerval { |
| 102 | struct timeval it_value, it_interval; |
| 103 | }; |
| 104 | #define ITIMER_REAL 0 |
| 105 | |
| 106 | struct utsname { |
| 107 | char sysname[16]; |
| 108 | char nodename[1]; |
| 109 | char release[16]; |
| 110 | char version[16]; |
| 111 | char machine[1]; |
| 112 | }; |
| 113 | |
| 114 | /* |
| 115 | * sanitize preprocessor namespace polluted by Windows headers defining |
| 116 | * macros which collide with git local versions |
| 117 | */ |
| 118 | #undef HELP_COMMAND /* from winuser.h */ |
| 119 | |
| 120 | /* |
| 121 | * trivial stubs |
| 122 | */ |
| 123 | |
| 124 | static inline int fchmod(int fildes UNUSED, mode_t mode UNUSED) |
| 125 | { errno = ENOSYS; return -1; } |
| 126 | #ifndef __MINGW64_VERSION_MAJOR |
| 127 | static inline pid_t fork(void) |
| 128 | { errno = ENOSYS; return -1; } |
| 129 | #endif |
| 130 | static inline unsigned int alarm(unsigned int seconds UNUSED) |
| 131 | { return 0; } |
| 132 | static inline int fsync(int fd) |
| 133 | { return _commit(fd); } |
| 134 | static inline void sync(void) |
| 135 | {} |
| 136 | static inline uid_t getuid(void) |
| 137 | { return 1; } |
| 138 | static inline struct passwd *getpwnam(const char *name UNUSED) |
| 139 | { return NULL; } |
| 140 | static inline int fcntl(int fd UNUSED, int cmd, ...) |
| 141 | { |
| 142 | if (cmd == F_GETFD || cmd == F_SETFD) |
| 143 | return 0; |
| 144 | errno = EINVAL; |
| 145 | return -1; |
| 146 | } |
| 147 | |
| 148 | #define sigemptyset(x) (void)0 |
| 149 | static inline int sigaddset(sigset_t *set UNUSED, int signum UNUSED) |
| 150 | { return 0; } |
| 151 | #define SIG_BLOCK 0 |
| 152 | #define SIG_UNBLOCK 0 |
| 153 | static inline int sigprocmask(int how UNUSED, const sigset_t *set UNUSED, sigset_t *oldset UNUSED) |
| 154 | { return 0; } |
| 155 | static inline pid_t getppid(void) |
| 156 | { return 1; } |
| 157 | static inline pid_t getpgid(pid_t pid) |
| 158 | { return pid == 0 ? getpid() : pid; } |
| 159 | static inline pid_t tcgetpgrp(int fd UNUSED) |
| 160 | { return getpid(); } |
| 161 | |
| 162 | /* |
| 163 | * simple adaptors |
| 164 | */ |
| 165 | |
| 166 | int mingw_mkdir(const char *path, int mode); |
| 167 | #define mkdir mingw_mkdir |
| 168 | |
| 169 | #define WNOHANG 1 |
| 170 | pid_t waitpid(pid_t pid, int *status, int options); |
| 171 | |
| 172 | #define kill mingw_kill |
| 173 | int mingw_kill(pid_t pid, int sig); |
| 174 | |
| 175 | #define locate_in_PATH mingw_locate_in_PATH |
| 176 | char *mingw_locate_in_PATH(const char *cmd); |
| 177 | |
| 178 | /* |
| 179 | * implementations of missing functions |
| 180 | */ |
| 181 | |
| 182 | int pipe(int filedes[2]); |
| 183 | unsigned int sleep (unsigned int seconds); |
| 184 | int mkstemp(char *template); |
| 185 | int gettimeofday(struct timeval *tv, void *tz); |
| 186 | #ifndef __MINGW64_VERSION_MAJOR |
| 187 | struct tm *gmtime_r(const time_t *timep, struct tm *result); |
| 188 | struct tm *localtime_r(const time_t *timep, struct tm *result); |
| 189 | #endif |
| 190 | int getpagesize(void); /* defined in MinGW's libgcc.a */ |
| 191 | struct passwd *getpwuid(uid_t uid); |
| 192 | int setitimer(int type, struct itimerval *in, struct itimerval *out); |
| 193 | int sigaction(int sig, struct sigaction *in, struct sigaction *out); |
| 194 | int link(const char *oldpath, const char *newpath); |
| 195 | int uname(struct utsname *buf); |
| 196 | int symlink(const char *target, const char *link); |
| 197 | int readlink(const char *path, char *buf, size_t bufsiz); |
| 198 | |
| 199 | /* |
| 200 | * replacements of existing functions |
| 201 | */ |
| 202 | |
| 203 | int mingw_unlink(const char *pathname, int handle_in_use_error); |
| 204 | #ifdef MINGW_DONT_HANDLE_IN_USE_ERROR |
| 205 | # define unlink(path) mingw_unlink(path, 0) |
| 206 | #else |
| 207 | # define unlink(path) mingw_unlink(path, 1) |
| 208 | #endif |
| 209 | |
| 210 | int mingw_rmdir(const char *path); |
| 211 | #define rmdir mingw_rmdir |
| 212 | |
| 213 | int mingw_open (const char *filename, int oflags, ...); |
| 214 | #define open mingw_open |
| 215 | #undef OPEN_RETURNS_EINTR |
| 216 | |
| 217 | int mingw_fgetc(FILE *stream); |
| 218 | #define fgetc mingw_fgetc |
| 219 | |
| 220 | FILE *mingw_fopen (const char *filename, const char *otype); |
| 221 | #define fopen mingw_fopen |
| 222 | |
| 223 | FILE *mingw_freopen (const char *filename, const char *otype, FILE *stream); |
| 224 | #define freopen mingw_freopen |
| 225 | |
| 226 | int mingw_fflush(FILE *stream); |
| 227 | #define fflush mingw_fflush |
| 228 | |
| 229 | ssize_t mingw_write(int fd, const void *buf, size_t len); |
| 230 | #define write mingw_write |
| 231 | |
| 232 | int mingw_access(const char *filename, int mode); |
| 233 | #undef access |
| 234 | #define access mingw_access |
| 235 | |
| 236 | int mingw_chdir(const char *dirname); |
| 237 | #define chdir mingw_chdir |
| 238 | |
| 239 | int mingw_chmod(const char *filename, int mode); |
| 240 | #define chmod mingw_chmod |
| 241 | |
| 242 | char *mingw_getcwd(char *pointer, int len); |
| 243 | #define getcwd mingw_getcwd |
| 244 | |
| 245 | #ifdef NO_UNSETENV |
| 246 | #error "NO_UNSETENV is incompatible with the Windows-specific startup code!" |
| 247 | #endif |
| 248 | |
| 249 | /* |
| 250 | * We bind *env() routines (even the mingw_ ones) to private mingw_ versions. |
| 251 | * These talk to the CRT using UNICODE/wchar_t, but maintain the original |
| 252 | * narrow-char API. |
| 253 | * |
| 254 | * Note that the MSCRT maintains both ANSI (getenv()) and UNICODE (_wgetenv()) |
| 255 | * routines and stores both versions of each environment variable in parallel |
| 256 | * (and secretly updates both when you set one or the other), but it uses CP_ACP |
| 257 | * to do the conversion rather than CP_UTF8. |
| 258 | * |
| 259 | * Since everything in the git code base is UTF8, we define the mingw_ routines |
| 260 | * to access the CRT using the UNICODE routines and manually convert them to |
| 261 | * UTF8. This also avoids round-trip problems. |
| 262 | * |
| 263 | * This also helps with our linkage, since "_wenviron" is publicly exported |
| 264 | * from the CRT. But to access "_environ" we would have to statically link |
| 265 | * to the CRT (/MT). |
| 266 | * |
| 267 | * We require NO_SETENV (and let gitsetenv() call our mingw_putenv). |
| 268 | */ |
| 269 | #define getenv mingw_getenv |
| 270 | #define putenv mingw_putenv |
| 271 | #define unsetenv mingw_putenv |
| 272 | char *mingw_getenv(const char *name); |
| 273 | int mingw_putenv(const char *name); |
| 274 | |
| 275 | int mingw_gethostname(char *host, int namelen); |
| 276 | #define gethostname mingw_gethostname |
| 277 | |
| 278 | struct hostent *mingw_gethostbyname(const char *host); |
| 279 | #define gethostbyname mingw_gethostbyname |
| 280 | |
| 281 | int mingw_getaddrinfo(const char *node, const char *service, |
| 282 | const struct addrinfo *hints, struct addrinfo **res); |
| 283 | #define getaddrinfo mingw_getaddrinfo |
| 284 | |
| 285 | int mingw_socket(int domain, int type, int protocol); |
| 286 | #define socket mingw_socket |
| 287 | |
| 288 | int mingw_connect(int sockfd, struct sockaddr *sa, size_t sz); |
| 289 | #define connect mingw_connect |
| 290 | |
| 291 | int mingw_bind(int sockfd, struct sockaddr *sa, size_t sz); |
| 292 | #define bind mingw_bind |
| 293 | |
| 294 | int mingw_setsockopt(int sockfd, int lvl, int optname, void *optval, int optlen); |
| 295 | #define setsockopt mingw_setsockopt |
| 296 | |
| 297 | int mingw_shutdown(int sockfd, int how); |
| 298 | #define shutdown mingw_shutdown |
| 299 | |
| 300 | int mingw_listen(int sockfd, int backlog); |
| 301 | #define listen mingw_listen |
| 302 | |
| 303 | int mingw_accept(int sockfd, struct sockaddr *sa, socklen_t *sz); |
| 304 | #define accept mingw_accept |
| 305 | |
| 306 | int mingw_rename(const char*, const char*); |
| 307 | #define rename mingw_rename |
| 308 | |
| 309 | #if defined(USE_WIN32_MMAP) || defined(_MSC_VER) |
| 310 | int mingw_getpagesize(void); |
| 311 | #define getpagesize mingw_getpagesize |
| 312 | #endif |
| 313 | |
| 314 | int win32_fsync_no_flush(int fd); |
| 315 | #define fsync_no_flush win32_fsync_no_flush |
| 316 | |
| 317 | #define FSYNC_COMPONENTS_PLATFORM_DEFAULT (FSYNC_COMPONENTS_DEFAULT | FSYNC_COMPONENT_LOOSE_OBJECT) |
| 318 | #define FSYNC_METHOD_DEFAULT (FSYNC_METHOD_BATCH) |
| 319 | |
| 320 | struct rlimit { |
| 321 | unsigned int rlim_cur; |
| 322 | }; |
| 323 | #define RLIMIT_NOFILE 0 |
| 324 | |
| 325 | static inline int getrlimit(int resource, struct rlimit *rlp) |
| 326 | { |
| 327 | if (resource != RLIMIT_NOFILE) { |
| 328 | errno = EINVAL; |
| 329 | return -1; |
| 330 | } |
| 331 | |
| 332 | rlp->rlim_cur = 2048; |
| 333 | return 0; |
| 334 | } |
| 335 | |
| 336 | /* |
| 337 | * Use mingw specific stat()/lstat()/fstat() implementations on Windows, |
| 338 | * including our own struct stat with 64 bit st_size and nanosecond-precision |
| 339 | * file times. |
| 340 | */ |
| 341 | #ifndef __MINGW64_VERSION_MAJOR |
| 342 | #define off_t off64_t |
| 343 | #define lseek _lseeki64 |
| 344 | #ifndef _MSC_VER |
| 345 | struct timespec { |
| 346 | time_t tv_sec; |
| 347 | long tv_nsec; |
| 348 | }; |
| 349 | #endif |
| 350 | #endif |
| 351 | |
| 352 | struct mingw_stat { |
| 353 | _dev_t st_dev; |
| 354 | _ino_t st_ino; |
| 355 | _mode_t st_mode; |
| 356 | short st_nlink; |
| 357 | short st_uid; |
| 358 | short st_gid; |
| 359 | _dev_t st_rdev; |
| 360 | off64_t st_size; |
| 361 | struct timespec st_atim; |
| 362 | struct timespec st_mtim; |
| 363 | struct timespec st_ctim; |
| 364 | }; |
| 365 | |
| 366 | #define st_atime st_atim.tv_sec |
| 367 | #define st_mtime st_mtim.tv_sec |
| 368 | #define st_ctime st_ctim.tv_sec |
| 369 | |
| 370 | #ifdef stat |
| 371 | #undef stat |
| 372 | #endif |
| 373 | #define stat mingw_stat |
| 374 | int mingw_lstat(const char *file_name, struct stat *buf); |
| 375 | int mingw_stat(const char *file_name, struct stat *buf); |
| 376 | int mingw_fstat(int fd, struct stat *buf); |
| 377 | #ifdef fstat |
| 378 | #undef fstat |
| 379 | #endif |
| 380 | #define fstat mingw_fstat |
| 381 | #ifdef lstat |
| 382 | #undef lstat |
| 383 | #endif |
| 384 | #define lstat mingw_lstat |
| 385 | |
| 386 | |
| 387 | int mingw_utime(const char *file_name, const struct utimbuf *times); |
| 388 | #define utime mingw_utime |
| 389 | size_t mingw_strftime(char *s, size_t max, |
| 390 | const char *format, const struct tm *tm); |
| 391 | #define strftime mingw_strftime |
| 392 | |
| 393 | pid_t mingw_spawnvpe(const char *cmd, const char **argv, char **env, |
| 394 | const char *dir, |
| 395 | int fhin, int fhout, int fherr); |
| 396 | int mingw_execvp(const char *cmd, char *const *argv); |
| 397 | #define execvp mingw_execvp |
| 398 | int mingw_execv(const char *cmd, char *const *argv); |
| 399 | #define execv mingw_execv |
| 400 | |
| 401 | static inline unsigned int git_ntohl(unsigned int x) |
| 402 | { return (unsigned int)ntohl(x); } |
| 403 | #define ntohl git_ntohl |
| 404 | |
| 405 | sig_handler_t mingw_signal(int sig, sig_handler_t handler); |
| 406 | #define signal mingw_signal |
| 407 | |
| 408 | int mingw_raise(int sig); |
| 409 | #define raise mingw_raise |
| 410 | |
| 411 | /* |
| 412 | * ANSI emulation wrappers |
| 413 | */ |
| 414 | |
| 415 | int winansi_isatty(int fd); |
| 416 | #define isatty winansi_isatty |
| 417 | |
| 418 | int winansi_dup2(int oldfd, int newfd); |
| 419 | #define dup2 winansi_dup2 |
| 420 | |
| 421 | void winansi_init(void); |
| 422 | HANDLE winansi_get_osfhandle(int fd); |
| 423 | |
| 424 | #if !defined(__MINGW64_VERSION_MAJOR) && (!defined(_MSC_VER) || _MSC_VER < 1800) |
| 425 | #define PRIuMAX "I64u" |
| 426 | #define PRId64 "I64d" |
| 427 | #else |
| 428 | #include <inttypes.h> |
| 429 | #endif |
| 430 | |
| 431 | #endif /* COMPAT_MINGW_POSIX_H */ |