1 /* $NetBSD: sane_link.c,v 1.1.1.2 2013/01/02 18:59:14 tron Exp $ */ 2 3 /*++ 4 /* NAME 5 /* sane_link 3 6 /* SUMMARY 7 /* sanitize link() error returns 8 /* SYNOPSIS 9 /* #include <sane_fsops.h> 10 /* 11 /* int sane_link(from, to) 12 /* const char *from; 13 /* const char *to; 14 /* DESCRIPTION 15 /* sane_link() implements the link(2) system call, and works 16 /* around some errors that are possible with NFS file systems. 17 /* LICENSE 18 /* .ad 19 /* .fi 20 /* The Secure Mailer license must be distributed with this software. 21 /* AUTHOR(S) 22 /* Wietse Venema 23 /* IBM T.J. Watson Research 24 /* P.O. Box 704 25 /* Yorktown Heights, NY 10598, USA 26 /*--*/ 27 28 /* System library. */ 29 30 #include "sys_defs.h" 31 #include <sys/stat.h> 32 #include <errno.h> 33 #include <unistd.h> 34 35 /* Utility library. */ 36 37 #include "msg.h" 38 #include "sane_fsops.h" 39 #include "warn_stat.h" 40 41 /* sane_link - sanitize link() error returns */ 42 43 int sane_link(const char *from, const char *to) 44 { 45 const char *myname = "sane_link"; 46 int saved_errno; 47 struct stat from_st; 48 struct stat to_st; 49 50 /* 51 * Normal case: link() succeeds. 52 */ 53 if (link(from, to) >= 0) 54 return (0); 55 56 /* 57 * Woops. Save errno, and see if the error is an NFS artefact. If it is, 58 * pretend the error never happened. 59 */ 60 saved_errno = errno; 61 if (stat(from, &from_st) >= 0 && stat(to, &to_st) >= 0 62 && from_st.st_dev == to_st.st_dev 63 && from_st.st_ino == to_st.st_ino) { 64 msg_info("%s(%s,%s): worked around spurious NFS error", 65 myname, from, to); 66 return (0); 67 } 68 69 /* 70 * Nope, it didn't. Restore errno and report the error. 71 */ 72 errno = saved_errno; 73 return (-1); 74 } 75