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

Commitd73cc58

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 parent697becf commitd73cc58

File tree

8 files changed

+97
-63
lines changed

8 files changed

+97
-63
lines changed

‎contrib/pg_archivecleanup/pg_archivecleanup.c‎

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

9999
if ((xldir=opendir(archiveLocation))!=NULL)
100100
{
101-
while ((xlde=readdir(xldir))!=NULL)
101+
while (errno=0,(xlde=readdir(xldir))!=NULL)
102102
{
103103
/*
104104
* We ignore the timeline part of the XLOG segment identifiers in
@@ -132,7 +132,19 @@ CleanupPriorWALFiles(void)
132132
}
133133
}
134134
}
135-
closedir(xldir);
135+
136+
#ifdefWIN32
137+
/* Bug in old Mingw dirent.c; fixed in mingw-runtime-3.2, 2003-10-10 */
138+
if (GetLastError()==ERROR_NO_MORE_FILES)
139+
errno=0;
140+
#endif
141+
142+
if (errno)
143+
fprintf(stderr,"%s: could not read archive location \"%s\": %s\n",
144+
progname,archiveLocation,strerror(errno));
145+
if (closedir(xldir))
146+
fprintf(stderr,"%s: could not close archive location \"%s\": %s\n",
147+
progname,archiveLocation,strerror(errno));
136148
}
137149
else
138150
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
}

‎contrib/pg_upgrade/file.c‎

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,7 @@ pg_scandir_internal(const char *dirname,
291291

292292
*namelist=NULL;
293293

294-
while ((direntry=readdir(dirdesc))!=NULL)
294+
while (errno=0,(direntry=readdir(dirdesc))!=NULL)
295295
{
296296
/* Invoke the selector function to see if the direntry matches */
297297
if (!selector|| (*selector) (direntry))
@@ -324,7 +324,17 @@ pg_scandir_internal(const char *dirname,
324324
}
325325
}
326326

327-
closedir(dirdesc);
327+
#ifdefWIN32
328+
/* Bug in old Mingw dirent.c; fixed in mingw-runtime-3.2, 2003-10-10 */
329+
if (GetLastError()==ERROR_NO_MORE_FILES)
330+
errno=0;
331+
#endif
332+
333+
if (errno)
334+
pg_log(PG_FATAL,"could not read directory \"%s\": %s\n",dirname,getErrorText(errno));
335+
336+
if (closedir(dirdesc))
337+
pg_log(PG_FATAL,"could not close directory \"%s\": %s\n",dirname,getErrorText(errno));
328338

329339
returncount;
330340
}

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

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

16891689
#ifdefWIN32
1690-
1691-
/*
1692-
* This fix is in mingw cvs (runtime/mingwex/dirent.c rev 1.4), but not in
1693-
* released version
1694-
*/
1690+
/* Bug in old Mingw dirent.c; fixed in mingw-runtime-3.2, 2003-10-10 */
16951691
if (GetLastError()==ERROR_NO_MORE_FILES)
16961692
errno=0;
16971693
#endif

‎src/bin/pg_resetxlog/pg_resetxlog.c‎

Lines changed: 33 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -742,8 +742,7 @@ FindEndOfXLOG(void)
742742
exit(1);
743743
}
744744

745-
errno=0;
746-
while ((xlde=readdir(xldir))!=NULL)
745+
while (errno=0, (xlde=readdir(xldir))!=NULL)
747746
{
748747
if (strlen(xlde->d_name)==24&&
749748
strspn(xlde->d_name,"0123456789ABCDEF")==24)
@@ -767,25 +766,27 @@ FindEndOfXLOG(void)
767766
newXlogSeg=seg;
768767
}
769768
}
770-
errno=0;
771769
}
772-
#ifdefWIN32
773770

774-
/*
775-
* This fix is in mingw cvs (runtime/mingwex/dirent.c rev 1.4), but not in
776-
* released version
777-
*/
771+
#ifdefWIN32
772+
/* Bug in old Mingw dirent.c; fixed in mingw-runtime-3.2, 2003-10-10 */
778773
if (GetLastError()==ERROR_NO_MORE_FILES)
779774
errno=0;
780775
#endif
781776

782777
if (errno)
783778
{
784-
fprintf(stderr,_("%s: could not read from directory \"%s\": %s\n"),
779+
fprintf(stderr,_("%s: could not read directory \"%s\": %s\n"),
780+
progname,XLOGDIR,strerror(errno));
781+
exit(1);
782+
}
783+
784+
if (closedir(xldir))
785+
{
786+
fprintf(stderr,_("%s: could not close directory \"%s\": %s\n"),
785787
progname,XLOGDIR,strerror(errno));
786788
exit(1);
787789
}
788-
closedir(xldir);
789790

790791
/*
791792
* Finally, convert to new xlog seg size, and advance by one to ensure we
@@ -817,8 +818,7 @@ KillExistingXLOG(void)
817818
exit(1);
818819
}
819820

820-
errno=0;
821-
while ((xlde=readdir(xldir))!=NULL)
821+
while (errno=0, (xlde=readdir(xldir))!=NULL)
822822
{
823823
if (strlen(xlde->d_name)==24&&
824824
strspn(xlde->d_name,"0123456789ABCDEF")==24)
@@ -831,25 +831,27 @@ KillExistingXLOG(void)
831831
exit(1);
832832
}
833833
}
834-
errno=0;
835834
}
836-
#ifdefWIN32
837835

838-
/*
839-
* This fix is in mingw cvs (runtime/mingwex/dirent.c rev 1.4), but not in
840-
* released version
841-
*/
836+
#ifdefWIN32
837+
/* Bug in old Mingw dirent.c; fixed in mingw-runtime-3.2, 2003-10-10 */
842838
if (GetLastError()==ERROR_NO_MORE_FILES)
843839
errno=0;
844840
#endif
845841

846842
if (errno)
847843
{
848-
fprintf(stderr,_("%s: could not read from directory \"%s\": %s\n"),
844+
fprintf(stderr,_("%s: could not read directory \"%s\": %s\n"),
845+
progname,XLOGDIR,strerror(errno));
846+
exit(1);
847+
}
848+
849+
if (closedir(xldir))
850+
{
851+
fprintf(stderr,_("%s: could not close directory \"%s\": %s\n"),
849852
progname,XLOGDIR,strerror(errno));
850853
exit(1);
851854
}
852-
closedir(xldir);
853855
}
854856

855857

@@ -873,8 +875,7 @@ KillExistingArchiveStatus(void)
873875
exit(1);
874876
}
875877

876-
errno=0;
877-
while ((xlde=readdir(xldir))!=NULL)
878+
while (errno=0, (xlde=readdir(xldir))!=NULL)
878879
{
879880
if (strspn(xlde->d_name,"0123456789ABCDEF")==24&&
880881
(strcmp(xlde->d_name+24,".ready")==0||
@@ -888,25 +889,27 @@ KillExistingArchiveStatus(void)
888889
exit(1);
889890
}
890891
}
891-
errno=0;
892892
}
893-
#ifdefWIN32
894893

895-
/*
896-
* This fix is in mingw cvs (runtime/mingwex/dirent.c rev 1.4), but not in
897-
* released version
898-
*/
894+
#ifdefWIN32
895+
/* Bug in old Mingw dirent.c; fixed in mingw-runtime-3.2, 2003-10-10 */
899896
if (GetLastError()==ERROR_NO_MORE_FILES)
900897
errno=0;
901898
#endif
902899

903900
if (errno)
904901
{
905-
fprintf(stderr,_("%s: could not read from directory \"%s\": %s\n"),
902+
fprintf(stderr,_("%s: could not read directory \"%s\": %s\n"),
903+
progname,ARCHSTATDIR,strerror(errno));
904+
exit(1);
905+
}
906+
907+
if (closedir(xldir))
908+
{
909+
fprintf(stderr,_("%s: could not close directory \"%s\": %s\n"),
906910
progname,ARCHSTATDIR,strerror(errno));
907911
exit(1);
908912
}
909-
closedir(xldir);
910913
}
911914

912915

‎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
@@ -448,8 +448,7 @@ pgfnames(const char *path)
448448

449449
filenames= (char**)palloc(fnsize*sizeof(char*));
450450

451-
errno=0;
452-
while ((file=readdir(dir))!=NULL)
451+
while (errno=0, (file=readdir(dir))!=NULL)
453452
{
454453
if (strcmp(file->d_name,".")!=0&&strcmp(file->d_name,"..")!=0)
455454
{
@@ -461,17 +460,14 @@ pgfnames(const char *path)
461460
}
462461
filenames[numnames++]=pstrdup(file->d_name);
463462
}
464-
errno=0;
465463
}
466-
#ifdefWIN32
467464

468-
/*
469-
* This fix is in mingw cvs (runtime/mingwex/dirent.c rev 1.4), but not in
470-
* released version
471-
*/
465+
#ifdefWIN32
466+
/* Bug in old Mingw dirent.c; fixed in mingw-runtime-3.2, 2003-10-10 */
472467
if (GetLastError()==ERROR_NO_MORE_FILES)
473468
errno=0;
474469
#endif
470+
475471
if (errno)
476472
{
477473
#ifndefFRONTEND
@@ -484,7 +480,15 @@ pgfnames(const char *path)
484480

485481
filenames[numnames]=NULL;
486482

487-
closedir(dir);
483+
if (closedir(dir))
484+
{
485+
#ifndefFRONTEND
486+
elog(WARNING,"could not close directory \"%s\": %m",path);
487+
#else
488+
fprintf(stderr,_("could not close directory \"%s\": %s\n"),
489+
path,strerror(errno));
490+
#endif
491+
}
488492

489493
returnfilenames;
490494
}

‎src/port/pgcheckdir.c‎

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,12 @@ pg_check_dir(const char *dir)
3232
DIR*chkdir;
3333
structdirent*file;
3434

35-
errno=0;
36-
3735
chkdir=opendir(dir);
3836

3937
if (chkdir==NULL)
4038
return (errno==ENOENT) ?0 :-1;
4139

42-
while ((file=readdir(chkdir))!=NULL)
40+
while (errno=0,(file=readdir(chkdir))!=NULL)
4341
{
4442
if (strcmp(".",file->d_name)==0||
4543
strcmp("..",file->d_name)==0)
@@ -55,18 +53,12 @@ pg_check_dir(const char *dir)
5553
}
5654

5755
#ifdefWIN32
58-
59-
/*
60-
* This fix is in mingw cvs (runtime/mingwex/dirent.c rev 1.4), but not in
61-
* released version
62-
*/
56+
/* Bug in old Mingw dirent.c; fixed in mingw-runtime-3.2, 2003-10-10 */
6357
if (GetLastError()==ERROR_NO_MORE_FILES)
6458
errno=0;
6559
#endif
6660

67-
closedir(chkdir);
68-
69-
if (errno!=0)
61+
if (errno||closedir(chkdir))
7062
result=-1;/* some kind of I/O error? */
7163

7264
returnresult;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp