summaryrefslogtreecommitdiffstats
path: root/osdep-freebsd.c
diff options
context:
space:
mode:
authorNicholas Marriott <nicholas.marriott@gmail.com>2014-11-06 14:00:56 +0000
committerNicholas Marriott <nicholas.marriott@gmail.com>2014-11-06 14:00:56 +0000
commit218b1819855a64e2d126a39a534f9a9d9ea9462c (patch)
tree09319a2425e51f4a8e5cdc9efde2a88ec55b57b2 /osdep-freebsd.c
parent6ca8c58462e5d1b47f98acee8c79a34bba1bd7df (diff)
Use KERN_PROC_CWD if supported, from Tiwei Bie.
Diffstat (limited to 'osdep-freebsd.c')
-rw-r--r--osdep-freebsd.c36
1 files changed, 34 insertions, 2 deletions
diff --git a/osdep-freebsd.c b/osdep-freebsd.c
index d596eab4..9d1acb85 100644
--- a/osdep-freebsd.c
+++ b/osdep-freebsd.c
@@ -132,8 +132,8 @@ error:
return (NULL);
}
-char *
-osdep_get_cwd(int fd)
+static char *
+osdep_get_cwd_fallback(int fd)
{
static char wd[PATH_MAX];
struct kinfo_file *info = NULL;
@@ -158,6 +158,38 @@ osdep_get_cwd(int fd)
return (NULL);
}
+#ifdef KERN_PROC_CWD
+char *
+osdep_get_cwd(int fd)
+{
+ static struct kinfo_file info;
+ static int fallback;
+ int name[] = { CTL_KERN, KERN_PROC, KERN_PROC_CWD, 0 };
+ size_t len = sizeof info;
+
+ if (fallback)
+ return (osdep_get_cwd_fallback(fd));
+
+ if ((name[3] = tcgetpgrp(fd)) == -1)
+ return (NULL);
+
+ if (sysctl(name, 4, &info, &len, NULL, 0) == -1) {
+ if (errno == ENOENT) {
+ fallback = 1;
+ return (osdep_get_cwd_fallback(fd));
+ }
+ return (NULL);
+ }
+ return (info.kf_path);
+}
+#else /* !KERN_PROC_CWD */
+char *
+osdep_get_cwd(int fd)
+{
+ return (osdep_get_cwd_fallback(fd));
+}
+#endif /* KERN_PROC_CWD */
+
struct event_base *
osdep_event_init(void)
{