* would normally create a console window. But
* since we'll be redirecting std streams, we do
* not need the console.
+ * It is necessary to use DETACHED_PROCESS
+ * instead of CREATE_NO_WINDOW to make ssh
+ * recognize that it has no console.
*/
- flags = CREATE_NO_WINDOW;
+ flags = DETACHED_PROCESS;
} else {
/* There is already a console. If we specified
- * CREATE_NO_WINDOW here, too, Windows would
+ * DETACHED_PROCESS here, too, Windows would
* disassociate the child from the console.
+ * The same is true for CREATE_NO_WINDOW.
* Go figure!
*/
flags = 0;
#undef rename
int mingw_rename(const char *pold, const char *pnew)
{
+ DWORD attrs;
+
/*
* Try native rename() first to get errno right.
* It is based on MoveFile(), which cannot overwrite existing files.
if (MoveFileEx(pold, pnew, MOVEFILE_REPLACE_EXISTING))
return 0;
/* TODO: translate more errors */
- if (GetLastError() == ERROR_ACCESS_DENIED) {
- DWORD attrs = GetFileAttributes(pnew);
- if (attrs != INVALID_FILE_ATTRIBUTES && (attrs & FILE_ATTRIBUTE_DIRECTORY)) {
+ if (GetLastError() == ERROR_ACCESS_DENIED &&
+ (attrs = GetFileAttributes(pnew)) != INVALID_FILE_ATTRIBUTES) {
+ if (attrs & FILE_ATTRIBUTE_DIRECTORY) {
errno = EISDIR;
return -1;
}
+ if ((attrs & FILE_ATTRIBUTE_READONLY) &&
+ SetFileAttributes(pnew, attrs & ~FILE_ATTRIBUTE_READONLY)) {
+ if (MoveFileEx(pold, pnew, MOVEFILE_REPLACE_EXISTING))
+ return 0;
+ /* revert file attributes on failure */
+ SetFileAttributes(pnew, attrs);
+ }
}
errno = EACCES;
return -1;