1169695Skan/* Libiberty realpath. Like realpath, but more consistent behavior. 2169695Skan Based on gdb_realpath from GDB. 3169695Skan 4169695Skan Copyright 2003 Free Software Foundation, Inc. 5169695Skan 6169695Skan This file is part of the libiberty library. 7169695Skan 8169695Skan This program is free software; you can redistribute it and/or modify 9169695Skan it under the terms of the GNU General Public License as published by 10169695Skan the Free Software Foundation; either version 2 of the License, or 11169695Skan (at your option) any later version. 12169695Skan 13169695Skan This program is distributed in the hope that it will be useful, 14169695Skan but WITHOUT ANY WARRANTY; without even the implied warranty of 15169695Skan MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16169695Skan GNU General Public License for more details. 17169695Skan 18169695Skan You should have received a copy of the GNU General Public License 19169695Skan along with this program; if not, write to the Free Software 20169695Skan Foundation, Inc., 51 Franklin Street - Fifth Floor, 21169695Skan Boston, MA 02110-1301, USA. */ 22169695Skan 23169695Skan/* 24169695Skan 25169695Skan@deftypefn Replacement {const char*} lrealpath (const char *@var{name}) 26169695Skan 27169695SkanGiven a pointer to a string containing a pathname, returns a canonical 28169695Skanversion of the filename. Symlinks will be resolved, and ``.'' and ``..'' 29169695Skancomponents will be simplified. The returned value will be allocated using 30169695Skan@code{malloc}, or @code{NULL} will be returned on a memory allocation error. 31169695Skan 32169695Skan@end deftypefn 33169695Skan 34169695Skan*/ 35169695Skan 36169695Skan#include "config.h" 37169695Skan#include "ansidecl.h" 38169695Skan#include "libiberty.h" 39169695Skan 40169695Skan#ifdef HAVE_LIMITS_H 41169695Skan#include <limits.h> 42169695Skan#endif 43169695Skan#ifdef HAVE_STDLIB_H 44169695Skan#include <stdlib.h> 45169695Skan#endif 46169695Skan#ifdef HAVE_UNISTD_H 47169695Skan#include <unistd.h> 48169695Skan#endif 49169695Skan#ifdef HAVE_STRING_H 50169695Skan#include <string.h> 51169695Skan#endif 52169695Skan 53169695Skan/* On GNU libc systems the declaration is only visible with _GNU_SOURCE. */ 54169695Skan#if defined(HAVE_CANONICALIZE_FILE_NAME) \ 55169695Skan && defined(NEED_DECLARATION_CANONICALIZE_FILE_NAME) 56169695Skanextern char *canonicalize_file_name (const char *); 57169695Skan#endif 58169695Skan 59169695Skan#if defined(HAVE_REALPATH) 60169695Skan# if defined (PATH_MAX) 61169695Skan# define REALPATH_LIMIT PATH_MAX 62169695Skan# else 63169695Skan# if defined (MAXPATHLEN) 64169695Skan# define REALPATH_LIMIT MAXPATHLEN 65169695Skan# endif 66169695Skan# endif 67169695Skan#else 68169695Skan /* cygwin has realpath, so it won't get here. */ 69169695Skan# if defined (_WIN32) 70169695Skan# define WIN32_LEAN_AND_MEAN 71169695Skan# include <windows.h> /* for GetFullPathName */ 72169695Skan# endif 73169695Skan#endif 74169695Skan 75169695Skanchar * 76169695Skanlrealpath (const char *filename) 77169695Skan{ 78169695Skan /* Method 1: The system has a compile time upper bound on a filename 79169695Skan path. Use that and realpath() to canonicalize the name. This is 80169695Skan the most common case. Note that, if there isn't a compile time 81169695Skan upper bound, you want to avoid realpath() at all costs. */ 82169695Skan#if defined(REALPATH_LIMIT) 83169695Skan { 84169695Skan char buf[REALPATH_LIMIT]; 85169695Skan const char *rp = realpath (filename, buf); 86169695Skan if (rp == NULL) 87169695Skan rp = filename; 88169695Skan return strdup (rp); 89169695Skan } 90169695Skan#endif /* REALPATH_LIMIT */ 91169695Skan 92169695Skan /* Method 2: The host system (i.e., GNU) has the function 93169695Skan canonicalize_file_name() which malloc's a chunk of memory and 94169695Skan returns that, use that. */ 95169695Skan#if defined(HAVE_CANONICALIZE_FILE_NAME) 96169695Skan { 97169695Skan char *rp = canonicalize_file_name (filename); 98169695Skan if (rp == NULL) 99169695Skan return strdup (filename); 100169695Skan else 101169695Skan return rp; 102169695Skan } 103169695Skan#endif 104169695Skan 105169695Skan /* Method 3: Now we're getting desperate! The system doesn't have a 106169695Skan compile time buffer size and no alternative function. Query the 107169695Skan OS, using pathconf(), for the buffer limit. Care is needed 108169695Skan though, some systems do not limit PATH_MAX (return -1 for 109169695Skan pathconf()) making it impossible to pass a correctly sized buffer 110169695Skan to realpath() (it could always overflow). On those systems, we 111169695Skan skip this. */ 112169695Skan#if defined (HAVE_REALPATH) && defined (HAVE_UNISTD_H) 113169695Skan { 114169695Skan /* Find out the max path size. */ 115169695Skan long path_max = pathconf ("/", _PC_PATH_MAX); 116169695Skan if (path_max > 0) 117169695Skan { 118169695Skan /* PATH_MAX is bounded. */ 119169695Skan char *buf, *rp, *ret; 120169695Skan buf = (char *) malloc (path_max); 121169695Skan if (buf == NULL) 122169695Skan return NULL; 123169695Skan rp = realpath (filename, buf); 124169695Skan ret = strdup (rp ? rp : filename); 125169695Skan free (buf); 126169695Skan return ret; 127169695Skan } 128169695Skan } 129169695Skan#endif 130169695Skan 131169695Skan /* The MS Windows method. If we don't have realpath, we assume we 132169695Skan don't have symlinks and just canonicalize to a Windows absolute 133169695Skan path. GetFullPath converts ../ and ./ in relative paths to 134169695Skan absolute paths, filling in current drive if one is not given 135169695Skan or using the current directory of a specified drive (eg, "E:foo"). 136169695Skan It also converts all forward slashes to back slashes. */ 137169695Skan#if defined (_WIN32) 138169695Skan { 139169695Skan char buf[MAX_PATH]; 140169695Skan char* basename; 141169695Skan DWORD len = GetFullPathName (filename, MAX_PATH, buf, &basename); 142169695Skan if (len == 0 || len > MAX_PATH - 1) 143169695Skan return strdup (filename); 144169695Skan else 145169695Skan { 146169695Skan /* The file system is case-preserving but case-insensitive, 147169695Skan Canonicalize to lowercase, using the codepage associated 148169695Skan with the process locale. */ 149169695Skan CharLowerBuff (buf, len); 150169695Skan return strdup (buf); 151169695Skan } 152169695Skan } 153169695Skan#endif 154169695Skan 155169695Skan /* This system is a lost cause, just duplicate the filename. */ 156169695Skan return strdup (filename); 157169695Skan} 158