Re: psql \i handling ~ in specified file name - Mailing list pgsql-patches

From Zach Irmen
Subject Re: psql \i handling ~ in specified file name
Date
Msg-id 00de01c3c79b$9ee26000$0b01010a@ed.shawcable.net
Whole thread Raw
In response to psql \i handling ~ in specified file name  (Zach Irmen <zirmen@shaw.ca>)
Responses Re: psql \i handling ~ in specified file name  ("Andrew Dunstan" <andrew@dunslane.net>)
List pgsql-patches
"Tom Lane" <tgl@sss.pgh.pa.us> writes:
> What happens if getenv("HOME") returns NULL?

Yeah, the strdup fails. I'll take it out to fix that.

> You also need to think about Windows

Can I just ifndef WIN32 and not think about it? I'm not sure how that would
work either.

> Finally, couldn't we reduce the number
> of times strings are strdup'd only to be freed again?  I don't think
> doing it this way makes the code simpler --- it took me a fair while
> to convince myself there was no memory leak.

Ok. I cut it down to one dup within the function. Attempt 2 is below.
--
Zach Irmen


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   21 Dec 2003 08:10:50 -0000
***************
*** 65,70 ****
--- 65,72 ----
  static bool do_connect(const char *new_dbname, const char *new_user);
  static bool do_shell(const char *command);

+ static char *expand_tilde(char **filename);
+
  /*----------
   * HandleSlashCmds:
   *
***************
*** 531,536 ****
--- 533,539 ----
                }
                else
                {
+                       expand_tilde(&fname);
                        success = (process_file(fname) == EXIT_SUCCESS);
                        free(fname);
                }
***************
*** 1678,1683 ****
--- 1681,1740 ----
  }


+ /* expand_tilde
+  *
+  * substitute '~' with HOME or '~username' with username's home dir
+  *
+  */
+ static char *
+ expand_tilde(char **filename)
+ {
+       if (!filename || !(*filename))
+               return NULL;
+
+ #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);
+                       strcpy(newfn,home);
+                       strcat(newfn,p);
+
+                       free(fn);
+                       *filename = newfn;
+               }
+       }
+
+ #endif
+
+       return *filename;
+ }

  /*
   * process_file


pgsql-patches by date:

Previous
From: Sean Chittenden
Date:
Subject: Re: [GENERAL] Temporary tables and miscellaneous schemas
Next
From: Christopher Kings-Lynne
Date:
Subject: Re: [GENERAL] Temporary tables and miscellaneous schemas