Alter how tmux handles the working directory to internally use file

descriptors rather than strings.

- Each session still has a current working directory.

- New sessions still get their working directory from the client that
  created them or its attached session if any.

- New windows are created by default in the session working directory.

- The -c flag to new, neww, splitw allows the working directory to be
  overridden.

- The -c flag to attach let's the session working directory be changed.

- The default-path option has been removed.

To get the equivalent to default-path '.', do:

        bind c neww -c $PWD

To get the equivalent of default-path '~', do:

        bind c neww -c ~

This also changes the client identify protocol to be a set of messages rather
than one as well as some other changes that should make it easier to make
backwards-compatible protocol changes in future.
This commit is contained in:
nicm
2013-10-10 12:26:34 +00:00
parent 165aa59760
commit 282c5f9644
17 changed files with 363 additions and 300 deletions

View File

@ -53,7 +53,6 @@ int client_attached;
int client_get_lock(char *);
int client_connect(char *, int);
void client_send_identify(int);
void client_send_environ(void);
int client_write_one(enum msgtype, int, const void *, size_t);
int client_write_server(enum msgtype, const void *, size_t);
void client_update_event(void);
@ -257,8 +256,7 @@ client_main(int argc, char **argv, int flags)
/* Establish signal handlers. */
set_signals(client_signal);
/* Send initial environment. */
client_send_environ();
/* Send identify messages. */
client_send_identify(flags);
/* Send first command. */
@ -316,45 +314,39 @@ client_main(int argc, char **argv, int flags)
return (client_exitval);
}
/* Send identify message to server with the file descriptors. */
/* Send identify messages to server. */
void
client_send_identify(int flags)
{
struct msg_identify_data data;
char *term;
int fd;
const char *s;
char **ss;
int fd;
data.flags = flags;
client_write_one(MSG_IDENTIFY_FLAGS, -1, &flags, sizeof flags);
if (getcwd(data.cwd, sizeof data.cwd) == NULL)
*data.cwd = '\0';
if ((s = getenv("TERM")) == NULL)
s = "";
client_write_one(MSG_IDENTIFY_TERM, -1, s, strlen(s) + 1);
term = getenv("TERM");
if (term == NULL ||
strlcpy(data.term, term, sizeof data.term) >= sizeof data.term)
*data.term = '\0';
if ((s = ttyname(STDIN_FILENO)) == NULL)
s = "";
client_write_one(MSG_IDENTIFY_TTYNAME, -1, s, strlen(s) + 1);
if ((fd = open(".", O_RDONLY)) == -1)
fd = open("/", O_RDONLY);
client_write_one(MSG_IDENTIFY_CWD, fd, NULL, 0);
if ((fd = dup(STDIN_FILENO)) == -1)
fatal("dup failed");
imsg_compose(&client_ibuf,
MSG_IDENTIFY, PROTOCOL_VERSION, -1, fd, &data, sizeof data);
client_write_one(MSG_IDENTIFY_STDIN, fd, NULL, 0);
for (ss = environ; *ss != NULL; ss++)
client_write_one(MSG_IDENTIFY_ENVIRON, -1, *ss, strlen(*ss) + 1);
client_write_one(MSG_IDENTIFY_DONE, -1, NULL, 0);
client_update_event();
}
/* Forward entire environment to server. */
void
client_send_environ(void)
{
struct msg_environ_data data;
char **var;
for (var = environ; *var != NULL; var++) {
if (strlcpy(data.var, *var, sizeof data.var) >= sizeof data.var)
continue;
client_write_server(MSG_ENVIRON, &data, sizeof data);
}
}
/* Helper to send one message. */
int
client_write_one(enum msgtype type, int fd, const void *buf, size_t len)
@ -595,8 +587,6 @@ client_dispatch_wait(void *data0)
case MSG_EXITED:
imsg_free(&imsg);
return (-1);
default:
fatalx("unexpected message");
}
imsg_free(&imsg);
@ -675,8 +665,6 @@ client_dispatch_attached(void)
system(data);
client_write_server(MSG_UNLOCK, NULL, 0);
break;
default:
fatalx("unexpected message");
}
imsg_free(&imsg);