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