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