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

Commit4859a71

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 parent192856b commit4859a71

File tree

8 files changed

+109
-63
lines changed

8 files changed

+109
-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 archiveLocation \"%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,13 +294,26 @@ 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: archiveLocation \"%s\" open error\n",progname,archiveLocation);
302312

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

‎contrib/pg_upgrade/file.c

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,7 @@ pg_scandir_internal(migratorContext *ctx, 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) (direntry))
@@ -318,7 +318,17 @@ pg_scandir_internal(migratorContext *ctx, const char *dirname,
318318
}
319319
}
320320

321-
closedir(dirdesc);
321+
#ifdefWIN32
322+
/* Bug in old Mingw dirent.c; fixed in mingw-runtime-3.2, 2003-10-10 */
323+
if (GetLastError()==ERROR_NO_MORE_FILES)
324+
errno=0;
325+
#endif
326+
327+
if (errno)
328+
pg_log(ctx,PG_FATAL,"Could not read directory \"%s\": %s\n",dirname,getErrorText(errno));
329+
330+
if (closedir(dirdesc))
331+
pg_log(ctx,PG_FATAL,"Could not close directory \"%s\": %s\n",dirname,getErrorText(errno));
322332

323333
returncount;
324334
}
@@ -415,7 +425,7 @@ copy_dir(const char *src, const char *dst, bool force)
415425
return-1;
416426
}
417427

418-
while ((de=readdir(srcdir))!=NULL)
428+
while (errno=0,(de=readdir(srcdir))!=NULL)
419429
{
420430
charsrc_file[MAXPGPATH];
421431
chardest_file[MAXPGPATH];
@@ -460,9 +470,19 @@ copy_dir(const char *src, const char *dst, bool force)
460470
}
461471
}
462472

473+
#ifdefWIN32
474+
/* Bug in old Mingw dirent.c; fixed in mingw-runtime-3.2, 2003-10-10 */
475+
if (GetLastError()==ERROR_NO_MORE_FILES)
476+
errno=0;
477+
#endif
478+
479+
if (errno)
480+
return-1;
481+
463482
if (srcdir!=NULL)
464483
{
465-
closedir(srcdir);
484+
if (closedir(srcdir))
485+
return-1;
466486
srcdir=NULL;
467487
}
468488
return1;

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

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

16161616
#ifdefWIN32
1617-
1618-
/*
1619-
* This fix is in mingw cvs (runtime/mingwex/dirent.c rev 1.4), but not in
1620-
* released version
1621-
*/
1617+
/* Bug in old Mingw dirent.c; fixed in mingw-runtime-3.2, 2003-10-10 */
16221618
if (GetLastError()==ERROR_NO_MORE_FILES)
16231619
errno=0;
16241620
#endif

‎src/bin/initdb/initdb.c

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -822,7 +822,7 @@ check_data_dir(char *dir)
822822
if (!chkdir)
823823
return (errno==ENOENT) ?0 :-1;
824824

825-
while ((file=readdir(chkdir))!=NULL)
825+
while (errno=0,(file=readdir(chkdir))!=NULL)
826826
{
827827
if (strcmp(".",file->d_name)==0||
828828
strcmp("..",file->d_name)==0)
@@ -838,18 +838,12 @@ check_data_dir(char *dir)
838838
}
839839

840840
#ifdefWIN32
841-
842-
/*
843-
* This fix is in mingw cvs (runtime/mingwex/dirent.c rev 1.4), but not in
844-
* released version
845-
*/
841+
/* Bug in old Mingw dirent.c; fixed in mingw-runtime-3.2, 2003-10-10 */
846842
if (GetLastError()==ERROR_NO_MORE_FILES)
847843
errno=0;
848844
#endif
849845

850-
closedir(chkdir);
851-
852-
if (errno!=0)
846+
if (errno||closedir(chkdir))
853847
result=-1;/* some kind of I/O error? */
854848

855849
returnresult;

‎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
@@ -100,15 +100,19 @@ readdir(DIR *d)
100100
strcpy(d->ret.d_name,fd.cFileName);/* Both strings are MAX_PATH
101101
* long */
102102
d->ret.d_namlen=strlen(d->ret.d_name);
103+
103104
return&d->ret;
104105
}
105106

106107
int
107108
closedir(DIR*d)
108109
{
110+
intret=0;
111+
109112
if (d->handle!=INVALID_HANDLE_VALUE)
110-
FindClose(d->handle);
113+
ret= !FindClose(d->handle);
111114
free(d->dirname);
112115
free(d);
113-
return0;
116+
117+
returnret;
114118
}

‎src/port/dirmod.c

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

331331
filenames= (char**)palloc(fnsize*sizeof(char*));
332332

333-
errno=0;
334-
while ((file=readdir(dir))!=NULL)
333+
while (errno=0, (file=readdir(dir))!=NULL)
335334
{
336335
if (strcmp(file->d_name,".")!=0&&strcmp(file->d_name,"..")!=0)
337336
{
@@ -343,17 +342,14 @@ pgfnames(const char *path)
343342
}
344343
filenames[numnames++]=pstrdup(file->d_name);
345344
}
346-
errno=0;
347345
}
348-
#ifdefWIN32
349346

350-
/*
351-
* This fix is in mingw cvs (runtime/mingwex/dirent.c rev 1.4), but not in
352-
* released version
353-
*/
347+
#ifdefWIN32
348+
/* Bug in old Mingw dirent.c; fixed in mingw-runtime-3.2, 2003-10-10 */
354349
if (GetLastError()==ERROR_NO_MORE_FILES)
355350
errno=0;
356351
#endif
352+
357353
if (errno)
358354
{
359355
#ifndefFRONTEND
@@ -366,7 +362,15 @@ pgfnames(const char *path)
366362

367363
filenames[numnames]=NULL;
368364

369-
closedir(dir);
365+
if (closedir(dir))
366+
{
367+
#ifndefFRONTEND
368+
elog(WARNING,"could not close directory \"%s\": %m",path);
369+
#else
370+
fprintf(stderr,_("could not close directory \"%s\": %s\n"),
371+
path,strerror(errno));
372+
#endif
373+
}
370374

371375
returnfilenames;
372376
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp