Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit53e8bec

Browse files
committed
The attached patch implements a symlink for win32 using junctions, and
uses that for win32 tablespaces.Andreas Pflug
1 parent27fedc8 commit53e8bec

File tree

2 files changed

+134
-18
lines changed

2 files changed

+134
-18
lines changed

‎src/include/port.h

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
77
* Portions Copyright (c) 1994, Regents of the University of California
88
*
9-
* $PostgreSQL: pgsql/src/include/port.h,v 1.47 2004/08/01 06:56:39 momjian Exp $
9+
* $PostgreSQL: pgsql/src/include/port.h,v 1.48 2004/08/07 21:48:09 momjian Exp $
1010
*
1111
*-------------------------------------------------------------------------
1212
*/
@@ -80,7 +80,7 @@ extern void set_pglocale_pgservice(const char *argv0, const char *app);
8080
externintfind_my_exec(constchar*argv0,char*retpath);
8181
externintfind_other_exec(constchar*argv0,constchar*target,
8282
constchar*versionstr,char*retpath);
83-
#if defined(__CYGWIN__)|| defined(WIN32)
83+
#if defined(WIN32)|| defined(__CYGWIN__)
8484
#defineEXE ".exe"
8585
#defineDEVNULL "nul"
8686
#else
@@ -140,14 +140,17 @@ extern int pgkill(int pid, int sig);
140140

141141
externintpclose_check(FILE*stream);
142142

143-
#if defined(__MINGW32__)|| defined(__CYGWIN__)
143+
#if defined(WIN32)|| defined(__CYGWIN__)
144144
/*
145-
* Win32 doesn't have reliable rename/unlink during concurrent access
145+
*Win32 doesn't have reliable rename/unlink during concurrent access,
146+
*and we need special code to do symlinks.
146147
*/
147148
externintpgrename(constchar*from,constchar*to);
148149
externintpgunlink(constchar*path);
149-
#definerename(from,to)pgrename(from, to)
150-
#defineunlink(path)pgunlink(path)
150+
externintpgsymlink(constchar*oldpath,constchar*newpath);
151+
#definerename(from,to)pgrename(from, to)
152+
#defineunlink(path)pgunlink(path)
153+
#definesymlink(oldpath,newpath)pgsymlink(oldpath, newpath)
151154
#endif
152155

153156
externboolrmtree(char*path,boolrmtopdir);

‎src/port/dirmod.c

Lines changed: 125 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
*Win32 (NT, Win2k, XP).replace() doesn't work on Win95/98/Me.
1111
*
1212
* IDENTIFICATION
13-
* $PostgreSQL: pgsql/src/port/dirmod.c,v 1.13 2004/08/01 06:19:26 momjian Exp $
13+
* $PostgreSQL: pgsql/src/port/dirmod.c,v 1.14 2004/08/07 21:48:09 momjian Exp $
1414
*
1515
*-------------------------------------------------------------------------
1616
*/
@@ -33,10 +33,14 @@
3333

3434

3535
#include"miscadmin.h"
36+
#include<winioctl.h>
3637

3738
#undef rename
3839
#undef unlink
3940

41+
/*
42+
*pgrename
43+
*/
4044
int
4145
pgrename(constchar*from,constchar*to)
4246
{
@@ -79,6 +83,9 @@ pgrename(const char *from, const char *to)
7983
}
8084

8185

86+
/*
87+
*pgunlink
88+
*/
8289
int
8390
pgunlink(constchar*path)
8491
{
@@ -110,12 +117,119 @@ pgunlink(const char *path)
110117
return0;
111118
}
112119

120+
121+
/*
122+
*pgsymlink support:
123+
*
124+
*This struct is a replacement for REPARSE_DATA_BUFFER which is defined in VC6 winnt.h
125+
*but omitted in later SDK functions.
126+
*We only need the SymbolicLinkReparseBuffer part of the original struct's union.
127+
*/
128+
typedefstruct
129+
{
130+
DWORDReparseTag;
131+
WORDReparseDataLength;
132+
WORDReserved;
133+
/* SymbolicLinkReparseBuffer */
134+
WORDSubstituteNameOffset;
135+
WORDSubstituteNameLength;
136+
WORDPrintNameOffset;
137+
WORDPrintNameLength;
138+
WCHARPathBuffer[1];
139+
}
140+
REPARSE_JUNCTION_DATA_BUFFER;
141+
142+
#defineREPARSE_JUNCTION_DATA_BUFFER_HEADER_SIZE \
143+
FIELD_OFFSET(REPARSE_JUNCTION_DATA_BUFFER, SubstituteNameOffset)
144+
145+
146+
/*
147+
*pgsymlink - uses Win32 junction points
148+
*
149+
*For reference:http://www.codeproject.com/w2k/junctionpoints.asp
150+
*/
151+
int
152+
pgsymlink(constchar*oldpath,constchar*newpath)
153+
{
154+
HANDLEdirhandle;
155+
DWORDlen;
156+
char*p=nativeTarget;
157+
charbuffer[MAX_PATH*sizeof(WCHAR)+sizeof(REPARSE_JUNCTION_DATA_BUFFER)];
158+
charnativeTarget[MAX_PATH];
159+
REPARSE_JUNCTION_DATA_BUFFER*reparseBuf= (REPARSE_JUNCTION_DATA_BUFFER*)buffer;
160+
161+
CreateDirectory(newpath,0);
162+
dirhandle=CreateFile(newpath,GENERIC_READ |GENERIC_WRITE,
163+
0,0,OPEN_EXISTING,
164+
FILE_FLAG_OPEN_REPARSE_POINT |FILE_FLAG_BACKUP_SEMANTICS,0);
165+
166+
if (dirhandle==INVALID_HANDLE_VALUE)
167+
return-1;
168+
169+
/* make sure we have an unparsed native win32 path */
170+
if (memcmp("\\??\\",oldpath,4))
171+
sprintf(nativeTarget,"\\??\\%s",oldpath);
172+
else
173+
strcpy(nativeTarget,oldpath);
174+
175+
while ((p=strchr(p,'/'))!=0)
176+
*p++='\\';
177+
178+
len=strlen(nativeTarget)*sizeof(WCHAR);
179+
reparseBuf->ReparseTag=IO_REPARSE_TAG_MOUNT_POINT;
180+
reparseBuf->ReparseDataLength=len+12;
181+
reparseBuf->Reserved=0;
182+
reparseBuf->SubstituteNameOffset=0;
183+
reparseBuf->SubstituteNameLength=len;
184+
reparseBuf->PrintNameOffset=len+sizeof(WCHAR);
185+
reparseBuf->PrintNameLength=0;
186+
MultiByteToWideChar(CP_ACP,0,nativeTarget,-1,
187+
reparseBuf->PathBuffer,MAX_PATH);
188+
189+
/*
190+
* FSCTL_SET_REPARSE_POINT is coded differently depending on SDK version;
191+
* we use our own definition
192+
*/
193+
if (!DeviceIoControl(dirhandle,
194+
CTL_CODE(FILE_DEVICE_FILE_SYSTEM,41,METHOD_BUFFERED,FILE_ANY_ACCESS),
195+
reparseBuf,
196+
reparseBuf->ReparseDataLength+REPARSE_JUNCTION_DATA_BUFFER_HEADER_SIZE,
197+
0,0,&len,0))
198+
{
199+
LPSTRmsg;
200+
201+
errno=0;
202+
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |FORMAT_MESSAGE_FROM_SYSTEM,
203+
NULL,GetLastError(),
204+
MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT),
205+
(LPSTR)&msg,0,NULL );
206+
ereport(ERROR, (errcode_for_file_access(),
207+
errmsg("Error setting junction for %s: %s",nativeTarget,msg)));
208+
209+
LocalFree(msg);
210+
211+
CloseHandle(dirhandle);
212+
RemoveDirectory(newpath);
213+
return-1;
214+
}
215+
216+
CloseHandle(dirhandle);
217+
218+
return0;
219+
}
220+
113221
#endif
114222

223+
224+
/* ----------------
225+
*rmtree routines
226+
* ----------------
227+
*/
228+
229+
230+
/* We undefined these above, so we redefine them */
115231
#if defined(WIN32)|| defined(__CYGWIN__)
116-
#definermt_unlink(path) pgunlink(path)
117-
#else
118-
#definermt_unlink(path) unlink(path)
232+
#defineunlink(path)pgunlink(path)
119233
#endif
120234

121235
#ifdefFRONTEND
@@ -175,16 +289,15 @@ rmt_cleanup(char ** filenames)
175289
xfree(filenames);
176290
}
177291

178-
179-
180292
/*
181-
* delete a directory tree recursively
182-
* assumes path points to a valid directory
183-
* deletes everything under path
184-
* if rmtopdir is true deletes the directory too
293+
*rmtree
294+
*
295+
*Delete a directory tree recursively.
296+
*Assumes path points to a valid directory.
297+
*Deletes everything under path.
298+
*If rmtopdir is true deletes the directory too.
185299
*
186300
*/
187-
188301
bool
189302
rmtree(char*path,boolrmtopdir)
190303
{
@@ -249,7 +362,7 @@ rmtree(char *path, bool rmtopdir)
249362
}
250363
else
251364
{
252-
if (rmt_unlink(filepath)!=0)
365+
if (unlink(filepath)!=0)
253366
{
254367
rmt_cleanup(filenames);
255368
return false;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp