From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 13490 invoked by alias); 16 Sep 2002 20:14:13 -0000 Mailing-List: contact gdb-patches-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sources.redhat.com Received: (qmail 13430 invoked from network); 16 Sep 2002 20:13:48 -0000 Received: from unknown (HELO msgbas1.cos.agilent.com) (192.25.240.36) by sources.redhat.com with SMTP; 16 Sep 2002 20:13:48 -0000 Received: from relcos2.cos.agilent.com (relcos2.cos.agilent.com [130.29.152.237]) by msgbas1.cos.agilent.com (Postfix) with ESMTP id B4867AC88; Mon, 16 Sep 2002 14:13:46 -0600 (MDT) Received: from websvr.canada.agilent.com (websvr.canada.agilent.com [141.184.122.102]) by relcos2.cos.agilent.com (Postfix) with ESMTP id B992B51C; Mon, 16 Sep 2002 14:12:59 -0600 (MDT) Received: from agilent.com (dhcp6burnaby.canada.agilent.com [141.184.123.147]) by websvr.canada.agilent.com (8.9.3 (PHNE_25183)/8.9.3 SMKit7.1.1_Agilent) with ESMTP id NAA06688; Mon, 16 Sep 2002 13:13:44 -0700 (PDT) Message-ID: <3D863B76.3EAA4F20@agilent.com> Date: Mon, 16 Sep 2002 13:14:00 -0000 From: Earl Chew Organization: Agilent Technologies X-Accept-Language: en MIME-Version: 1.0 To: gdb-patches@sources.redhat.com, cgf@redhat.com Subject: Re: Finding source files under Cygwin References: <3D82897C.81376AD6@agilent.com> <3D862BD0.A5298600@agilent.com> Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit X-SW-Source: 2002-09/txt/msg00317.txt.bz2 Christopher Faylor wrote: > I'm sorry but it is rarely a good idea to mix functionality like this. > You're mixing an (arguable) bug fix with an (arguable) gdb enhancement. > > Please submit each as a separate patch. Ok. Here's the patch to robustly handle the presence of DIRNAME_SEPARATOR in the file names embedded in the object file. Earl -- > ---------------------------------------------------------------------+ > Earl Chew http://www.agilent.com | > Agilent Technologies mailto:earl_chew@agilent.com | > Advanced Networks Division Tel: +1 604 454 3411 | > 2500-4710 Kingsway Fax: +1 604 454 3401 | > Burnaby BC V5H 4M2 Canada | > ---------------------------------------------------------------------+ ChangeLog: * source.c: Source file lookup changes. (openp): Delegate to openp_1. (openp_1): Allow arbitrary path component separators. (open_source_file): Use \0 to separate path components when splitting path to insert $cdir. --- ../../gdb-5.2.1-orig/gdb/source.c 2002-01-17 13:15:18.000000000 -0800 +++ source.c 2002-09-16 13:08:17.000000000 -0700 @@ -71,6 +71,11 @@ /* Prototypes for local functions. */ +static int openp_1 (const char *path, int pathlen, char sep, + int try_cwd_first, const char *string, + int mode, int prot, + char **filename_opened); + static int get_filename_and_charpos (struct symtab *, char **); static void reverse_search_command (char *, int); @@ -507,6 +512,11 @@ /* Open a file named STRING, searching path PATH (dir names sep by some char) using mode MODE and protection bits PROT in the calls to open. + The internal function openp_1 accepts an additional arguemnt SEP + which is normally set to DIRNAME_SEPARATOR by openp, but for internal use + (see open_source_file) it may be set to \0 to avoid any ambiguity + when separating path components. + If TRY_CWD_FIRST, try to open ./STRING before searching PATH. (ie pretend the first element of PATH is "."). This also indicates that a slash in STRING disables searching of the path (this is @@ -524,20 +534,37 @@ /* >>>> This should only allow files of certain types, >>>> eg executable, non-directory */ + int openp (const char *path, int try_cwd_first, const char *string, int mode, int prot, char **filename_opened) { + int pathlen = path ? strlen (path) : 0; + + return openp_1 (path, pathlen, DIRNAME_SEPARATOR, try_cwd_first, string, + mode, prot, filename_opened); +} + +static int +openp_1 (const char *path, int pathlen, char sep, + int try_cwd_first, const char *string, + int mode, int prot, + char **filename_opened) +{ register int fd; register char *filename; const char *p; + const char *ep; const char *p1; register int len; int alloclen; if (!path) - path = "."; + { + path = "."; + pathlen = 1; + } #if defined(_WIN32) || defined(__CYGWIN__) mode |= O_BINARY; @@ -560,12 +587,12 @@ while (string[0] == '.' && IS_DIR_SEPARATOR (string[1])) string += 2; - alloclen = strlen (path) + strlen (string) + 2; + alloclen = pathlen + strlen (string) + 2; filename = alloca (alloclen); fd = -1; - for (p = path; p; p = p1 ? p1 + 1 : 0) + for (p = path, ep = p + pathlen; p && (p < ep); p = p1 ? p1 + 1 : 0) { - p1 = strchr (p, DIRNAME_SEPARATOR); + p1 = strchr (p, sep); if (p1) len = p1 - p; else @@ -666,6 +693,8 @@ open_source_file (struct symtab *s) { char *path = source_path; + int pathlen = strlen (path); + char sep = DIRNAME_SEPARATOR; const char *p; int result; char *fullname; @@ -692,23 +721,36 @@ && (p[cdir_len] == DIRNAME_SEPARATOR || p[cdir_len] == '\0')) { int len; + char *q; path = (char *) - alloca (strlen (source_path) + 1 + strlen (s->dirname) + 1); + alloca (pathlen + 1 + strlen (s->dirname) + 1); len = p - source_path; strncpy (path, source_path, len); /* Before $cdir */ strcpy (path + len, s->dirname); /* new stuff */ strcat (path + len, source_path + len + cdir_len); /* After $cdir */ + + /* The segment inserted for $cdir may contain instances of + DIRNAME_SEPARATOR which causes ambiguity when parsing + the revised path. Use \0 to separate the path components + instead. */ + pathlen = strlen (path); + sep = '\0'; + for (q = path; len; len--, q++) + if (*q == DIRNAME_SEPARATOR) *q = sep; + for (q += strlen (s->dirname); *q; q++) + if (*q == DIRNAME_SEPARATOR) *q = sep; } } - result = openp (path, 0, s->filename, OPEN_MODE, 0, &s->fullname); + result = openp_1 (path, pathlen, sep, 0, + s->filename, OPEN_MODE, 0, &s->fullname); if (result < 0) { /* Didn't work. Try using just the basename. */ p = lbasename (s->filename); if (p != s->filename) - result = openp (path, 0, p, OPEN_MODE, 0, &s->fullname); + result = openp_1 (path, pathlen, sep, 0, p, OPEN_MODE, 0, &s->fullname); } if (result >= 0)