summaryrefslogtreecommitdiff
path: root/byterun/win32.c
diff options
context:
space:
mode:
authorXavier Leroy <xavier.leroy@inria.fr>2016-09-05 08:49:25 +0200
committerXavier Leroy <xavier.leroy@inria.fr>2016-09-05 08:49:25 +0200
commita91d6a5470ab5d97f425d5a9f9e1a507356b292e (patch)
treede80f709a7ebc14faa70749ca3b7258e2bd26325 /byterun/win32.c
parent1b1f5e2470397525c46e0340137a1af185fa055f (diff)
downloadocaml-a91d6a5470ab5d97f425d5a9f9e1a507356b292e.tar.gz
Improve OS-dependent determination of file name for the current executable
In several places, the old code was limiting this file name to 256 characters at most. At least one user is bothered by this restriction. - Change API of caml_executable_name() to return a string dynamically allocated with caml_stat_alloc. - Update implementation of caml_executable_name() byterun/unix.c and byterun/win32.c to handle file names of (almost) arbitrary length. - Add special code for MacOS X, not tested yet. Fun fact of the day: under (some versions of) Linux, lstat() on "/proc/self/exe" returns 0 as length, so we can't use it to determine the size of the name in advance.
Diffstat (limited to 'byterun/win32.c')
-rw-r--r--byterun/win32.c21
1 files changed, 15 insertions, 6 deletions
diff --git a/byterun/win32.c b/byterun/win32.c
index 6241231bbe..dc5aa365cd 100644
--- a/byterun/win32.c
+++ b/byterun/win32.c
@@ -609,13 +609,22 @@ void caml_install_invalid_parameter_handler()
/* Recover executable name */
-int caml_executable_name(char * name, int name_len)
+char * caml_executable_name(void)
{
- int retcode;
-
- int ret = GetModuleFileName(NULL, name, name_len);
- if (0 == ret || ret >= name_len) return -1;
- return 0;
+ char * name;
+ DWORD namelen, ret;
+
+ namelen = 256;
+ while (1) {
+ name = caml_stat_alloc(namelen);
+ ret = GetModuleFileName(NULL, name, namelen);
+ if (ret == 0) { caml_stat_free(name); return NULL; }
+ if (ret < namelen) break;
+ caml_stat_free(name);
+ if (namelen >= 1024*1024) return NULL; /* avoid runaway and overflow */
+ namelen *= 2;
+ }
+ return name;
}
/* snprintf emulation */