Raw
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 */