X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=compat%2Fmingw.c;h=e190fddf41d6b15d9254859fca8b638ed7c0f428;hb=9619ff14159ab3401636b9883a715b0f20b051df;hp=2839d9df6ee8ed1e7227769877b04dd9b542f496;hpb=85b7bd50c47e0f5236cdb93d1be3163a8a1a3be6;p=git.git diff --git a/compat/mingw.c b/compat/mingw.c index 2839d9df6..e190fddf4 100644 --- a/compat/mingw.c +++ b/compat/mingw.c @@ -396,7 +396,7 @@ repeat: * its own input data to become available. But since * the process (pack-objects) is itself CPU intensive, * it will happily pick up the time slice that we are - * relinguishing here. + * relinquishing here. */ Sleep(0); goto repeat; @@ -525,8 +525,8 @@ static const char *parse_interpreter(const char *cmd) if (buf[0] != '#' || buf[1] != '!') return NULL; buf[n] = '\0'; - p = strchr(buf, '\n'); - if (!p) + p = buf + strcspn(buf, "\r\n"); + if (!*p) return NULL; *p = '\0'; @@ -562,7 +562,7 @@ static char **get_path_split(void) if (!n) return NULL; - path = xmalloc((n+1)*sizeof(char*)); + path = xmalloc((n+1)*sizeof(char *)); p = envpath; i = 0; do { @@ -934,7 +934,9 @@ int mingw_connect(int sockfd, struct sockaddr *sa, size_t sz) #undef rename int mingw_rename(const char *pold, const char *pnew) { - DWORD attrs; + DWORD attrs, gle; + int tries = 0; + static const int delay[] = { 0, 1, 10, 20, 40 }; /* * Try native rename() first to get errno right. @@ -944,10 +946,12 @@ int mingw_rename(const char *pold, const char *pnew) return 0; if (errno != EEXIST) return -1; +repeat: if (MoveFileEx(pold, pnew, MOVEFILE_REPLACE_EXISTING)) return 0; /* TODO: translate more errors */ - if (GetLastError() == ERROR_ACCESS_DENIED && + gle = GetLastError(); + if (gle == ERROR_ACCESS_DENIED && (attrs = GetFileAttributes(pnew)) != INVALID_FILE_ATTRIBUTES) { if (attrs & FILE_ATTRIBUTE_DIRECTORY) { errno = EISDIR; @@ -957,10 +961,23 @@ int mingw_rename(const char *pold, const char *pnew) SetFileAttributes(pnew, attrs & ~FILE_ATTRIBUTE_READONLY)) { if (MoveFileEx(pold, pnew, MOVEFILE_REPLACE_EXISTING)) return 0; + gle = GetLastError(); /* revert file attributes on failure */ SetFileAttributes(pnew, attrs); } } + if (tries < ARRAY_SIZE(delay) && gle == ERROR_ACCESS_DENIED) { + /* + * We assume that some other process had the source or + * destination file open at the wrong moment and retry. + * In order to give the other process a higher chance to + * complete its operation, we give up our time slice now. + * If we have to retry again, we do sleep a bit. + */ + Sleep(delay[tries]); + tries++; + goto repeat; + } errno = EACCES; return -1; } @@ -1139,3 +1156,18 @@ int link(const char *oldpath, const char *newpath) } return 0; } + +char *getpass(const char *prompt) +{ + struct strbuf buf = STRBUF_INIT; + + fputs(prompt, stderr); + for (;;) { + char c = _getch(); + if (c == '\r' || c == '\n') + break; + strbuf_addch(&buf, c); + } + fputs("\n", stderr); + return strbuf_detach(&buf, NULL); +}