diff --git a/contrib/pg_upgrade/util.c b/contrib/pg_upgrade/util.c
new file mode 100644
index a67bd64..c3d4523
*** a/contrib/pg_upgrade/util.c
--- b/contrib/pg_upgrade/util.c
*************** quote_identifier(const char *s)
*** 203,234 ****
  
  /*
   * get_user_info()
-  * (copied from initdb.c) find the current user
   */
  int
  get_user_info(char **user_name)
  {
  	int			user_id;
  
  #ifndef WIN32
- 	struct passwd *pw = getpwuid(geteuid());
- 
  	user_id = geteuid();
! #else							/* the windows code */
! 	struct passwd_win32
! 	{
! 		int			pw_uid;
! 		char		pw_name[128];
! 	}			pass_win32;
! 	struct passwd_win32 *pw = &pass_win32;
! 	DWORD		pwname_size = sizeof(pass_win32.pw_name) - 1;
! 
! 	GetUserName(pw->pw_name, &pwname_size);
! 
  	user_id = 1;
  #endif
  
! 	*user_name = pg_strdup(pw->pw_name);
  
  	return user_id;
  }
--- 203,227 ----
  
  /*
   * get_user_info()
   */
  int
  get_user_info(char **user_name)
  {
  	int			user_id;
+ 	char	   *errstr;
  
  #ifndef WIN32
  	user_id = geteuid();
! #else
  	user_id = 1;
  #endif
  
! 	*user_name = get_user_name(&errstr);
! 	if (!*user_name)
! 		pg_fatal("%s\n", errstr);
! 
! 	/* make a copy */
! 	*user_name = pg_strdup(*user_name);
  
  	return user_id;
  }
diff --git a/src/backend/libpq/auth.c b/src/backend/libpq/auth.c
new file mode 100644
index 2dbf7e5..6d11e57
*** a/src/backend/libpq/auth.c
--- b/src/backend/libpq/auth.c
*************** auth_peer(hbaPort *port)
*** 1771,1777 ****
  	char		ident_user[IDENT_USERNAME_MAX + 1];
  	uid_t		uid;
  	gid_t		gid;
! 	struct passwd *pass;
  
  	errno = 0;
  	if (getpeereid(port->sock, &uid, &gid) != 0)
--- 1771,1778 ----
  	char		ident_user[IDENT_USERNAME_MAX + 1];
  	uid_t		uid;
  	gid_t		gid;
! 	const char *user_name;
! 	char	   *errstr;
  
  	errno = 0;
  	if (getpeereid(port->sock, &uid, &gid) != 0)
*************** auth_peer(hbaPort *port)
*** 1788,1804 ****
  		return STATUS_ERROR;
  	}
  
! 	pass = getpwuid(uid);
! 
! 	if (pass == NULL)
  	{
! 		ereport(LOG,
! 				(errmsg("local user with ID %d does not exist",
! 						(int) uid)));
  		return STATUS_ERROR;
  	}
  
! 	strlcpy(ident_user, pass->pw_name, IDENT_USERNAME_MAX + 1);
  
  	return check_usermap(port->hba->usermap, port->user_name, ident_user, false);
  }
--- 1789,1803 ----
  		return STATUS_ERROR;
  	}
  
! 	user_name = get_user_name(&errstr);
! 	if (!user_name)
  	{
! 		ereport(LOG, (errmsg_internal("%s", errstr)));
! 		pfree(errstr);
  		return STATUS_ERROR;
  	}
  
! 	strlcpy(ident_user, user_name, IDENT_USERNAME_MAX + 1);
  
  	return check_usermap(port->hba->usermap, port->user_name, ident_user, false);
  }
diff --git a/src/backend/main/main.c b/src/backend/main/main.c
new file mode 100644
index d71885d..376aa39
*** a/src/backend/main/main.c
--- b/src/backend/main/main.c
***************
*** 20,26 ****
   */
  #include "postgres.h"
  
- #include <pwd.h>
  #include <unistd.h>
  
  #if defined(__alpha) && defined(__osf__)		/* no __alpha__ ? */
--- 20,25 ----
*************** const char *progname;
*** 49,55 ****
  static void startup_hacks(const char *progname);
  static void help(const char *progname);
  static void check_root(const char *progname);
- static char *get_current_username(const char *progname);
  
  
  /*
--- 48,53 ----
*************** main(int argc, char *argv[])
*** 191,197 ****
  	else if (argc > 1 && strcmp(argv[1], "--single") == 0)
  		PostgresMain(argc, argv,
  					 NULL,		/* no dbname */
! 					 get_current_username(progname));	/* does not return */
  	else
  		PostmasterMain(argc, argv);		/* does not return */
  	abort();					/* should not get here */
--- 189,195 ----
  	else if (argc > 1 && strcmp(argv[1], "--single") == 0)
  		PostgresMain(argc, argv,
  					 NULL,		/* no dbname */
! 					 strdup(get_user_name_or_exit(progname)));	/* does not return */
  	else
  		PostmasterMain(argc, argv);		/* does not return */
  	abort();					/* should not get here */
*************** check_root(const char *progname)
*** 372,407 ****
  	}
  #endif   /* WIN32 */
  }
- 
- 
- 
- static char *
- get_current_username(const char *progname)
- {
- #ifndef WIN32
- 	struct passwd *pw;
- 
- 	pw = getpwuid(geteuid());
- 	if (pw == NULL)
- 	{
- 		write_stderr("%s: invalid effective UID: %d\n",
- 					 progname, (int) geteuid());
- 		exit(1);
- 	}
- 	/* Allocate new memory because later getpwuid() calls can overwrite it. */
- 	return strdup(pw->pw_name);
- #else
- 	unsigned long namesize = 256 /* UNLEN */ + 1;
- 	char	   *name;
- 
- 	name = malloc(namesize);
- 	if (!GetUserName(name, &namesize))
- 	{
- 		write_stderr("%s: could not determine user name (GetUserName failed)\n",
- 					 progname);
- 		exit(1);
- 	}
- 
- 	return name;
- #endif
- }
--- 370,372 ----
diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c
new file mode 100644
index 30e3701..65d6b3f
*** a/src/bin/initdb/initdb.c
--- b/src/bin/initdb/initdb.c
*************** exit_nicely(void)
*** 770,784 ****
  /*
   * find the current user
   *
!  * on unix make sure it isn't really root
   */
  static char *
  get_id(void)
  {
! #ifndef WIN32
! 
! 	struct passwd *pw;
  
  	if (geteuid() == 0)			/* 0 is root's uid */
  	{
  		fprintf(stderr,
--- 770,783 ----
  /*
   * find the current user
   *
!  * on unix make sure it isn't root
   */
  static char *
  get_id(void)
  {
! 	const char	   *username;
  
+ #ifndef WIN32
  	if (geteuid() == 0)			/* 0 is root's uid */
  	{
  		fprintf(stderr,
*************** get_id(void)
*** 789,823 ****
  				progname);
  		exit(1);
  	}
- 
- 	pw = getpwuid(geteuid());
- 	if (!pw)
- 	{
- 		fprintf(stderr,
- 			  _("%s: could not obtain information about current user: %s\n"),
- 				progname, strerror(errno));
- 		exit(1);
- 	}
- #else							/* the windows code */
- 
- 	struct passwd_win32
- 	{
- 		int			pw_uid;
- 		char		pw_name[128];
- 	}			pass_win32;
- 	struct passwd_win32 *pw = &pass_win32;
- 	DWORD		pwname_size = sizeof(pass_win32.pw_name) - 1;
- 
- 	pw->pw_uid = 1;
- 	if (!GetUserName(pw->pw_name, &pwname_size))
- 	{
- 		fprintf(stderr, _("%s: could not get current user name: %s\n"),
- 				progname, strerror(errno));
- 		exit(1);
- 	}
  #endif
  
! 	return pg_strdup(pw->pw_name);
  }
  
  static char *
--- 788,798 ----
  				progname);
  		exit(1);
  	}
  #endif
  
! 	username = get_user_name_or_exit(progname);
! 
! 	return pg_strdup(username);
  }
  
  static char *
diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c
new file mode 100644
index 638d8cb..d60a661
*** a/src/bin/psql/command.c
--- b/src/bin/psql/command.c
*************** exec_command(const char *cmd,
*** 265,274 ****
  #ifndef WIN32
  			struct passwd *pw;
  
  			pw = getpwuid(geteuid());
  			if (!pw)
  			{
! 				psql_error("could not get home directory: %s\n", strerror(errno));
  				exit(EXIT_FAILURE);
  			}
  			dir = pw->pw_dir;
--- 265,277 ----
  #ifndef WIN32
  			struct passwd *pw;
  
+ 			errno = 0;	/* clear errno before call */
  			pw = getpwuid(geteuid());
  			if (!pw)
  			{
! 				psql_error("could not get home directory for user id %d: %s\n",
! 						   (int) geteuid(), errno ?
! 						   strerror(errno) : "user does not exist");
  				exit(EXIT_FAILURE);
  			}
  			dir = pw->pw_dir;
diff --git a/src/bin/psql/help.c b/src/bin/psql/help.c
new file mode 100644
index 30530f2..80b1ec0
*** a/src/bin/psql/help.c
--- b/src/bin/psql/help.c
***************
*** 8,16 ****
  #include "postgres_fe.h"
  
  #ifndef WIN32
- #ifdef HAVE_PWD_H
- #include <pwd.h>				/* for getpwuid() */
- #endif
  #include <sys/types.h>			/* (ditto) */
  #include <unistd.h>				/* for geteuid() */
  #else
--- 8,13 ----
*************** usage(void)
*** 52,82 ****
  {
  	const char *env;
  	const char *user;
! 
! #ifndef WIN32
! 	struct passwd *pw = NULL;
! #endif
  
  	/* Find default user, in case we need it. */
  	user = getenv("PGUSER");
  	if (!user)
  	{
! #if !defined(WIN32) && !defined(__OS2__)
! 		pw = getpwuid(geteuid());
! 		if (pw)
! 			user = pw->pw_name;
! 		else
  		{
! 			psql_error("could not get current user name: %s\n", strerror(errno));
  			exit(EXIT_FAILURE);
  		}
- #else							/* WIN32 */
- 		char		buf[128];
- 		DWORD		bufsize = sizeof(buf) - 1;
- 
- 		if (GetUserName(buf, &bufsize))
- 			user = buf;
- #endif   /* WIN32 */
  	}
  
  	printf(_("psql is the PostgreSQL interactive terminal.\n\n"));
--- 49,66 ----
  {
  	const char *env;
  	const char *user;
! 	char	   *errstr;
  
  	/* Find default user, in case we need it. */
  	user = getenv("PGUSER");
  	if (!user)
  	{
! 		user = get_user_name(&errstr);
! 		if (!user)
  		{
! 			psql_error("%s\n", errstr);
  			exit(EXIT_FAILURE);
  		}
  	}
  
  	printf(_("psql is the PostgreSQL interactive terminal.\n\n"));
diff --git a/src/bin/scripts/clusterdb.c b/src/bin/scripts/clusterdb.c
new file mode 100644
index cd54e8f..e7065ce
*** a/src/bin/scripts/clusterdb.c
--- b/src/bin/scripts/clusterdb.c
*************** main(int argc, char *argv[])
*** 160,166 ****
  			else if (getenv("PGUSER"))
  				dbname = getenv("PGUSER");
  			else
! 				dbname = get_user_name(progname);
  		}
  
  		if (tables.head != NULL)
--- 160,166 ----
  			else if (getenv("PGUSER"))
  				dbname = getenv("PGUSER");
  			else
! 				dbname = get_user_name_or_exit(progname);
  		}
  
  		if (tables.head != NULL)
diff --git a/src/bin/scripts/common.c b/src/bin/scripts/common.c
new file mode 100644
index 4645bc1..e57e520
*** a/src/bin/scripts/common.c
--- b/src/bin/scripts/common.c
***************
*** 14,20 ****
  
  #include "postgres_fe.h"
  
- #include <pwd.h>
  #include <signal.h>
  #include <unistd.h>
  
--- 14,19 ----
*************** static CRITICAL_SECTION cancelConnLock;
*** 30,67 ****
  #endif
  
  /*
-  * Returns the current user name.
-  */
- const char *
- get_user_name(const char *progname)
- {
- #ifndef WIN32
- 	struct passwd *pw;
- 
- 	pw = getpwuid(geteuid());
- 	if (!pw)
- 	{
- 		fprintf(stderr, _("%s: could not obtain information about current user: %s\n"),
- 				progname, strerror(errno));
- 		exit(1);
- 	}
- 	return pw->pw_name;
- #else
- 	static char username[128];	/* remains after function exit */
- 	DWORD		len = sizeof(username) - 1;
- 
- 	if (!GetUserName(username, &len))
- 	{
- 		fprintf(stderr, _("%s: could not get current user name: %s\n"),
- 				progname, strerror(errno));
- 		exit(1);
- 	}
- 	return username;
- #endif
- }
- 
- 
- /*
   * Provide strictly harmonized handling of --help and --version
   * options.
   */
--- 29,34 ----
diff --git a/src/bin/scripts/common.h b/src/bin/scripts/common.h
new file mode 100644
index 6cf490f..a8a81f6
*** a/src/bin/scripts/common.h
--- b/src/bin/scripts/common.h
*************** enum trivalue
*** 22,29 ****
  
  typedef void (*help_handler) (const char *progname);
  
- extern const char *get_user_name(const char *progname);
- 
  extern void handle_help_version_opts(int argc, char *argv[],
  						 const char *fixed_progname,
  						 help_handler hlp);
--- 22,27 ----
diff --git a/src/bin/scripts/createdb.c b/src/bin/scripts/createdb.c
new file mode 100644
index 14cd128..856a04d
*** a/src/bin/scripts/createdb.c
--- b/src/bin/scripts/createdb.c
*************** main(int argc, char *argv[])
*** 174,180 ****
  		else if (getenv("PGUSER"))
  			dbname = getenv("PGUSER");
  		else
! 			dbname = get_user_name(progname);
  	}
  
  	initPQExpBuffer(&sql);
--- 174,180 ----
  		else if (getenv("PGUSER"))
  			dbname = getenv("PGUSER");
  		else
! 			dbname = get_user_name_or_exit(progname);
  	}
  
  	initPQExpBuffer(&sql);
diff --git a/src/bin/scripts/createlang.c b/src/bin/scripts/createlang.c
new file mode 100644
index ff544a8..5cfba8e
*** a/src/bin/scripts/createlang.c
--- b/src/bin/scripts/createlang.c
*************** main(int argc, char *argv[])
*** 127,133 ****
  		else if (getenv("PGUSER"))
  			dbname = getenv("PGUSER");
  		else
! 			dbname = get_user_name(progname);
  	}
  
  	initPQExpBuffer(&sql);
--- 127,133 ----
  		else if (getenv("PGUSER"))
  			dbname = getenv("PGUSER");
  		else
! 			dbname = get_user_name_or_exit(progname);
  	}
  
  	initPQExpBuffer(&sql);
diff --git a/src/bin/scripts/createuser.c b/src/bin/scripts/createuser.c
new file mode 100644
index 83623ea..e4e6e64
*** a/src/bin/scripts/createuser.c
--- b/src/bin/scripts/createuser.c
*************** main(int argc, char *argv[])
*** 188,194 ****
  			if (getenv("PGUSER"))
  				newuser = getenv("PGUSER");
  			else
! 				newuser = get_user_name(progname);
  		}
  	}
  
--- 188,194 ----
  			if (getenv("PGUSER"))
  				newuser = getenv("PGUSER");
  			else
! 				newuser = get_user_name_or_exit(progname);
  		}
  	}
  
diff --git a/src/bin/scripts/droplang.c b/src/bin/scripts/droplang.c
new file mode 100644
index de20317..b9664a9
*** a/src/bin/scripts/droplang.c
--- b/src/bin/scripts/droplang.c
*************** main(int argc, char *argv[])
*** 126,132 ****
  		else if (getenv("PGUSER"))
  			dbname = getenv("PGUSER");
  		else
! 			dbname = get_user_name(progname);
  	}
  
  	initPQExpBuffer(&sql);
--- 126,132 ----
  		else if (getenv("PGUSER"))
  			dbname = getenv("PGUSER");
  		else
! 			dbname = get_user_name_or_exit(progname);
  	}
  
  	initPQExpBuffer(&sql);
diff --git a/src/bin/scripts/reindexdb.c b/src/bin/scripts/reindexdb.c
new file mode 100644
index f7c09be..4e762ea
*** a/src/bin/scripts/reindexdb.c
--- b/src/bin/scripts/reindexdb.c
*************** main(int argc, char *argv[])
*** 188,194 ****
  			else if (getenv("PGUSER"))
  				dbname = getenv("PGUSER");
  			else
! 				dbname = get_user_name(progname);
  		}
  
  		reindex_system_catalogs(dbname, host, port, username, prompt_password,
--- 188,194 ----
  			else if (getenv("PGUSER"))
  				dbname = getenv("PGUSER");
  			else
! 				dbname = get_user_name_or_exit(progname);
  		}
  
  		reindex_system_catalogs(dbname, host, port, username, prompt_password,
*************** main(int argc, char *argv[])
*** 203,209 ****
  			else if (getenv("PGUSER"))
  				dbname = getenv("PGUSER");
  			else
! 				dbname = get_user_name(progname);
  		}
  
  		if (indexes.head != NULL)
--- 203,209 ----
  			else if (getenv("PGUSER"))
  				dbname = getenv("PGUSER");
  			else
! 				dbname = get_user_name_or_exit(progname);
  		}
  
  		if (indexes.head != NULL)
diff --git a/src/bin/scripts/vacuumdb.c b/src/bin/scripts/vacuumdb.c
new file mode 100644
index 616d933..8970ec6
*** a/src/bin/scripts/vacuumdb.c
--- b/src/bin/scripts/vacuumdb.c
*************** main(int argc, char *argv[])
*** 202,208 ****
  			else if (getenv("PGUSER"))
  				dbname = getenv("PGUSER");
  			else
! 				dbname = get_user_name(progname);
  		}
  
  		if (tables.head != NULL)
--- 202,208 ----
  			else if (getenv("PGUSER"))
  				dbname = getenv("PGUSER");
  			else
! 				dbname = get_user_name_or_exit(progname);
  		}
  
  		if (tables.head != NULL)
diff --git a/src/include/port.h b/src/include/port.h
new file mode 100644
index 5ef4b0a..473c4f6
*** a/src/include/port.h
--- b/src/include/port.h
*************** extern pqsigfunc pqsignal(int signo, pqs
*** 473,478 ****
--- 473,482 ----
  /* port/quotes.c */
  extern char *escape_single_quotes_ascii(const char *src);
  
+ /* port/username.c */
+ extern const char *get_user_name(char **errstr);
+ extern const char *get_user_name_or_exit(const char *progname);
+ 
  /* port/wait_error.c */
  extern char *wait_result_to_str(int exit_status);
  
diff --git a/src/port/Makefile b/src/port/Makefile
new file mode 100644
index 1be4ff5..a50e0af
*** a/src/port/Makefile
--- b/src/port/Makefile
*************** LIBS += $(PTHREAD_LIBS)
*** 33,39 ****
  OBJS = $(LIBOBJS) chklocale.o dirmod.o erand48.o fls.o inet_net_ntop.o \
  	noblock.o path.o pgcheckdir.o pg_crc.o pgmkdirp.o pgsleep.o \
  	pgstrcasecmp.o pqsignal.o \
! 	qsort.o qsort_arg.o quotes.o sprompt.o tar.o thread.o
  
  # foo_srv.o and foo.o are both built from foo.c, but only foo.o has -DFRONTEND
  OBJS_SRV = $(OBJS:%.o=%_srv.o)
--- 33,39 ----
  OBJS = $(LIBOBJS) chklocale.o dirmod.o erand48.o fls.o inet_net_ntop.o \
  	noblock.o path.o pgcheckdir.o pg_crc.o pgmkdirp.o pgsleep.o \
  	pgstrcasecmp.o pqsignal.o \
! 	qsort.o qsort_arg.o quotes.o sprompt.o tar.o thread.o username.o
  
  # foo_srv.o and foo.o are both built from foo.c, but only foo.o has -DFRONTEND
  OBJS_SRV = $(OBJS:%.o=%_srv.o)
diff --git a/src/port/username.c b/src/port/username.c
new file mode 100644
index ...25dc939
*** a/src/port/username.c
--- b/src/port/username.c
***************
*** 0 ****
--- 1,84 ----
+ /*-------------------------------------------------------------------------
+  *
+  * username.c
+  *	  get user name
+  *
+  * Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group
+  * Portions Copyright (c) 1994, Regents of the University of California
+  *
+  * IDENTIFICATION
+  *	  src/port/username.c
+  *
+  *-------------------------------------------------------------------------
+  */
+ 
+ #ifndef FRONTEND
+ #include "postgres.h"
+ #else
+ #include "postgres_fe.h"
+ #endif
+ 
+ #include <errno.h>
+ #include <pwd.h>
+ #include <unistd.h>
+ #include <sys/types.h>
+ 
+ 
+ /*
+  * Returns the current user name in a static buffer, or NULL on error and
+  * sets errstr
+  */
+ const char *
+ get_user_name(char **errstr)
+ {
+ #ifndef WIN32
+ 	struct passwd *pw;
+ 	uid_t user_id = geteuid();
+ 
+ 	*errstr = NULL;
+ 
+ 	errno = 0;	/* clear errno before call */
+ 	pw = getpwuid(user_id);
+ 	if (!pw)
+ 	{
+ 		*errstr = psprintf(_("failed to look up effective user id %d: %s"),
+ 				(int) user_id, errno ? strerror(errno) :
+ 				_("user does not exist"));
+ 		return NULL;
+ 	}
+ 
+ 	return pw->pw_name;
+ #else
+ 	/* UNLEN = 256, 'static' variable remains after function exit */
+ 	static char username[256 + 1]; 
+ 	DWORD		len = sizeof(username) - 1;
+ 
+ 	if (!GetUserName(username, &len))
+ 	{
+ 		*errstr = psprintf(_("user name lookup failure: %s"), strerror(errno));
+ 		return NULL;
+ 	}
+ 
+ 	return username;
+ #endif
+ }
+ 
+ 
+ /*
+  * Returns the current user name in a static buffer or exits
+  */
+ const char *
+ get_user_name_or_exit(const char *progname)
+ {
+ 	const char *user_name;
+ 	char 	   *errstr;
+ 
+ 	user_name = get_user_name(&errstr);
+ 
+ 	if (!user_name)
+ 	{
+ 		fprintf(stderr, "%s: %s\n", progname, errstr);
+ 		exit(1);
+ 	}
+ 	return user_name;
+ }
diff --git a/src/tools/msvc/Mkvcbuild.pm b/src/tools/msvc/Mkvcbuild.pm
new file mode 100644
index bc7f449..d6b6eaf
*** a/src/tools/msvc/Mkvcbuild.pm
--- b/src/tools/msvc/Mkvcbuild.pm
*************** sub mkvcbuild
*** 70,77 ****
  	  erand48.c snprintf.c strlcat.c strlcpy.c dirmod.c noblock.c path.c
  	  pgcheckdir.c pg_crc.c pgmkdirp.c pgsleep.c pgstrcasecmp.c pqsignal.c
  	  qsort.c qsort_arg.c quotes.c
! 	  sprompt.c tar.c thread.c getopt.c getopt_long.c dirent.c rint.c win32env.c
! 	  win32error.c win32setlocale.c);
  
  	our @pgcommonallfiles = qw(
  	  exec.c pgfnames.c psprintf.c relpath.c rmtree.c wait_error.c);
--- 70,77 ----
  	  erand48.c snprintf.c strlcat.c strlcpy.c dirmod.c noblock.c path.c
  	  pgcheckdir.c pg_crc.c pgmkdirp.c pgsleep.c pgstrcasecmp.c pqsignal.c
  	  qsort.c qsort_arg.c quotes.c
! 	  sprompt.c tar.c thread.c getopt.c getopt_long.c dirent.c rint.c username.c
! 	  win32env.c win32error.c win32setlocale.c);
  
  	our @pgcommonallfiles = qw(
  	  exec.c pgfnames.c psprintf.c relpath.c rmtree.c wait_error.c);
