Path: utzoo!utgpu!water!watmath!clyde!att!osu-cis!tut.cis.ohio-state.edu!rutgers!ucsd!ucbvax!hplabs!hpda!hptsug2!taylor@limbo.ptp.hp.com From: taylor@limbo.ptp.hp.com (Dave Taylor) Newsgroups: comp.sys.hp Subject: Re: Compatible HP-UX 5.1 function "rename" from Berkley 4.3 Message-ID: <541@hptsug2.HP.COM> Date: 24 Sep 88 05:29:51 GMT References: <908@arctic.nprdc.arpa> Sender: taylor@hptsug2.HP.COM Organization: Hewlett-Packard University Grants Program Lines: 134 A while back, while working on porting some BSD code to HP-UX, I also had need for the rename() command. What I ended up doing was reading the BSD man page and attempting to duplicate the behaviour of the command as much as possible -- I have attached this routine below. Note: This comes to you with no warrantee or guarantee --- it worked for the application I was porting, but your milage may vary... -- Dave Taylor Technical Project Team University Grants Program Hewlett-Packard Company ----- attachment: "rename.c" /** rename.c **/ /** This is a short routine to emulate the Berkeley rename() function. The function is defined as: rename(from, to) char *from, *to; Rename causes the link named `from' to be renamed as `to'. If `to' exists then it is first removed. Both `from' and `to' must be of the same type (that is, both directories or both non-directories), and must reside on the same file system. Rename guarantees that an instance of `to' will always exist, even if the system should crash in the middle of the operation. A 0 value is returned if the operation succeeds, otherwise a -1 is returned and ERRNO is set accordingly. What our function does is attempt as much as possible to preserve the functionality listed above. The tough part is ensure that we are never at a point where we might lose both copies of the file... Dave Taylor, Hewlett-Packard Labs, May 1987 with additional code by Debbie Caswell, HP Labs **/ #include#include extern int errno; char *base_directory_name(); rename(from, to) char *from, *to; { char tempfname[256]; /* valid parameters?? */ if ((to == 0 || *to == 0) || (from == 0 || *from == 0)) { errno = ENOENT; return(-1); } /* next let's create the tempfile and save 'to' for luck */ sprintf(tempfname, "%s/rename.%d", base_directory_name(from), getpid()); if (link(to, tempfname) != 0) { if (errno != ENOENT) { /* NOENT is no problem .. continue */ #ifdef DEBUG fprintf(stderr, "rename: Couldn't make the initial link of %s to %s\n", to, tempfname); #endif return(-1); } } (void) unlink(to); if (link(from, to) != 0) { if (link(tempfname, to) != 0) #ifdef DEBUG fprintf(stderr,"rename: couldn't restore %s. Left as %s instead\n", to, tempfname); else fprintf(stderr,"rename: couldn't link %s to %s. Left both.\n", from, to); #else /* nothing to do */ ; #endif return(-1); } /* linked okay, so let's get rid of the tempfile */ (void) unlink(tempfname); /* and the 'from' file.. */ (void) unlink(from); /* and return no errors */ return(0); } char *base_directory_name(filename) char *filename; { /** this returns a pointer to either the directory name specified or to "." if no directory is specified as part of the given filename. **/ static char mybuffer[256]; char *ptr; strcpy(mybuffer, filename); ptr = mybuffer + strlen(mybuffer); while (*ptr != '/' && ptr != mybuffer) ptr--; if (*ptr == '/') *ptr = '\0'; else strcpy(mybuffer, "."); return( (char *) mybuffer); } /***** end of rename.c *****/