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