Thanks for this. The OpenBSD kernel bits are in so I've applied your diff with some minor tweaks and the required bits for osdep-openbsd.c.
Anyone wants to do AIX, Darwin, DFLY, HP/UX, or NetBSD send the code :-). On Tue, Dec 06, 2011 at 07:35:18PM +0100, Romain Francoise wrote: > Nicholas Marriott <nicholas.marri...@gmail.com> writes: > > > Ok, so OpenBSD should have a way to do this soon, either a new > > second-level sysctl KERN_PROC_CWD or a new third-level under > > KERN_PROC_ARGS. Don't worry about that though, let's move forward with > > your diff and I'll add OpenBSD when my code goes in. > > Awesome, thanks. > > Here's a v2 patch with the following changes: > - logic updated as per your suggestion (note, default-path already > defaults to "") > - support for FreeBSD, tested on FreeBSD 8.2 > - support for Solaris, untested but it's similar to Linux > - doc updated for 'default-path' > > diff --git a/cmd-new-window.c b/cmd-new-window.c > index 065e2b1..30ddd64 100644 > --- a/cmd-new-window.c > +++ b/cmd-new-window.c > @@ -98,13 +98,7 @@ cmd_new_window_exec(struct cmd *self, struct cmd_ctx *ctx) > cmd = options_get_string(&s->options, "default-command"); > else > cmd = args->argv[0]; > - cwd = options_get_string(&s->options, "default-path"); > - if (*cwd == '\0') { > - if (ctx->cmdclient != NULL && ctx->cmdclient->cwd != NULL) > - cwd = ctx->cmdclient->cwd; > - else > - cwd = s->cwd; > - } > + cwd = cmd_get_default_path(ctx); > > if (idx == -1) > idx = -1 - options_get_number(&s->options, "base-index"); > diff --git a/cmd-split-window.c b/cmd-split-window.c > index 258c632..7089193 100644 > --- a/cmd-split-window.c > +++ b/cmd-split-window.c > @@ -77,13 +77,7 @@ cmd_split_window_exec(struct cmd *self, struct cmd_ctx > *ctx) > cmd = options_get_string(&s->options, "default-command"); > else > cmd = args->argv[0]; > - cwd = options_get_string(&s->options, "default-path"); > - if (*cwd == '\0') { > - if (ctx->cmdclient != NULL && ctx->cmdclient->cwd != NULL) > - cwd = ctx->cmdclient->cwd; > - else > - cwd = s->cwd; > - } > + cwd = cmd_get_default_path(ctx); > > type = LAYOUT_TOPBOTTOM; > if (args_has(args, 'h')) > diff --git a/cmd.c b/cmd.c > index 2027f75..a1b96c3 100644 > --- a/cmd.c > +++ b/cmd.c > @@ -1212,3 +1212,31 @@ cmd_template_replace(char *template, const char *s, > int idx) > > return (buf); > } > + > +/* > + * Return a default path for new windows appropriate for this command > + * context. > + */ > +char * > +cmd_get_default_path(struct cmd_ctx *ctx) > +{ > + char *cwd; > + struct session *s; > + struct window_pane *wp; > + > + if ((s = cmd_current_session(ctx, 0)) == NULL) > + return (NULL); > + > + cwd = options_get_string(&s->options, "default-path"); > + if (*cwd == '\0') { > + if (ctx->cmdclient != NULL && ctx->cmdclient->cwd != NULL) > + return (ctx->cmdclient->cwd); > + if (ctx->curclient != NULL) { > + wp = s->curw->window->active; > + if ((cwd = osdep_get_pid_cwd(wp->pid)) != NULL) > + return (cwd); > + } > + return (s->cwd); > + } > + return (cwd); > +} > diff --git a/osdep-aix.c b/osdep-aix.c > index 0dc07d6..02a650d 100644 > --- a/osdep-aix.c > +++ b/osdep-aix.c > @@ -28,6 +28,12 @@ osdep_get_name(unused int fd, unused char *tty) > return (NULL); > } > > +char * > +osdep_get_pid_cwd(pid_t pid) > +{ > + return (NULL); > +} > + > struct event_base * > osdep_event_init(void) > { > diff --git a/osdep-darwin.c b/osdep-darwin.c > index 229a493..092adde 100644 > --- a/osdep-darwin.c > +++ b/osdep-darwin.c > @@ -48,6 +48,12 @@ osdep_get_name(int fd, unused char *tty) > return (strdup(kp.kp_proc.p_comm)); > } > > +char * > +osdep_get_pid_cwd(pid_t pid) > +{ > + return (NULL); > +} > + > struct event_base * > osdep_event_init(void) > { > diff --git a/osdep-dragonfly.c b/osdep-dragonfly.c > index b15abf9..6cb656f 100644 > --- a/osdep-dragonfly.c > +++ b/osdep-dragonfly.c > @@ -119,6 +119,12 @@ error: > return (NULL); > } > > +char * > +osdep_get_pid_cwd(pid_t pid) > +{ > + return (NULL); > +} > + > struct event_base * > osdep_event_init(void) > { > diff --git a/osdep-freebsd.c b/osdep-freebsd.c > index 6b0c888..077a2c0 100644 > --- a/osdep-freebsd.c > +++ b/osdep-freebsd.c > @@ -29,9 +29,11 @@ > #include <stdlib.h> > #include <string.h> > #include <unistd.h> > +#include <libutil.h> > > struct kinfo_proc *cmp_procs(struct kinfo_proc *, struct kinfo_proc *); > char *osdep_get_name(int, char *); > +char *osdep_get_pid_cwd(pid_t); > struct event_base *osdep_event_init(void); > > #ifndef nitems > @@ -130,6 +132,28 @@ error: > return (NULL); > } > > +char * > +osdep_get_pid_cwd(pid_t pid) > +{ > + static char wd[PATH_MAX]; > + struct kinfo_file *info = NULL; > + int nrecords, i; > + > + if ((info = kinfo_getfile(pid, &nrecords)) == NULL) > + return (NULL); > + > + for (i = 0; i < nrecords; i++) { > + if (info[i].kf_fd == KF_FD_TYPE_CWD) { > + strlcpy(wd, info[i].kf_path, sizeof wd); > + free(info); > + return (wd); > + } > + } > + > + free(info); > + return (NULL); > +} > + > struct event_base * > osdep_event_init(void) > { > diff --git a/osdep-hpux.c b/osdep-hpux.c > index 3bec98e..e7ec565 100644 > --- a/osdep-hpux.c > +++ b/osdep-hpux.c > @@ -28,6 +28,12 @@ osdep_get_name(unused int fd, unused char *tty) > return (NULL); > } > > +char * > +osdep_get_pid_cwd(pid_t pid) > +{ > + return (NULL); > +} > + > struct event_base * > osdep_event_init(void) > { > diff --git a/osdep-linux.c b/osdep-linux.c > index b4a1a9f..3d3cf1f 100644 > --- a/osdep-linux.c > +++ b/osdep-linux.c > @@ -60,6 +60,23 @@ osdep_get_name(int fd, unused char *tty) > return (buf); > } > > +char * > +osdep_get_pid_cwd(pid_t pid) > +{ > + static char target[MAXPATHLEN + 1]; > + char *path; > + ssize_t n; > + > + xasprintf(&path, "/proc/%d/cwd", pid); > + n = readlink(path, target, MAXPATHLEN); > + xfree(path); > + if (n > 0) { > + target[n] = '\0'; > + return (target); > + } > + return (NULL); > +} > + > struct event_base * > osdep_event_init(void) > { > diff --git a/osdep-netbsd.c b/osdep-netbsd.c > index 64fcb3e..8a2b13f 100644 > --- a/osdep-netbsd.c > +++ b/osdep-netbsd.c > @@ -123,6 +123,12 @@ error: > return (NULL); > } > > +char * > +osdep_get_pid_cwd(pid_t pid) > +{ > + return (NULL); > +} > + > struct event_base * > osdep_event_init(void) > { > diff --git a/osdep-openbsd.c b/osdep-openbsd.c > index 9eefc44..74059c2 100644 > --- a/osdep-openbsd.c > +++ b/osdep-openbsd.c > @@ -133,6 +133,12 @@ error: > return (NULL); > } > > +char * > +osdep_get_pid_cwd(pid_t pid) > +{ > + return (NULL); > +} > + > struct event_base * > osdep_event_init(void) > { > diff --git a/osdep-sunos.c b/osdep-sunos.c > index 5d1e582..58adf20 100644 > --- a/osdep-sunos.c > +++ b/osdep-sunos.c > @@ -64,6 +64,23 @@ osdep_get_name(int fd, char *tty) > return (xstrdup(p.pr_fname)); > } > > +char * > +osdep_get_pid_cwd(pid_t pid) > +{ > + static char target[MAXPATHLEN + 1]; > + char *path; > + ssize_t n; > + > + xasprintf(&path, "/proc/%u/path/cwd", (u_int) pid); > + n = readlink(path, target, MAXPATHLEN); > + xfree(path); > + if (n > 0) { > + target[n] = '\0'; > + return (target); > + } > + return (NULL); > +} > + > struct event_base * > osdep_event_init(void) > { > diff --git a/osdep-unknown.c b/osdep-unknown.c > index 3bec98e..e7ec565 100644 > --- a/osdep-unknown.c > +++ b/osdep-unknown.c > @@ -28,6 +28,12 @@ osdep_get_name(unused int fd, unused char *tty) > return (NULL); > } > > +char * > +osdep_get_pid_cwd(pid_t pid) > +{ > + return (NULL); > +} > + > struct event_base * > osdep_event_init(void) > { > diff --git a/tmux.1 b/tmux.1 > index cbe8062..c5d51fb 100644 > --- a/tmux.1 > +++ b/tmux.1 > @@ -1843,10 +1843,12 @@ to create a login shell using the value of the > .Ic default-shell > option. > .It Ic default-path Ar path > -Set the default working directory for processes created from keys, or > -interactively from the prompt. > -The default is empty, which means to use the working directory of the shell > -from which the server was started if it is available or the user's home if > not. > +Set the default working directory for new processes. If empty (the > +default), the working directory is determined dynamically from the > +calling context: when called from keys or the command prompt the working > +directory of the process living in the active window is used, when > +called from the command line the working directory of the client is > +used, otherwise the directory from which the server was started is used. > .It Ic default-shell Ar path > Specify the default shell. > This is used as the login shell for new windows when the > diff --git a/tmux.h b/tmux.h > index 8c9f9e7..226c3d6 100644 > --- a/tmux.h > +++ b/tmux.h > @@ -1556,6 +1556,7 @@ int cmd_find_index( > struct winlink *cmd_find_pane(struct cmd_ctx *, > const char *, struct session **, struct window_pane **); > char *cmd_template_replace(char *, const char *, int); > +char *cmd_get_default_path(struct cmd_ctx *ctx); > extern const struct cmd_entry *cmd_table[]; > extern const struct cmd_entry cmd_attach_session_entry; > extern const struct cmd_entry cmd_bind_key_entry; > @@ -2073,6 +2074,7 @@ u_int utf8_split2(u_int, u_char *); > > /* osdep-*.c */ > char *osdep_get_name(int, char *); > +char *osdep_get_pid_cwd(pid_t); > struct event_base *osdep_event_init(void); > > /* log.c */ ------------------------------------------------------------------------------ Cloud Services Checklist: Pricing and Packaging Optimization This white paper is intended to serve as a reference, checklist and point of discussion for anyone considering optimizing the pricing and packaging model of a cloud services business. Read Now! http://www.accelacomm.com/jaw/sfnl/114/51491232/ _______________________________________________ tmux-users mailing list tmux-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/tmux-users