From 3410b5be3e361f9fc6c429a21d332a220436bca1 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Tue, 3 Aug 2004 14:37:26 +0000 Subject: [PATCH] * errno.cc (errmap): Add ERROR_TOO_MANY_LINKS -> EMLINK mapping. * syscalls.cc (link): Only copy files if FS doesn't support hard links. --- winsup/cygwin/ChangeLog | 5 +++++ winsup/cygwin/errno.cc | 1 + winsup/cygwin/syscalls.cc | 41 ++++++++++++++++++++++++++++++++++++--- 3 files changed, 44 insertions(+), 3 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index d7f447ae9..b15de937d 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,8 @@ +2004-08-03 Corinna Vinschen + + * errno.cc (errmap): Add ERROR_TOO_MANY_LINKS -> EMLINK mapping. + * syscalls.cc (link): Only copy files if FS doesn't support hard links. + 2004-07-26 Christopher January * fhandler_proc.cc (format_proc_cpuinfo): Remove Intel-specific flags diff --git a/winsup/cygwin/errno.cc b/winsup/cygwin/errno.cc index 7d99f7512..d0a5419e2 100644 --- a/winsup/cygwin/errno.cc +++ b/winsup/cygwin/errno.cc @@ -120,6 +120,7 @@ static NO_COPY struct X (DEVICE_REQUIRES_CLEANING, EIO), X (DEVICE_DOOR_OPEN, EIO), X (IO_PENDING, EAGAIN), + X (TOO_MANY_LINKS, EMLINK), { 0, NULL, 0} }; diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc index 81688fd54..49a039d6b 100644 --- a/winsup/cygwin/syscalls.cc +++ b/winsup/cygwin/syscalls.cc @@ -707,6 +707,24 @@ link (const char *a, const char *b) if (CreateHardLinkA (real_b, real_a, NULL)) goto success; + /* There are two cases to consider: + - The FS doesn't support hard links ==> ERROR_INVALID_FUNCTION + We copy the file. + - CreateHardLinkA is not supported ==> ERROR_PROC_NOT_FOUND + In that case (<= NT4) we try the old-style method. + Any other error should be taken seriously. */ + if (GetLastError () == ERROR_INVALID_FUNCTION) + { + syscall_printf ("FS doesn't support hard links: Copy file"); + goto docopy; + } + if (GetLastError () != ERROR_PROC_NOT_FOUND) + { + syscall_printf ("CreateHardLinkA failed"); + __seterrno (); + goto done; + } + HANDLE hFileSource; WIN32_STREAM_ID StreamId; @@ -717,6 +735,7 @@ link (const char *a, const char *b) WCHAR wbuf[CYG_MAX_PATH]; BOOL bSuccess; + DWORD write_err; hFileSource = CreateFile (real_a, FILE_WRITE_ATTRIBUTES, FILE_SHARE_READ | FILE_SHARE_WRITE /*| FILE_SHARE_DELETE*/, @@ -767,7 +786,10 @@ link (const char *a, const char *b) ); if (!bSuccess) - syscall_printf ("cannot write linkname, %E"); + { + write_err = GetLastError (); + syscall_printf ("cannot write linkname, %E"); + } /* Free context */ BackupWrite ( @@ -780,12 +802,25 @@ link (const char *a, const char *b) &lpContext); } else - syscall_printf ("cannot write streamId, %E"); + { + write_err = GetLastError (); + syscall_printf ("cannot write streamId, %E"); + } CloseHandle (hFileSource); if (!bSuccess) - goto docopy; + { + /* Only copy file if FS doesn't support hard links */ + if (write_err == ERROR_INVALID_FUNCTION) + { + syscall_printf ("FS doesn't support hard links: Copy file"); + goto docopy; + } + + __seterrno_from_win_error (write_err); + goto done; + } success: res = 0;