2003-11-12 00:52:45 +01:00
|
|
|
/*-------------------------------------------------------------------------
|
|
|
|
*
|
|
|
|
* dirmod.c
|
|
|
|
* rename/unlink()
|
|
|
|
*
|
|
|
|
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
|
|
|
|
* Portions Copyright (c) 1994, Regents of the University of California
|
|
|
|
*
|
2003-04-24 18:40:17 +02:00
|
|
|
* These are replacement versions of unlink and rename that work on
|
2003-08-04 02:43:34 +02:00
|
|
|
* Win32 (NT, Win2k, XP). replace() doesn't work on Win95/98/Me.
|
2003-11-12 00:52:45 +01:00
|
|
|
*
|
|
|
|
* IDENTIFICATION
|
2004-02-02 23:20:33 +01:00
|
|
|
* $PostgreSQL: pgsql/src/port/dirmod.c,v 1.10 2004/02/02 22:20:33 momjian Exp $
|
2003-11-12 00:52:45 +01:00
|
|
|
*
|
|
|
|
*-------------------------------------------------------------------------
|
2003-04-24 18:40:17 +02:00
|
|
|
*/
|
2003-08-04 02:43:34 +02:00
|
|
|
|
2003-04-22 04:18:48 +02:00
|
|
|
#ifndef TEST_VERSION
|
|
|
|
|
2004-02-02 23:20:33 +01:00
|
|
|
#if defined(WIN32) || defined(CYGWIN)
|
|
|
|
|
|
|
|
#ifndef FRONTEND
|
2003-05-15 18:35:30 +02:00
|
|
|
#include "postgres.h"
|
2004-02-02 23:20:33 +01:00
|
|
|
#else
|
|
|
|
#include "postgres_fe.h"
|
|
|
|
#endif
|
2003-05-15 18:35:30 +02:00
|
|
|
|
2003-04-22 04:18:48 +02:00
|
|
|
#undef rename
|
|
|
|
#undef unlink
|
|
|
|
|
2003-07-27 19:10:07 +02:00
|
|
|
int
|
|
|
|
pgrename(const char *from, const char *to)
|
2003-04-22 04:18:48 +02:00
|
|
|
{
|
2003-08-04 02:43:34 +02:00
|
|
|
int loops = 0;
|
2003-04-22 04:18:48 +02:00
|
|
|
|
2004-02-02 01:17:23 +01:00
|
|
|
#ifdef WIN32
|
2003-04-22 04:18:48 +02:00
|
|
|
while (!MoveFileEx(from, to, MOVEFILE_REPLACE_EXISTING))
|
2004-02-02 01:17:23 +01:00
|
|
|
#endif
|
|
|
|
#ifdef CYGWIN
|
|
|
|
while (rename(from, to) < 0)
|
|
|
|
#endif
|
2003-04-22 04:18:48 +02:00
|
|
|
{
|
2004-02-02 01:17:23 +01:00
|
|
|
#ifdef WIN32
|
2003-04-22 04:18:48 +02:00
|
|
|
if (GetLastError() != ERROR_ACCESS_DENIED)
|
2004-02-02 01:17:23 +01:00
|
|
|
#endif
|
|
|
|
#ifdef CYGWIN
|
|
|
|
if (errno != EACCES)
|
|
|
|
#endif
|
2003-04-22 04:18:48 +02:00
|
|
|
/* set errno? */
|
|
|
|
return -1;
|
2003-08-04 02:43:34 +02:00
|
|
|
Sleep(100); /* ms */
|
2003-10-10 05:27:58 +02:00
|
|
|
if (loops == 30)
|
2003-04-22 04:18:48 +02:00
|
|
|
#ifndef FRONTEND
|
2003-07-27 19:10:07 +02:00
|
|
|
elog(LOG, "could not rename \"%s\" to \"%s\", continuing to try",
|
|
|
|
from, to);
|
2003-04-22 04:18:48 +02:00
|
|
|
#else
|
2003-07-27 19:10:07 +02:00
|
|
|
fprintf(stderr, "could not rename \"%s\" to \"%s\", continuing to try\n",
|
|
|
|
from, to);
|
2003-04-22 04:18:48 +02:00
|
|
|
#endif
|
|
|
|
loops++;
|
|
|
|
}
|
|
|
|
|
2003-10-10 05:27:58 +02:00
|
|
|
if (loops > 30)
|
2003-04-22 04:18:48 +02:00
|
|
|
#ifndef FRONTEND
|
2003-07-27 19:10:07 +02:00
|
|
|
elog(LOG, "completed rename of \"%s\" to \"%s\"", from, to);
|
2003-04-22 04:18:48 +02:00
|
|
|
#else
|
2003-07-27 19:10:07 +02:00
|
|
|
fprintf(stderr, "completed rename of \"%s\" to \"%s\"\n", from, to);
|
2003-04-22 04:18:48 +02:00
|
|
|
#endif
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-07-27 19:10:07 +02:00
|
|
|
int
|
|
|
|
pgunlink(const char *path)
|
2003-04-22 04:18:48 +02:00
|
|
|
{
|
2003-08-04 02:43:34 +02:00
|
|
|
int loops = 0;
|
2003-04-22 04:18:48 +02:00
|
|
|
|
|
|
|
while (unlink(path))
|
|
|
|
{
|
|
|
|
if (errno != EACCES)
|
|
|
|
/* set errno? */
|
|
|
|
return -1;
|
2003-08-04 02:43:34 +02:00
|
|
|
Sleep(100); /* ms */
|
2003-10-10 05:27:58 +02:00
|
|
|
if (loops == 30)
|
2003-04-22 04:18:48 +02:00
|
|
|
#ifndef FRONTEND
|
2003-07-27 19:10:07 +02:00
|
|
|
elog(LOG, "could not unlink \"%s\", continuing to try",
|
|
|
|
path);
|
2003-04-22 04:18:48 +02:00
|
|
|
#else
|
2003-07-27 19:10:07 +02:00
|
|
|
fprintf(stderr, "could not unlink \"%s\", continuing to try\n",
|
|
|
|
path);
|
2003-04-22 04:18:48 +02:00
|
|
|
#endif
|
|
|
|
loops++;
|
|
|
|
}
|
|
|
|
|
2003-10-10 05:27:58 +02:00
|
|
|
if (loops > 30)
|
2003-04-22 04:18:48 +02:00
|
|
|
#ifndef FRONTEND
|
2003-07-27 19:10:07 +02:00
|
|
|
elog(LOG, "completed unlink of \"%s\"", path);
|
2003-04-22 04:18:48 +02:00
|
|
|
#else
|
2003-07-27 19:10:07 +02:00
|
|
|
fprintf(stderr, "completed unlink of \"%s\"\n", path);
|
2003-04-22 04:18:48 +02:00
|
|
|
#endif
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2004-02-02 23:20:33 +01:00
|
|
|
#endif
|
2003-04-22 04:18:48 +02:00
|
|
|
|
|
|
|
#else
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
2003-08-04 02:43:34 +02:00
|
|
|
* Illustrates problem with Win32 rename() and unlink()
|
2003-04-22 04:18:48 +02:00
|
|
|
* under concurrent access.
|
|
|
|
*
|
|
|
|
* Run with arg '1', then less than 5 seconds later, run with
|
|
|
|
* arg '2' (rename) or '3'(unlink) to see the problem.
|
|
|
|
*/
|
2003-08-04 02:43:34 +02:00
|
|
|
|
2003-04-22 04:18:48 +02:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <errno.h>
|
|
|
|
#include <windows.h>
|
|
|
|
|
|
|
|
#define halt(str) \
|
|
|
|
do { \
|
|
|
|
fputs(str, stderr); \
|
|
|
|
exit(1); \
|
|
|
|
} while (0)
|
|
|
|
|
|
|
|
int
|
2003-08-04 02:43:34 +02:00
|
|
|
main(int argc, char *argv[])
|
2003-04-22 04:18:48 +02:00
|
|
|
{
|
2003-08-04 02:43:34 +02:00
|
|
|
FILE *fd;
|
2003-04-22 04:18:48 +02:00
|
|
|
|
|
|
|
if (argc != 2)
|
|
|
|
halt("Arg must be '1' (test), '2' (rename), or '3' (unlink)\n"
|
|
|
|
"Run '1' first, then less than 5 seconds later, run\n"
|
|
|
|
"'2' to test rename, or '3' to test unlink.\n");
|
|
|
|
|
|
|
|
if (atoi(argv[1]) == 1)
|
|
|
|
{
|
|
|
|
if ((fd = fopen("/rtest.txt", "w")) == NULL)
|
|
|
|
halt("Can not create file\n");
|
|
|
|
fclose(fd);
|
|
|
|
if ((fd = fopen("/rtest.txt", "r")) == NULL)
|
|
|
|
halt("Can not open file\n");
|
|
|
|
Sleep(5000);
|
|
|
|
}
|
|
|
|
else if (atoi(argv[1]) == 2)
|
|
|
|
{
|
|
|
|
unlink("/rtest.new");
|
|
|
|
if ((fd = fopen("/rtest.new", "w")) == NULL)
|
|
|
|
halt("Can not create file\n");
|
|
|
|
fclose(fd);
|
|
|
|
while (!MoveFileEx("/rtest.new", "/rtest.txt", MOVEFILE_REPLACE_EXISTING))
|
|
|
|
{
|
|
|
|
if (GetLastError() != ERROR_ACCESS_DENIED)
|
|
|
|
halt("Unknown failure\n");
|
|
|
|
else
|
|
|
|
fprintf(stderr, "move failed\n");
|
|
|
|
Sleep(500);
|
|
|
|
}
|
|
|
|
halt("move successful\n");
|
|
|
|
}
|
|
|
|
else if (atoi(argv[1]) == 3)
|
|
|
|
{
|
|
|
|
while (unlink("/rtest.txt"))
|
|
|
|
{
|
|
|
|
if (errno != EACCES)
|
|
|
|
halt("Unknown failure\n");
|
|
|
|
else
|
|
|
|
fprintf(stderr, "unlink failed\n");
|
|
|
|
Sleep(500);
|
|
|
|
}
|
|
|
|
halt("unlink successful\n");
|
|
|
|
}
|
2003-08-04 02:43:34 +02:00
|
|
|
else
|
2003-04-22 04:18:48 +02:00
|
|
|
halt("invalid arg\n");
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
2003-07-27 19:10:07 +02:00
|
|
|
|
2003-04-22 04:18:48 +02:00
|
|
|
#endif
|