X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;f=lib%2Flink.c;h=94a6dda11c27414616b5da5c24fc9ac78633d5a4;hb=a77413333408e54b8d6c4e19918098794cef4b4b;hp=994ae4569cd233bdc74f83e02a9852597dd44a7e;hpb=f7b182c11bce2ba412f47a764dd7555a488dbfb1;p=gnulib.git diff --git a/lib/link.c b/lib/link.c index 994ae4569..94a6dda11 100644 --- a/lib/link.c +++ b/lib/link.c @@ -1,6 +1,6 @@ /* Emulate link on platforms that lack it, namely native Windows platforms. - Copyright (C) 2009 Free Software Foundation, Inc. + Copyright (C) 2009-2013 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -13,8 +13,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + along with this program; if not, see . */ #include @@ -33,8 +32,8 @@ /* CreateHardLink was introduced only in Windows 2000. */ typedef BOOL (WINAPI * CreateHardLinkFuncType) (LPCTSTR lpFileName, - LPCTSTR lpExistingFileName, - LPSECURITY_ATTRIBUTES lpSecurityAttributes); + LPCTSTR lpExistingFileName, + LPSECURITY_ATTRIBUTES lpSecurityAttributes); static CreateHardLinkFuncType CreateHardLinkFunc = NULL; static BOOL initialized = FALSE; @@ -45,7 +44,7 @@ initialize (void) if (kernel32 != NULL) { CreateHardLinkFunc = - (CreateHardLinkFuncType) GetProcAddress (kernel32, "CreateHardLinkA"); + (CreateHardLinkFuncType) GetProcAddress (kernel32, "CreateHardLinkA"); } initialized = TRUE; } @@ -103,39 +102,39 @@ link (const char *file1, const char *file2) * system. */ DWORD err = GetLastError (); switch (err) - { - case ERROR_ACCESS_DENIED: - errno = EACCES; - break; - - case ERROR_INVALID_FUNCTION: /* fs does not support hard links */ - errno = EPERM; - break; - - case ERROR_NOT_SAME_DEVICE: - errno = EXDEV; - break; - - case ERROR_PATH_NOT_FOUND: - case ERROR_FILE_NOT_FOUND: - errno = ENOENT; - break; - - case ERROR_INVALID_PARAMETER: - errno = ENAMETOOLONG; - break; - - case ERROR_TOO_MANY_LINKS: - errno = EMLINK; - break; - - case ERROR_ALREADY_EXISTS: - errno = EEXIST; - break; - - default: - errno = EIO; - } + { + case ERROR_ACCESS_DENIED: + errno = EACCES; + break; + + case ERROR_INVALID_FUNCTION: /* fs does not support hard links */ + errno = EPERM; + break; + + case ERROR_NOT_SAME_DEVICE: + errno = EXDEV; + break; + + case ERROR_PATH_NOT_FOUND: + case ERROR_FILE_NOT_FOUND: + errno = ENOENT; + break; + + case ERROR_INVALID_PARAMETER: + errno = ENAMETOOLONG; + break; + + case ERROR_TOO_MANY_LINKS: + errno = EMLINK; + break; + + case ERROR_ALREADY_EXISTS: + errno = EEXIST; + break; + + default: + errno = EIO; + } return -1; } @@ -155,9 +154,20 @@ link (const char *file1, const char *file2) int rpl_link (char const *file1, char const *file2) { + size_t len1; + size_t len2; + struct stat st; + + /* Don't allow IRIX to dereference dangling file2 symlink. */ + if (!lstat (file2, &st)) + { + errno = EEXIST; + return -1; + } + /* Reject trailing slashes on non-directories. */ - size_t len1 = strlen (file1); - size_t len2 = strlen (file2); + len1 = strlen (file1); + len2 = strlen (file2); if ((len1 && file1[len1 - 1] == '/') || (len2 && file2[len2 - 1] == '/')) { @@ -165,7 +175,6 @@ rpl_link (char const *file1, char const *file2) If stat() fails, then link() should fail for the same reason (although on Solaris 9, link("file/","oops") mistakenly succeeds); if stat() succeeds, require a directory. */ - struct stat st; if (stat (file1, &st)) return -1; if (!S_ISDIR (st.st_mode)) @@ -178,7 +187,6 @@ rpl_link (char const *file1, char const *file2) { /* Fix Cygwin 1.5.x bug where link("a","b/.") creates file "b". */ char *dir = strdup (file2); - struct stat st; char *p; if (!dir) return -1;