andy@garnet.berkeley.edu (Andy Lieberman) (05/17/89)
I'm running on a SUN 3/50 with OS4.something. I need to rename a file from
within a C program, but my call to rename must return an error if a file
with the new name already exists. I cannot simply check for the presence of
the file before calling rename because there's a slight chance that another
process (_completely_ out of my control) may create the file at any time.
I thought of doing a system call to mv (probably through popen), but this
seems very wasteful.
Anybody else faced this before? Is there some way to create a critical
section of code so that I could have:
dont_swap;
if (file_doesnt_exist) {
rename();
}
swap_as_needed;
Please e-mail responses to andy@garnet.Berkeley.EDU and I will post a summary.
Thanks in advance,
Andy Lieberman
Library Systems Office
UC Berkeley
andy@garnet.berkeley.edu (Andy Lieberman) (05/18/89)
The original problem was how to do a rename that would return an error if the file already exists. A number of people showed me how simple this is. Thanks for all the help. From chris@mimsy.umd.edu (many others said the same thing): Use link(), and then, iff it succeeds, unlink(). (rename is like the sequence (void) unlink("dst"); if (link("src", "dst") == 0) (void) unlink("src"); and you want to skip the first part.) Chris -------- From barnett@unclejack.crd.ge.com Wed May 17 07:24:13 1989: Rochkind's book "advanced unix programming" has some simple examples of a file locking mechanism. Page 22 i.e.: #include <stdio.h> #include <errno.h> #define LOCKDIR "/tmp/" #define MAXTRIES 3 #define NAPTIME 5 #define BOOLEAN int #define FALSE 0 #define TRUE 1 BOOLEAN lock(name) /* acquire lock */ char *name; { char *path, *lockpath(); int fd, tries; extern int errno; path = lockpath(name); tries = 0; while ((fd = create(path,0)) == -1 && errno == EACCES) { if (++tries <= MAXTRIES) return (FALSE); sleep (NAPTIME); } if (fd == -1 || clode(fd) == -1) syserr("lock"); return(TRUE); } void unlock(name) /* free lock */ char *name; { char *lockpath(); if (unlink(lockpath(name)) == -1) syserr("unlock"); } static char *lockpath(name) /* generate lock filepath */ char *name; { static char path[20]; char *strcat(); strcpy(path, LOCKDIR); retrun(strcat(path,name)); }