diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c
new file mode 100644
index 41d4606..539f197
*** a/src/bin/pg_upgrade/check.c
--- b/src/bin/pg_upgrade/check.c
*************** create_script_for_cluster_analyze(char *
*** 421,427 ****
  
  	if ((script = fopen_priv(*analyze_script_file_name, "w")) == NULL)
  		pg_fatal("Could not open file \"%s\": %s\n",
! 				 *analyze_script_file_name, getErrorText(errno));
  
  #ifndef WIN32
  	/* add shebang header */
--- 421,427 ----
  
  	if ((script = fopen_priv(*analyze_script_file_name, "w")) == NULL)
  		pg_fatal("Could not open file \"%s\": %s\n",
! 				 *analyze_script_file_name, getErrorText());
  
  #ifndef WIN32
  	/* add shebang header */
*************** create_script_for_cluster_analyze(char *
*** 476,482 ****
  #ifndef WIN32
  	if (chmod(*analyze_script_file_name, S_IRWXU) != 0)
  		pg_fatal("Could not add execute permission to file \"%s\": %s\n",
! 				 *analyze_script_file_name, getErrorText(errno));
  #endif
  
  	if (os_info.user_specified)
--- 476,482 ----
  #ifndef WIN32
  	if (chmod(*analyze_script_file_name, S_IRWXU) != 0)
  		pg_fatal("Could not add execute permission to file \"%s\": %s\n",
! 				 *analyze_script_file_name, getErrorText());
  #endif
  
  	if (os_info.user_specified)
*************** create_script_for_old_cluster_deletion(c
*** 532,538 ****
  
  	if ((script = fopen_priv(*deletion_script_file_name, "w")) == NULL)
  		pg_fatal("Could not open file \"%s\": %s\n",
! 				 *deletion_script_file_name, getErrorText(errno));
  
  #ifndef WIN32
  	/* add shebang header */
--- 532,538 ----
  
  	if ((script = fopen_priv(*deletion_script_file_name, "w")) == NULL)
  		pg_fatal("Could not open file \"%s\": %s\n",
! 				 *deletion_script_file_name, getErrorText());
  
  #ifndef WIN32
  	/* add shebang header */
*************** create_script_for_old_cluster_deletion(c
*** 588,594 ****
  #ifndef WIN32
  	if (chmod(*deletion_script_file_name, S_IRWXU) != 0)
  		pg_fatal("Could not add execute permission to file \"%s\": %s\n",
! 				 *deletion_script_file_name, getErrorText(errno));
  #endif
  
  	check_ok();
--- 588,594 ----
  #ifndef WIN32
  	if (chmod(*deletion_script_file_name, S_IRWXU) != 0)
  		pg_fatal("Could not add execute permission to file \"%s\": %s\n",
! 				 *deletion_script_file_name, getErrorText());
  #endif
  
  	check_ok();
*************** check_for_isn_and_int8_passing_mismatch(
*** 790,796 ****
  			found = true;
  			if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
  				pg_fatal("Could not open file \"%s\": %s\n",
! 						 output_path, getErrorText(errno));
  			if (!db_used)
  			{
  				fprintf(script, "Database: %s\n", active_db->db_name);
--- 790,796 ----
  			found = true;
  			if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
  				pg_fatal("Could not open file \"%s\": %s\n",
! 						 output_path, getErrorText());
  			if (!db_used)
  			{
  				fprintf(script, "Database: %s\n", active_db->db_name);
*************** check_for_reg_data_type_usage(ClusterInf
*** 893,899 ****
  			found = true;
  			if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
  				pg_fatal("Could not open file \"%s\": %s\n",
! 						 output_path, getErrorText(errno));
  			if (!db_used)
  			{
  				fprintf(script, "Database: %s\n", active_db->db_name);
--- 893,899 ----
  			found = true;
  			if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
  				pg_fatal("Could not open file \"%s\": %s\n",
! 						 output_path, getErrorText());
  			if (!db_used)
  			{
  				fprintf(script, "Database: %s\n", active_db->db_name);
*************** check_for_jsonb_9_4_usage(ClusterInfo *c
*** 984,990 ****
  			found = true;
  			if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
  				pg_fatal("Could not open file \"%s\": %s\n",
! 						 output_path, getErrorText(errno));
  			if (!db_used)
  			{
  				fprintf(script, "Database: %s\n", active_db->db_name);
--- 984,990 ----
  			found = true;
  			if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
  				pg_fatal("Could not open file \"%s\": %s\n",
! 						 output_path, getErrorText());
  			if (!db_used)
  			{
  				fprintf(script, "Database: %s\n", active_db->db_name);
*************** get_bin_version(ClusterInfo *cluster)
*** 1032,1038 ****
  	if ((output = popen(cmd, "r")) == NULL ||
  		fgets(cmd_output, sizeof(cmd_output), output) == NULL)
  		pg_fatal("Could not get pg_ctl version data using %s: %s\n",
! 				 cmd, getErrorText(errno));
  
  	pclose(output);
  
--- 1032,1038 ----
  	if ((output = popen(cmd, "r")) == NULL ||
  		fgets(cmd_output, sizeof(cmd_output), output) == NULL)
  		pg_fatal("Could not get pg_ctl version data using %s: %s\n",
! 				 cmd, getErrorText());
  
  	pclose(output);
  
diff --git a/src/bin/pg_upgrade/controldata.c b/src/bin/pg_upgrade/controldata.c
new file mode 100644
index 8a86e45..8da4ce3
*** a/src/bin/pg_upgrade/controldata.c
--- b/src/bin/pg_upgrade/controldata.c
*************** get_control_data(ClusterInfo *cluster, b
*** 120,126 ****
  
  	if ((output = popen(cmd, "r")) == NULL)
  		pg_fatal("Could not get control data using %s: %s\n",
! 				 cmd, getErrorText(errno));
  
  	/* Only in <= 9.2 */
  	if (GET_MAJOR_VERSION(cluster->major_version) <= 902)
--- 120,126 ----
  
  	if ((output = popen(cmd, "r")) == NULL)
  		pg_fatal("Could not get control data using %s: %s\n",
! 				 cmd, getErrorText());
  
  	/* Only in <= 9.2 */
  	if (GET_MAJOR_VERSION(cluster->major_version) <= 902)
diff --git a/src/bin/pg_upgrade/exec.c b/src/bin/pg_upgrade/exec.c
new file mode 100644
index 7d31912..92c3766
*** a/src/bin/pg_upgrade/exec.c
--- b/src/bin/pg_upgrade/exec.c
*************** pid_lock_file_exists(const char *datadir
*** 191,197 ****
  		/* ENOTDIR means we will throw a more useful error later */
  		if (errno != ENOENT && errno != ENOTDIR)
  			pg_fatal("could not open file \"%s\" for reading: %s\n",
! 					 path, getErrorText(errno));
  
  		return false;
  	}
--- 191,197 ----
  		/* ENOTDIR means we will throw a more useful error later */
  		if (errno != ENOENT && errno != ENOTDIR)
  			pg_fatal("could not open file \"%s\" for reading: %s\n",
! 					 path, getErrorText());
  
  		return false;
  	}
*************** check_data_dir(const char *pg_data)
*** 285,291 ****
  
  		if (stat(subDirName, &statBuf) != 0)
  			report_status(PG_FATAL, "check for \"%s\" failed: %s\n",
! 						  subDirName, getErrorText(errno));
  		else if (!S_ISDIR(statBuf.st_mode))
  			report_status(PG_FATAL, "%s is not a directory\n",
  						  subDirName);
--- 285,291 ----
  
  		if (stat(subDirName, &statBuf) != 0)
  			report_status(PG_FATAL, "check for \"%s\" failed: %s\n",
! 						  subDirName, getErrorText());
  		else if (!S_ISDIR(statBuf.st_mode))
  			report_status(PG_FATAL, "%s is not a directory\n",
  						  subDirName);
*************** check_bin_dir(ClusterInfo *cluster)
*** 309,315 ****
  	/* check bindir */
  	if (stat(cluster->bindir, &statBuf) != 0)
  		report_status(PG_FATAL, "check for \"%s\" failed: %s\n",
! 					  cluster->bindir, getErrorText(errno));
  	else if (!S_ISDIR(statBuf.st_mode))
  		report_status(PG_FATAL, "%s is not a directory\n",
  					  cluster->bindir);
--- 309,315 ----
  	/* check bindir */
  	if (stat(cluster->bindir, &statBuf) != 0)
  		report_status(PG_FATAL, "check for \"%s\" failed: %s\n",
! 					  cluster->bindir, getErrorText());
  	else if (!S_ISDIR(statBuf.st_mode))
  		report_status(PG_FATAL, "%s is not a directory\n",
  					  cluster->bindir);
*************** validate_exec(const char *dir, const cha
*** 352,358 ****
  	 */
  	if (stat(path, &buf) < 0)
  		pg_fatal("check for \"%s\" failed: %s\n",
! 				 path, getErrorText(errno));
  	else if (!S_ISREG(buf.st_mode))
  		pg_fatal("check for \"%s\" failed: not an executable file\n",
  				 path);
--- 352,358 ----
  	 */
  	if (stat(path, &buf) < 0)
  		pg_fatal("check for \"%s\" failed: %s\n",
! 				 path, getErrorText());
  	else if (!S_ISREG(buf.st_mode))
  		pg_fatal("check for \"%s\" failed: not an executable file\n",
  				 path);
diff --git a/src/bin/pg_upgrade/file.c b/src/bin/pg_upgrade/file.c
new file mode 100644
index 37eb832..c84783c
*** a/src/bin/pg_upgrade/file.c
--- b/src/bin/pg_upgrade/file.c
*************** copyAndUpdateFile(pageCnvCtx *pageConver
*** 37,45 ****
  #ifndef WIN32
  		if (copy_file(src, dst, force) == -1)
  #else
! 		if (CopyFile(src, dst, force) == 0)
  #endif
! 			return getErrorText(errno);
  		else
  			return NULL;
  	}
--- 37,45 ----
  #ifndef WIN32
  		if (copy_file(src, dst, force) == -1)
  #else
! 		if (CopyFile(src, dst, !force) == 0)
  #endif
! 			return getErrorText();
  		else
  			return NULL;
  	}
*************** linkAndUpdateFile(pageCnvCtx *pageConver
*** 121,127 ****
  		return "Cannot in-place update this cluster, page-by-page conversion is required";
  
  	if (pg_link_file(src, dst) == -1)
! 		return getErrorText(errno);
  	else
  		return NULL;
  }
--- 121,127 ----
  		return "Cannot in-place update this cluster, page-by-page conversion is required";
  
  	if (pg_link_file(src, dst) == -1)
! 		return getErrorText();
  	else
  		return NULL;
  }
*************** check_hard_link(void)
*** 219,225 ****
  	{
  		pg_fatal("Could not create hard link between old and new data directories: %s\n"
  				 "In link mode the old and new data directories must be on the same file system volume.\n",
! 				 getErrorText(errno));
  	}
  	unlink(new_link_file);
  }
--- 219,225 ----
  	{
  		pg_fatal("Could not create hard link between old and new data directories: %s\n"
  				 "In link mode the old and new data directories must be on the same file system volume.\n",
! 				 getErrorText());
  	}
  	unlink(new_link_file);
  }
diff --git a/src/bin/pg_upgrade/function.c b/src/bin/pg_upgrade/function.c
new file mode 100644
index 04492a5..0fb8c31
*** a/src/bin/pg_upgrade/function.c
--- b/src/bin/pg_upgrade/function.c
*************** check_loadable_libraries(void)
*** 214,220 ****
  
  			if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
  				pg_fatal("Could not open file \"%s\": %s\n",
! 						 output_path, getErrorText(errno));
  			fprintf(script, "Could not load library \"%s\"\n%s\n",
  					lib,
  					PQerrorMessage(conn));
--- 214,220 ----
  
  			if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
  				pg_fatal("Could not open file \"%s\": %s\n",
! 						 output_path, getErrorText());
  			fprintf(script, "Could not load library \"%s\"\n%s\n",
  					lib,
  					PQerrorMessage(conn));
diff --git a/src/bin/pg_upgrade/option.c b/src/bin/pg_upgrade/option.c
new file mode 100644
index 90f1401..a8571f0
*** a/src/bin/pg_upgrade/option.c
--- b/src/bin/pg_upgrade/option.c
*************** adjust_data_dir(ClusterInfo *cluster)
*** 423,429 ****
  	if ((output = popen(cmd, "r")) == NULL ||
  		fgets(cmd_output, sizeof(cmd_output), output) == NULL)
  		pg_fatal("Could not get data directory using %s: %s\n",
! 				 cmd, getErrorText(errno));
  
  	pclose(output);
  
--- 423,429 ----
  	if ((output = popen(cmd, "r")) == NULL ||
  		fgets(cmd_output, sizeof(cmd_output), output) == NULL)
  		pg_fatal("Could not get data directory using %s: %s\n",
! 				 cmd, getErrorText());
  
  	pclose(output);
  
diff --git a/src/bin/pg_upgrade/pg_upgrade.c b/src/bin/pg_upgrade/pg_upgrade.c
new file mode 100644
index 00cc938..4a7281b
*** a/src/bin/pg_upgrade/pg_upgrade.c
--- b/src/bin/pg_upgrade/pg_upgrade.c
*************** setup(char *argv0, bool *live_check)
*** 224,230 ****
  
  	/* get path to pg_upgrade executable */
  	if (find_my_exec(argv0, exec_path) < 0)
! 		pg_fatal("Could not get path name to pg_upgrade: %s\n", getErrorText(errno));
  
  	/* Trim off program name and keep just path */
  	*last_dir_separator(exec_path) = '\0';
--- 224,230 ----
  
  	/* get path to pg_upgrade executable */
  	if (find_my_exec(argv0, exec_path) < 0)
! 		pg_fatal("Could not get path name to pg_upgrade: %s\n", getErrorText());
  
  	/* Trim off program name and keep just path */
  	*last_dir_separator(exec_path) = '\0';
diff --git a/src/bin/pg_upgrade/pg_upgrade.h b/src/bin/pg_upgrade/pg_upgrade.h
new file mode 100644
index fa4661b..a43dff5
*** a/src/bin/pg_upgrade/pg_upgrade.h
--- b/src/bin/pg_upgrade/pg_upgrade.h
*************** void		pg_fatal(const char *fmt,...) pg_a
*** 460,466 ****
  void		end_progress_output(void);
  void		prep_status(const char *fmt,...) pg_attribute_printf(1, 2);
  void		check_ok(void);
! const char *getErrorText(int errNum);
  unsigned int str2uint(const char *str);
  void		pg_putenv(const char *var, const char *val);
  
--- 460,466 ----
  void		end_progress_output(void);
  void		prep_status(const char *fmt,...) pg_attribute_printf(1, 2);
  void		check_ok(void);
! const char *getErrorText(void);
  unsigned int str2uint(const char *str);
  void		pg_putenv(const char *var, const char *val);
  
diff --git a/src/bin/pg_upgrade/relfilenode.c b/src/bin/pg_upgrade/relfilenode.c
new file mode 100644
index c22df42..bfde1b1
*** a/src/bin/pg_upgrade/relfilenode.c
--- b/src/bin/pg_upgrade/relfilenode.c
*************** transfer_relfile(pageCnvCtx *pageConvert
*** 258,264 ****
  				else
  					pg_fatal("error while checking for file existence \"%s.%s\" (\"%s\" to \"%s\"): %s\n",
  							 map->nspname, map->relname, old_file, new_file,
! 							 getErrorText(errno));
  			}
  			close(fd);
  		}
--- 258,264 ----
  				else
  					pg_fatal("error while checking for file existence \"%s.%s\" (\"%s\" to \"%s\"): %s\n",
  							 map->nspname, map->relname, old_file, new_file,
! 							 getErrorText());
  			}
  			close(fd);
  		}
diff --git a/src/bin/pg_upgrade/tablespace.c b/src/bin/pg_upgrade/tablespace.c
new file mode 100644
index ce7097e..a20cbc6
*** a/src/bin/pg_upgrade/tablespace.c
--- b/src/bin/pg_upgrade/tablespace.c
*************** get_tablespace_paths(void)
*** 91,97 ****
  			else
  				report_status(PG_FATAL,
  						   "cannot stat() tablespace directory \"%s\": %s\n",
! 					   os_info.old_tablespaces[tblnum], getErrorText(errno));
  		}
  		if (!S_ISDIR(statBuf.st_mode))
  			report_status(PG_FATAL,
--- 91,97 ----
  			else
  				report_status(PG_FATAL,
  						   "cannot stat() tablespace directory \"%s\": %s\n",
! 					   os_info.old_tablespaces[tblnum], getErrorText());
  		}
  		if (!S_ISDIR(statBuf.st_mode))
  			report_status(PG_FATAL,
diff --git a/src/bin/pg_upgrade/util.c b/src/bin/pg_upgrade/util.c
new file mode 100644
index 7f328f0..5a2ecbb
*** a/src/bin/pg_upgrade/util.c
--- b/src/bin/pg_upgrade/util.c
*************** get_user_info(char **user_name_p)
*** 236,252 ****
   * getErrorText()
   *
   *	Returns the text of the error message for the given error number
-  *
-  *	This feature is factored into a separate function because it is
-  *	system-dependent.
   */
  const char *
! getErrorText(int errNum)
  {
  #ifdef WIN32
  	_dosmaperr(GetLastError());
  #endif
! 	return pg_strdup(strerror(errNum));
  }
  
  
--- 236,249 ----
   * getErrorText()
   *
   *	Returns the text of the error message for the given error number
   */
  const char *
! getErrorText(void)
  {
  #ifdef WIN32
  	_dosmaperr(GetLastError());
  #endif
! 	return pg_strdup(strerror(errno));
  }
  
  
diff --git a/src/bin/pg_upgrade/version.c b/src/bin/pg_upgrade/version.c
new file mode 100644
index 9954dae..b93c414
*** a/src/bin/pg_upgrade/version.c
--- b/src/bin/pg_upgrade/version.c
*************** new_9_0_populate_pg_largeobject_metadata
*** 49,55 ****
  			if (!check_mode)
  			{
  				if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
! 					pg_fatal("could not open file \"%s\": %s\n", output_path, getErrorText(errno));
  				fprintf(script, "\\connect %s\n",
  						quote_identifier(active_db->db_name));
  				fprintf(script,
--- 49,55 ----
  			if (!check_mode)
  			{
  				if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
! 					pg_fatal("could not open file \"%s\": %s\n", output_path, getErrorText());
  				fprintf(script, "\\connect %s\n",
  						quote_identifier(active_db->db_name));
  				fprintf(script,
*************** old_9_3_check_for_line_data_type_usage(C
*** 143,149 ****
  		{
  			found = true;
  			if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
! 				pg_fatal("could not open file \"%s\": %s\n", output_path, getErrorText(errno));
  			if (!db_used)
  			{
  				fprintf(script, "Database: %s\n", active_db->db_name);
--- 143,149 ----
  		{
  			found = true;
  			if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
! 				pg_fatal("could not open file \"%s\": %s\n", output_path, getErrorText());
  			if (!db_used)
  			{
  				fprintf(script, "Database: %s\n", active_db->db_name);
