1 /**********************************************************************
2  *
3  * Project:  CPL - Common Portability Library
4  * Purpose:  Implement CPLGetExecPath().
5  * Author:   Frank Warmerdam, warmerdam@pobox.com
6  *
7  **********************************************************************
8  * Copyright (c) 2005, Frank Warmerdam
9  *
10  * Permission is hereby granted, free of charge, to any person obtaining a
11  * copy of this software and associated documentation files (the "Software"),
12  * to deal in the Software without restriction, including without limitation
13  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
14  * and/or sell copies of the Software, and to permit persons to whom the
15  * Software is furnished to do so, subject to the following conditions:
16  *
17  * The above copyright notice and this permission notice shall be included
18  * in all copies or substantial portions of the Software.
19  *
20  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
23  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
25  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26  * DEALINGS IN THE SOFTWARE.
27  ****************************************************************************/
28 
29 #include "cpl_port.h"
30 #include "cpl_conv.h"
31 
32 #if HAVE_UNISTD_H
33 #include <unistd.h>
34 #endif
35 
36 #include "cpl_multiproc.h"
37 #include "cpl_string.h"
38 
39 
40 CPL_CVSID("$Id: cpl_getexecpath.cpp 7e07230bbff24eb333608de4dbd460b7312839d0 2017-12-11 19:08:47Z Even Rouault $")
41 
42 #if defined(WIN32)
43 
44 #define HAVE_IMPLEMENTATION 1
45 
46 #include <windows.h>
47 
48 /************************************************************************/
49 /*                           CPLGetExecPath()                           */
50 /************************************************************************/
51 
CPLGetExecPath(char * pszPathBuf,int nMaxLength)52 int CPLGetExecPath( char *pszPathBuf, int nMaxLength )
53 {
54     if( CPLTestBool( CPLGetConfigOption( "GDAL_FILENAME_IS_UTF8", "YES" ) ) )
55     {
56         wchar_t *pwszPathBuf = static_cast<wchar_t *>(
57             CPLCalloc(nMaxLength + 1, sizeof(wchar_t)));
58 
59         if( GetModuleFileNameW( nullptr, pwszPathBuf, nMaxLength ) == 0 )
60         {
61             CPLFree( pwszPathBuf );
62             return FALSE;
63         }
64         else
65         {
66             char *pszDecoded =
67                 CPLRecodeFromWChar(pwszPathBuf, CPL_ENC_UCS2, CPL_ENC_UTF8);
68 
69             strncpy( pszPathBuf, pszDecoded, nMaxLength );
70             CPLFree( pszDecoded );
71             CPLFree( pwszPathBuf );
72             return TRUE;
73         }
74     }
75     else
76     {
77         if( GetModuleFileNameA( nullptr, pszPathBuf, nMaxLength ) == 0 )
78             return FALSE;
79         else
80             return TRUE;
81     }
82 }
83 
84 #endif
85 
86 /************************************************************************/
87 /*                           CPLGetExecPath()                           */
88 /************************************************************************/
89 
90 #if !defined(HAVE_IMPLEMENTATION) && defined(__linux)
91 
92 #include "cpl_multiproc.h"
93 
94 #define HAVE_IMPLEMENTATION 1
95 
CPLGetExecPath(char * pszPathBuf,int nMaxLength)96 int CPLGetExecPath( char *pszPathBuf, int nMaxLength )
97 {
98     long nPID = getpid();
99     CPLString osExeLink;
100 
101     osExeLink.Printf( "/proc/%ld/exe", nPID );
102     ssize_t nResultLen = readlink( osExeLink, pszPathBuf, nMaxLength );
103     if( nResultLen >= 0 )
104         pszPathBuf[nResultLen] = '\0';
105     else
106         pszPathBuf[0] = '\0';
107 
108     return nResultLen > 0;
109 }
110 
111 #endif
112 
113 /************************************************************************/
114 /*                           CPLGetExecPath()                           */
115 /************************************************************************/
116 
117 /**
118  * Fetch path of executable.
119  *
120  * The path to the executable currently running is returned.  This path
121  * includes the name of the executable.   Currently this only works on
122  * win32 and linux platforms.  The returned path is UTF-8 encoded.
123  *
124  * @param pszPathBuf the buffer into which the path is placed.
125  * @param nMaxLength the buffer size, MAX_PATH+1 is suggested.
126  *
127  * @return FALSE on failure or TRUE on success.
128  */
129 
130 #ifndef HAVE_IMPLEMENTATION
131 
CPLGetExecPath(CPL_UNUSED char * pszPathBuf,CPL_UNUSED int nMaxLength)132 int CPLGetExecPath( CPL_UNUSED char * pszPathBuf, CPL_UNUSED int nMaxLength )
133 {
134     return FALSE;
135 }
136 
137 #endif
138