On Wed, Jul 25, 2012 at 04:30:10PM -0400, Tom Lane wrote:
> Bruce Momjian <br...@momjian.us> writes:
> > Tom suggested that load_directory() return a (char *) array, rather than
> > a struct dirent array, greatly simplifying the code.
> > I have done this in the attached patch, and because of the uncertainty
> > of ths fix, I would like to apply this to 9.2 as well.
> 
> BTW, the patch neglects to update the header comment for load_directory.

Oh, good point.  Updated patch attached.

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

  + It's impossible for everything to be true. +
diff --git a/contrib/pg_upgrade/file.c b/contrib/pg_upgrade/file.c
new file mode 100644
index 962cbac..5509670
*** a/contrib/pg_upgrade/file.c
--- b/contrib/pg_upgrade/file.c
*************** copy_file(const char *srcfile, const cha
*** 225,247 ****
   * load_directory()
   *
   * Read all the file names in the specified directory, and return them as
!  * an array of "struct dirent" pointers.  The array address is returned in
   * *namelist, and the function result is the count of file names.
   *
!  * To free the result data, free each namelist array member, then free the
   * namelist array itself.
   */
  int
! load_directory(const char *dirname, struct dirent *** namelist)
  {
  	DIR		   *dirdesc;
  	struct dirent *direntry;
  	int			count = 0;
! 	int			allocsize = 64;
! 	size_t		entrysize;
  
! 	*namelist = (struct dirent **)
! 		pg_malloc(allocsize * sizeof(struct dirent *));
  
  	if ((dirdesc = opendir(dirname)) == NULL)
  		pg_log(PG_FATAL, "could not open directory \"%s\": %s\n",
--- 225,245 ----
   * load_directory()
   *
   * Read all the file names in the specified directory, and return them as
!  * an array of "char *" pointers.  The array address is returned in
   * *namelist, and the function result is the count of file names.
   *
!  * To free the result data, free each (char *) array member, then free the
   * namelist array itself.
   */
  int
! load_directory(const char *dirname, char ***namelist)
  {
  	DIR		   *dirdesc;
  	struct dirent *direntry;
  	int			count = 0;
! 	int			allocsize = 64;		/* initial array size */
  
! 	*namelist = (char **) pg_malloc(allocsize * sizeof(char *));
  
  	if ((dirdesc = opendir(dirname)) == NULL)
  		pg_log(PG_FATAL, "could not open directory \"%s\": %s\n",
*************** load_directory(const char *dirname, stru
*** 252,269 ****
  		if (count >= allocsize)
  		{
  			allocsize *= 2;
! 			*namelist = (struct dirent **)
! 				pg_realloc(*namelist, allocsize * sizeof(struct dirent *));
  		}
  
! 		entrysize = offsetof(struct dirent, d_name) +
! 			strlen(direntry->d_name) + 1;
! 
! 		(*namelist)[count] = (struct dirent *) pg_malloc(entrysize);
! 
! 		memcpy((*namelist)[count], direntry, entrysize);
! 
! 		count++;
  	}
  
  #ifdef WIN32
--- 250,260 ----
  		if (count >= allocsize)
  		{
  			allocsize *= 2;
! 			*namelist = (char **)
! 						pg_realloc(*namelist, allocsize * sizeof(char *));
  		}
  
! 		(*namelist)[count++] = pg_strdup(direntry->d_name);
  	}
  
  #ifdef WIN32
diff --git a/contrib/pg_upgrade/pg_upgrade.h b/contrib/pg_upgrade/pg_upgrade.h
new file mode 100644
index f0d84a0..9a23176
*** a/contrib/pg_upgrade/pg_upgrade.h
--- b/contrib/pg_upgrade/pg_upgrade.h
*************** const char *setupPageConverter(pageCnvCt
*** 356,362 ****
  typedef void *pageCnvCtx;
  #endif
  
! int			load_directory(const char *dirname, struct dirent *** namelist);
  const char *copyAndUpdateFile(pageCnvCtx *pageConverter, const char *src,
  				  const char *dst, bool force);
  const char *linkAndUpdateFile(pageCnvCtx *pageConverter, const char *src,
--- 356,362 ----
  typedef void *pageCnvCtx;
  #endif
  
! int			load_directory(const char *dirname, char ***namelist);
  const char *copyAndUpdateFile(pageCnvCtx *pageConverter, const char *src,
  				  const char *dst, bool force);
  const char *linkAndUpdateFile(pageCnvCtx *pageConverter, const char *src,
diff --git a/contrib/pg_upgrade/relfilenode.c b/contrib/pg_upgrade/relfilenode.c
new file mode 100644
index 659b614..7688914
*** a/contrib/pg_upgrade/relfilenode.c
--- b/contrib/pg_upgrade/relfilenode.c
*************** transfer_single_new_db(pageCnvCtx *pageC
*** 133,139 ****
  {
  	char		old_dir[MAXPGPATH];
  	char		file_pattern[MAXPGPATH];
! 	struct dirent **namelist = NULL;
  	int			numFiles = 0;
  	int			mapnum;
  	int			fileno;
--- 133,139 ----
  {
  	char		old_dir[MAXPGPATH];
  	char		file_pattern[MAXPGPATH];
! 	char		**namelist = NULL;
  	int			numFiles = 0;
  	int			mapnum;
  	int			fileno;
*************** transfer_single_new_db(pageCnvCtx *pageC
*** 192,212 ****
  
  			for (fileno = 0; fileno < numFiles; fileno++)
  			{
! 				char	   *vm_offset = strstr(namelist[fileno]->d_name, "_vm");
  				bool		is_vm_file = false;
  
  				/* Is a visibility map file? (name ends with _vm) */
  				if (vm_offset && strlen(vm_offset) == strlen("_vm"))
  					is_vm_file = true;
  
! 				if (strncmp(namelist[fileno]->d_name, file_pattern,
  							strlen(file_pattern)) == 0 &&
  					(!is_vm_file || !vm_crashsafe_change))
  				{
  					snprintf(old_file, sizeof(old_file), "%s/%s", maps[mapnum].old_dir,
! 							 namelist[fileno]->d_name);
  					snprintf(new_file, sizeof(new_file), "%s/%u%s", maps[mapnum].new_dir,
! 							 maps[mapnum].new_relfilenode, strchr(namelist[fileno]->d_name, '_'));
  
  					unlink(new_file);
  					transfer_relfile(pageConverter, old_file, new_file,
--- 192,212 ----
  
  			for (fileno = 0; fileno < numFiles; fileno++)
  			{
! 				char	   *vm_offset = strstr(namelist[fileno], "_vm");
  				bool		is_vm_file = false;
  
  				/* Is a visibility map file? (name ends with _vm) */
  				if (vm_offset && strlen(vm_offset) == strlen("_vm"))
  					is_vm_file = true;
  
! 				if (strncmp(namelist[fileno], file_pattern,
  							strlen(file_pattern)) == 0 &&
  					(!is_vm_file || !vm_crashsafe_change))
  				{
  					snprintf(old_file, sizeof(old_file), "%s/%s", maps[mapnum].old_dir,
! 							 namelist[fileno]);
  					snprintf(new_file, sizeof(new_file), "%s/%u%s", maps[mapnum].new_dir,
! 							 maps[mapnum].new_relfilenode, strchr(namelist[fileno], '_'));
  
  					unlink(new_file);
  					transfer_relfile(pageConverter, old_file, new_file,
*************** transfer_single_new_db(pageCnvCtx *pageC
*** 227,239 ****
  
  		for (fileno = 0; fileno < numFiles; fileno++)
  		{
! 			if (strncmp(namelist[fileno]->d_name, file_pattern,
  						strlen(file_pattern)) == 0)
  			{
  				snprintf(old_file, sizeof(old_file), "%s/%s", maps[mapnum].old_dir,
! 						 namelist[fileno]->d_name);
  				snprintf(new_file, sizeof(new_file), "%s/%u%s", maps[mapnum].new_dir,
! 						 maps[mapnum].new_relfilenode, strchr(namelist[fileno]->d_name, '.'));
  
  				unlink(new_file);
  				transfer_relfile(pageConverter, old_file, new_file,
--- 227,239 ----
  
  		for (fileno = 0; fileno < numFiles; fileno++)
  		{
! 			if (strncmp(namelist[fileno], file_pattern,
  						strlen(file_pattern)) == 0)
  			{
  				snprintf(old_file, sizeof(old_file), "%s/%s", maps[mapnum].old_dir,
! 						 namelist[fileno]);
  				snprintf(new_file, sizeof(new_file), "%s/%u%s", maps[mapnum].new_dir,
! 						 maps[mapnum].new_relfilenode, strchr(namelist[fileno], '.'));
  
  				unlink(new_file);
  				transfer_relfile(pageConverter, old_file, new_file,
-- 
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