1 /* $NetBSD: sane_rename.c,v 1.2 2022/10/08 16:12:50 christos Exp $ */
2
3 /*++
4 /* NAME
5 /* sane_rename 3
6 /* SUMMARY
7 /* sanitize rename() error returns
8 /* SYNOPSIS
9 /* #include <sane_fsops.h>
10 /*
11 /* int sane_rename(old, new)
12 /* const char *from;
13 /* const char *to;
14 /* DESCRIPTION
15 /* sane_rename() implements the rename(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 <stdio.h> /* rename(2) syscall in stdio.h? */
34
35 /* Utility library. */
36
37 #include "msg.h"
38 #include "sane_fsops.h"
39 #include "warn_stat.h"
40
41 /* sane_rename - sanitize rename() error returns */
42
sane_rename(const char * from,const char * to)43 int sane_rename(const char *from, const char *to)
44 {
45 const char *myname = "sane_rename";
46 int saved_errno;
47 struct stat st;
48
49 /*
50 * Normal case: rename() succeeds.
51 */
52 if (rename(from, to) >= 0)
53 return (0);
54
55 /*
56 * Woops. Save errno, and see if the error is an NFS artifact. If it is,
57 * pretend the error never happened.
58 */
59 saved_errno = errno;
60 if (stat(from, &st) < 0 && stat(to, &st) >= 0) {
61 msg_info("%s(%s,%s): worked around spurious NFS error",
62 myname, from, to);
63 return (0);
64 }
65
66 /*
67 * Nope, it didn't. Restore errno and report the error.
68 */
69 errno = saved_errno;
70 return (-1);
71 }
72