4 #include "../git-compat-util.h"
6 unsigned int _CRT_fmode
= _O_BINARY
;
8 int readlink(const char *path
, char *buf
, size_t bufsiz
)
14 int symlink(const char *oldpath
, const char *newpath
)
20 int fchmod(int fildes
, mode_t mode
)
26 int lstat(const char *file_name
, struct stat
*buf
)
29 static char alt_name
[PATH_MAX
];
31 if (!stat(file_name
, buf
))
34 /* if file_name ended in a '/', Windows returned ENOENT;
35 * try again without trailing slashes
39 namelen
= strlen(file_name
);
40 if (namelen
&& file_name
[namelen
-1] != '/')
42 while (namelen
&& file_name
[namelen
-1] == '/')
44 if (!namelen
|| namelen
>= PATH_MAX
)
46 memcpy(alt_name
, file_name
, namelen
);
47 alt_name
[namelen
] = 0;
48 return stat(alt_name
, buf
);
51 /* missing: link, mkstemp, fchmod, getuid (?), gettimeofday */
52 int socketpair(int d
, int type
, int protocol
, int sv
[2])
56 int syslog(int type
, char *bufp
, ...)
60 unsigned int alarm(unsigned int seconds
)
70 int kill(pid_t pid
, int sig
)
74 unsigned int sleep (unsigned int __seconds
)
76 Sleep(__seconds
*1000);
79 const char *inet_ntop(int af
, const void *src
,
80 char *dst
, size_t cnt
)
84 int mkstemp (char *__template
)
86 char *filename
= mktemp(__template
);
89 return open(filename
, O_RDWR
| O_CREAT
, 0600);
92 int gettimeofday(struct timeval
*tv
, void *tz
)
94 extern time_t my_mktime(struct tm
*tm
);
98 tm
.tm_year
= st
.wYear
-1900;
99 tm
.tm_mon
= st
.wMonth
-1;
100 tm
.tm_mday
= st
.wDay
;
101 tm
.tm_hour
= st
.wHour
;
102 tm
.tm_min
= st
.wMinute
;
103 tm
.tm_sec
= st
.wSecond
;
104 tv
->tv_sec
= my_mktime(&tm
);
107 tv
->tv_usec
= st
.wMilliseconds
*1000;
111 int pipe(int filedes
[2])
116 if (_pipe(filedes
, 8192, 0) < 0)
119 parent
= GetCurrentProcess();
121 if (!DuplicateHandle (parent
, (HANDLE
)_get_osfhandle(filedes
[0]),
122 parent
, &h
[0], 0, FALSE
, DUPLICATE_SAME_ACCESS
)) {
127 if (!DuplicateHandle (parent
, (HANDLE
)_get_osfhandle(filedes
[1]),
128 parent
, &h
[1], 0, FALSE
, DUPLICATE_SAME_ACCESS
)) {
134 fd
= _open_osfhandle( (int) h
[0], O_NOINHERIT
);
144 fd
= _open_osfhandle( (int) h
[1], O_NOINHERIT
);
156 int poll(struct pollfd
*ufds
, unsigned int nfds
, int timeout
)
163 struct tm
*gmtime_r(const time_t *timep
, struct tm
*result
)
165 memcpy(result
, gmtime(timep
), sizeof(struct tm
));
169 struct tm
*localtime_r(const time_t *timep
, struct tm
*result
)
171 memcpy(result
, localtime(timep
), sizeof(struct tm
));
176 char *mingw_getcwd(char *pointer
, int len
)
178 char *ret
= getcwd(pointer
, len
);
181 if (pointer
[0] != 0 && pointer
[1] == ':') {
183 for (i
= 2; pointer
[i
]; i
++)
184 /* Thanks, Bill. You'll burn in hell for that. */
185 if (pointer
[i
] == '\\')
195 void openlog(const char *ident
, int option
, int facility
)
199 static const char *quote_arg(const char *arg
)
201 /* count chars to quote */
203 int force_quotes
= 0;
209 else if (*p
== '"' || *p
== '\\')
214 if (!force_quotes
&& n
== 0)
217 /* insert \ where necessary */
218 d
= q
= xmalloc(len
+n
+3);
221 if (*arg
== '"' || *arg
== '\\')
230 void quote_argv(const char **dst
, const char **src
)
233 *dst
++ = quote_arg(*src
++);
237 const char *parse_interpreter(const char *cmd
)
239 static char buf
[100];
243 /* don't even try a .exe */
245 if (n
>= 4 && !strcasecmp(cmd
+n
-4, ".exe"))
248 fd
= open(cmd
, O_RDONLY
);
251 n
= read(fd
, buf
, sizeof(buf
)-1);
253 if (n
< 4) /* at least '#!/x' and not error */
256 if (buf
[0] != '#' || buf
[1] != '!')
259 p
= strchr(buf
, '\n');
264 if (!(p
= strrchr(buf
+2, '/')) && !(p
= strrchr(buf
+2, '\\')))
267 if ((opt
= strchr(p
+1, ' ')))
272 static int try_shell_exec(const char *cmd
, const char **argv
, const char **env
)
274 const char **sh_argv
;
276 const char *interpr
= parse_interpreter(cmd
);
286 for (n
= 0; argv
[n
];) n
++;
287 sh_argv
= xmalloc((n
+2)*sizeof(char*));
288 sh_argv
[0] = interpr
;
289 sh_argv
[1] = quote_arg(cmd
);
290 quote_argv(&sh_argv
[2], &argv
[1]);
291 n
= spawnvpe(_P_WAIT
, interpr
, sh_argv
, env
);
293 return 1; /* indicate that we tried but failed */
297 void mingw_execve(const char *cmd
, const char **argv
, const char **env
)
299 /* check if git_command is a shell script */
300 if (!try_shell_exec(cmd
, argv
, env
)) {
301 int ret
= spawnve(_P_WAIT
, cmd
, argv
, env
);
307 int mingw_socket(int domain
, int type
, int protocol
)
309 SOCKET s
= WSASocket(domain
, type
, protocol
, NULL
, 0, 0);
310 if (s
== INVALID_SOCKET
) {
312 * WSAGetLastError() values are regular BSD error codes
313 * biased by WSABASEERR.
314 * However, strerror() does not know about networking
315 * specific errors, which are values beginning at 38 or so.
316 * Therefore, we choose to leave the biased error code
317 * in errno so that _if_ someone looks up the code somewhere,
318 * then it is at least the number that are usually listed.
320 errno
= WSAGetLastError();
327 int git_exit(int code
)