Skip site navigation (1) Skip section navigation (2)

Re: psql \i handling ~ in specified file name

From: Zach Irmen <zirmen(at)shaw(dot)ca>
To: Bruce Momjian <pgman(at)candle(dot)pha(dot)pa(dot)us>
Cc: pgsql-patches(at)postgresql(dot)org
Subject: Re: psql \i handling ~ in specified file name
Date: 2004-01-09 07:35:34
Message-ID: Pine.WNT.4.58.0401090019350.-501301@zi.ed.shawcable.net (view raw or flat)
Thread:
Lists: pgsql-patches
Bruce Momjian wrote:
> Yes, seems like that will be required.  Please use my attached version
> to make the adjustments.

Ok. Adjustments made.  All psql commands should be handled.

> Zach Irmen wrote:
> > And finally, I was wondering if arguments with leading pipes
> > (e.g. "|~/file") should  also get substituted.
>
> Yep, that too.

Actually, I found out that popen calls seem to handle the tilde fine as
this was already working on my FreeBSD box without
substitution. I'm not sure if this is true for all Unix systems in
general, but I won't bother putting that in unless it turns out
to be needed.

Index: command.c
===================================================================
RCS file: /projects/cvsroot/pgsql-server/src/bin/psql/command.c,v
retrieving revision 1.108
diff -c -r1.108 command.c
*** command.c	1 Dec 2003 22:21:54 -0000	1.108
--- command.c	9 Jan 2004 06:51:55 -0000
***************
*** 413,418 ****
--- 413,419 ----
  		else
  		{
  			fname = scan_option(&string, OT_NORMAL, NULL, true);
+ 			expand_tilde(&fname);
  			status = do_edit(fname, query_buf) ? CMD_NEWEDIT : CMD_ERROR;
  			free(fname);
  		}
***************
*** 494,500 ****
--- 495,504 ----
  		if (!fname)
  			pset.gfname = NULL;
  		else
+ 		{
+ 			expand_tilde(&fname);
  			pset.gfname = xstrdup(fname);
+ 		}
  		free(fname);
  		status = CMD_SEND;
  	}
***************
*** 531,536 ****
--- 535,541 ----
  		}
  		else
  		{
+ 			expand_tilde(&fname);
  			success = (process_file(fname) == EXIT_SUCCESS);
  			free(fname);
  		}
***************
*** 561,567 ****
--- 566,575 ----
  				success = false;
  			}
  			else
+ 			{
+ 				expand_tilde(&opt2);
  				success = do_lo_export(opt1, opt2);
+ 			}
  		}

  		else if (strcmp(cmd + 3, "import") == 0)
***************
*** 572,578 ****
--- 580,589 ----
  				success = false;
  			}
  			else
+ 			{
+ 				expand_tilde(&opt1);
  				success = do_lo_import(opt1, opt2);
+ 			}
  		}

  		else if (strcmp(cmd + 3, "list") == 0)
***************
*** 602,607 ****
--- 613,619 ----
  	{
  		char	   *fname = scan_option(&string, OT_FILEPIPE, NULL, true);

+ 		expand_tilde(&fname);
  		success = setQFout(fname);
  		free(fname);
  	}
***************
*** 653,658 ****
--- 665,671 ----
  	{
  		char	   *fname = scan_option(&string, OT_NORMAL, NULL, true);

+ 		expand_tilde(&fname);
  		success = saveHistory(fname ? fname : "/dev/tty");

  		if (success && !quiet && fname)
***************
*** 771,776 ****
--- 784,790 ----
  		else
  		{
  			fname = scan_option(&string, OT_FILEPIPE, NULL, true);
+ 			expand_tilde(&fname);

  			if (!fname)
  			{
Index: common.c
===================================================================
RCS file: /projects/cvsroot/pgsql-server/src/bin/psql/common.c,v
retrieving revision 1.78
diff -c -r1.78 common.c
*** common.c	29 Nov 2003 19:52:06 -0000	1.78
--- common.c	9 Jan 2004 06:51:56 -0000
***************
*** 814,816 ****
--- 814,878 ----
  	else
  		return PQuser(pset.db);
  }
+
+
+ /* expand_tilde
+  *
+  * substitute '~' with HOME or '~username' with username's home dir
+  *
+  */
+ char *
+ expand_tilde(char **filename)
+ {
+ 	if (!filename || !(*filename))
+ 		return NULL;
+
+ 	/* MSDOS uses tilde for short versions of long file names, so skip it. */
+ #ifndef WIN32
+
+ 	/* try tilde expansion */
+ 	if (**filename == '~')
+ 	{
+ 		char	   *fn;
+ 		char	   *home;
+ 		char		oldp,
+ 				   *p;
+ 		struct passwd *pw;
+
+ 		fn = *filename;
+ 		home = NULL;
+
+ 		p = fn + 1;
+ 		while (*p != '/' && *p != '\0')
+ 			p++;
+
+ 		oldp = *p;
+ 		*p = '\0';
+
+ 		if (*(fn + 1) == '\0')
+ 			home = getenv("HOME");
+ 		else if ((pw = getpwnam(fn + 1)) != NULL)
+ 			home = pw->pw_dir;
+
+ 		*p = oldp;
+ 		if (home)
+ 		{
+ 			char	   *newfn;
+
+ 			newfn = malloc(strlen(home) + strlen(p) + 1);
+ 			if (!newfn)
+ 			{
+ 				psql_error("out of memory\n");
+ 				exit(EXIT_FAILURE);
+ 			}
+ 			strcpy(newfn, home);
+ 			strcat(newfn, p);
+
+ 			free(fn);
+ 			*filename = newfn;
+ 		}
+ 	}
+ #endif
+
+ 	return *filename;
+ }
Index: common.h
===================================================================
RCS file: /projects/cvsroot/pgsql-server/src/bin/psql/common.h,v
retrieving revision 1.31
diff -c -r1.31 common.h
*** common.h	1 Dec 2003 22:14:40 -0000	1.31
--- common.h	9 Jan 2004 06:51:56 -0000
***************
*** 58,61 ****
--- 58,63 ----
  #define pclose(x) _pclose(x)
  #endif

+ extern char *expand_tilde(char **filename);
+
  #endif   /* COMMON_H */
Index: copy.c
===================================================================
RCS file: /projects/cvsroot/pgsql-server/src/bin/psql/copy.c,v
retrieving revision 1.35
diff -c -r1.35 copy.c
*** copy.c	1 Dec 2003 22:14:40 -0000	1.35
--- copy.c	9 Jan 2004 06:51:56 -0000
***************
*** 221,226 ****
--- 221,227 ----
  		result->file = NULL;
  	else
  		result->file = xstrdup(token);
+ 	expand_tilde(&result->file);

  	token = strtokx(NULL, whitespace, NULL, NULL,
  					0, false, pset.encoding);


Responses

pgsql-patches by date

Next:From: Kris JurkaDate: 2004-01-09 09:00:07
Subject: Dev version doesn't acknowledge cross type indexes
Previous:From: Tom LaneDate: 2004-01-09 06:36:43
Subject: Re: fork/exec patch: pre-CreateProcess finalization

Privacy Policy | About PostgreSQL
Copyright © 1996-2014 The PostgreSQL Global Development Group