aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/w32.c65
1 files changed, 54 insertions, 11 deletions
diff --git a/src/w32.c b/src/w32.c
index 757c536b191..ab97e39c7be 100644
--- a/src/w32.c
+++ b/src/w32.c
@@ -1304,7 +1304,7 @@ filename_from_utf16 (const wchar_t *fn_in, char *fn_out)
1304static int 1304static int
1305filename_to_ansi (const char *fn_in, char *fn_out) 1305filename_to_ansi (const char *fn_in, char *fn_out)
1306{ 1306{
1307 wchar_t fn_utf16[MAXPATHLEN]; 1307 wchar_t fn_utf16[MAX_PATH];
1308 1308
1309 if (filename_to_utf16 (fn_in, fn_utf16) == 0) 1309 if (filename_to_utf16 (fn_in, fn_utf16) == 0)
1310 { 1310 {
@@ -1312,7 +1312,7 @@ filename_to_ansi (const char *fn_in, char *fn_out)
1312 int codepage = codepage_for_filenames (NULL); 1312 int codepage = codepage_for_filenames (NULL);
1313 1313
1314 result = WideCharToMultiByte (codepage, 0, fn_utf16, -1, 1314 result = WideCharToMultiByte (codepage, 0, fn_utf16, -1,
1315 fn_out, MAX_UTF8_PATH, NULL, NULL); 1315 fn_out, MAX_PATH, NULL, NULL);
1316 if (!result) 1316 if (!result)
1317 { 1317 {
1318 DWORD err = GetLastError (); 1318 DWORD err = GetLastError ();
@@ -1339,7 +1339,7 @@ filename_to_ansi (const char *fn_in, char *fn_out)
1339int 1339int
1340filename_from_ansi (const char *fn_in, char *fn_out) 1340filename_from_ansi (const char *fn_in, char *fn_out)
1341{ 1341{
1342 wchar_t fn_utf16[MAXPATHLEN]; 1342 wchar_t fn_utf16[MAX_PATH];
1343 int codepage = codepage_for_filenames (NULL); 1343 int codepage = codepage_for_filenames (NULL);
1344 int result = MultiByteToWideChar (codepage, MB_ERR_INVALID_CHARS, fn_in, -1, 1344 int result = MultiByteToWideChar (codepage, MB_ERR_INVALID_CHARS, fn_in, -1,
1345 fn_utf16, MAX_PATH); 1345 fn_utf16, MAX_PATH);
@@ -4573,13 +4573,32 @@ utime (const char *name, struct utimbuf *times)
4573 times = &deftime; 4573 times = &deftime;
4574 } 4574 }
4575 4575
4576 /* Need write access to set times. */ 4576 if (w32_unicode_filenames)
4577 fh = CreateFile (name, FILE_WRITE_ATTRIBUTES, 4577 {
4578 /* If NAME specifies a directory, FILE_SHARE_DELETE 4578 wchar_t name_utf16[MAX_PATH];
4579 allows other processes to delete files inside it, 4579
4580 while we have the directory open. */ 4580 if (filename_to_utf16 (name, name_utf16) != 0)
4581 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 4581 return -1; /* errno set by filename_to_utf16 */
4582 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); 4582
4583 /* Need write access to set times. */
4584 fh = CreateFileW (name_utf16, FILE_WRITE_ATTRIBUTES,
4585 /* If NAME specifies a directory, FILE_SHARE_DELETE
4586 allows other processes to delete files inside it,
4587 while we have the directory open. */
4588 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
4589 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
4590 }
4591 else
4592 {
4593 char name_ansi[MAX_PATH];
4594
4595 if (filename_to_ansi (name, name_ansi) != 0)
4596 return -1; /* errno set by filename_to_ansi */
4597
4598 fh = CreateFileA (name_ansi, FILE_WRITE_ATTRIBUTES,
4599 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
4600 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
4601 }
4583 if (fh != INVALID_HANDLE_VALUE) 4602 if (fh != INVALID_HANDLE_VALUE)
4584 { 4603 {
4585 convert_from_time_t (times->actime, &atime); 4604 convert_from_time_t (times->actime, &atime);
@@ -4594,7 +4613,31 @@ utime (const char *name, struct utimbuf *times)
4594 } 4613 }
4595 else 4614 else
4596 { 4615 {
4597 errno = EINVAL; 4616 DWORD err = GetLastError ();
4617
4618 switch (err)
4619 {
4620 case ERROR_FILE_NOT_FOUND:
4621 case ERROR_PATH_NOT_FOUND:
4622 case ERROR_INVALID_DRIVE:
4623 case ERROR_BAD_NETPATH:
4624 case ERROR_DEV_NOT_EXIST:
4625 /* ERROR_INVALID_NAME is the error CreateFile sets when the
4626 file name includes ?s, i.e. translation to ANSI failed. */
4627 case ERROR_INVALID_NAME:
4628 errno = ENOENT;
4629 break;
4630 case ERROR_TOO_MANY_OPEN_FILES:
4631 errno = ENFILE;
4632 break;
4633 case ERROR_ACCESS_DENIED:
4634 case ERROR_SHARING_VIOLATION:
4635 errno = EACCES;
4636 break;
4637 default:
4638 errno = EINVAL;
4639 break;
4640 }
4598 return -1; 4641 return -1;
4599 } 4642 }
4600 return 0; 4643 return 0;