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 Berkeleyandy@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));
}