On Mon, Dec  9, 2013 at 11:27:28AM -0500, Robert Haas wrote:
> On Thu, Dec 5, 2013 at 6:15 PM, Tom Lane <t...@sss.pgh.pa.us> wrote:
> > But the other usages seem to be in assorted utilities, which
> > will need to do it right for themselves.  initdb.c's walkdir() seems to
> > have it right and might be a reasonable model to follow.  Or maybe we
> > should invent a frontend-friendly version of ReadDir() rather than
> > duplicating all the error checking code in ten-and-counting places?
> 
> If there's enough uniformity in all of those places to make that
> feasible, it certainly seems wise to do it that way.  I don't know if
> that's the case, though - e.g. maybe some callers want to exit and
> others do not.  pg_resetxlog wants to exit; pg_archivecleanup and
> pg_standby most likely want to print an error and carry on.

I have developed the attached patch which fixes all cases where
readdir() wasn't checking for errno, and cleaned up the syntax in other
cases to be consistent.

While I am not a fan of backpatching, the fact we are ignoring errors in
some critical cases seems the non-cosmetic parts should be backpatched.

-- 
  Bruce Momjian  <br...@momjian.us>        http://momjian.us
  EnterpriseDB                             http://enterprisedb.com

  + Everyone has their own god. +
diff --git a/contrib/pg_archivecleanup/pg_archivecleanup.c b/contrib/pg_archivecleanup/pg_archivecleanup.c
new file mode 100644
index 7b5484b..fbc3e5a
*** a/contrib/pg_archivecleanup/pg_archivecleanup.c
--- b/contrib/pg_archivecleanup/pg_archivecleanup.c
*************** CleanupPriorWALFiles(void)
*** 106,112 ****
  
  	if ((xldir = opendir(archiveLocation)) != NULL)
  	{
! 		while ((xlde = readdir(xldir)) != NULL)
  		{
  			strncpy(walfile, xlde->d_name, MAXPGPATH);
  			TrimExtension(walfile, additional_ext);
--- 106,112 ----
  
  	if ((xldir = opendir(archiveLocation)) != NULL)
  	{
! 		while (errno = 0, (xlde = readdir(xldir)) != NULL)
  		{
  			strncpy(walfile, xlde->d_name, MAXPGPATH);
  			TrimExtension(walfile, additional_ext);
*************** CleanupPriorWALFiles(void)
*** 164,169 ****
--- 164,172 ----
  				}
  			}
  		}
+ 		if (errno)
+ 			fprintf(stderr, "%s: could not read archive location \"%s\": %s\n",
+ 					progname, archiveLocation, strerror(errno));
  		closedir(xldir);
  	}
  	else
diff --git a/contrib/pg_standby/pg_standby.c b/contrib/pg_standby/pg_standby.c
new file mode 100644
index 8ddd486..be4d31f
*** a/contrib/pg_standby/pg_standby.c
--- b/contrib/pg_standby/pg_standby.c
*************** CustomizableCleanupPriorWALFiles(void)
*** 245,251 ****
  		 */
  		if ((xldir = opendir(archiveLocation)) != NULL)
  		{
! 			while ((xlde = readdir(xldir)) != NULL)
  			{
  				/*
  				 * We ignore the timeline part of the XLOG segment identifiers
--- 245,251 ----
  		 */
  		if ((xldir = opendir(archiveLocation)) != NULL)
  		{
! 			while (errno = 0, (xlde = readdir(xldir)) != NULL)
  			{
  				/*
  				 * We ignore the timeline part of the XLOG segment identifiers
*************** CustomizableCleanupPriorWALFiles(void)
*** 283,288 ****
--- 283,291 ----
  					}
  				}
  			}
+ 			if (errno)
+ 				fprintf(stderr, "%s: could not read archive location \"%s\": %s\n",
+ 						progname, archiveLocation, strerror(errno));
  			if (debug)
  				fprintf(stderr, "\n");
  		}
diff --git a/src/bin/pg_basebackup/pg_receivexlog.c b/src/bin/pg_basebackup/pg_receivexlog.c
new file mode 100644
index 2478789..e252405
*** a/src/bin/pg_basebackup/pg_receivexlog.c
--- b/src/bin/pg_basebackup/pg_receivexlog.c
*************** FindStreamingStart(uint32 *tli)
*** 139,145 ****
  		disconnect_and_exit(1);
  	}
  
! 	while ((dirent = readdir(dir)) != NULL)
  	{
  		uint32		tli;
  		XLogSegNo	segno;
--- 139,145 ----
  		disconnect_and_exit(1);
  	}
  
! 	while (errno = 0, (dirent = readdir(dir)) != NULL)
  	{
  		uint32		tli;
  		XLogSegNo	segno;
*************** FindStreamingStart(uint32 *tli)
*** 209,214 ****
--- 209,221 ----
  		}
  	}
  
+ 	if (errno)
+ 	{
+ 		fprintf(stderr, _("%s: could not read directory \"%s\": %s\n"),
+ 				progname, basedir, strerror(errno));
+ 		disconnect_and_exit(1);
+ 	}
+ 
  	closedir(dir);
  
  	if (high_segno > 0)
diff --git a/src/bin/pg_dump/pg_backup_directory.c b/src/bin/pg_dump/pg_backup_directory.c
new file mode 100644
index 1bed8a9..c24f7e3
*** a/src/bin/pg_dump/pg_backup_directory.c
--- b/src/bin/pg_dump/pg_backup_directory.c
*************** InitArchiveFmt_Directory(ArchiveHandle *
*** 177,183 ****
  				struct dirent *d;
  
  				is_empty = true;
! 				while ((d = readdir(dir)))
  				{
  					if (strcmp(d->d_name, ".") != 0 && strcmp(d->d_name, "..") != 0)
  					{
--- 177,183 ----
  				struct dirent *d;
  
  				is_empty = true;
! 				while (errno = 0, (d = readdir(dir)))
  				{
  					if (strcmp(d->d_name, ".") != 0 && strcmp(d->d_name, "..") != 0)
  					{
*************** InitArchiveFmt_Directory(ArchiveHandle *
*** 185,190 ****
--- 185,193 ----
  						break;
  					}
  				}
+ 				if (errno)
+ 					exit_horribly(modulename, "could not read directory \"%s\": %s\n",
+ 								  ctx->directory, strerror(errno));
  				closedir(dir);
  			}
  		}
diff --git a/src/bin/pg_resetxlog/pg_resetxlog.c b/src/bin/pg_resetxlog/pg_resetxlog.c
new file mode 100644
index 28a4f19..7bd8052
*** a/src/bin/pg_resetxlog/pg_resetxlog.c
--- b/src/bin/pg_resetxlog/pg_resetxlog.c
*************** FindEndOfXLOG(void)
*** 821,828 ****
  		exit(1);
  	}
  
! 	errno = 0;
! 	while ((xlde = readdir(xldir)) != NULL)
  	{
  		if (strlen(xlde->d_name) == 24 &&
  			strspn(xlde->d_name, "0123456789ABCDEF") == 24)
--- 821,827 ----
  		exit(1);
  	}
  
! 	while (errno = 0, (xlde = readdir(xldir)) != NULL)
  	{
  		if (strlen(xlde->d_name) == 24 &&
  			strspn(xlde->d_name, "0123456789ABCDEF") == 24)
*************** FindEndOfXLOG(void)
*** 844,850 ****
  			if (segno > newXlogSegNo)
  				newXlogSegNo = segno;
  		}
- 		errno = 0;
  	}
  
  #ifdef WIN32
--- 843,848 ----
*************** KillExistingXLOG(void)
*** 892,899 ****
  		exit(1);
  	}
  
! 	errno = 0;
! 	while ((xlde = readdir(xldir)) != NULL)
  	{
  		if (strlen(xlde->d_name) == 24 &&
  			strspn(xlde->d_name, "0123456789ABCDEF") == 24)
--- 890,896 ----
  		exit(1);
  	}
  
! 	while (errno = 0, (xlde = readdir(xldir)) != NULL)
  	{
  		if (strlen(xlde->d_name) == 24 &&
  			strspn(xlde->d_name, "0123456789ABCDEF") == 24)
*************** KillExistingXLOG(void)
*** 906,912 ****
  				exit(1);
  			}
  		}
- 		errno = 0;
  	}
  
  #ifdef WIN32
--- 903,908 ----
*************** KillExistingArchiveStatus(void)
*** 948,955 ****
  		exit(1);
  	}
  
! 	errno = 0;
! 	while ((xlde = readdir(xldir)) != NULL)
  	{
  		if (strspn(xlde->d_name, "0123456789ABCDEF") == 24 &&
  			(strcmp(xlde->d_name + 24, ".ready") == 0 ||
--- 944,950 ----
  		exit(1);
  	}
  
! 	while (errno = 0, (xlde = readdir(xldir)) != NULL)
  	{
  		if (strspn(xlde->d_name, "0123456789ABCDEF") == 24 &&
  			(strcmp(xlde->d_name + 24, ".ready") == 0 ||
*************** KillExistingArchiveStatus(void)
*** 963,969 ****
  				exit(1);
  			}
  		}
- 		errno = 0;
  	}
  
  #ifdef WIN32
--- 958,963 ----
diff --git a/src/common/pgfnames.c b/src/common/pgfnames.c
new file mode 100644
index 9a68163..0d852b1
*** a/src/common/pgfnames.c
--- b/src/common/pgfnames.c
*************** pgfnames(const char *path)
*** 50,57 ****
  
  	filenames = (char **) palloc(fnsize * sizeof(char *));
  
! 	errno = 0;
! 	while ((file = readdir(dir)) != NULL)
  	{
  		if (strcmp(file->d_name, ".") != 0 && strcmp(file->d_name, "..") != 0)
  		{
--- 50,56 ----
  
  	filenames = (char **) palloc(fnsize * sizeof(char *));
  
! 	while (errno = 0, (file = readdir(dir)) != NULL)
  	{
  		if (strcmp(file->d_name, ".") != 0 && strcmp(file->d_name, "..") != 0)
  		{
*************** pgfnames(const char *path)
*** 63,69 ****
  			}
  			filenames[numnames++] = pstrdup(file->d_name);
  		}
- 		errno = 0;
  	}
  
  #ifdef WIN32
--- 62,67 ----
diff --git a/src/port/pgcheckdir.c b/src/port/pgcheckdir.c
new file mode 100644
index fc97f8c..6454525
*** a/src/port/pgcheckdir.c
--- b/src/port/pgcheckdir.c
*************** pg_check_dir(const char *dir)
*** 33,46 ****
  	struct dirent *file;
  	bool		dot_found = false;
  
- 	errno = 0;
- 
  	chkdir = opendir(dir);
- 
  	if (chkdir == NULL)
  		return (errno == ENOENT) ? 0 : -1;
  
! 	while ((file = readdir(chkdir)) != NULL)
  	{
  		if (strcmp(".", file->d_name) == 0 ||
  			strcmp("..", file->d_name) == 0)
--- 33,43 ----
  	struct dirent *file;
  	bool		dot_found = false;
  
  	chkdir = opendir(dir);
  	if (chkdir == NULL)
  		return (errno == ENOENT) ? 0 : -1;
  
! 	while (errno = 0, (file = readdir(chkdir)) != NULL)
  	{
  		if (strcmp(".", file->d_name) == 0 ||
  			strcmp("..", file->d_name) == 0)
*************** pg_check_dir(const char *dir)
*** 76,84 ****
  		errno = 0;
  #endif
  
! 	closedir(chkdir);
! 
! 	if (errno != 0)
  		result = -1;			/* some kind of I/O error? */
  
  	/* We report on dot-files if we _only_ find dot files */
--- 73,79 ----
  		errno = 0;
  #endif
  
! 	if (errno || closedir(chkdir) == -1)
  		result = -1;			/* some kind of I/O error? */
  
  	/* We report on dot-files if we _only_ find dot files */
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to