Skip to content

Commit 4867afe

Browse files
committed
Code cleanup in path.c and exec.c. Handle Windows drive and network specs
everywhere not just some places, get rid of . and .. when joining path sections together. This should eliminate most of the ugly paths like /foo/bar/./baz that we've been generating.
1 parent 3d6e538 commit 4867afe

File tree

3 files changed

+176
-166
lines changed

3 files changed

+176
-166
lines changed

src/include/port.h

Lines changed: 14 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
/*-------------------------------------------------------------------------
22
*
33
* port.h
4-
* Header for /port compatibility functions.
4+
* Header for src/port/ compatibility functions.
55
*
66
* Portions Copyright (c) 1996-2004, PostgreSQL Global Development Group
77
* Portions Copyright (c) 1994, Regents of the University of California
88
*
9-
* $PostgreSQL: pgsql/src/include/port.h,v 1.64 2004/10/11 22:50:33 momjian Exp $
9+
* $PostgreSQL: pgsql/src/include/port.h,v 1.65 2004/11/06 01:16:14 tgl Exp $
1010
*
1111
*-------------------------------------------------------------------------
1212
*/
@@ -20,25 +20,15 @@
2020
#include <ctype.h>
2121

2222
/* non-blocking */
23-
bool set_noblock(int sock);
23+
extern bool set_noblock(int sock);
2424

2525
/* Portable path handling for Unix/Win32 */
2626

27-
/* Find the location of the first directory separator, return
28-
* NULL if not found.
29-
*/
3027
extern char *first_dir_separator(const char *filename);
31-
32-
/* Find the location of the last directory separator, return
33-
* NULL if not found.
34-
*/
3528
extern char *last_dir_separator(const char *filename);
36-
37-
/* Find the location of the first path separator (i.e. ':' on
38-
* Unix, ';' on Windows), return NULL if not found.
39-
*/
40-
extern char *first_path_separator(const char *filename);
41-
29+
extern char *first_path_separator(const char *pathlist);
30+
extern void join_path_components(char *ret_path,
31+
const char *head, const char *tail);
4232
extern void canonicalize_path(char *path);
4333
extern void make_native_path(char *path);
4434
extern const char *get_progname(const char *argv0);
@@ -123,11 +113,6 @@ extern unsigned char pg_tolower(unsigned char ch);
123113
/* Portable prompt handling */
124114
extern char *simple_prompt(const char *prompt, int maxlen, bool echo);
125115

126-
#if defined(bsdi) || defined(netbsd)
127-
extern int fseeko(FILE *stream, off_t offset, int whence);
128-
extern off_t ftello(FILE *stream);
129-
#endif
130-
131116
/*
132117
* WIN32 doesn't allow descriptors returned by pipe() to be used in select(),
133118
* so for that platform we use socket() instead of pipe().
@@ -185,7 +170,7 @@ extern int pgsymlink(const char *oldpath, const char *newpath);
185170
#define symlink(oldpath, newpath) pgsymlink(oldpath, newpath)
186171
#endif
187172

188-
#endif
173+
#endif /* defined(WIN32) || defined(__CYGWIN__) */
189174

190175
extern bool rmtree(char *path, bool rmtopdir);
191176

@@ -212,14 +197,14 @@ extern void srand48(long seed);
212197
/* Last parameter not used */
213198
extern int gettimeofday(struct timeval * tp, struct timezone * tzp);
214199

215-
#else
200+
#else /* !WIN32 */
216201

217202
/*
218203
* Win32 requires a special close for sockets and pipes, while on Unix
219204
* close() does them all.
220205
*/
221206
#define closesocket close
222-
#endif
207+
#endif /* WIN32 */
223208

224209
/*
225210
* Default "extern" declarations or macro substitutes for library routines.
@@ -229,6 +214,11 @@ extern int gettimeofday(struct timeval * tp, struct timezone * tzp);
229214
extern char *crypt(const char *key, const char *setting);
230215
#endif
231216

217+
#if defined(bsdi) || defined(netbsd)
218+
extern int fseeko(FILE *stream, off_t offset, int whence);
219+
extern off_t ftello(FILE *stream);
220+
#endif
221+
232222
#ifndef HAVE_FSEEKO
233223
#define fseeko(a, b, c) fseek((a), (b), (c))
234224
#define ftello(a) ftell((a))

src/port/exec.c

Lines changed: 32 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
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
*/
@@ -42,15 +42,12 @@
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 because of 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
180177
if (!getcwd(cwd, MAXPGPATH))
178+
strcpy(cwd, "."); /* cheesy, but better than nothing */
181179
#else
182180
if (!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-
205189
if (is_absolute_path(argv0))
206190
StrNCpy(retpath, argv0, MAXPGPATH);
207191
else
208-
snprintf(retpath, MAXPGPATH, "%s/%s", cwd, argv0);
209-
192+
join_path_components(retpath, cwd, argv0);
210193
canonicalize_path(retpath);
194+
211195
if (validate_exec(retpath) == 0)
212-
{
213-
win32_make_absolute(retpath);
214196
return 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)
229206
return 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'll use the same PATH.
210+
* Since no explicit path was supplied, the user must have
211+
* been relying on PATH. We'll search the same PATH.
236212
*/
237213
if ((path = getenv("PATH")) && *path)
238214
{
@@ -253,40 +229,33 @@ find_my_exec(const char *argv0, char *retpath)
253229
StrNCpy(test_path, startp, Min(endp - startp + 1, MAXPGPATH));
254230

255231
if (is_absolute_path(test_path))
256-
snprintf(retpath, MAXPGPATH, "%s/%s", test_path, argv0);
232+
join_path_components(retpath, test_path, argv0);
257233
else
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+
}
260238
canonicalize_path(retpath);
239+
261240
switch (validate_exec(retpath))
262241
{
263-
case 0: /* found ok */
264-
win32_make_absolute(retpath);
242+
case 0: /* found ok */
265243
return 0;
266244
case -1: /* wasn't even a candidate, keep looking */
267-
continue;
245+
break;
268246
case -2: /* found but disqualified */
269247
log_error("could not read binary \"%s\"", retpath);
270-
continue;
248+
break;
271249
}
272250
} while (*endp);
273251
}
274252

275253
log_error("could not find a \"%s\" to execute", argv0);
276254
return -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 runtime librarys popen() on win32 does not work when being
258+
* The runtime library'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+
* Find another program in our binary's directory,
401+
* then make sure it is the proper version.
434402
*/
435403
int
436404
find_other_exec(const char *argv0, const char *target,
@@ -487,41 +455,19 @@ pclose_check(FILE *stream)
487455
}
488456
else 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"),
491459
WEXITSTATUS(exitstatus));
492460
}
493461
else 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"),
496464
WTERMSIG(exitstatus));
497465
}
498466
else
499467
{
500-
log_error(_("child process exited with unrecognized status %d\n"),
468+
log_error(_("child process exited with unrecognized status %d"),
501469
exitstatus);
502470
}
503471

504472
return -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-
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy