77 *
88 *
99 * IDENTIFICATION
10- * $PostgreSQL: pgsql/src/port/exec.c,v 1.30 2004/10/18 19:08:58 momjian Exp $
10+ * $PostgreSQL: pgsql/src/port/exec.c,v 1.31 2004/11/06 01:16:22 tgl Exp $
1111 *
1212 *-------------------------------------------------------------------------
1313 */
4242
4343#ifndef FRONTEND
4444/* We use only 3-parameter elog calls in this file, for simplicity */
45- #define log_error (str ,param )elog(LOG,( str), ( param) )
45+ #define log_error (str ,param )elog(LOG, str, param)
4646#else
47- #define log_error (str ,param )fprintf(stderr,( str),(param ))
47+ #define log_error (str ,param )( fprintf(stderr, str, param ),fputc('\n', stderr ))
4848#endif
4949
5050
51- static void win32_make_absolute (char * path );
52-
53-
5451/*
5552 * validate_exec -- validate "path" as an executable file
5653 *
@@ -165,7 +162,7 @@ validate_exec(const char *path)
165162 * executable's location. Also, we need a full path not a relative
166163 * path because we will later change working directory.
167164 *
168- * This function is not thread-safe becauseof it calls validate_exec(),
165+ * This function is not thread-safe because it calls validate_exec(),
169166 * which calls getgrgid().This function should be used only in
170167 * non-threaded binaries, not in library routines.
171168 */
@@ -178,61 +175,40 @@ find_my_exec(const char *argv0, char *retpath)
178175
179176#ifndef WIN32_CLIENT_ONLY
180177if (!getcwd (cwd ,MAXPGPATH ))
178+ strcpy (cwd ,"." );/* cheesy, but better than nothing */
181179#else
182180if (!GetCurrentDirectory (MAXPGPATH ,cwd ))
181+ strcpy (cwd ,"." );/* cheesy, but better than nothing */
183182#endif
184- cwd [0 ]= '\0' ;
185183
186184/*
187- * First try: use the binary that's located in the same directory if
188- * it was invoked with an explicit path. Presumably the user used an
189- * explicit path because it wasn't in PATH, and we don't want to use
190- * incompatible executables.
191- *
192- * For the binary: First try: if we're given some kind of path, use it
193- * (making sure that a relative path is made absolute before returning
194- * it).
185+ * If argv0 contains a separator, then PATH wasn't used.
195186 */
196- /* Does argv0 have a separator? */
197- if ((path = last_dir_separator (argv0 )))
187+ if (first_dir_separator (argv0 )!= NULL )
198188{
199- if (* ++ path == '\0' )
200- {
201- log_error ("argv[0] ends with a path separator \"%s\"" ,argv0 );
202- return -1 ;
203- }
204-
205189if (is_absolute_path (argv0 ))
206190StrNCpy (retpath ,argv0 ,MAXPGPATH );
207191else
208- snprintf (retpath ,MAXPGPATH ,"%s/%s" ,cwd ,argv0 );
209-
192+ join_path_components (retpath ,cwd ,argv0 );
210193canonicalize_path (retpath );
194+
211195if (validate_exec (retpath )== 0 )
212- {
213- win32_make_absolute (retpath );
214196return 0 ;
215- }
216- else
217- {
218- log_error ("invalid binary \"%s\"" ,retpath );
219- return -1 ;
220- }
197+
198+ log_error ("invalid binary \"%s\"" ,retpath );
199+ return -1 ;
221200}
222201
223202#ifdef WIN32
224203/* Win32 checks the current directory first for names without slashes */
225- if (validate_exec (argv0 )== 0 )
226- {
227- snprintf (retpath ,MAXPGPATH ,"%s/%s" ,cwd ,argv0 );
228- win32_make_absolute (retpath );
204+ join_path_components (retpath ,cwd ,argv0 );
205+ if (validate_exec (retpath )== 0 )
229206return 0 ;
230- }
231207#endif
232208
233209/*
234- *Second try: since no explicit path was supplied, the user must have
235- * been relying on PATH. We'lluse the same PATH.
210+ *Since no explicit path was supplied, the user must have
211+ * been relying on PATH. We'llsearch the same PATH.
236212 */
237213if ((path = getenv ("PATH" ))&& * path )
238214{
@@ -253,40 +229,33 @@ find_my_exec(const char *argv0, char *retpath)
253229StrNCpy (test_path ,startp ,Min (endp - startp + 1 ,MAXPGPATH ));
254230
255231if (is_absolute_path (test_path ))
256- snprintf (retpath , MAXPGPATH , "%s/%s" ,test_path ,argv0 );
232+ join_path_components (retpath ,test_path ,argv0 );
257233else
258- snprintf (retpath ,MAXPGPATH ,"%s/%s/%s" ,cwd ,test_path ,argv0 );
259-
234+ {
235+ join_path_components (retpath ,cwd ,test_path );
236+ join_path_components (retpath ,retpath ,argv0 );
237+ }
260238canonicalize_path (retpath );
239+
261240switch (validate_exec (retpath ))
262241{
263- case 0 :/* found ok */
264- win32_make_absolute (retpath );
242+ case 0 :/* found ok */
265243return 0 ;
266244case -1 :/* wasn't even a candidate, keep looking */
267- continue ;
245+ break ;
268246case -2 :/* found but disqualified */
269247log_error ("could not read binary \"%s\"" ,retpath );
270- continue ;
248+ break ;
271249}
272250}while (* endp );
273251}
274252
275253log_error ("could not find a \"%s\" to execute" ,argv0 );
276254return -1 ;
277-
278- #if NOT_USED
279- /*
280- * Win32 has a native way to find the executable name, but the above
281- * method works too.
282- */
283- if (GetModuleFileName (NULL ,retpath ,MAXPGPATH )== 0 )
284- log_error ("GetModuleFileName failed (%i)" , (int )GetLastError ());
285- #endif
286255}
287256
288257/*
289- * The runtimelibrarys popen() on win32 does not work when being
258+ * The runtimelibrary's popen() on win32 does not work when being
290259 * called from a service when running on windows <= 2000, because
291260 * there is no stdin/stdout/stderr.
292261 *
@@ -427,10 +396,9 @@ pipe_read_line(char *cmd, char *line, int maxsize)
427396}
428397
429398
430-
431399/*
432- * Find our binary directory, then make sure the "target" executable
433- * is the proper version.
400+ * Findanother program in our binary's directory,
401+ *then make sure it is the proper version.
434402 */
435403int
436404find_other_exec (const char * argv0 ,const char * target ,
@@ -487,41 +455,19 @@ pclose_check(FILE *stream)
487455}
488456else if (WIFEXITED (exitstatus ))
489457{
490- log_error (_ ("child process exited with exit code %d\n " ),
458+ log_error (_ ("child process exited with exit code %d" ),
491459WEXITSTATUS (exitstatus ));
492460}
493461else if (WIFSIGNALED (exitstatus ))
494462{
495- log_error (_ ("child process was terminated by signal %d\n " ),
463+ log_error (_ ("child process was terminated by signal %d" ),
496464WTERMSIG (exitstatus ));
497465}
498466else
499467{
500- log_error (_ ("child process exited with unrecognized status %d\n " ),
468+ log_error (_ ("child process exited with unrecognized status %d" ),
501469exitstatus );
502470}
503471
504472return -1 ;
505473}
506-
507-
508- /*
509- * Windows doesn't like relative paths to executables (other things work fine)
510- * so we call its builtin function to expand them. Elsewhere this is a NOOP
511- */
512- static void
513- win32_make_absolute (char * path )
514- {
515- #ifdef WIN32
516- char abspath [MAXPGPATH ];
517-
518- if (_fullpath (abspath ,path ,MAXPGPATH )== NULL )
519- {
520- log_error ("Win32 path expansion failed: %s" ,strerror (errno ));
521- StrNCpy (abspath ,path ,MAXPGPATH );
522- }
523- canonicalize_path (abspath );
524-
525- StrNCpy (path ,abspath ,MAXPGPATH );
526- #endif
527- }