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