--- path_self.c 2003/02/16 11:39:23 1.3
+++ path_self.c 2006/08/23 09:13:24 1.4
@@ -32,6 +32,10 @@
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
+#if defined(__FreeBSD__)
+#include <sys/sysctl.h>
+#include <limits.h>
+#endif
#include <unistd.h>
#include "path.h"
@@ -45,10 +49,40 @@
struct stat sb;
char *cpB, *cpE;
size_t argv0_len;
+#if defined(__FreeBSD__)
+ int mib[4];
+#endif
if (res_buf == NULL || res_size == 0 || argv0 == NULL)
return PATH_ERR_ARG;
+#if defined(__FreeBSD__)
+ /* retrieve path via sysctl(3) (FreeBSD only) */
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_PROC;
+ mib[2] = KERN_PROC_PATHNAME;
+ mib[3] = -1;
+ l = res_size - 1;
+ if (sysctl(mib, 4, res_buf, &l, NULL, 0) == 0) {
+ res_buf[l] = '\0';
+ if (path_resolve(res_buf, res_size, res_buf) == NULL)
+ return PATH_ERR_SYS;
+ }
+#endif
+
+ /* search for /proc entries (Linux only) */
+ if ((l = readlink("/proc/self/exe" /* Linux */, res_buf, res_size-1)) == -1)
+ if ((l = readlink("/proc/self/path/a.out" /* Solaris */, res_buf, res_size-1)) == -1)
+ l = readlink("/proc/curproc/file" /* BSD */, res_buf, res_size-1);
+ if (l > 0) {
+ if (res_buf[l-1] == '\0')
+ l--;
+ res_buf[l] = '\0';
+ if (strcmp(res_buf, "unknown") != 0)
+ if (path_resolve(res_buf, res_size, res_buf) == NULL)
+ return PATH_ERR_SYS;
+ }
+
/* determine length of argv[0] */
argv0_len = strlen(argv0);
@@ -80,18 +114,6 @@
return PATH_OK;
}
- /* else search for /proc entries (at least possible under Linux and FreeBSD) */
- if ((l = readlink("/proc/self/exe", res_buf, res_size-1)) == -1)
- l = readlink("/proc/curproc/file", res_buf, res_size-1);
- if (l > 0) {
- if (res_buf[l-1] == '\0')
- l--;
- res_buf[l] = '\0';
- if (strcmp(res_buf, "unknown") != 0)
- if (path_resolve(res_buf, res_size, res_buf) == NULL)
- return PATH_ERR_SYS;
- }
-
/* else search argv[0] in $PATH */
if ((path = getenv("PATH")) == NULL)
path = PATH_DEFAULT;
|