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

Commitfb91874

Browse files
committed
Properly check for readdir/closedir() failures
Clear errno before calling readdir() and handle old MinGW errno bugwhile adding full test coverage for readdir/closedir failures.Backpatch through 8.4.
1 parent7f857a5 commitfb91874

File tree

10 files changed

+127
-72
lines changed

10 files changed

+127
-72
lines changed

‎contrib/pg_archivecleanup/pg_archivecleanup.c

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ CleanupPriorWALFiles(void)
117117

118118
if ((xldir=opendir(archiveLocation))!=NULL)
119119
{
120-
while ((xlde=readdir(xldir))!=NULL)
120+
while (errno=0,(xlde=readdir(xldir))!=NULL)
121121
{
122122
strncpy(walfile,xlde->d_name,MAXPGPATH);
123123
TrimExtension(walfile,additional_ext);
@@ -175,7 +175,19 @@ CleanupPriorWALFiles(void)
175175
}
176176
}
177177
}
178-
closedir(xldir);
178+
179+
#ifdefWIN32
180+
/* Bug in old Mingw dirent.c; fixed in mingw-runtime-3.2, 2003-10-10 */
181+
if (GetLastError()==ERROR_NO_MORE_FILES)
182+
errno=0;
183+
#endif
184+
185+
if (errno)
186+
fprintf(stderr,"%s: could not read archive location \"%s\": %s\n",
187+
progname,archiveLocation,strerror(errno));
188+
if (closedir(xldir))
189+
fprintf(stderr,"%s: could not close archive location \"%s\": %s\n",
190+
progname,archiveLocation,strerror(errno));
179191
}
180192
else
181193
fprintf(stderr,"%s: could not open archive location \"%s\": %s\n",

‎contrib/pg_standby/pg_standby.c

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,7 @@ CustomizableCleanupPriorWALFiles(void)
256256
*/
257257
if ((xldir=opendir(archiveLocation))!=NULL)
258258
{
259-
while ((xlde=readdir(xldir))!=NULL)
259+
while (errno=0,(xlde=readdir(xldir))!=NULL)
260260
{
261261
/*
262262
* We ignore the timeline part of the XLOG segment identifiers
@@ -294,14 +294,27 @@ CustomizableCleanupPriorWALFiles(void)
294294
}
295295
}
296296
}
297+
298+
#ifdefWIN32
299+
/* Bug in old Mingw dirent.c; fixed in mingw-runtime-3.2, 2003-10-10 */
300+
if (GetLastError()==ERROR_NO_MORE_FILES)
301+
errno=0;
302+
#endif
303+
304+
if (errno)
305+
fprintf(stderr,"%s: could not read archive location \"%s\": %s\n",
306+
progname,archiveLocation,strerror(errno));
297307
if (debug)
298308
fprintf(stderr,"\n");
299309
}
300310
else
301311
fprintf(stderr,"%s: could not open archive location \"%s\": %s\n",
302312
progname,archiveLocation,strerror(errno));
303313

304-
closedir(xldir);
314+
if (closedir(xldir))
315+
fprintf(stderr,"%s: could not close archive location \"%s\": %s\n",
316+
progname,archiveLocation,strerror(errno));
317+
305318
fflush(stderr);
306319
}
307320
}

‎src/backend/storage/file/fd.c

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1901,11 +1901,7 @@ ReadDir(DIR *dir, const char *dirname)
19011901
returndent;
19021902

19031903
#ifdefWIN32
1904-
1905-
/*
1906-
* This fix is in mingw cvs (runtime/mingwex/dirent.c rev 1.4), but not in
1907-
* released version
1908-
*/
1904+
/* Bug in old Mingw dirent.c; fixed in mingw-runtime-3.2, 2003-10-10 */
19091905
if (GetLastError()==ERROR_NO_MORE_FILES)
19101906
errno=0;
19111907
#endif

‎src/bin/initdb/initdb.c

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -557,11 +557,7 @@ walkdir(char *path, void (*action) (char *fname, bool isdir))
557557
}
558558

559559
#ifdefWIN32
560-
561-
/*
562-
* This fix is in mingw cvs (runtime/mingwex/dirent.c rev 1.4), but not in
563-
* released version
564-
*/
560+
/* Bug in old Mingw dirent.c; fixed in mingw-runtime-3.2, 2003-10-10 */
565561
if (GetLastError()==ERROR_NO_MORE_FILES)
566562
errno=0;
567563
#endif
@@ -573,7 +569,12 @@ walkdir(char *path, void (*action) (char *fname, bool isdir))
573569
exit_nicely();
574570
}
575571

576-
closedir(dir);
572+
if (closedir(dir))
573+
{
574+
fprintf(stderr,_("%s: could not close directory \"%s\": %s\n"),
575+
progname,path,strerror(errno));
576+
exit_nicely();
577+
}
577578

578579
/*
579580
* It's important to fsync the destination directory itself as individual

‎src/bin/pg_basebackup/pg_receivexlog.c

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ FindStreamingStart(uint32 *tli)
138138
disconnect_and_exit(1);
139139
}
140140

141-
while ((dirent=readdir(dir))!=NULL)
141+
while (errno=0,(dirent=readdir(dir))!=NULL)
142142
{
143143
uint32tli;
144144
XLogSegNosegno;
@@ -208,7 +208,25 @@ FindStreamingStart(uint32 *tli)
208208
}
209209
}
210210

211-
closedir(dir);
211+
#ifdefWIN32
212+
/* Bug in old Mingw dirent.c; fixed in mingw-runtime-3.2, 2003-10-10 */
213+
if (GetLastError()==ERROR_NO_MORE_FILES)
214+
errno=0;
215+
#endif
216+
217+
if (errno)
218+
{
219+
fprintf(stderr,_("%s: could not read directory \"%s\": %s\n"),
220+
progname,basedir,strerror(errno));
221+
disconnect_and_exit(1);
222+
}
223+
224+
if (closedir(dir))
225+
{
226+
fprintf(stderr,_("%s: could not close directory \"%s\": %s\n"),
227+
progname,basedir,strerror(errno));
228+
disconnect_and_exit(1);
229+
}
212230

213231
if (high_segno>0)
214232
{

‎src/bin/pg_dump/pg_backup_directory.c

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -177,15 +177,28 @@ InitArchiveFmt_Directory(ArchiveHandle *AH)
177177
structdirent*d;
178178

179179
is_empty= true;
180-
while ((d=readdir(dir)))
180+
while (errno=0,(d=readdir(dir)))
181181
{
182182
if (strcmp(d->d_name,".")!=0&&strcmp(d->d_name,"..")!=0)
183183
{
184184
is_empty= false;
185185
break;
186186
}
187187
}
188-
closedir(dir);
188+
189+
#ifdefWIN32
190+
/* Bug in old Mingw dirent.c; fixed in mingw-runtime-3.2, 2003-10-10 */
191+
if (GetLastError()==ERROR_NO_MORE_FILES)
192+
errno=0;
193+
#endif
194+
195+
if (errno)
196+
exit_horribly(modulename,"could not read directory \"%s\": %s\n",
197+
ctx->directory,strerror(errno));
198+
199+
if (closedir(dir))
200+
exit_horribly(modulename,"could not close directory \"%s\": %s\n",
201+
ctx->directory,strerror(errno));
189202
}
190203
}
191204

‎src/bin/pg_resetxlog/pg_resetxlog.c

Lines changed: 33 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -765,8 +765,7 @@ FindEndOfXLOG(void)
765765
exit(1);
766766
}
767767

768-
errno=0;
769-
while ((xlde=readdir(xldir))!=NULL)
768+
while (errno=0, (xlde=readdir(xldir))!=NULL)
770769
{
771770
if (strlen(xlde->d_name)==24&&
772771
strspn(xlde->d_name,"0123456789ABCDEF")==24)
@@ -788,25 +787,27 @@ FindEndOfXLOG(void)
788787
if (segno>newXlogSegNo)
789788
newXlogSegNo=segno;
790789
}
791-
errno=0;
792790
}
793-
#ifdefWIN32
794791

795-
/*
796-
* This fix is in mingw cvs (runtime/mingwex/dirent.c rev 1.4), but not in
797-
* released version
798-
*/
792+
#ifdefWIN32
793+
/* Bug in old Mingw dirent.c; fixed in mingw-runtime-3.2, 2003-10-10 */
799794
if (GetLastError()==ERROR_NO_MORE_FILES)
800795
errno=0;
801796
#endif
802797

803798
if (errno)
804799
{
805-
fprintf(stderr,_("%s: could not read from directory \"%s\": %s\n"),
800+
fprintf(stderr,_("%s: could not read directory \"%s\": %s\n"),
801+
progname,XLOGDIR,strerror(errno));
802+
exit(1);
803+
}
804+
805+
if (closedir(xldir))
806+
{
807+
fprintf(stderr,_("%s: could not close directory \"%s\": %s\n"),
806808
progname,XLOGDIR,strerror(errno));
807809
exit(1);
808810
}
809-
closedir(xldir);
810811

811812
/*
812813
* Finally, convert to new xlog seg size, and advance by one to ensure we
@@ -836,8 +837,7 @@ KillExistingXLOG(void)
836837
exit(1);
837838
}
838839

839-
errno=0;
840-
while ((xlde=readdir(xldir))!=NULL)
840+
while (errno=0, (xlde=readdir(xldir))!=NULL)
841841
{
842842
if (strlen(xlde->d_name)==24&&
843843
strspn(xlde->d_name,"0123456789ABCDEF")==24)
@@ -850,25 +850,27 @@ KillExistingXLOG(void)
850850
exit(1);
851851
}
852852
}
853-
errno=0;
854853
}
855-
#ifdefWIN32
856854

857-
/*
858-
* This fix is in mingw cvs (runtime/mingwex/dirent.c rev 1.4), but not in
859-
* released version
860-
*/
855+
#ifdefWIN32
856+
/* Bug in old Mingw dirent.c; fixed in mingw-runtime-3.2, 2003-10-10 */
861857
if (GetLastError()==ERROR_NO_MORE_FILES)
862858
errno=0;
863859
#endif
864860

865861
if (errno)
866862
{
867-
fprintf(stderr,_("%s: could not read from directory \"%s\": %s\n"),
863+
fprintf(stderr,_("%s: could not read directory \"%s\": %s\n"),
864+
progname,XLOGDIR,strerror(errno));
865+
exit(1);
866+
}
867+
868+
if (closedir(xldir))
869+
{
870+
fprintf(stderr,_("%s: could not close directory \"%s\": %s\n"),
868871
progname,XLOGDIR,strerror(errno));
869872
exit(1);
870873
}
871-
closedir(xldir);
872874
}
873875

874876

@@ -892,8 +894,7 @@ KillExistingArchiveStatus(void)
892894
exit(1);
893895
}
894896

895-
errno=0;
896-
while ((xlde=readdir(xldir))!=NULL)
897+
while (errno=0, (xlde=readdir(xldir))!=NULL)
897898
{
898899
if (strspn(xlde->d_name,"0123456789ABCDEF")==24&&
899900
(strcmp(xlde->d_name+24,".ready")==0||
@@ -907,25 +908,27 @@ KillExistingArchiveStatus(void)
907908
exit(1);
908909
}
909910
}
910-
errno=0;
911911
}
912-
#ifdefWIN32
913912

914-
/*
915-
* This fix is in mingw cvs (runtime/mingwex/dirent.c rev 1.4), but not in
916-
* released version
917-
*/
913+
#ifdefWIN32
914+
/* Bug in old Mingw dirent.c; fixed in mingw-runtime-3.2, 2003-10-10 */
918915
if (GetLastError()==ERROR_NO_MORE_FILES)
919916
errno=0;
920917
#endif
921918

922919
if (errno)
923920
{
924-
fprintf(stderr,_("%s: could not read from directory \"%s\": %s\n"),
921+
fprintf(stderr,_("%s: could not read directory \"%s\": %s\n"),
922+
progname,ARCHSTATDIR,strerror(errno));
923+
exit(1);
924+
}
925+
926+
if (closedir(xldir))
927+
{
928+
fprintf(stderr,_("%s: could not close directory \"%s\": %s\n"),
925929
progname,ARCHSTATDIR,strerror(errno));
926930
exit(1);
927931
}
928-
closedir(xldir);
929932
}
930933

931934

‎src/port/dirent.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,15 +105,19 @@ readdir(DIR *d)
105105
strcpy(d->ret.d_name,fd.cFileName);/* Both strings are MAX_PATH
106106
* long */
107107
d->ret.d_namlen=strlen(d->ret.d_name);
108+
108109
return&d->ret;
109110
}
110111

111112
int
112113
closedir(DIR*d)
113114
{
115+
intret=0;
116+
114117
if (d->handle!=INVALID_HANDLE_VALUE)
115-
FindClose(d->handle);
118+
ret= !FindClose(d->handle);
116119
free(d->dirname);
117120
free(d);
118-
return0;
121+
122+
returnret;
119123
}

‎src/port/dirmod.c

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -382,8 +382,7 @@ pgfnames(const char *path)
382382

383383
filenames= (char**)palloc(fnsize*sizeof(char*));
384384

385-
errno=0;
386-
while ((file=readdir(dir))!=NULL)
385+
while (errno=0, (file=readdir(dir))!=NULL)
387386
{
388387
if (strcmp(file->d_name,".")!=0&&strcmp(file->d_name,"..")!=0)
389388
{
@@ -395,17 +394,14 @@ pgfnames(const char *path)
395394
}
396395
filenames[numnames++]=pstrdup(file->d_name);
397396
}
398-
errno=0;
399397
}
400-
#ifdefWIN32
401398

402-
/*
403-
* This fix is in mingw cvs (runtime/mingwex/dirent.c rev 1.4), but not in
404-
* released version
405-
*/
399+
#ifdefWIN32
400+
/* Bug in old Mingw dirent.c; fixed in mingw-runtime-3.2, 2003-10-10 */
406401
if (GetLastError()==ERROR_NO_MORE_FILES)
407402
errno=0;
408403
#endif
404+
409405
if (errno)
410406
{
411407
#ifndefFRONTEND
@@ -418,7 +414,15 @@ pgfnames(const char *path)
418414

419415
filenames[numnames]=NULL;
420416

421-
closedir(dir);
417+
if (closedir(dir))
418+
{
419+
#ifndefFRONTEND
420+
elog(WARNING,"could not close directory \"%s\": %m",path);
421+
#else
422+
fprintf(stderr,_("could not close directory \"%s\": %s\n"),
423+
path,strerror(errno));
424+
#endif
425+
}
422426

423427
returnfilenames;
424428
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp