1 Commits
1.2 ... 1.0

Author SHA1 Message Date
no_author
be20fc8699 This commit was manufactured by cvs2svn to create tag 'TMUX_1_0'. 2009-09-20 18:54:22 +00:00
166 changed files with 6885 additions and 10698 deletions

111
CHANGES
View File

@@ -1,112 +1,3 @@
CHANGES FROM 1.1 TO 1.2, 10 March 2010
* Switch to libevent.
* Emulate the ri (reverse index) capability, ergo allowing tmux to at least
start on Sun consoles (TERM=sun, or sun-color).
* Assign each entry a number, or lowercase letter in choose mode, and accept
that as a shortcut key.
* Permit top-bit-set characters to be entered in the status line.
* Mark no-prefix keys with (no prefix), rather than [] in list-keys.
* New command show-messages (alias showmsgs), and new session option
message-limit, to show a per-client log of status lines messages up to the
number defined by message-limit.
* Do not interpret #() for display-message to avoid leaking commands.
* New window options window-status-format, and window-status-current-format to
control the format of each window in the status line.
* Add a -p flag to display-message to print the output, instead of displaying
it in the status line.
* Emulate il1, dl1, ich1 to run with vt100 feature set.
* New command capture-pane (alias capturep) to copy the entire pane contents
to a paste buffer.
* Avoid duplicating code by adding a -w flag to set-option, and show-options to
set, and show window options. The commands set-window-option, and
show-window-options are now aliases.
* Panes can now be referred to as top, bottom, top-left, etc.
* Add server-wide options, which can be set with set-option -s, and shown with
show-options -s.
* New server option quiet (like -q from the command line).
* New server option escape-time to set the timeout used to detect if escapes
are alone, part of a function key, or meta sequence.
* New session options pane-active-border-bg, pane-active-border-fg,
pane-border-bg, and pane-border-fg to set pane colours.
* Make split-window accept a pane target, instead of a window.
* New command join-pane (alias joinp) to split, and move an existing pane into
the space (the opposite of break-pane), thus simplifying calls to
split-window, followed by move-window.
* Permit S- prefix on keys for shift when the terminal/terminfo supports them.
* Window targets (-t flag) can now refer to the last window (!), next (+), and
previous (-) window by number.
* Mode keys to jump to the bottom/top of history, end of the next word, scroll
up/down, and reverse search in copy mode.
* New session option display-panes-active-colour to display the active pane in
a different colour with the display-panes command.
* Read the socket path from $TMUX if it's present, and -L, and -S are not
given.
* Vi-style mode keys B, W, and E to navigate between words in copy mode.
* Start in more mode when configuration file errors are detected.
* Rectangle copy support added.
* If attach-session was specified with the -r flag, make the client read-only.
* Per-window alternate-screen option.
* Make load-buffer work with FIFOs.
* New window option word-separators to set the characters considered as word
separators in copy mode.
* Permit keys in copy mode to be prefixed by a repeat count, entered with [1-9]
in vi mode, or M-[1-9] in emacs mode.
* utf8 improvements.
* As usual, additional code reduction, bug fixes, and manpage enhancements.
CHANGES FROM 1.0 TO 1.1, 05 November 2009
* New run-shell (alias run) command to run an external command without a
window, capture it's stdout, and send it to output mode.
* Ability to define multiple prefix keys.
* Internal locking mechanism removed. Instead, detach each client and run the
external command specified in the new session option lock-command (by default
lock -np), thus allowing the system password to be used.
* set-password command, and -U command line flag removed per the above change.
* Add support for -c command line flag to execute a shell command.
* New lock-client (alias lockc), and lock-session (alias locks) commands to
lock a particular client, or all clients attached to a session.
* Support C-n/C-p/C-v/M-v with emacs keys in choice mode.
* Use : for goto line rather than g in vi mode.
* Try to guess which client to use when no target client was specified. Finds
the current session, and if only one client is present, use it. Otherwise,
return the most recently used client.
* Make C-Down/C-Up in copy mode scroll the screen down/up one line without
moving the cursor.
* Scroll mode superseded by copy mode.
* New synchronize-panes window option to send all input to all other panes in
the same window.
* New lock-server session option to lock, when off (on by default), each
session when it has been idle for the lock-after-time setting. When on, the
entire server locks when all sessions have been idle for their individual
lock-after-time setting.
* Add support for grouped sessions which have independent name, options,
current window, but where the linked windows are synchronized (ie creating,
killing windows are mirrored between the sessions). A grouped session may be
created by passing -t to new-session.
* New mouse-select-pane session option to select the current pane with the
mouse.
* Queue, and run commands in the background for if-shell, status-left,
status-right, and #() by starting each once every status-interval. Adds the
capability to call some programs which would previously cause the server to
hang (eg sleep/tmux). It also avoids running commands excessively (ie if used
multiple times, it will be run only once).
* When a window is zombified and automatic-rename is on, append [dead] to the
name.
* Split list-panes (alias lsp) off from list-windows.
* New pipe-pane (alias pipep) to redirect a pane output to an external command.
* Support for automatic-renames for Solaris.
* Permit attributes to be turned off in #[] by prefixing with no (eg nobright).
* Add H/M/L in vi mode, and M-R/M-r in emacs to move the cursor to the top,
middle, and bottom of the screen.
* -a option added to kill-pane to kill all except current pane.
* The -d command line flag is now gone (can be replaced by terminal-overrides).
Just use op/AX to detect default colours.
* input/tty/utf8 improvements.
* xterm-keys rewrite.
* Additional code reduction, and bug fixes.
CHANGES FROM 0.9 TO 1.0, 20 Sept 2009
* Option to alter the format of the window title set by tmux.
@@ -1467,7 +1358,7 @@ The list of older changes is below.
(including mutt, emacs). No status bar yet and no key remapping or other
customisation.
$Id: CHANGES,v 1.302 2010-03-10 15:18:11 tcunha Exp $
$Id: CHANGES,v 1.300 2009-09-20 18:54:21 nicm Exp $
LocalWords: showw utf UTF fulvio ciriaco joshe OSC APC gettime abc DEF OA clr
LocalWords: rivo nurges lscm Erdely eol smysession mysession ek dstname RB ms

58
FAQ
View File

@@ -1,17 +1,5 @@
tmux frequently asked questions
******************************************************************************
* PLEASE NOTE: most display problems are due to incorrect TERM! Before *
* reporting problems make SURE that TERM settings are correct inside and *
* outside tmux. *
* *
* Inside tmux TERM must be "screen" or similar (such as "screen-256color"). *
* Don't bother reporting problems where it isn't! *
* *
* Outside, it must match your terminal: particularly, use "rxvt" for rxvt *
* and derivatives. *
******************************************************************************
* How is tmux different from GNU screen? What else does it offer?
tmux offers several advantages over screen:
@@ -38,9 +26,8 @@ There are still a few features screen includes that tmux omits:
* I found a bug! What do I do?
Please send bug reports by email to nicm@users.sourceforge.net or
tmux-users@lists.sourceforge.net. Please include as much of the following
information as possible:
Please send bug reports by email to nicm@users.sourceforge.net. Please
include as much of the following information as possible:
- the version of tmux you are running;
- the operating system you are using and its version;
@@ -95,17 +82,19 @@ default) to the new key. For example:
* How do I use UTF-8?
When running tmux in a UTF-8 capable terminal, UTF-8 must be turned on in tmux;
as of release 0.9, tmux attempts to autodetect a UTF-8-capable terminal by
When running tmux in a UTF-8 capable terminal, two things must be done to
enable support. UTF-8 must be turned on in tmux; this may be done separately
for each tmux window or globally by setting the "utf8" flag:
setw -g utf8 on
As of release 0.9, tmux attempts to autodetect a UTF-8-capable terminal by
checking the LC_ALL, LC_CTYPE and LANG environment variables. list-clients may
be used to check if this is detected correctly; if not, the -u command-line
flag may be specified when creating or attaching a client to a tmux session:
$ tmux -u new
Since the 1.0 release, tmux will turn on UTF-8 related options automatically
(ie status-utf8, and utf8) if the above conditions are met.
* How do I use a 256 colour terminal?
Provided the underlying terminal supports 256 colours, it is usually sufficient
@@ -212,31 +201,4 @@ on the Window -> Translation configuration page. For example, change UTF-8 to
ISO-8859-1 or CP437. It may also be necessary to adjust the way PuTTY treats
line drawing characters in the lower part of the same configuration page.
* What is the best way to display the load average? Why no #L?
It isn't possible to get the load average portably in code and it is preferable
not to add portability goop. The following works on at least Linux, *BSD and OS
X:
uptime|awk '{split(substr($0, index($0, "load")), a, ":"); print a[2]}'
* How do I attach the same session to multiple clients but with a different
current window, like screen -x?
One or more of the windows can be linked into multiple sessions manually with
link-window, or a grouped session with all the windows can be created with
new-session -t.
* Ctrl and arrow keys doesn't work in putty! What do I do?
putty inverts the sense of the cursor key mode on ctrl, which is a bit hard for
tmux to detect properly. To get ctrl keys right, change the terminfo settings
so kUP5 (Ctrl-Up etc) are the adjusted versions, and disable smkx/rmkx so tmux
doesn't change the mode. For example with this line in .tmux.conf (assuming you
have TERM set to xterm):
set -g terminal-overrides "xterm*:kLFT5=\eOD:kRIT5=\eOC:kUP5=\eOA:kDN5=\eOB:smkx@:rmkx@"
Note that this will only work in tmux 1.2 and above.
$Id: FAQ,v 1.36 2010-02-04 21:01:59 nicm Exp $
$Id: FAQ,v 1.29 2009-08-08 20:46:26 nicm Exp $

View File

@@ -1,37 +1,16 @@
# $Id: GNUmakefile,v 1.122 2010-03-10 15:15:33 tcunha Exp $
#
# Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
# IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
# OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#
# $Id: GNUmakefile,v 1.114 2009-09-20 18:54:21 nicm Exp $
.PHONY: clean
VERSION= 1.2
VERSION= 1.0
#FDEBUG= 1
CC?= cc
CC?= gcc
CFLAGS+= -DBUILD="\"$(VERSION)\""
LDFLAGS+= -L/usr/local/lib
LIBS+=
# Sun CC
ifneq ($(shell ($(CC) -V 2>&1|awk '/Sun C/' || true)), )
CFLAGS+=-erroff=E_EMPTY_DECLARATION
FDEBUG=
endif
ifdef FDEBUG
CFLAGS+= -g -ggdb -DDEBUG
CFLAGS+= -Wno-long-long -Wall -W -Wnested-externs -Wformat=2
@@ -69,7 +48,7 @@ depend: $(SRCS)
$(CC) $(CPPFLAGS) $(CFLAGS) -MM $(SRCS) > .depend
clean:
rm -f tmux *.o *~ *.core *.log compat/*.o compat/*~
rm -f tmux *.o *~ *.core *.log compat/*.o
clean-depend:
rm -f .depend

View File

@@ -1,24 +1,9 @@
# $Id: Makefile,v 1.155 2010-03-10 15:15:33 tcunha Exp $
#
# Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
# IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
# OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#
# $Id: Makefile,v 1.149 2009-09-20 18:54:21 nicm Exp $
.SUFFIXES: .c .o
.PHONY: clean
VERSION= 1.2
VERSION= 1.0
#FDEBUG= 1
@@ -68,7 +53,7 @@ depend:
mkdep ${CPPFLAGS} ${CFLAGS} ${SRCS:M*.c}
clean:
rm -f tmux *.o *~ *.core *.log compat/*.o compat/*~
rm -f tmux *.o *~ *.core *.log compat/*.o
clean-depend:
rm -f .depend

29
NOTES
View File

@@ -4,15 +4,15 @@ tmux is a "terminal multiplexer", it enables a number of terminals (or windows)
to be accessed and controlled from a single terminal. tmux is intended to be a
simple, modern, BSD-licensed alternative to programs such as GNU screen.
This release runs on OpenBSD, FreeBSD, NetBSD, Linux and OS X and may still
run on Solaris and AIX (although they haven't been tested in a while). It is
This 0.9 release runs on OpenBSD, FreeBSD, NetBSD, Linux and OS X and may still
run on Solaris and AIX (although they hasn't been tested in a while). It is
usable, although there remain a number of missing features and some remaining
bugs are expected.
Since the 1.2 release that tmux depends on libevent. Download the stable
version from:
http://www.monkey.org/~provos/libevent/
If upgrading from 0.5, PLEASE NOTE the following configuration file changes: it
is now required to pass the -g flag to set-option or set-window-option to set
global options; remain-by-default and utf8-default are now gone, use global
window options (set-window-option -g) instead.
tmux consists of a server part and multiple clients. The server is created when
required and runs continuously unless killed by the user. Clients access the
@@ -37,19 +37,22 @@ The following is a summary of major features implemented in this version:
- Support for VT100 line drawing characters.
- A large command set.
- Vertical window splitting and layout.
- Automatic server locking on inactivity by running an external command.
- Automatic server locking on inactivity.
- A configuration file.
- UTF-8 support.
A more extensive, but rough, todo list is included in the TODO file.
tmux also depends on several features of the client terminal (TERM), if these
are missing it may refuse to run, or not behave correctly.
are missing it may refuse to run, or not behave correctly. Known working are
TERM=screen (tmux in screen), xterm, xterm-color and rxvt. Note that TERM=xterm
does not support colour on OpenBSD. screen ignores this, tmux does not: use
xterm-color or rxvt for colour.
tmux supports UTF-8. To use it, the utf8 option must be set on each window;
this may be turned on for all windows by setting it as a global option, see
tmux(1) and the FAQ file. As of 0.9, tmux attempts to autodetect a
UTF-8 capable terminal by checking the LC_ALL, LC_CTYPE and LANG environment
UTF-8-capable terminal by checking the LC_ALL, LC_CTYPE and LANG environment
variables. list-clients may be used to check if this is detected correctly; if
not, the -u command-line flag may be specified.
@@ -78,12 +81,6 @@ welcome. Please send by email to:
nicm@users.sf.net
This file and the CHANGES, FAQ and TODO files are licensed under the ISC
license. Files under examples/ remain copyright their authors unless otherwise
stated in the file but permission has been received to distribute them with
tmux. All other files have a license and copyright notice at their
start. Please contact me with any queries.
-- Nicholas Marriott <nicm@users.sf.net>
$Id: NOTES,v 1.53 2010-03-10 15:18:11 tcunha Exp $
$Id: NOTES,v 1.49 2009-07-06 18:53:24 nicm Exp $

111
TODO
View File

@@ -9,127 +9,98 @@
- garbage collect window history (100 lines at a time?) if it hasn't been used
in $x time (need window creation/use times)
- lift SHRT_MAX limits for history?
- better mode features: search
- flags to centre screen in window
- better terminal emulation
- activity/bell should be per-window not per-link? what if it is cur win in
session not being watched?
- next prev word etc in command prompt
- next prev word etc in command prompt; also ^K
- many more info() displays for various things
- backspace should perhaps wrap backwards over newlines which were not moved
down by a newline: screen and the OS X terminal does this but xterm and most
others do not. this might be hard: a flag for each grid line (top bit of size
maybe)? a single flag is insufficient as can't then tell when to /stop/
unwrapping
- input.c is too complicated. simplify?
- use a better termcap internally instead of screen, perhaps xterm
- kill all but current pane
- fix rxvt cursor fg issue (text under cursor can have non-white fg)
- client sx/sy should be in tty, then can let the terminal wrap at edge
to allow xterm to pick up it should be one line for its c/p
- should be able to move to a hidden pane and it would be moved into view. pane
number in status line/top-right would be cool for this
- support other mouse modes (highlight etc) and use it in copy mode
- set-remain-on-exit is a bit of a hack, some way to do it generically?
- set-option should be set-session-option and should be overall global options
for stuff like mode keys?
also quiet, utf8 and maybe other flags?
-g is a bit unexpected in conf file
- clear window title on exit
- the output code (tty.c) could do with optimisation depending on term
capabilities
capibilities
- would be nice to be able to use "--" to mark start of command w/ neww etc
to avoid quoting
- goto line and search history in copy/scroll modes
- clone session command
- make command sequences more usable: don't require space after ;, handle
errors better
- key to switch to copy mode from scroll mode
- attach should have a flag to create session if it doesn't exist
- rename split-window -> split-pane??
- fix UTF-8 guesswork on sparc64, improve tty checks
- choice and more mode would be better per client than per window?
- hooks to which commands may be attached, for example: tmux add-hook
"new-session" if-shell "[ -e $HOME/.tmux-session.conf ]" source-file
$HOME/.tmux-session.conf
- get it passing all the vttest tests that don't require resizing the terminal
- esc seq to set window name and title should be documented, and name variant
should clear automatic-rename
- esc seq to set window title should be documented and should set
automatic-rename
- way to set socket path from config file
- XXX once env stuff is in, default-path and VISUAL/EDITOR should be picked up
when session is started
- what about utmp etc? can tmux update it like screen? setgid?
- H/M/L commands in copy mode with vi-keys, for jumping to the top/middle/last
line on the screen
- split list-windows into separate list-windows and list-panes
- warts on current naming:
- display-time but message-fg/bg/attr
- list-* vs show-*
- server-info
- up-pane/down-pane/swap-pane -U/swap-pane -D vs next-*/previous-*
- split-window -> split-pane??
- pcvt25 doesn't work properly, why? (bce?)
- tidy up and prioritise todo list ;-)
- it is only possible to specify 8 colours to fg/bg options; should be able to
set 256 as well
- neww and attach can create a session if none exists?
would work fine with config file since
- a way for force-width/height to apply to only one pane (how?)
- **** a command to run something without a window and send any output to the
window-more. if no output, info() a line saying "'%s' returned %d". so i can
bind mpc control commands to function keys ;-)
- command to list what is actually running in each window with command line,
pid (need some adaption of the osdep code)
- string option to change/remove the symbols (*-+ etc) in status line
- support for bce
- it would be nice if the start/end line keys in copy mode were aware of
wrapped lines
- per session locking
- some way to force a screen to use the entire terminal even if it is forced
to be smaller by other clients. pan smaller terminal? (like screen F)
-- idea of a "view" onto a window, need base x/y offsets
for redraw
- a window option which means data is echoed to all panes in a window
- support running tmux from inside tmux [#(), if-shell] --
generic system-like function which may take a callback
also sets up environment (TMUX) and has a timeout
for #(): command schedular, status line queues it with a time, run in
main loop, and uses most recent result -- can also be used for persistent
commands which never exit just continually output
for if-shell, callback??
- handle resize better in copy mode
- way to copy stuff that is off screen due to resize
- fix line wrapping c&p problems in xterm etc
- a way to address panes by name ("top-left") and position ("0,0")
- ability to specify multiple prefix keys
- commands should be able to succeed or fail and have || or && for command
lists
- support the mouse wheel to scroll through history
- some way to KEEP a command running continually and just use its LAST line of
output
- bind commands to mouse buttons
- UTF-8 to a non-UTF-8 terminal should not be able to balls up
the terminal - www/ruby-addressable; make regress
- copy mode needs a tidy/cleanup
- ability to save history (to buffer?)
- multiple keys could be done with tables, ie have prefixes go and instead
bind -n ^A prefix-table "default"
where prefix-table sets command lookup table and sets prefix flag, then next
key is looked up in that table
- UTF-8 should be a pointer into a combined string buffer
- check irssi (term_charset) works with UTF-8
- support esc-esc to quit in modes
- fix ctrl+F1-F4 output. to what?
- look into xterm clearing its selection when scrolling etc
- better utf8 support:
window names
prompt input
message display
copy and paste cursor and wide characters
...?
- option so that when session is destroyed, attach client to another session
rather than exiting
- session history for client and last-session command
- option to change status line colour when current window is in a mode?
- option to move copy mode indicator into status line
- list-buffer/show-buffer should display UTF-8
- selection behaviour closer to vi in vi mode
- live update: server started with -U connects to server, requests sessions and
windows, receives fds
- convert status line history to be server global (anything else?)
- something for -t "last window in session" so a session can be used as a stack
- command to show a tree of sessions-windows-panes (active marked with *)
- sort out inheriting config from shell on new sessions/windows:
should pick up default-path/termios/etc from client if possible,
else leave empty/default
- define custom layouts
- link panes into multiple windows
- -h option to capture-pane to capture the history as well
- bells should be passed between sessions with visual-bell etc
- use screen-256color when started on 256 colour terminal??
- if-shell/run-shell should block further command execution in the same command
sequence until its shell exits, to allow them to be used from the config file
- better session sharing: create-socket command to create socket somewhere (-r
flag for readonly)
- allow buffer to be specified when copying in copy mode
- multiline status line
- flag for absolute pane size to resize-pane
- sanity check input to socket
- stdin fd should be passed up to parent so load-buffer and others could use it
for nonattaching clients
- environment should be set up for jobs
- select-buffer command
- fix jobs so they block in config file rather than executing at an arbitrary
future point -- need state stored in client so other clients can proceed
- rectangle copy:
when selecting leftward, cursor should be inside block per emacs
key to rotate corner at which cursor is
- double C-a should walk back over wrapped lines like C-e
- support title stack, both internally and externally
http://docs.freebsd.org/cgi/getmsg.cgi?fetch=1149299+0+archive/2010/freebsd-questions/20100207.freebsd-questions
- copy buffers should be global, limit can be server option, nuke copy-buffer
command
- command to show status line information briefly when it is off

View File

@@ -1,4 +1,4 @@
/* $Id: array.h,v 1.10 2010-02-08 18:29:32 tcunha Exp $ */
/* $Id: array.h,v 1.7 2008-09-29 16:58:02 nicm Exp $ */
/*
* Copyright (c) 2006 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -19,8 +19,6 @@
#ifndef ARRAY_H
#define ARRAY_H
#define ARRAY_INITIALIZER { NULL, 0, 0 }
#define ARRAY_DECL(n, c) \
struct n { \
c *list; \
@@ -87,7 +85,7 @@
ARRAY_ITEMSIZE(a) * ((a)->num - (i) - 1)); \
} \
(a)->num--; \
if ((a)->num == 0) \
if ((a)->num == 0) \
ARRAY_FREE(a); \
} while (0)
@@ -104,7 +102,7 @@
#define ARRAY_CONCAT(a, b) do { \
ARRAY_ENSURE(a, (b)->num); \
memcpy((a)->list + (a)->num, (b)->list, (b)->num * ARRAY_ITEMSIZE(a)); \
memcpy((a)->list + (a)->num, (b)->list, (b)->num * ARRAY_ITEMSIZE(a)) \
(a)->num += (b)->num; \
} while (0)

View File

@@ -1,4 +1,4 @@
/* $Id: attributes.c,v 1.3 2009-11-28 14:46:23 tcunha Exp $ */
/* $Id: attributes.c,v 1.2 2009-06-25 15:25:45 nicm Exp $ */
/*
* Copyright (c) 2009 Joshua Elsasser <josh@elsasser.org>
@@ -23,29 +23,29 @@
#include "tmux.h"
const char *
attributes_tostring(u_char attr)
attributes_tostring(u_char ch)
{
static char buf[128];
if (attr == 0)
if (ch == 0)
return ("default");
buf[0] = '\0';
if (attr & GRID_ATTR_BRIGHT)
if (ch & GRID_ATTR_BRIGHT)
strlcat(buf, "bright,", sizeof (buf));
if (attr & GRID_ATTR_DIM)
if (ch & GRID_ATTR_DIM)
strlcat(buf, "dim,", sizeof (buf));
if (attr & GRID_ATTR_UNDERSCORE)
if (ch & GRID_ATTR_UNDERSCORE)
strlcat(buf, "underscore,", sizeof (buf));
if (attr & GRID_ATTR_BLINK)
if (ch & GRID_ATTR_BLINK)
strlcat(buf, "blink,", sizeof (buf));
if (attr & GRID_ATTR_REVERSE)
if (ch & GRID_ATTR_REVERSE)
strlcat(buf, "reverse,", sizeof (buf));
if (attr & GRID_ATTR_HIDDEN)
if (ch & GRID_ATTR_HIDDEN)
strlcat(buf, "hidden,", sizeof (buf));
if (attr & GRID_ATTR_ITALICS)
if (ch & GRID_ATTR_ITALICS)
strlcat(buf, "italics,", sizeof (buf));
if (*buf != '\0')
if (*buf)
*(strrchr(buf, ',')) = '\0';
return (buf);
@@ -55,7 +55,7 @@ int
attributes_fromstring(const char *str)
{
const char delimiters[] = " ,|";
u_char attr;
u_char ch;
size_t end;
if (*str == '\0' || strcspn(str, delimiters) == 0)
@@ -66,28 +66,28 @@ attributes_fromstring(const char *str)
if (strcasecmp(str, "default") == 0)
return (0);
attr = 0;
ch = 0;
do {
end = strcspn(str, delimiters);
if ((end == 6 && strncasecmp(str, "bright", end) == 0) ||
(end == 4 && strncasecmp(str, "bold", end) == 0))
attr |= GRID_ATTR_BRIGHT;
ch |= GRID_ATTR_BRIGHT;
else if (end == 3 && strncasecmp(str, "dim", end) == 0)
attr |= GRID_ATTR_DIM;
ch |= GRID_ATTR_DIM;
else if (end == 10 && strncasecmp(str, "underscore", end) == 0)
attr |= GRID_ATTR_UNDERSCORE;
ch |= GRID_ATTR_UNDERSCORE;
else if (end == 5 && strncasecmp(str, "blink", end) == 0)
attr |= GRID_ATTR_BLINK;
ch |= GRID_ATTR_BLINK;
else if (end == 7 && strncasecmp(str, "reverse", end) == 0)
attr |= GRID_ATTR_REVERSE;
ch |= GRID_ATTR_REVERSE;
else if (end == 6 && strncasecmp(str, "hidden", end) == 0)
attr |= GRID_ATTR_HIDDEN;
ch |= GRID_ATTR_HIDDEN;
else if (end == 7 && strncasecmp(str, "italics", end) == 0)
attr |= GRID_ATTR_ITALICS;
ch |= GRID_ATTR_ITALICS;
else
return (-1);
str += end + strspn(str + end, delimiters);
} while (*str != '\0');
return (attr);
return (ch);
}

View File

@@ -1,7 +1,7 @@
/* $Id: cmd-lock-client.c,v 1.2 2009-11-14 17:56:39 tcunha Exp $ */
/* $Id: buffer-poll.c,v 1.16 2009-08-19 09:28:10 nicm Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -18,36 +18,37 @@
#include <sys/types.h>
#include <errno.h>
#include <unistd.h>
#include "tmux.h"
/*
* Lock a single client.
*/
int cmd_lock_client_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_lock_client_entry = {
"lock-client", "lockc",
CMD_TARGET_CLIENT_USAGE,
0, "",
cmd_target_init,
cmd_target_parse,
cmd_lock_client_exec,
cmd_target_free,
cmd_target_print
};
/* Fill buffers from socket based on poll results. */
int
cmd_lock_client_exec(struct cmd *self, struct cmd_ctx *ctx)
buffer_poll(struct pollfd *pfd, struct buffer *in, struct buffer *out)
{
struct cmd_target_data *data = self->data;
struct client *c;
ssize_t n;
if ((c = cmd_find_client(ctx, data->target)) == NULL)
if (pfd->revents & (POLLERR|POLLNVAL|POLLHUP))
return (-1);
server_lock_client(c);
recalculate_sizes();
if (pfd->revents & POLLIN) {
buffer_ensure(in, BUFSIZ);
n = read(pfd->fd, BUFFER_IN(in), BUFFER_FREE(in));
if (n == 0)
return (-1);
if (n == -1) {
if (errno != EINTR && errno != EAGAIN)
return (-1);
} else
buffer_add(in, n);
}
if (BUFFER_USED(out) > 0 && pfd->revents & POLLOUT) {
n = write(pfd->fd, BUFFER_OUT(out), BUFFER_USED(out));
if (n == -1) {
if (errno != EINTR && errno != EAGAIN)
return (-1);
} else
buffer_remove(out, n);
}
return (0);
}

139
buffer.c Normal file
View File

@@ -0,0 +1,139 @@
/* $Id: buffer.c,v 1.8 2009-08-21 21:09:13 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <sys/types.h>
#include <string.h>
#include "tmux.h"
/* Create a buffer. */
struct buffer *
buffer_create(size_t size)
{
struct buffer *b;
if (size == 0)
fatalx("zero size");
b = xcalloc(1, sizeof *b);
b->base = xmalloc(size);
b->space = size;
return (b);
}
/* Destroy a buffer. */
void
buffer_destroy(struct buffer *b)
{
xfree(b->base);
xfree(b);
}
/* Ensure free space for size in buffer. */
void
buffer_ensure(struct buffer *b, size_t size)
{
if (size == 0)
fatalx("zero size");
if (BUFFER_FREE(b) >= size)
return;
if (b->off > 0) {
if (b->size > 0)
memmove(b->base, b->base + b->off, b->size);
b->off = 0;
}
if (SIZE_MAX - b->size < size)
fatalx("size too big");
while (b->space < b->size + size) {
b->base = xrealloc(b->base, 2, b->space);
b->space *= 2;
}
}
/* Adjust buffer after data appended. */
void
buffer_add(struct buffer *b, size_t size)
{
if (size == 0)
fatalx("zero size");
if (size > b->space - b->size)
fatalx("overflow");
b->size += size;
}
/* Adjust buffer after data removed. */
void
buffer_remove(struct buffer *b, size_t size)
{
if (size == 0)
fatalx("zero size");
if (size > b->size)
fatalx("underflow");
b->size -= size;
b->off += size;
}
/* Copy data into a buffer. */
void
buffer_write(struct buffer *b, const void *data, size_t size)
{
buffer_ensure(b, size);
memcpy(BUFFER_IN(b), data, size);
buffer_add(b, size);
}
/* Copy data out of a buffer. */
void
buffer_read(struct buffer *b, void *data, size_t size)
{
if (size == 0)
fatalx("zero size");
if (size > b->size)
fatalx("underflow");
memcpy(data, BUFFER_OUT(b), size);
buffer_remove(b, size);
}
/* Store an 8-bit value. */
void
buffer_write8(struct buffer *b, uint8_t n)
{
buffer_ensure(b, 1);
BUFFER_IN(b)[0] = n;
b->size++;
}
/* Extract an 8-bit value. */
uint8_t
buffer_read8(struct buffer *b)
{
uint8_t n;
n = BUFFER_OUT(b)[0];
buffer_remove(b, 1);
return (n);
}

60
cfg.c
View File

@@ -1,4 +1,4 @@
/* $Id: cfg.c,v 1.26 2010-02-08 18:29:32 tcunha Exp $ */
/* $Id: cfg.c,v 1.22 2009-08-24 16:27:03 tcunha Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -33,17 +33,13 @@
void printflike2 cfg_print(struct cmd_ctx *, const char *, ...);
void printflike2 cfg_error(struct cmd_ctx *, const char *, ...);
char *cfg_cause;
int cfg_finished;
struct causelist cfg_causes = ARRAY_INITIALIZER;
char *cfg_cause;
/* ARGSUSED */
void printflike2
cfg_print(unused struct cmd_ctx *ctx, unused const char *fmt, ...)
{
}
/* ARGSUSED */
void printflike2
cfg_error(unused struct cmd_ctx *ctx, const char *fmt, ...)
{
@@ -54,36 +50,19 @@ cfg_error(unused struct cmd_ctx *ctx, const char *fmt, ...)
va_end(ap);
}
void printflike2
cfg_add_cause(struct causelist *causes, const char *fmt, ...)
{
char *cause;
va_list ap;
va_start(ap, fmt);
xvasprintf(&cause, fmt, ap);
va_end(ap);
ARRAY_ADD(causes, cause);
}
/*
* Load configuration file. Returns -1 for an error with a list of messages in
* causes. Note that causes and ncauses must be initialised by the caller!
*/
int
load_cfg(const char *path, struct cmd_ctx *ctxin, struct causelist *causes)
load_cfg(const char *path, struct cmd_ctx *ctxin, char **cause)
{
FILE *f;
FILE *f;
u_int n;
char *buf, *line, *cause;
char *buf, *line, *ptr;
size_t len;
struct cmd_list *cmdlist;
struct cmd_ctx ctx;
if ((f = fopen(path, "rb")) == NULL) {
cfg_add_cause(causes, "%s: %s", path, strerror(errno));
return (-1);
xasprintf(cause, "%s: %s", path, strerror(errno));
return (1);
}
n = 0;
@@ -99,12 +78,10 @@ load_cfg(const char *path, struct cmd_ctx *ctxin, struct causelist *causes)
}
n++;
if (cmd_string_parse(buf, &cmdlist, &cause) != 0) {
if (cause == NULL)
if (cmd_string_parse(buf, &cmdlist, cause) != 0) {
if (*cause == NULL)
continue;
cfg_add_cause(causes, "%s: %u: %s", path, n, cause);
xfree(cause);
continue;
goto error;
}
if (cmdlist == NULL)
continue;
@@ -128,16 +105,23 @@ load_cfg(const char *path, struct cmd_ctx *ctxin, struct causelist *causes)
cmd_list_exec(cmdlist, &ctx);
cmd_list_free(cmdlist);
if (cfg_cause != NULL) {
cfg_add_cause(causes, "%s: %d: %s", path, n, cfg_cause);
xfree(cfg_cause);
continue;
*cause = cfg_cause;
goto error;
}
}
if (line != NULL)
xfree(line);
fclose(f);
if (ARRAY_LENGTH(causes) != 0)
return (-1);
return (0);
error:
if (line != NULL)
xfree(line);
fclose(f);
xasprintf(&ptr, "%s: %s at line %u", path, *cause, n);
xfree(*cause);
*cause = ptr;
return (1);
}

90
client-fn.c Normal file
View File

@@ -0,0 +1,90 @@
/* $Id: client-fn.c,v 1.10 2009-08-14 21:04:04 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <sys/types.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "tmux.h"
void
client_fill_session(struct msg_command_data *data)
{
char *env, *ptr1, *ptr2, buf[256];
size_t len;
const char *errstr;
long long ll;
data->pid = -1;
if ((env = getenv("TMUX")) == NULL)
return;
if ((ptr2 = strrchr(env, ',')) == NULL || ptr2 == env)
return;
for (ptr1 = ptr2 - 1; ptr1 > env && *ptr1 != ','; ptr1--)
;
if (*ptr1 != ',')
return;
ptr1++;
ptr2++;
len = ptr2 - ptr1 - 1;
if (len > (sizeof buf) - 1)
return;
memcpy(buf, ptr1, len);
buf[len] = '\0';
ll = strtonum(buf, 0, LONG_MAX, &errstr);
if (errstr != NULL)
return;
data->pid = ll;
ll = strtonum(ptr2, 0, UINT_MAX, &errstr);
if (errstr != NULL)
return;
data->idx = ll;
}
void
client_write_server(
struct client_ctx *cctx, enum msgtype type, void *buf, size_t len)
{
imsg_compose(&cctx->ibuf, type, PROTOCOL_VERSION, -1, -1, buf, len);
}
void
client_suspend(void)
{
struct sigaction act;
memset(&act, 0, sizeof act);
sigemptyset(&act.sa_mask);
act.sa_flags = SA_RESTART;
act.sa_handler = SIG_DFL;
if (sigaction(SIGTSTP, &act, NULL) != 0)
fatal("sigaction failed");
act.sa_handler = sighandler;
if (sigaction(SIGCONT, &act, NULL) != 0)
fatal("sigaction failed");
kill(getpid(), SIGTSTP);
}

425
client.c
View File

@@ -1,4 +1,4 @@
/* $Id: client.c,v 1.90 2009-12-04 22:14:47 tcunha Exp $ */
/* $Id: client.c,v 1.70 2009-09-03 21:06:30 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -24,7 +24,6 @@
#include <sys/wait.h>
#include <errno.h>
#include <event.h>
#include <fcntl.h>
#include <pwd.h>
#include <stdlib.h>
@@ -34,27 +33,21 @@
#include "tmux.h"
struct imsgbuf client_ibuf;
struct event client_event;
const char *client_exitmsg;
int client_exitval;
void client_send_environ(struct client_ctx *);
void client_handle_winch(struct client_ctx *);
void client_send_identify(int);
void client_send_environ(void);
void client_write_server(enum msgtype, void *, size_t);
void client_update_event(void);
void client_signal(int, short, void *);
void client_callback(int, short, void *);
int client_dispatch(void);
struct imsgbuf *
client_init(char *path, int cmdflags, int flags)
int
client_init(char *path, struct client_ctx *cctx, int cmdflags, int flags)
{
struct sockaddr_un sa;
size_t size;
int fd, mode;
struct sockaddr_un sa;
struct stat sb;
struct msg_identify_data data;
struct winsize ws;
size_t size;
int fd, fd2, mode;
char *name, *term;
#ifdef HAVE_SETPROCTITLE
char rpathbuf[MAXPATHLEN];
char rpathbuf[MAXPATHLEN];
#endif
#ifdef HAVE_SETPROCTITLE
@@ -63,6 +56,19 @@ client_init(char *path, int cmdflags, int flags)
setproctitle("client (%s)", rpathbuf);
#endif
if (lstat(path, &sb) != 0) {
if (cmdflags & CMD_STARTSERVER && errno == ENOENT) {
if ((fd = server_start(path)) == -1)
goto start_failed;
goto server_started;
}
goto not_found;
}
if (!S_ISSOCK(sb.st_mode)) {
errno = ENOTSOCK;
goto not_found;
}
memset(&sa, 0, sizeof sa);
sa.sun_family = AF_UNIX;
size = strlcpy(sa.sun_path, path, sizeof sa.sun_path);
@@ -72,17 +78,12 @@ client_init(char *path, int cmdflags, int flags)
}
if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
fatal("socket failed");
fatal("socket");
if (connect(fd, (struct sockaddr *) &sa, SUN_LEN(&sa)) == -1) {
if (!(cmdflags & CMD_STARTSERVER))
goto not_found;
switch (errno) {
case ECONNREFUSED:
if (unlink(path) != 0)
if (errno == ECONNREFUSED) {
if (unlink(path) != 0 || !(cmdflags & CMD_STARTSERVER))
goto not_found;
/* FALLTHROUGH */
case ENOENT:
if ((fd = server_start(path)) == -1)
goto start_failed;
goto server_started;
@@ -95,225 +96,211 @@ server_started:
fatal("fcntl failed");
if (fcntl(fd, F_SETFL, mode|O_NONBLOCK) == -1)
fatal("fcntl failed");
if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1)
fatal("fcntl failed");
imsg_init(&client_ibuf, fd);
imsg_init(&cctx->ibuf, fd);
if (cmdflags & CMD_SENDENVIRON)
client_send_environ();
if (isatty(STDIN_FILENO))
client_send_identify(flags);
client_send_environ(cctx);
if (isatty(STDIN_FILENO)) {
if (ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) == -1)
fatal("ioctl(TIOCGWINSZ)");
data.flags = flags;
data.sx = ws.ws_col;
data.sy = ws.ws_row;
return (&client_ibuf);
if (getcwd(data.cwd, sizeof data.cwd) == NULL)
*data.cwd = '\0';
*data.term = '\0';
if ((term = getenv("TERM")) != NULL) {
if (strlcpy(data.term,
term, sizeof data.term) >= sizeof data.term)
*data.term = '\0';
}
*data.tty = '\0';
if ((name = ttyname(STDIN_FILENO)) == NULL)
fatal("ttyname failed");
if (strlcpy(data.tty, name, sizeof data.tty) >= sizeof data.tty)
fatalx("ttyname failed");
fd2 = dup(STDIN_FILENO);
imsg_compose(&cctx->ibuf, MSG_IDENTIFY,
PROTOCOL_VERSION, -1, fd2, &data, sizeof data);
}
return (0);
start_failed:
log_warnx("server failed to start");
return (NULL);
return (1);
not_found:
log_warn("server not found");
return (NULL);
return (1);
}
void
client_send_identify(int flags)
client_send_environ(struct client_ctx *cctx)
{
struct msg_identify_data data;
struct winsize ws;
char *term;
int fd;
if (ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) == -1)
fatal("ioctl(TIOCGWINSZ)");
data.flags = flags;
if (getcwd(data.cwd, sizeof data.cwd) == NULL)
*data.cwd = '\0';
term = getenv("TERM");
if (term == NULL ||
strlcpy(data.term, term, sizeof data.term) >= sizeof data.term)
*data.term = '\0';
if ((fd = dup(STDIN_FILENO)) == -1)
fatal("dup failed");
imsg_compose(&client_ibuf,
MSG_IDENTIFY, PROTOCOL_VERSION, -1, fd, &data, sizeof data);
}
void
client_send_environ(void)
{
struct msg_environ_data data;
char **var;
struct msg_environ_data data;
for (var = environ; *var != NULL; 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);
client_write_server(cctx, MSG_ENVIRON, &data, sizeof data);
}
}
void
client_write_server(enum msgtype type, void *buf, size_t len)
{
imsg_compose(&client_ibuf, type, PROTOCOL_VERSION, -1, -1, buf, len);
}
void
client_update_event(void)
{
short events;
event_del(&client_event);
events = EV_READ;
if (client_ibuf.w.queued > 0)
events |= EV_WRITE;
event_set(&client_event, client_ibuf.fd, events, client_callback, NULL);
event_add(&client_event, NULL);
}
__dead void
client_main(void)
{
struct event ev_sigcont, ev_sigterm, ev_sigwinch;
struct sigaction sigact;
logfile("client");
/* Note: event_init() has already been called. */
/* Set up signals. */
memset(&sigact, 0, sizeof sigact);
sigemptyset(&sigact.sa_mask);
sigact.sa_flags = SA_RESTART;
sigact.sa_handler = SIG_IGN;
if (sigaction(SIGINT, &sigact, NULL) != 0)
fatal("sigaction failed");
if (sigaction(SIGPIPE, &sigact, NULL) != 0)
fatal("sigaction failed");
if (sigaction(SIGUSR1, &sigact, NULL) != 0)
fatal("sigaction failed");
if (sigaction(SIGUSR2, &sigact, NULL) != 0)
fatal("sigaction failed");
if (sigaction(SIGTSTP, &sigact, NULL) != 0)
fatal("sigaction failed");
signal_set(&ev_sigcont, SIGCONT, client_signal, NULL);
signal_add(&ev_sigcont, NULL);
signal_set(&ev_sigterm, SIGTERM, client_signal, NULL);
signal_add(&ev_sigterm, NULL);
signal_set(&ev_sigwinch, SIGWINCH, client_signal, NULL);
signal_add(&ev_sigwinch, NULL);
/*
* imsg_read in the first client poll loop (before the terminal has
* been initialised) may have read messages into the buffer after the
* MSG_READY switched to here. Process anything outstanding now to
* avoid hanging waiting for messages that have already arrived.
*/
if (client_dispatch() != 0)
goto out;
/* Set the event and dispatch. */
client_update_event();
event_dispatch();
out:
/* Print the exit message, if any, and exit. */
if (client_exitmsg != NULL && !login_shell)
printf("[%s]\n", client_exitmsg);
exit(client_exitval);
}
/* ARGSUSED */
void
client_signal(int sig, unused short events, unused void *data)
{
struct sigaction sigact;
switch (sig) {
case SIGTERM:
client_exitmsg = "terminated";
client_exitval = 1;
client_write_server(MSG_EXITING, NULL, 0);
break;
case SIGWINCH:
client_write_server(MSG_RESIZE, NULL, 0);
break;
case SIGCONT:
memset(&sigact, 0, sizeof sigact);
sigemptyset(&sigact.sa_mask);
sigact.sa_flags = SA_RESTART;
sigact.sa_handler = SIG_IGN;
if (sigaction(SIGTSTP, &sigact, NULL) != 0)
fatal("sigaction failed");
client_write_server(MSG_WAKEUP, NULL, 0);
break;
}
client_update_event();
}
/* ARGSUSED */
void
client_callback(unused int fd, short events, unused void *data)
{
ssize_t n;
if (events & EV_READ) {
if ((n = imsg_read(&client_ibuf)) == -1 || n == 0)
goto lost_server;
if (client_dispatch() != 0) {
event_loopexit(NULL);
return;
}
}
if (events & EV_WRITE) {
if (msgbuf_write(&client_ibuf.w) < 0)
goto lost_server;
}
client_update_event();
return;
lost_server:
client_exitmsg = "lost server";
client_exitval = 1;
event_loopexit(NULL);
}
int
client_dispatch(void)
client_main(struct client_ctx *cctx)
{
struct imsg imsg;
struct msg_lock_data lockdata;
struct sigaction sigact;
ssize_t n, datalen;
struct pollfd pfd;
int n, nfds;
siginit();
logfile("client");
/*
* imsg_read in the first client poll loop (before the terminal has
* been initialiased) may have read messages into the buffer after the
* MSG_READY switched to here. Process anything outstanding now so poll
* doesn't hang waiting for messages that have already arrived.
*/
if (client_msg_dispatch(cctx) != 0)
goto out;
for (;;) {
if ((n = imsg_get(&client_ibuf, &imsg)) == -1)
if (sigterm)
client_write_server(cctx, MSG_EXITING, NULL, 0);
if (sigchld) {
waitpid(WAIT_ANY, NULL, WNOHANG);
sigchld = 0;
}
if (sigwinch)
client_handle_winch(cctx);
if (sigcont) {
siginit();
client_write_server(cctx, MSG_WAKEUP, NULL, 0);
sigcont = 0;
}
pfd.fd = cctx->ibuf.fd;
pfd.events = POLLIN;
if (cctx->ibuf.w.queued > 0)
pfd.events |= POLLOUT;
if ((nfds = poll(&pfd, 1, INFTIM)) == -1) {
if (errno == EAGAIN || errno == EINTR)
continue;
fatal("poll failed");
}
if (nfds == 0)
continue;
if (pfd.revents & (POLLERR|POLLHUP|POLLNVAL))
fatalx("socket error");
if (pfd.revents & POLLIN) {
if ((n = imsg_read(&cctx->ibuf)) == -1 || n == 0) {
cctx->exittype = CCTX_DIED;
break;
}
if (client_msg_dispatch(cctx) != 0)
break;
}
if (pfd.revents & POLLOUT) {
if (msgbuf_write(&cctx->ibuf.w) < 0) {
cctx->exittype = CCTX_DIED;
break;
}
}
}
out:
if (sigterm) {
printf("[terminated]\n");
return (1);
}
switch (cctx->exittype) {
case CCTX_DIED:
printf("[lost server]\n");
return (0);
case CCTX_SHUTDOWN:
printf("[server exited]\n");
return (0);
case CCTX_EXIT:
if (cctx->errstr != NULL) {
printf("[error: %s]\n", cctx->errstr);
return (1);
}
printf("[exited]\n");
return (0);
case CCTX_DETACH:
printf("[detached]\n");
return (0);
default:
printf("[unknown error]\n");
return (1);
}
}
void
client_handle_winch(struct client_ctx *cctx)
{
struct msg_resize_data data;
struct winsize ws;
if (ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) == -1)
fatal("ioctl failed");
data.sx = ws.ws_col;
data.sy = ws.ws_row;
client_write_server(cctx, MSG_RESIZE, &data, sizeof data);
sigwinch = 0;
}
int
client_msg_dispatch(struct client_ctx *cctx)
{
struct imsg imsg;
struct msg_print_data printdata;
ssize_t n, datalen;
for (;;) {
if ((n = imsg_get(&cctx->ibuf, &imsg)) == -1)
fatalx("imsg_get failed");
if (n == 0)
return (0);
datalen = imsg.hdr.len - IMSG_HEADER_SIZE;
log_debug("client got %d", imsg.hdr.type);
switch (imsg.hdr.type) {
case MSG_DETACH:
if (datalen != 0)
fatalx("bad MSG_DETACH size");
client_write_server(MSG_EXITING, NULL, 0);
client_exitmsg = "detached";
client_write_server(cctx, MSG_EXITING, NULL, 0);
cctx->exittype = CCTX_DETACH;
break;
case MSG_ERROR:
if (datalen != sizeof printdata)
fatalx("bad MSG_ERROR size");
memcpy(&printdata, imsg.data, sizeof printdata);
printdata.msg[(sizeof printdata.msg) - 1] = '\0';
/* Error string used after exit message from server. */
cctx->errstr = xstrdup(printdata.msg);
imsg_free(&imsg);
return (-1);
case MSG_EXIT:
if (datalen != 0)
fatalx("bad MSG_EXIT size");
client_write_server(MSG_EXITING, NULL, 0);
client_exitmsg = "exited";
client_write_server(cctx, MSG_EXITING, NULL, 0);
cctx->exittype = CCTX_EXIT;
break;
case MSG_EXITED:
if (datalen != 0)
@@ -325,30 +312,14 @@ client_dispatch(void)
if (datalen != 0)
fatalx("bad MSG_SHUTDOWN size");
client_write_server(MSG_EXITING, NULL, 0);
client_exitmsg = "server exited";
client_exitval = 1;
client_write_server(cctx, MSG_EXITING, NULL, 0);
cctx->exittype = CCTX_SHUTDOWN;
break;
case MSG_SUSPEND:
if (datalen != 0)
fatalx("bad MSG_SUSPEND size");
memset(&sigact, 0, sizeof sigact);
sigemptyset(&sigact.sa_mask);
sigact.sa_flags = SA_RESTART;
sigact.sa_handler = SIG_DFL;
if (sigaction(SIGTSTP, &sigact, NULL) != 0)
fatal("sigaction failed");
kill(getpid(), SIGTSTP);
break;
case MSG_LOCK:
if (datalen != sizeof lockdata)
fatalx("bad MSG_LOCK size");
memcpy(&lockdata, imsg.data, sizeof lockdata);
lockdata.cmd[(sizeof lockdata.cmd) - 1] = '\0';
system(lockdata.cmd);
client_write_server(MSG_UNLOCK, NULL, 0);
client_suspend();
break;
default:
fatalx("unexpected message");

12
clock.c
View File

@@ -1,4 +1,4 @@
/* $Id: clock.c,v 1.9 2009-12-04 22:14:47 tcunha Exp $ */
/* $Id: clock.c,v 1.7 2009-09-11 14:13:52 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -97,7 +97,7 @@ const char clock_table[14][5][5] = {
};
void
clock_draw(struct screen_write_ctx *ctx, int colour, int style)
clock_draw(struct screen_write_ctx *ctx, u_int colour, int style)
{
struct screen *s = ctx->s;
struct grid_cell gc;
@@ -134,13 +134,13 @@ clock_draw(struct screen_write_ctx *ctx, int colour, int style)
for (ptr = tim; *ptr != '\0'; ptr++) {
if (*ptr >= '0' && *ptr <= '9')
idx = *ptr - '0';
else if (*ptr == ':')
else if (*ptr == ':')
idx = 10;
else if (*ptr == 'A')
else if (*ptr == 'A')
idx = 11;
else if (*ptr == 'P')
else if (*ptr == 'P')
idx = 12;
else if (*ptr == 'M')
else if (*ptr == 'M')
idx = 13;
else {
x += 6;

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-attach-session.c,v 1.36 2010-02-08 18:27:34 tcunha Exp $ */
/* $Id: cmd-attach-session.c,v 1.32 2009-08-09 17:48:55 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -28,8 +28,8 @@ int cmd_attach_session_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_attach_session_entry = {
"attach-session", "attach",
"[-dr] " CMD_TARGET_SESSION_USAGE,
CMD_CANTNEST|CMD_STARTSERVER|CMD_SENDENVIRON, "dr",
"[-d] " CMD_TARGET_SESSION_USAGE,
CMD_CANTNEST|CMD_STARTSERVER|CMD_SENDENVIRON, CMD_CHFLAG('d'),
cmd_target_init,
cmd_target_parse,
cmd_attach_session_exec,
@@ -58,8 +58,8 @@ cmd_attach_session_exec(struct cmd *self, struct cmd_ctx *ctx)
return (0);
if (ctx->cmdclient == NULL) {
if (cmd_check_flag(data->chflags, 'd')) {
/*
if (data->chflags & CMD_CHFLAG('d')) {
/*
* Can't use server_write_session in case attaching to
* the same session as currently attached to.
*/
@@ -72,7 +72,7 @@ cmd_attach_session_exec(struct cmd *self, struct cmd_ctx *ctx)
server_write_client(c, MSG_DETACH, NULL, 0);
}
}
ctx->curclient->session = s;
server_redraw_client(ctx->curclient);
} else {
@@ -89,10 +89,7 @@ cmd_attach_session_exec(struct cmd *self, struct cmd_ctx *ctx)
return (-1);
}
if (cmd_check_flag(data->chflags, 'r'))
ctx->cmdclient->flags |= CLIENT_READONLY;
if (cmd_check_flag(data->chflags, 'd'))
if (data->chflags & CMD_CHFLAG('d'))
server_write_session(s, MSG_DETACH, NULL, 0);
ctx->cmdclient->session = s;
@@ -104,7 +101,6 @@ cmd_attach_session_exec(struct cmd *self, struct cmd_ctx *ctx)
server_redraw_client(ctx->cmdclient);
}
recalculate_sizes();
server_update_socket();
return (1); /* 1 means don't tell command client to exit */
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-bind-key.c,v 1.28 2010-01-25 17:12:44 tcunha Exp $ */
/* $Id: cmd-bind-key.c,v 1.25 2009-07-28 23:19:06 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -46,7 +46,7 @@ struct cmd_bind_key_data {
const struct cmd_entry cmd_bind_key_entry = {
"bind-key", "bind",
"[-cnr] [-t key-table] key command [arguments]",
0, "",
0, 0,
NULL,
cmd_bind_key_parse,
cmd_bind_key_exec,
@@ -79,8 +79,7 @@ cmd_bind_key_parse(struct cmd *self, int argc, char **argv, char **cause)
data->can_repeat = 1;
break;
case 't':
if (data->tablename == NULL)
data->tablename = xstrdup(optarg);
data->tablename = xstrdup(optarg);
break;
default:
goto usage;
@@ -153,7 +152,7 @@ cmd_bind_key_table(struct cmd *self, struct cmd_ctx *ctx)
ctx->error(ctx, "unknown command: %s", data->modecmd);
return (-1);
}
mtmp.key = data->key & ~KEYC_PREFIX;
mtmp.mode = data->command_key ? 1 : 0;
if ((mbind = SPLAY_FIND(mode_key_tree, mtab->tree, &mtmp)) != NULL) {

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-break-pane.c,v 1.11 2009-12-04 22:14:47 tcunha Exp $ */
/* $Id: cmd-break-pane.c,v 1.8 2009-08-16 19:16:27 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -31,7 +31,7 @@ int cmd_break_pane_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_break_pane_entry = {
"break-pane", "breakp",
CMD_TARGET_PANE_USAGE " [-d]",
0, "d",
0, CMD_CHFLAG('d'),
cmd_target_init,
cmd_target_parse,
cmd_break_pane_exec,
@@ -64,21 +64,20 @@ cmd_break_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
if (wl->window->active == NULL)
wl->window->active = TAILQ_NEXT(wp, entry);
}
layout_close_pane(wp);
layout_close_pane(wp);
w = wp->window = window_create1(s->sx, s->sy);
TAILQ_INSERT_HEAD(&w->panes, wp, entry);
w->active = wp;
w->name = default_window_name(w);
w = wp->window = window_create1(s->sx, s->sy);
TAILQ_INSERT_HEAD(&w->panes, wp, entry);
w->active = wp;
w->name = default_window_name(w);
layout_init(w);
base_idx = options_get_number(&s->options, "base-index");
wl = session_attach(s, w, -1 - base_idx, &cause); /* can't fail */
if (!cmd_check_flag(data->chflags, 'd'))
session_select(s, wl->idx);
wl = session_attach(s, w, -1 - base_idx, &cause); /* can't fail */
if (!(data->chflags & CMD_CHFLAG('d')))
session_select(s, wl->idx);
server_redraw_session(s);
server_status_session_group(s);
return (0);
}

View File

@@ -1,83 +0,0 @@
/* $Id: cmd-capture-pane.c,v 1.3 2010-01-22 17:29:19 tcunha Exp $ */
/*
* Copyright (c) 2009 Jonathan Alvarado <radobobo@users.sourceforge.net>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <sys/types.h>
#include <string.h>
#include "tmux.h"
/*
* Write the entire contents of a pane to a buffer.
*/
int cmd_capture_pane_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_capture_pane_entry = {
"capture-pane", "capturep",
CMD_BUFFER_PANE_USAGE,
0, "",
cmd_buffer_init,
cmd_buffer_parse,
cmd_capture_pane_exec,
cmd_buffer_free,
cmd_buffer_print
};
int
cmd_capture_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_buffer_data *data = self->data;
struct window_pane *wp;
char *buf, *line;
struct screen *s;
struct session *sess;
u_int i, limit;
size_t len, linelen;
if (cmd_find_pane(ctx, data->target, &sess, &wp) == NULL)
return (-1);
s = &wp->base;
buf = NULL;
len = 0;
for (i = 0; i < screen_size_y(s); i++) {
line = grid_view_string_cells(s->grid, 0, i, screen_size_x(s));
linelen = strlen(line);
buf = xrealloc(buf, 1, len + linelen + 1);
memcpy(buf + len, line, linelen);
len += linelen;
buf[len++] = '\n';
xfree(line);
}
limit = options_get_number(&sess->options, "buffer-limit");
if (data->buffer == -1) {
paste_add(&sess->buffers, buf, len, limit);
return (0);
}
if (paste_replace(&sess->buffers, data->buffer, buf, len) != 0) {
ctx->error(ctx, "no buffer %d", data->buffer);
xfree(buf);
return (-1);
}
return (0);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-choose-client.c,v 1.4 2009-11-14 17:56:39 tcunha Exp $ */
/* $Id: cmd-choose-client.c,v 1.3 2009-09-07 23:59:19 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -34,7 +34,7 @@ void cmd_choose_client_free(void *);
const struct cmd_entry cmd_choose_client_entry = {
"choose-client", NULL,
CMD_TARGET_WINDOW_USAGE " [template]",
CMD_ARG01, "",
CMD_ARG01, 0,
cmd_target_init,
cmd_target_parse,
cmd_choose_client_exec,

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-choose-session.c,v 1.15 2009-11-14 17:56:39 tcunha Exp $ */
/* $Id: cmd-choose-session.c,v 1.13 2009-09-07 23:59:19 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -34,7 +34,7 @@ void cmd_choose_session_free(void *);
const struct cmd_entry cmd_choose_session_entry = {
"choose-session", NULL,
CMD_TARGET_WINDOW_USAGE " [template]",
CMD_ARG01, "",
CMD_ARG01, 0,
cmd_target_init,
cmd_target_parse,
cmd_choose_session_exec,
@@ -54,9 +54,7 @@ cmd_choose_session_exec(struct cmd *self, struct cmd_ctx *ctx)
struct cmd_choose_session_data *cdata;
struct winlink *wl;
struct session *s;
struct session_group *sg;
u_int i, idx, cur;
char tmp[64];
if (ctx->curclient == NULL) {
ctx->error(ctx, "must be run interactively");
@@ -78,18 +76,10 @@ cmd_choose_session_exec(struct cmd *self, struct cmd_ctx *ctx)
cur = idx;
idx++;
sg = session_group_find(s);
if (sg == NULL)
*tmp = '\0';
else {
idx = session_group_index(sg);
xsnprintf(tmp, sizeof tmp, " (group %u)", idx);
}
window_choose_add(wl->window->active, i,
"%s: %u windows [%ux%u]%s%s", s->name,
"%s: %u windows [%ux%u]%s", s->name,
winlink_count(&s->windows), s->sx, s->sy,
tmp, s->flags & SESSION_UNATTACHED ? "" : " (attached)");
s->flags & SESSION_UNATTACHED ? "" : " (attached)");
}
cdata = xmalloc(sizeof *cdata);

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-choose-window.c,v 1.20 2009-12-04 22:14:47 tcunha Exp $ */
/* $Id: cmd-choose-window.c,v 1.17 2009-09-07 23:59:19 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -34,7 +34,7 @@ void cmd_choose_window_free(void *);
const struct cmd_entry cmd_choose_window_entry = {
"choose-window", NULL,
CMD_TARGET_WINDOW_USAGE " [template]",
CMD_ARG01, "",
CMD_ARG01, 0,
cmd_target_init,
cmd_target_parse,
cmd_choose_window_exec,
@@ -89,7 +89,7 @@ cmd_choose_window_exec(struct cmd *self, struct cmd_ctx *ctx)
flag = '+';
else if (wm == s->curw)
flag = '*';
else if (wm == TAILQ_FIRST(&s->lastw))
else if (wm == SLIST_FIRST(&s->lastw))
flag = '-';
title = w->active->screen->title;
@@ -116,10 +116,10 @@ cmd_choose_window_exec(struct cmd *self, struct cmd_ctx *ctx)
cdata->client = ctx->curclient;
cdata->client->references++;
window_choose_ready(wl->window->active,
window_choose_ready(wl->window->active,
cur, cmd_choose_window_callback, cmd_choose_window_free, cdata);
return (0);
return (0);
}
void
@@ -133,7 +133,7 @@ cmd_choose_window_callback(void *data, int idx)
if (idx == -1)
return;
if (cdata->client->flags & CLIENT_DEAD)
return;
return;
if (cdata->session->flags & SESSION_DEAD)
return;
if (cdata->client->session != cdata->session)

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-clear-history.c,v 1.8 2009-11-14 17:56:39 tcunha Exp $ */
/* $Id: cmd-clear-history.c,v 1.7 2009-07-30 21:04:40 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,7 +29,7 @@ int cmd_clear_history_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_clear_history_entry = {
"clear-history", "clearhist",
CMD_TARGET_PANE_USAGE,
0, "",
0, 0,
cmd_target_init,
cmd_target_parse,
cmd_clear_history_exec,

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-clock-mode.c,v 1.7 2009-11-14 17:56:39 tcunha Exp $ */
/* $Id: cmd-clock-mode.c,v 1.6 2009-08-20 11:37:46 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,7 +29,7 @@ int cmd_clock_mode_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_clock_mode_entry = {
"clock-mode", NULL,
CMD_TARGET_PANE_USAGE,
0, "",
0, 0,
cmd_target_init,
cmd_target_parse,
cmd_clock_mode_exec,

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-command-prompt.c,v 1.27 2009-11-14 17:56:39 tcunha Exp $ */
/* $Id: cmd-command-prompt.c,v 1.25 2009-08-25 13:53:39 tcunha Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -39,7 +39,7 @@ void cmd_command_prompt_cfree(void *);
const struct cmd_entry cmd_command_prompt_entry = {
"command-prompt", NULL,
CMD_TARGET_CLIENT_USAGE " [-p prompts] [template]",
0, "",
0, 0,
cmd_command_prompt_init,
cmd_command_prompt_parse,
cmd_command_prompt_exec,
@@ -90,7 +90,7 @@ cmd_command_prompt_parse(struct cmd *self, int argc, char **argv, char **cause)
struct cmd_command_prompt_data *data;
int opt;
self->entry->init(self, KEYC_NONE);
self->entry->init(self, 0);
data = self->data;
while ((opt = getopt(argc, argv, "p:t:")) != -1) {

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-confirm-before.c,v 1.12 2009-11-14 17:56:39 tcunha Exp $ */
/* $Id: cmd-confirm-before.c,v 1.11 2009-08-24 16:24:18 tcunha Exp $ */
/*
* Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org>
@@ -34,7 +34,7 @@ void cmd_confirm_before_free(void *);
const struct cmd_entry cmd_confirm_before_entry = {
"confirm-before", "confirm",
CMD_TARGET_CLIENT_USAGE " command",
CMD_ARG1, "",
CMD_ARG1, 0,
cmd_confirm_before_init,
cmd_target_parse,
cmd_confirm_before_exec,

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-copy-buffer.c,v 1.7 2009-11-28 14:50:36 tcunha Exp $ */
/* $Id: cmd-copy-buffer.c,v 1.4 2009-09-07 23:48:54 tcunha Exp $ */
/*
* Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org>
@@ -43,7 +43,7 @@ struct cmd_copy_buffer_data {
const struct cmd_entry cmd_copy_buffer_entry = {
"copy-buffer", "copyb",
"[-a src-index] [-b dst-index] [-s src-session] [-t dst-session]",
0, "",
0, 0,
cmd_copy_buffer_init,
cmd_copy_buffer_parse,
cmd_copy_buffer_exec,
@@ -51,7 +51,6 @@ const struct cmd_entry cmd_copy_buffer_entry = {
cmd_copy_buffer_print
};
/* ARGSUSED */
void
cmd_copy_buffer_init(struct cmd *self, unused int arg)
{
@@ -71,7 +70,7 @@ cmd_copy_buffer_parse(struct cmd *self, int argc, char **argv, char **cause)
const char *errstr;
int n, opt;
self->entry->init(self, KEYC_NONE);
self->entry->init(self, 0);
data = self->data;
while ((opt = getopt(argc, argv, "a:b:s:t:")) != -1) {

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-copy-mode.c,v 1.26 2010-01-05 23:50:22 tcunha Exp $ */
/* $Id: cmd-copy-mode.c,v 1.23 2009-08-20 11:37:46 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -24,35 +24,19 @@
* Enter copy mode.
*/
void cmd_copy_mode_init(struct cmd *, int);
int cmd_copy_mode_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_copy_mode_entry = {
"copy-mode", NULL,
"[-u] " CMD_TARGET_PANE_USAGE,
0, "u",
cmd_copy_mode_init,
0, CMD_CHFLAG('u'),
cmd_target_init,
cmd_target_parse,
cmd_copy_mode_exec,
cmd_target_free,
cmd_target_print
NULL
};
void
cmd_copy_mode_init(struct cmd *self, int key)
{
struct cmd_target_data *data;
cmd_target_init(self, key);
data = self->data;
switch (key) {
case KEYC_PPAGE:
cmd_set_flag(&data->chflags, 'u');
break;
}
}
int
cmd_copy_mode_exec(struct cmd *self, struct cmd_ctx *ctx)
{
@@ -63,7 +47,7 @@ cmd_copy_mode_exec(struct cmd *self, struct cmd_ctx *ctx)
return (-1);
window_pane_set_mode(wp, &window_copy_mode);
if (wp->mode == &window_copy_mode && cmd_check_flag(data->chflags, 'u'))
if (wp->mode == &window_copy_mode && data->chflags & CMD_CHFLAG('u'))
window_copy_pageup(wp);
return (0);

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-delete-buffer.c,v 1.8 2009-11-14 17:56:39 tcunha Exp $ */
/* $Id: cmd-delete-buffer.c,v 1.7 2009-07-28 22:12:16 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -31,7 +31,7 @@ int cmd_delete_buffer_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_delete_buffer_entry = {
"delete-buffer", "deleteb",
CMD_BUFFER_SESSION_USAGE,
0, "",
0, 0,
cmd_buffer_init,
cmd_buffer_parse,
cmd_delete_buffer_exec,

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-detach-client.c,v 1.11 2010-02-08 18:27:34 tcunha Exp $ */
/* $Id: cmd-detach-client.c,v 1.9 2009-07-28 22:12:16 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,7 +29,7 @@ int cmd_detach_client_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_detach_client_entry = {
"detach-client", "detach",
CMD_TARGET_CLIENT_USAGE,
CMD_READONLY, "",
0, 0,
cmd_target_init,
cmd_target_parse,
cmd_detach_client_exec,

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-display-message.c,v 1.7 2009-11-28 14:39:53 tcunha Exp $ */
/* $Id: cmd-display-message.c,v 1.2 2009-07-28 22:12:16 tcunha Exp $ */
/*
* Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org>
@@ -30,8 +30,8 @@ int cmd_display_message_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_display_message_entry = {
"display-message", "display",
"[-p] " CMD_TARGET_CLIENT_USAGE " [message]",
CMD_ARG01, "p",
CMD_TARGET_CLIENT_USAGE " [message]",
CMD_ARG01, 0,
cmd_target_init,
cmd_target_parse,
cmd_display_message_exec,
@@ -55,11 +55,8 @@ cmd_display_message_exec(struct cmd *self, struct cmd_ctx *ctx)
else
template = data->arg;
msg = status_replace(c, NULL, template, time(NULL), 0);
if (cmd_check_flag(data->chflags, 'p'))
ctx->print(ctx, "%s", msg);
else
status_message_set(c, "%s", msg);
msg = status_replace(c->session, template, time(NULL));
status_message_set(c, "%s", msg);
xfree(msg);
return (0);

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-display-panes.c,v 1.2 2009-11-14 17:56:39 tcunha Exp $ */
/* $Id: cmd-display-panes.c,v 1.1 2009-08-31 22:30:15 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,7 +29,7 @@ int cmd_display_panes_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_display_panes_entry = {
"display-panes", "displayp",
CMD_TARGET_CLIENT_USAGE,
0, "",
0, 0,
cmd_target_init,
cmd_target_parse,
cmd_display_panes_exec,

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-down-pane.c,v 1.14 2010-01-05 23:52:37 tcunha Exp $ */
/* $Id: cmd-down-pane.c,v 1.12 2009-07-28 22:12:16 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,7 +29,7 @@ int cmd_down_pane_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_down_pane_entry = {
"down-pane", "downp",
CMD_TARGET_WINDOW_USAGE,
0, "",
0, 0,
cmd_target_init,
cmd_target_parse,
cmd_down_pane_exec,
@@ -54,7 +54,6 @@ cmd_down_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
w->active = TAILQ_FIRST(&w->panes);
} while (!window_pane_visible(w->active));
server_status_window(wl->window);
server_redraw_window_borders(wl->window);
return (0);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-find-window.c,v 1.14 2009-11-14 17:56:39 tcunha Exp $ */
/* $Id: cmd-find-window.c,v 1.13 2009-07-28 22:12:16 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -34,7 +34,7 @@ void cmd_find_window_callback(void *, int);
const struct cmd_entry cmd_find_window_entry = {
"find-window", "findw",
CMD_TARGET_WINDOW_USAGE " match-string",
CMD_ARG1, "",
CMD_ARG1, 0,
cmd_target_init,
cmd_target_parse,
cmd_find_window_exec,

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-generic.c,v 1.38 2009-12-04 22:14:47 tcunha Exp $ */
/* $Id: cmd-generic.c,v 1.34 2009-08-26 22:13:52 tcunha Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -23,8 +23,8 @@
#include "tmux.h"
int cmd_getopt(int, char **, const char *, const char *);
int cmd_parse_flags(int, const char *, uint64_t *);
int cmd_getopt(int, char **, const char *, uint64_t);
int cmd_flags(int, uint64_t, uint64_t *);
size_t cmd_print_flags(char *, size_t, size_t, uint64_t);
int cmd_fill_argument(int, char **, char **, int, char **);
@@ -36,56 +36,54 @@ cmd_prarg(char *buf, size_t len, const char *prefix, char *arg)
return (xsnprintf(buf, len, "%s%s", prefix, arg));
}
/* Append two flag strings together and call getopt. */
/* Prepend flags from chflags onto flagstr and call getopt. */
int
cmd_getopt(int argc, char **argv, const char *flagstr, const char *chflagstr)
cmd_getopt(int argc, char **argv, const char *flagstr, uint64_t chflags)
{
char tmp[BUFSIZ];
u_char ch;
char buf[128];
size_t len, off;
if (strlcpy(tmp, flagstr, sizeof tmp) >= sizeof tmp)
fatalx("strlcpy overflow");
if (strlcat(tmp, chflagstr, sizeof tmp) >= sizeof tmp)
fatalx("strlcat overflow");
return (getopt(argc, argv, tmp));
*buf = '\0';
len = sizeof buf;
off = 0;
for (ch = 0; ch < 26; ch++) {
if (chflags & CMD_CHFLAG('a' + ch))
off += xsnprintf(buf + off, len - off, "%c", 'a' + ch);
if (chflags & CMD_CHFLAG('A' + ch))
off += xsnprintf(buf + off, len - off, "%c", 'A' + ch);
}
strlcat(buf, flagstr, sizeof buf);
return (getopt(argc, argv, buf));
}
/* Return if flag character is set. */
/*
* If this option is expected (in ichflags), set it in ochflags, otherwise
* return -1.
*/
int
cmd_check_flag(uint64_t chflags, int flag)
cmd_flags(int opt, uint64_t ichflags, uint64_t *ochflags)
{
if (flag >= 'A' && flag <= 'Z')
flag = 26 + flag - 'A';
else if (flag >= 'a' && flag <= 'z')
flag = flag - 'a';
else
return (0);
return ((chflags & (1ULL << flag)) != 0);
u_char ch;
for (ch = 0; ch < 26; ch++) {
if (opt == 'a' + ch && ichflags & CMD_CHFLAG(opt)) {
(*ochflags) |= CMD_CHFLAG(opt);
return (0);
}
if (opt == 'A' + ch && ichflags & CMD_CHFLAG(opt)) {
(*ochflags) |= CMD_CHFLAG(opt);
return (0);
}
}
return (-1);
}
/* Set flag character. */
void
cmd_set_flag(uint64_t *chflags, int flag)
{
if (flag >= 'A' && flag <= 'Z')
flag = 26 + flag - 'A';
else if (flag >= 'a' && flag <= 'z')
flag = flag - 'a';
else
return;
(*chflags) |= (1ULL << flag);
}
/* If this option is expected, set it in chflags, otherwise return -1. */
int
cmd_parse_flags(int opt, const char *chflagstr, uint64_t *chflags)
{
if (strchr(chflagstr, opt) == NULL)
return (-1);
cmd_set_flag(chflags, opt);
return (0);
}
/* Print the flags present in chflags. */
/* Print the flags supported in chflags. */
size_t
cmd_print_flags(char *buf, size_t len, size_t off, uint64_t chflags)
{
@@ -97,9 +95,9 @@ cmd_print_flags(char *buf, size_t len, size_t off, uint64_t chflags)
off += xsnprintf(buf + off, len - off, " -");
for (ch = 0; ch < 26; ch++) {
if (cmd_check_flag(chflags, 'a' + ch))
if (chflags & CMD_CHFLAG('a' + ch))
off += xsnprintf(buf + off, len - off, "%c", 'a' + ch);
if (cmd_check_flag(chflags, 'A' + ch))
if (chflags & CMD_CHFLAG('A' + ch))
off += xsnprintf(buf + off, len - off, "%c", 'A' + ch);
}
return (off - boff);
@@ -141,14 +139,13 @@ cmd_fill_argument(int flags, char **arg, char **arg2, int argc, char **argv)
if (argc == 2)
*arg2 = xstrdup(argv[1]);
return (0);
}
}
if (argc != 0)
return (-1);
return (0);
}
/* ARGSUSED */
void
cmd_target_init(struct cmd *self, unused int key)
{
@@ -173,7 +170,7 @@ cmd_target_parse(struct cmd *self, int argc, char **argv, char **cause)
data = self->data;
while ((opt = cmd_getopt(argc, argv, "t:", entry->chflags)) != -1) {
if (cmd_parse_flags(opt, entry->chflags, &data->chflags) == 0)
if (cmd_flags(opt, entry->chflags, &data->chflags) == 0)
continue;
switch (opt) {
case 't':
@@ -225,14 +222,13 @@ cmd_target_print(struct cmd *self, char *buf, size_t len)
off += cmd_print_flags(buf, len, off, data->chflags);
if (off < len && data->target != NULL)
off += cmd_prarg(buf + off, len - off, " -t ", data->target);
if (off < len && data->arg != NULL)
if (off < len && data->arg != NULL)
off += cmd_prarg(buf + off, len - off, " ", data->arg);
if (off < len && data->arg2 != NULL)
if (off < len && data->arg2 != NULL)
off += cmd_prarg(buf + off, len - off, " ", data->arg2);
return (off);
}
/* ARGSUSED */
void
cmd_srcdst_init(struct cmd *self, unused int key)
{
@@ -257,7 +253,7 @@ cmd_srcdst_parse(struct cmd *self, int argc, char **argv, char **cause)
data = self->data;
while ((opt = cmd_getopt(argc, argv, "s:t:", entry->chflags)) != -1) {
if (cmd_parse_flags(opt, entry->chflags, &data->chflags) == 0)
if (cmd_flags(opt, entry->chflags, &data->chflags) == 0)
continue;
switch (opt) {
case 's':
@@ -317,14 +313,13 @@ cmd_srcdst_print(struct cmd *self, char *buf, size_t len)
off += xsnprintf(buf + off, len - off, " -s %s", data->src);
if (off < len && data->dst != NULL)
off += xsnprintf(buf + off, len - off, " -t %s", data->dst);
if (off < len && data->arg != NULL)
if (off < len && data->arg != NULL)
off += cmd_prarg(buf + off, len - off, " ", data->arg);
if (off < len && data->arg2 != NULL)
if (off < len && data->arg2 != NULL)
off += cmd_prarg(buf + off, len - off, " ", data->arg2);
return (off);
}
/* ARGSUSED */
void
cmd_buffer_init(struct cmd *self, unused int key)
{
@@ -350,7 +345,7 @@ cmd_buffer_parse(struct cmd *self, int argc, char **argv, char **cause)
data = self->data;
while ((opt = cmd_getopt(argc, argv, "b:t:", entry->chflags)) != -1) {
if (cmd_parse_flags(opt, entry->chflags, &data->chflags) == 0)
if (cmd_flags(opt, entry->chflags, &data->chflags) == 0)
continue;
switch (opt) {
case 'b':
@@ -415,9 +410,9 @@ cmd_buffer_print(struct cmd *self, char *buf, size_t len)
off += xsnprintf(buf + off, len - off, " -b %d", data->buffer);
if (off < len && data->target != NULL)
off += cmd_prarg(buf + off, len - off, " -t ", data->target);
if (off < len && data->arg != NULL)
if (off < len && data->arg != NULL)
off += cmd_prarg(buf + off, len - off, " ", data->arg);
if (off < len && data->arg2 != NULL)
if (off < len && data->arg2 != NULL)
off += cmd_prarg(buf + off, len - off, " ", data->arg2);
return (off);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-has-session.c,v 1.15 2009-11-14 17:56:39 tcunha Exp $ */
/* $Id: cmd-has-session.c,v 1.14 2009-07-28 22:12:16 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,7 +29,7 @@ int cmd_has_session_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_has_session_entry = {
"has-session", "has",
CMD_TARGET_SESSION_USAGE,
0, "",
0, 0,
cmd_target_init,
cmd_target_parse,
cmd_has_session_exec,

View File

@@ -1,8 +1,7 @@
/* $Id: cmd-if-shell.c,v 1.8 2009-11-14 17:56:39 tcunha Exp $ */
/* $Id: cmd-if-shell.c,v 1.4 2009-07-28 22:12:16 tcunha Exp $ */
/*
* Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org>
* Copyright (c) 2009 Nicholas Marriott <nicm@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -18,8 +17,9 @@
*/
#include <sys/types.h>
#include <sys/wait.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include "tmux.h"
@@ -28,90 +28,124 @@
* Executes a tmux command if a shell command returns true.
*/
int cmd_if_shell_parse(struct cmd *, int, char **, char **);
int cmd_if_shell_exec(struct cmd *, struct cmd_ctx *);
void cmd_if_shell_free(struct cmd *);
void cmd_if_shell_init(struct cmd *, int);
size_t cmd_if_shell_print(struct cmd *, char *, size_t);
void cmd_if_shell_callback(struct job *);
void cmd_if_shell_free(void *);
struct cmd_if_shell_data {
char *cmd;
char *sh_cmd;
};
const struct cmd_entry cmd_if_shell_entry = {
"if-shell", "if",
"shell-command command",
CMD_ARG2, "",
cmd_target_init,
cmd_target_parse,
0, 0,
cmd_if_shell_init,
cmd_if_shell_parse,
cmd_if_shell_exec,
cmd_target_free,
cmd_target_print
cmd_if_shell_free,
cmd_if_shell_print
};
struct cmd_if_shell_data {
char *cmd;
struct cmd_ctx ctx;
};
void
cmd_if_shell_init(struct cmd *self, unused int arg)
{
struct cmd_if_shell_data *data;
self->data = data = xmalloc(sizeof *data);
data->cmd = NULL;
data->sh_cmd = NULL;
}
int
cmd_if_shell_parse(struct cmd *self, int argc, char **argv, char **cause)
{
struct cmd_if_shell_data *data;
int opt;
self->entry->init(self, 0);
data = self->data;
while ((opt = getopt(argc, argv, "")) != -1) {
switch (opt) {
default:
goto usage;
}
}
argc -= optind;
argv += optind;
if (argc != 2)
goto usage;
data->sh_cmd = xstrdup(argv[0]);
data->cmd = xstrdup(argv[1]);
return (0);
usage:
xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
self->entry->free(self);
return (-1);
}
int
cmd_if_shell_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_target_data *data = self->data;
struct cmd_if_shell_data *cdata;
struct job *job;
cdata = xmalloc(sizeof *cdata);
cdata->cmd = xstrdup(data->arg2);
memcpy(&cdata->ctx, ctx, sizeof cdata->ctx);
if (ctx->cmdclient != NULL)
ctx->cmdclient->references++;
if (ctx->curclient != NULL)
ctx->curclient->references++;
job = job_add(NULL, 0, NULL,
data->arg, cmd_if_shell_callback, cmd_if_shell_free, cdata);
job_run(job);
return (1); /* don't let client exit */
}
void
cmd_if_shell_callback(struct job *job)
{
struct cmd_if_shell_data *cdata = job->data;
struct cmd_ctx *ctx = &cdata->ctx;
struct cmd_if_shell_data *data = self->data;
struct cmd_list *cmdlist;
char *cause;
int ret;
if (!WIFEXITED(job->status) || WEXITSTATUS(job->status) != 0)
return;
if ((ret = system(data->sh_cmd)) < 0) {
ctx->error(ctx, "system error: %s", strerror(errno));
return (-1);
} else if (ret != 0)
return (0);
if (cmd_string_parse(cdata->cmd, &cmdlist, &cause) != 0) {
if (cmd_string_parse(data->cmd, &cmdlist, &cause) != 0) {
if (cause != NULL) {
ctx->error(ctx, "%s", cause);
xfree(cause);
}
return;
return (-1);
}
if (cmd_list_exec(cmdlist, ctx) < 0) {
cmd_list_free(cmdlist);
return;
return (-1);
}
cmd_list_free(cmdlist);
return (0);
}
void
cmd_if_shell_free(void *data)
cmd_if_shell_free(struct cmd *self)
{
struct cmd_if_shell_data *cdata = data;
struct cmd_ctx *ctx = &cdata->ctx;
struct cmd_if_shell_data *data = self->data;
if (ctx->cmdclient != NULL) {
ctx->cmdclient->references--;
server_write_client(ctx->cmdclient, MSG_EXIT, NULL, 0);
}
if (ctx->curclient != NULL)
ctx->curclient->references--;
xfree(cdata->cmd);
xfree(cdata);
if (data->cmd != NULL)
xfree(data->cmd);
if (data->sh_cmd != NULL)
xfree(data->sh_cmd);
xfree(data);
}
size_t
cmd_if_shell_print(struct cmd *self, char *buf, size_t len)
{
struct cmd_if_shell_data *data = self->data;
size_t off = 0;
off += xsnprintf(buf, len, "%s", self->entry->name);
if (data == NULL)
return (off);
if (off < len && data->sh_cmd != NULL)
off += cmd_prarg(buf + off, len - off, " ", data->sh_cmd);
if (off < len && data->cmd != NULL)
off += cmd_prarg(buf + off, len - off, " ", data->cmd);
return (off);
}

View File

@@ -1,256 +0,0 @@
/* $Id: cmd-join-pane.c,v 1.2 2010-01-08 16:34:17 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <sys/types.h>
#include <stdlib.h>
#include <unistd.h>
#include "tmux.h"
/*
* Join a pane into another (like split/swap/kill).
*/
int cmd_join_pane_parse(struct cmd *, int, char **, char **);
int cmd_join_pane_exec(struct cmd *, struct cmd_ctx *);
void cmd_join_pane_free(struct cmd *);
void cmd_join_pane_init(struct cmd *, int);
size_t cmd_join_pane_print(struct cmd *, char *, size_t);
struct cmd_join_pane_data {
char *src;
char *dst;
int flag_detached;
int flag_horizontal;
int percentage;
int size;
};
const struct cmd_entry cmd_join_pane_entry = {
"join-pane", "joinp",
"[-dhv] [-p percentage|-l size] [-t src-pane] [-t dst-pane] [command]",
0, "",
cmd_join_pane_init,
cmd_join_pane_parse,
cmd_join_pane_exec,
cmd_join_pane_free,
cmd_join_pane_print
};
void
cmd_join_pane_init(struct cmd *self, int key)
{
struct cmd_join_pane_data *data;
self->data = data = xmalloc(sizeof *data);
data->src = NULL;
data->dst = NULL;
data->flag_detached = 0;
data->flag_horizontal = 0;
data->percentage = -1;
data->size = -1;
switch (key) {
case '%':
data->flag_horizontal = 1;
break;
case '"':
data->flag_horizontal = 0;
break;
}
}
int
cmd_join_pane_parse(struct cmd *self, int argc, char **argv, char **cause)
{
struct cmd_join_pane_data *data;
int opt;
const char *errstr;
self->entry->init(self, KEYC_NONE);
data = self->data;
while ((opt = getopt(argc, argv, "dhl:p:s:t:v")) != -1) {
switch (opt) {
case 'd':
data->flag_detached = 1;
break;
case 'h':
data->flag_horizontal = 1;
break;
case 's':
if (data->src == NULL)
data->src = xstrdup(optarg);
break;
case 't':
if (data->dst == NULL)
data->dst = xstrdup(optarg);
break;
case 'l':
if (data->percentage != -1 || data->size != -1)
break;
data->size = strtonum(optarg, 1, INT_MAX, &errstr);
if (errstr != NULL) {
xasprintf(cause, "size %s", errstr);
goto error;
}
break;
case 'p':
if (data->size != -1 || data->percentage != -1)
break;
data->percentage = strtonum(optarg, 1, 100, &errstr);
if (errstr != NULL) {
xasprintf(cause, "percentage %s", errstr);
goto error;
}
break;
case 'v':
data->flag_horizontal = 0;
break;
default:
goto usage;
}
}
argc -= optind;
argv += optind;
if (argc != 0)
goto usage;
return (0);
usage:
xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
error:
self->entry->free(self);
return (-1);
}
int
cmd_join_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_join_pane_data *data = self->data;
struct session *dst_s;
struct winlink *src_wl, *dst_wl;
struct window *src_w, *dst_w;
struct window_pane *src_wp, *dst_wp;
int size;
enum layout_type type;
struct layout_cell *lc;
if ((dst_wl = cmd_find_pane(ctx, data->dst, &dst_s, &dst_wp)) == NULL)
return (-1);
dst_w = dst_wl->window;
if ((src_wl = cmd_find_pane(ctx, data->src, NULL, &src_wp)) == NULL)
return (-1);
src_w = src_wl->window;
if (src_w == dst_w) {
ctx->error(ctx, "can't join a pane to its own window");
return (-1);
}
type = LAYOUT_TOPBOTTOM;
if (data->flag_horizontal)
type = LAYOUT_LEFTRIGHT;
size = -1;
if (data->size != -1)
size = data->size;
else if (data->percentage != -1) {
if (type == LAYOUT_TOPBOTTOM)
size = (dst_wp->sy * data->percentage) / 100;
else
size = (dst_wp->sx * data->percentage) / 100;
}
if ((lc = layout_split_pane(dst_wp, type, size)) == NULL) {
ctx->error(ctx, "create pane failed: pane too small");
return (-1);
}
layout_close_pane(src_wp);
if (src_w->active == src_wp) {
src_w->active = TAILQ_PREV(src_wp, window_panes, entry);
if (src_w->active == NULL)
src_w->active = TAILQ_NEXT(src_wp, entry);
}
TAILQ_REMOVE(&src_w->panes, src_wp, entry);
if (window_count_panes(src_w) == 0)
server_kill_window(src_w);
src_wp->window = dst_w;
TAILQ_INSERT_AFTER(&dst_w->panes, dst_wp, src_wp, entry);
layout_assign_pane(lc, src_wp);
recalculate_sizes();
server_redraw_window(src_w);
server_redraw_window(dst_w);
if (!data->flag_detached) {
window_set_active_pane(dst_w, src_wp);
session_select(dst_s, dst_wl->idx);
server_redraw_session(dst_s);
} else
server_status_session(dst_s);
return (0);
}
void
cmd_join_pane_free(struct cmd *self)
{
struct cmd_join_pane_data *data = self->data;
if (data->src != NULL)
xfree(data->src);
if (data->dst != NULL)
xfree(data->dst);
xfree(data);
}
size_t
cmd_join_pane_print(struct cmd *self, char *buf, size_t len)
{
struct cmd_join_pane_data *data = self->data;
size_t off = 0;
off += xsnprintf(buf, len, "%s", self->entry->name);
if (data == NULL)
return (off);
if (off < len && data->flag_detached)
off += xsnprintf(buf + off, len - off, " -d");
if (off < len && data->flag_horizontal)
off += xsnprintf(buf + off, len - off, " -h");
if (off < len && data->size > 0)
off += xsnprintf(buf + off, len - off, " -l %d", data->size);
if (off < len && data->percentage > 0) {
off += xsnprintf(
buf + off, len - off, " -p %d", data->percentage);
}
if (off < len && data->src != NULL)
off += cmd_prarg(buf + off, len - off, " -s ", data->src);
if (off < len && data->dst != NULL)
off += cmd_prarg(buf + off, len - off, " -t ", data->dst);
return (off);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-kill-pane.c,v 1.15 2009-11-14 17:56:39 tcunha Exp $ */
/* $Id: cmd-kill-pane.c,v 1.12 2009-07-30 20:45:20 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -30,8 +30,8 @@ int cmd_kill_pane_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_kill_pane_entry = {
"kill-pane", "killp",
"[-a] " CMD_TARGET_PANE_USAGE,
0, "a",
CMD_TARGET_PANE_USAGE,
0, 0,
cmd_target_init,
cmd_target_parse,
cmd_kill_pane_exec,
@@ -44,7 +44,7 @@ cmd_kill_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_target_data *data = self->data;
struct winlink *wl;
struct window_pane *loopwp, *nextwp, *wp;
struct window_pane *wp;
if ((wl = cmd_find_pane(ctx, data->target, NULL, &wp)) == NULL)
return (-1);
@@ -52,25 +52,11 @@ cmd_kill_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
if (window_count_panes(wl->window) == 1) {
/* Only one pane, kill the window. */
server_kill_window(wl->window);
recalculate_sizes();
return (0);
}
if (cmd_check_flag(data->chflags, 'a')) {
loopwp = TAILQ_FIRST(&wl->window->panes);
while (loopwp != NULL) {
nextwp = TAILQ_NEXT(loopwp, entry);
if (loopwp != wp) {
layout_close_pane(loopwp);
window_remove_pane(wl->window, loopwp);
}
loopwp = nextwp;
}
} else {
layout_close_pane(wp);
window_remove_pane(wl->window, wp);
}
layout_close_pane(wp);
window_remove_pane(wl->window, wp);
server_redraw_window(wl->window);
return (0);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-kill-server.c,v 1.11 2009-11-28 14:50:36 tcunha Exp $ */
/* $Id: cmd-kill-server.c,v 1.8 2009-07-28 22:12:16 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -32,7 +32,7 @@ int cmd_kill_server_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_kill_server_entry = {
"kill-server", NULL,
"",
0, "",
0, 0,
NULL,
NULL,
cmd_kill_server_exec,
@@ -40,11 +40,10 @@ const struct cmd_entry cmd_kill_server_entry = {
NULL
};
/* ARGSUSED */
int
cmd_kill_server_exec(unused struct cmd *self, unused struct cmd_ctx *ctx)
{
kill(getpid(), SIGTERM);
sigterm = 1;
return (0);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-kill-session.c,v 1.17 2009-12-04 22:14:47 tcunha Exp $ */
/* $Id: cmd-kill-session.c,v 1.14 2009-07-28 22:12:16 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -32,7 +32,7 @@ int cmd_kill_session_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_kill_session_entry = {
"kill-session", NULL,
CMD_TARGET_SESSION_USAGE,
0, "",
0, 0,
cmd_target_init,
cmd_target_parse,
cmd_kill_session_exec,
@@ -45,7 +45,7 @@ cmd_kill_session_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_target_data *data = self->data;
struct session *s;
struct client *c;
struct client *c;
u_int i;
if ((s = cmd_find_session(ctx, data->target)) == NULL)
@@ -53,7 +53,7 @@ cmd_kill_session_exec(struct cmd *self, struct cmd_ctx *ctx)
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
c = ARRAY_ITEM(&clients, i);
if (c != NULL && c->session == s) {
if (c->session == s) {
c->session = NULL;
server_write_client(c, MSG_EXIT, NULL, 0);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-kill-window.c,v 1.21 2009-11-14 17:56:39 tcunha Exp $ */
/* $Id: cmd-kill-window.c,v 1.19 2009-07-28 22:12:16 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,7 +29,7 @@ int cmd_kill_window_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_kill_window_entry = {
"kill-window", "killw",
CMD_TARGET_WINDOW_USAGE,
0, "",
0, 0,
cmd_target_init,
cmd_target_parse,
cmd_kill_window_exec,
@@ -47,7 +47,6 @@ cmd_kill_window_exec(struct cmd *self, struct cmd_ctx *ctx)
return (-1);
server_kill_window(wl->window);
recalculate_sizes();
return (0);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-last-window.c,v 1.19 2009-11-14 17:56:39 tcunha Exp $ */
/* $Id: cmd-last-window.c,v 1.18 2009-07-28 22:12:16 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,7 +29,7 @@ int cmd_last_window_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_last_window_entry = {
"last-window", "last",
CMD_TARGET_SESSION_USAGE,
0, "",
0, 0,
cmd_target_init,
cmd_target_parse,
cmd_last_window_exec,

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-link-window.c,v 1.36 2009-11-14 17:56:39 tcunha Exp $ */
/* $Id: cmd-link-window.c,v 1.32 2009-08-16 19:16:27 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -31,7 +31,7 @@ int cmd_link_window_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_link_window_entry = {
"link-window", "linkw",
"[-dk] " CMD_SRCDST_WINDOW_USAGE,
0, "dk",
0, CMD_CHFLAG('d')|CMD_CHFLAG('k'),
cmd_srcdst_init,
cmd_srcdst_parse,
cmd_link_window_exec,
@@ -43,23 +43,55 @@ int
cmd_link_window_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_srcdst_data *data = self->data;
struct session *src, *dst;
struct winlink *wl;
struct session *dst;
struct winlink *wl_src, *wl_dst;
char *cause;
int idx, kflag, dflag;
int idx;
if ((wl = cmd_find_window(ctx, data->src, &src)) == NULL)
if ((wl_src = cmd_find_window(ctx, data->src, NULL)) == NULL)
return (-1);
if ((idx = cmd_find_index(ctx, data->dst, &dst)) == -2)
return (-1);
kflag = cmd_check_flag(data->chflags, 'k');
dflag = cmd_check_flag(data->chflags, 'd');
if (server_link_window(src, wl, dst, idx, kflag, !dflag, &cause) != 0) {
ctx->error(ctx, "can't link window: %s", cause);
wl_dst = NULL;
if (idx != -1)
wl_dst = winlink_find_by_index(&dst->windows, idx);
if (wl_dst != NULL) {
if (wl_dst->window == wl_src->window)
return (0);
if (data->chflags & CMD_CHFLAG('k')) {
/*
* Can't use session_detach as it will destroy session
* if this makes it empty.
*/
session_alert_cancel(dst, wl_dst);
winlink_stack_remove(&dst->lastw, wl_dst);
winlink_remove(&dst->windows, wl_dst);
/* Force select/redraw if current. */
if (wl_dst == dst->curw) {
data->chflags &= ~CMD_CHFLAG('d');
dst->curw = NULL;
}
}
}
if (idx == -1)
idx = -1 - options_get_number(&dst->options, "base-index");
wl_dst = session_attach(dst, wl_src->window, idx, &cause);
if (wl_dst == NULL) {
ctx->error(ctx, "create session failed: %s", cause);
xfree(cause);
return (-1);
}
if (data->chflags & CMD_CHFLAG('d'))
server_status_session(dst);
else {
session_select(dst, wl_dst->idx);
server_redraw_session(dst);
}
recalculate_sizes();
return (0);

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-list-buffers.c,v 1.15 2009-12-04 22:14:47 tcunha Exp $ */
/* $Id: cmd-list-buffers.c,v 1.12 2009-09-07 23:48:54 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -31,7 +31,7 @@ int cmd_list_buffers_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_list_buffers_entry = {
"list-buffers", "lsb",
CMD_TARGET_SESSION_USAGE,
0, "",
0, 0,
cmd_target_init,
cmd_target_parse,
cmd_list_buffers_exec,
@@ -63,14 +63,14 @@ cmd_list_buffers_exec(struct cmd *self, struct cmd_ctx *ctx)
strvisx(tmp, pb->data, len, VIS_OCTAL|VIS_TAB|VIS_NL);
/*
* If the first 50 characters were encoded as a longer string,
* If the first 50 characterswere encoded as a longer string,
* or there is definitely more data, add "...".
*/
if (size > 50 || strlen(tmp) > 50) {
tmp[50 - 3] = '\0';
strlcat(tmp, "...", sizeof tmp);
}
ctx->print(ctx, "%u: %zu bytes: \"%s\"", idx - 1, size, tmp);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-list-clients.c,v 1.20 2009-11-28 14:50:36 tcunha Exp $ */
/* $Id: cmd-list-clients.c,v 1.18 2009-07-28 22:12:16 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -32,7 +32,7 @@ int cmd_list_clients_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_list_clients_entry = {
"list-clients", "lsc",
"",
0, "",
0, 0,
NULL,
NULL,
cmd_list_clients_exec,
@@ -40,7 +40,6 @@ const struct cmd_entry cmd_list_clients_entry = {
NULL
};
/* ARGSUSED */
int
cmd_list_clients_exec(unused struct cmd *self, struct cmd_ctx *ctx)
{

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-list-commands.c,v 1.7 2009-11-28 14:50:36 tcunha Exp $ */
/* $Id: cmd-list-commands.c,v 1.5 2009-07-28 22:12:16 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,7 +29,7 @@ int cmd_list_commands_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_list_commands_entry = {
"list-commands", "lscm",
"",
0, "",
0, 0,
NULL,
NULL,
cmd_list_commands_exec,
@@ -37,7 +37,6 @@ const struct cmd_entry cmd_list_commands_entry = {
NULL
};
/* ARGSUSED */
int
cmd_list_commands_exec(unused struct cmd *self, struct cmd_ctx *ctx)
{

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-list-keys.c,v 1.24 2009-12-04 22:14:47 tcunha Exp $ */
/* $Id: cmd-list-keys.c,v 1.20 2009-07-28 23:19:06 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -33,7 +33,7 @@ int cmd_list_keys_table(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_list_keys_entry = {
"list-keys", "lsk",
"[-t key-table]",
0, "",
0, 0,
cmd_target_init,
cmd_target_parse,
cmd_list_keys_exec,
@@ -47,8 +47,7 @@ cmd_list_keys_exec(struct cmd *self, struct cmd_ctx *ctx)
struct cmd_target_data *data = self->data;
struct key_binding *bd;
const char *key;
char tmp[BUFSIZ];
size_t used;
char tmp[BUFSIZ], keytmp[64];
int width, keywidth;
if (data->target != NULL)
@@ -71,17 +70,14 @@ cmd_list_keys_exec(struct cmd *self, struct cmd_ctx *ctx)
key = key_string_lookup_key(bd->key & ~KEYC_PREFIX);
if (key == NULL)
continue;
used = xsnprintf(tmp, sizeof tmp, "%*s: ", width, key);
if (used >= sizeof tmp)
continue;
*tmp = '\0';
cmd_list_print(bd->cmdlist, tmp, sizeof tmp);
if (!(bd->key & KEYC_PREFIX)) {
used = strlcat(tmp, "(no prefix) ", sizeof tmp);
if (used >= sizeof tmp)
continue;
xsnprintf(keytmp, sizeof keytmp, "[%s]", key);
key = keytmp;
}
cmd_list_print(bd->cmdlist, tmp + used, (sizeof tmp) - used);
ctx->print(ctx, "%s", tmp);
ctx->print(ctx, "%*s: %s", width, key, tmp);
}
return (0);

View File

@@ -1,74 +0,0 @@
/* $Id: cmd-list-panes.c,v 1.4 2009-12-04 22:14:47 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <sys/types.h>
#include <unistd.h>
#include "tmux.h"
/*
* List panes on given window.
*/
int cmd_list_panes_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_list_panes_entry = {
"list-panes", "lsp",
CMD_TARGET_WINDOW_USAGE,
0, "",
cmd_target_init,
cmd_target_parse,
cmd_list_panes_exec,
cmd_target_free,
cmd_target_print
};
int
cmd_list_panes_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_target_data *data = self->data;
struct winlink *wl;
struct window_pane *wp;
struct grid *gd;
struct grid_line *gl;
u_int i, n;
unsigned long long size;
if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
return (-1);
n = 0;
TAILQ_FOREACH(wp, &wl->window->panes, entry) {
gd = wp->base.grid;
size = 0;
for (i = 0; i < gd->hsize; i++) {
gl = &gd->linedata[i];
size += gl->cellsize * sizeof *gl->celldata;
size += gl->utf8size * sizeof *gl->utf8data;
}
size += gd->hsize * sizeof *gd->linedata;
ctx->print(ctx, "%u: [%ux%u] [history %u/%u, %llu bytes]",
n, wp->sx, wp->sy, gd->hsize, gd->hlimit, size);
n++;
}
return (0);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-list-sessions.c,v 1.25 2009-11-28 14:50:36 tcunha Exp $ */
/* $Id: cmd-list-sessions.c,v 1.21 2009-07-28 22:12:16 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -31,7 +31,7 @@ int cmd_list_sessions_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_list_sessions_entry = {
"list-sessions", "ls", "",
0, "",
0, 0,
NULL,
NULL,
cmd_list_sessions_exec,
@@ -39,36 +39,26 @@ const struct cmd_entry cmd_list_sessions_entry = {
NULL
};
/* ARGSUSED */
int
cmd_list_sessions_exec(unused struct cmd *self, struct cmd_ctx *ctx)
{
struct session *s;
struct session_group *sg;
char *tim, tmp[64];
u_int i, idx;
time_t t;
struct session *s;
char *tim;
u_int i;
time_t t;
for (i = 0; i < ARRAY_LENGTH(&sessions); i++) {
s = ARRAY_ITEM(&sessions, i);
if (s == NULL)
continue;
sg = session_group_find(s);
if (sg == NULL)
*tmp = '\0';
else {
idx = session_group_index(sg);
xsnprintf(tmp, sizeof tmp, " (group %u)", idx);
}
t = s->creation_time.tv_sec;
t = s->tv.tv_sec;
tim = ctime(&t);
*strchr(tim, '\n') = '\0';
ctx->print(ctx, "%s: %u windows (created %s) [%ux%u]%s%s",
ctx->print(ctx, "%s: %u windows (created %s) [%ux%u]%s",
s->name, winlink_count(&s->windows), tim, s->sx, s->sy,
tmp, s->flags & SESSION_UNATTACHED ? "" : " (attached)");
s->flags & SESSION_UNATTACHED ? "" : " (attached)");
}
return (0);

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-list-windows.c,v 1.42 2009-11-14 17:56:39 tcunha Exp $ */
/* $Id: cmd-list-windows.c,v 1.40 2009-08-09 17:28:23 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -31,7 +31,7 @@ int cmd_list_windows_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_list_windows_entry = {
"list-windows", "lsw",
CMD_TARGET_SESSION_USAGE,
0, "",
0, 0,
cmd_target_init,
cmd_target_parse,
cmd_list_windows_exec,
@@ -45,13 +45,42 @@ cmd_list_windows_exec(struct cmd *self, struct cmd_ctx *ctx)
struct cmd_target_data *data = self->data;
struct session *s;
struct winlink *wl;
struct window *w;
struct window_pane *wp;
struct grid *gd;
struct grid_line *gl;
u_int i;
unsigned long long size;
const char *name;
if ((s = cmd_find_session(ctx, data->target)) == NULL)
return (-1);
RB_FOREACH(wl, winlinks, &s->windows) {
ctx->print(ctx, "%d: %s [%ux%u]",
wl->idx, wl->window->name, wl->window->sx, wl->window->sy);
w = wl->window;
ctx->print(ctx,
"%3d: %s [%ux%u]", wl->idx, w->name, w->sx, w->sy);
TAILQ_FOREACH(wp, &w->panes, entry) {
gd = wp->base.grid;
size = 0;
for (i = 0; i < gd->hsize; i++) {
gl = &gd->linedata[i];
size += gl->cellsize * sizeof *gl->celldata;
size += gl->utf8size * sizeof *gl->utf8data;
}
size += gd->hsize * sizeof *gd->linedata;
name = NULL;
if (wp->fd != -1)
name = ttyname(wp->fd);
if (name == NULL)
name = "unknown";
ctx->print(ctx,
" %s [%ux%u] [history %u/%u, %llu bytes]",
name, wp->sx, wp->sy, gd->hsize, gd->hlimit, size);
}
}
return (0);

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-list.c,v 1.7 2010-02-02 23:51:04 tcunha Exp $ */
/* $Id: cmd-list.c,v 1.6 2009-07-28 22:12:16 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -77,32 +77,13 @@ int
cmd_list_exec(struct cmd_list *cmdlist, struct cmd_ctx *ctx)
{
struct cmd *cmd;
int n, retval;
int n;
retval = 0;
TAILQ_FOREACH(cmd, cmdlist, qentry) {
if ((n = cmd_exec(cmd, ctx)) == -1)
return (-1);
/*
* A 1 return value means the command client is being attached
* (sent MSG_READY).
*/
if (n == 1) {
retval = 1;
/*
* The command client has been attached, so mangle the
* context to treat any following commands as if they
* were called from inside.
*/
if (ctx->curclient == NULL) {
ctx->curclient = ctx->cmdclient;
ctx->cmdclient = NULL;
}
}
if ((n = cmd_exec(cmd, ctx)) != 0)
return (n);
}
return (retval);
return (0);
}
void

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-load-buffer.c,v 1.15 2010-02-26 13:30:07 tcunha Exp $ */
/* $Id: cmd-load-buffer.c,v 1.10 2009-09-07 23:48:54 tcunha Exp $ */
/*
* Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org>
@@ -16,10 +16,13 @@
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "tmux.h"
@@ -32,7 +35,7 @@ int cmd_load_buffer_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_load_buffer_entry = {
"load-buffer", "loadb",
CMD_BUFFER_SESSION_USAGE " path",
CMD_ARG1, "",
CMD_ARG1, 0,
cmd_buffer_init,
cmd_buffer_parse,
cmd_load_buffer_exec,
@@ -45,55 +48,53 @@ cmd_load_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_buffer_data *data = self->data;
struct session *s;
struct stat sb;
FILE *f;
char *pdata, *new_pdata;
size_t psize;
u_char *buf;
u_int limit;
int ch;
if ((s = cmd_find_session(ctx, data->target)) == NULL)
return (-1);
if (stat(data->arg, &sb) < 0) {
ctx->error(ctx, "%s: %s", data->arg, strerror(errno));
return (-1);
}
if ((f = fopen(data->arg, "rb")) == NULL) {
ctx->error(ctx, "%s: %s", data->arg, strerror(errno));
return (-1);
}
pdata = NULL;
psize = 0;
while ((ch = getc(f)) != EOF) {
/* Do not let the server die due to memory exhaustion. */
if ((new_pdata = realloc(pdata, psize + 2)) == NULL) {
ctx->error(ctx, "realloc error: %s", strerror(errno));
goto error;
}
pdata = new_pdata;
pdata[psize++] = ch;
/*
* We don't want to die due to memory exhaustion, hence xmalloc can't
* be used here.
*/
if ((buf = malloc(sb.st_size + 1)) == NULL) {
ctx->error(ctx, "malloc error: %s", strerror(errno));
fclose(f);
return (-1);
}
if (ferror(f)) {
ctx->error(ctx, "%s: read error", data->arg);
goto error;
if (fread(buf, 1, sb.st_size, f) != (size_t) sb.st_size) {
ctx->error(ctx, "%s: fread error", data->arg);
xfree(buf);
fclose(f);
return (-1);
}
if (pdata != NULL)
pdata[psize] = '\0';
fclose(f);
limit = options_get_number(&s->options, "buffer-limit");
if (data->buffer == -1) {
paste_add(&s->buffers, pdata, psize, limit);
paste_add(&s->buffers, buf, sb.st_size, limit);
return (0);
}
if (paste_replace(&s->buffers, data->buffer, pdata, psize) != 0) {
if (paste_replace(&s->buffers, data->buffer, buf, sb.st_size) != 0) {
ctx->error(ctx, "no buffer %d", data->buffer);
goto error;
xfree(buf);
return (-1);
}
return (0);
error:
if (pdata != NULL)
xfree(pdata);
fclose(f);
return (-1);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-lock-server.c,v 1.9 2009-11-28 14:50:36 tcunha Exp $ */
/* $Id: cmd-lock-server.c,v 1.6 2009-07-28 22:12:16 tcunha Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -33,7 +33,7 @@ int cmd_lock_server_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_lock_server_entry = {
"lock-server", "lock",
"",
0, "",
0, 0,
NULL,
NULL,
cmd_lock_server_exec,
@@ -41,12 +41,10 @@ const struct cmd_entry cmd_lock_server_entry = {
NULL,
};
/* ARGSUSED */
int
cmd_lock_server_exec(unused struct cmd *self, unused struct cmd_ctx *ctx)
{
server_lock();
recalculate_sizes();
return (0);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-move-window.c,v 1.13 2009-11-14 17:56:39 tcunha Exp $ */
/* $Id: cmd-move-window.c,v 1.9 2009-08-16 19:16:27 tcunha Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -31,7 +31,7 @@ int cmd_move_window_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_move_window_entry = {
"move-window", "movew",
"[-dk] " CMD_SRCDST_WINDOW_USAGE,
0, "dk",
0, CMD_CHFLAG('d')|CMD_CHFLAG('k'),
cmd_srcdst_init,
cmd_srcdst_parse,
cmd_move_window_exec,
@@ -44,23 +44,68 @@ cmd_move_window_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_srcdst_data *data = self->data;
struct session *src, *dst;
struct winlink *wl;
struct winlink *wl_src, *wl_dst;
struct client *c;
u_int i;
int destroyed, idx;
char *cause;
int idx, kflag, dflag;
if ((wl = cmd_find_window(ctx, data->src, &src)) == NULL)
if ((wl_src = cmd_find_window(ctx, data->src, &src)) == NULL)
return (-1);
if ((idx = cmd_find_index(ctx, data->dst, &dst)) == -2)
return (-1);
kflag = cmd_check_flag(data->chflags, 'k');
dflag = cmd_check_flag(data->chflags, 'd');
if (server_link_window(src, wl, dst, idx, kflag, !dflag, &cause) != 0) {
ctx->error(ctx, "can't move window: %s", cause);
wl_dst = NULL;
if (idx != -1)
wl_dst = winlink_find_by_index(&dst->windows, idx);
if (wl_dst != NULL) {
if (wl_dst->window == wl_src->window)
return (0);
if (data->chflags & CMD_CHFLAG('k')) {
/*
* Can't use session_detach as it will destroy session
* if this makes it empty.
*/
session_alert_cancel(dst, wl_dst);
winlink_stack_remove(&dst->lastw, wl_dst);
winlink_remove(&dst->windows, wl_dst);
/* Force select/redraw if current. */
if (wl_dst == dst->curw) {
data->chflags &= ~CMD_CHFLAG('d');
dst->curw = NULL;
}
}
}
if (idx == -1)
idx = -1 - options_get_number(&dst->options, "base-index");
wl_dst = session_attach(dst, wl_src->window, idx, &cause);
if (wl_dst == NULL) {
ctx->error(ctx, "attach window failed: %s", cause);
xfree(cause);
return (-1);
}
server_unlink_window(src, wl);
destroyed = session_detach(src, wl_src);
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
c = ARRAY_ITEM(&clients, i);
if (c == NULL || c->session != src)
continue;
if (destroyed) {
c->session = NULL;
server_write_client(c, MSG_EXIT, NULL, 0);
} else
server_redraw_client(c);
}
if (data->chflags & CMD_CHFLAG('d'))
server_status_session(dst);
else {
session_select(dst, wl_dst->idx);
server_redraw_session(dst);
}
recalculate_sizes();
return (0);

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-new-session.c,v 1.76 2010-02-26 13:28:15 tcunha Exp $ */
/* $Id: cmd-new-session.c,v 1.66 2009-09-16 12:36:27 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -20,6 +20,7 @@
#include <string.h>
#include <termios.h>
#include <unistd.h>
#include "tmux.h"
@@ -34,7 +35,6 @@ void cmd_new_session_init(struct cmd *, int);
size_t cmd_new_session_print(struct cmd *, char *, size_t);
struct cmd_new_session_data {
char *target;
char *newname;
char *winname;
char *cmd;
@@ -43,8 +43,8 @@ struct cmd_new_session_data {
const struct cmd_entry cmd_new_session_entry = {
"new-session", "new",
"[-d] [-n window-name] [-s session-name] [-t target-session] [command]",
CMD_STARTSERVER|CMD_CANTNEST|CMD_SENDENVIRON, "",
"[-d] [-n window-name] [-s session-name] [command]",
CMD_STARTSERVER|CMD_CANTNEST|CMD_SENDENVIRON, 0,
cmd_new_session_init,
cmd_new_session_parse,
cmd_new_session_exec,
@@ -52,7 +52,6 @@ const struct cmd_entry cmd_new_session_entry = {
cmd_new_session_print
};
/* ARGSUSED */
void
cmd_new_session_init(struct cmd *self, unused int arg)
{
@@ -60,7 +59,6 @@ cmd_new_session_init(struct cmd *self, unused int arg)
self->data = data = xmalloc(sizeof *data);
data->flag_detached = 0;
data->target = NULL;
data->newname = NULL;
data->winname = NULL;
data->cmd = NULL;
@@ -72,10 +70,10 @@ cmd_new_session_parse(struct cmd *self, int argc, char **argv, char **cause)
struct cmd_new_session_data *data;
int opt;
self->entry->init(self, KEYC_NONE);
self->entry->init(self, 0);
data = self->data;
while ((opt = getopt(argc, argv, "ds:t:n:")) != -1) {
while ((opt = getopt(argc, argv, "ds:n:")) != -1) {
switch (opt) {
case 'd':
data->flag_detached = 1;
@@ -84,10 +82,6 @@ cmd_new_session_parse(struct cmd *self, int argc, char **argv, char **cause)
if (data->newname == NULL)
data->newname = xstrdup(optarg);
break;
case 't':
if (data->target == NULL)
data->target = xstrdup(optarg);
break;
case 'n':
if (data->winname == NULL)
data->winname = xstrdup(optarg);
@@ -101,9 +95,6 @@ cmd_new_session_parse(struct cmd *self, int argc, char **argv, char **cause)
if (argc != 0 && argc != 1)
goto usage;
if (data->target != NULL && (argc == 1 || data->winname != NULL))
goto usage;
if (argc == 1)
data->cmd = xstrdup(argv[0]);
@@ -120,26 +111,20 @@ int
cmd_new_session_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_new_session_data *data = self->data;
struct session *s, *groupwith;
struct session *s;
struct window *w;
struct window_pane *wp;
struct environ env;
struct termios tio, *tiop;
const char *update;
char *overrides, *cmd, *cwd, *cause;
int detached, idx;
u_int sx, sy, i;
u_int sx, sy;
if (data->newname != NULL && session_find(data->newname) != NULL) {
ctx->error(ctx, "duplicate session: %s", data->newname);
return (-1);
}
groupwith = NULL;
if (data->target != NULL &&
(groupwith = cmd_find_session(ctx, data->target)) == NULL)
return (-1);
/*
* There are three cases:
*
@@ -185,8 +170,8 @@ cmd_new_session_exec(struct cmd *self, struct cmd_ctx *ctx)
ctx->error(ctx, "not a terminal");
return (-1);
}
overrides =
overrides =
options_get_string(&global_s_options, "terminal-overrides");
if (tty_open(&ctx->cmdclient->tty, overrides, &cause) != 0) {
ctx->error(ctx, "open terminal failed: %s", cause);
@@ -220,9 +205,7 @@ cmd_new_session_exec(struct cmd *self, struct cmd_ctx *ctx)
sy = 1;
/* Figure out the command for the new window. */
if (data->target != NULL)
cmd = NULL;
else if (data->cmd != NULL)
if (data->cmd != NULL)
cmd = data->cmd;
else
cmd = options_get_string(&global_s_options, "default-command");
@@ -245,7 +228,7 @@ cmd_new_session_exec(struct cmd *self, struct cmd_ctx *ctx)
environ_free(&env);
/* Set the initial window name if one given. */
if (cmd != NULL && data->winname != NULL) {
if (data->winname != NULL) {
w = s->curw->window;
xfree(w->name);
@@ -254,47 +237,21 @@ cmd_new_session_exec(struct cmd *self, struct cmd_ctx *ctx)
options_set_number(&w->options, "automatic-rename", 0);
}
/*
* If a target session is given, this is to be part of a session group,
* so add it to the group and synchronize.
*/
if (groupwith != NULL) {
session_group_add(groupwith, s);
session_group_synchronize_to(s);
session_select(s, RB_ROOT(&s->windows)->idx);
}
/*
* Set the client to the new session. If a command client exists, it is
* taking this session and needs to get MSG_READY and stay around.
*/
if (!detached) {
if (!detached) {
if (ctx->cmdclient != NULL) {
server_write_client(ctx->cmdclient, MSG_READY, NULL, 0);
ctx->cmdclient->session = s;
ctx->cmdclient->session = s;
server_redraw_client(ctx->cmdclient);
} else {
ctx->curclient->session = s;
ctx->curclient->session = s;
server_redraw_client(ctx->curclient);
}
}
recalculate_sizes();
server_update_socket();
/*
* If there are still configuration file errors to display, put the new
* session's current window into more mode and display them now.
*/
if (cfg_finished && !ARRAY_EMPTY(&cfg_causes)) {
wp = s->curw->window->active;
window_pane_set_mode(wp, &window_more_mode);
for (i = 0; i < ARRAY_LENGTH(&cfg_causes); i++) {
cause = ARRAY_ITEM(&cfg_causes, i);
window_more_add(wp, "%s", cause);
xfree(cause);
}
ARRAY_FREE(&cfg_causes);
}
return (!detached); /* 1 means don't tell command client to exit */
}
@@ -324,12 +281,10 @@ cmd_new_session_print(struct cmd *self, char *buf, size_t len)
return (off);
if (off < len && data->flag_detached)
off += xsnprintf(buf + off, len - off, " -d");
if (off < len && data->winname != NULL)
off += cmd_prarg(buf + off, len - off, " -n ", data->winname);
if (off < len && data->newname != NULL)
off += cmd_prarg(buf + off, len - off, " -s ", data->newname);
if (off < len && data->target != NULL)
off += cmd_prarg(buf + off, len - off, " -t ", data->target);
if (off < len && data->winname != NULL)
off += cmd_prarg(buf + off, len - off, " -n ", data->winname);
if (off < len && data->cmd != NULL)
off += cmd_prarg(buf + off, len - off, " ", data->cmd);
return (off);

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-new-window.c,v 1.43 2010-01-22 17:28:34 tcunha Exp $ */
/* $Id: cmd-new-window.c,v 1.37 2009-08-16 19:16:27 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -43,7 +43,7 @@ struct cmd_new_window_data {
const struct cmd_entry cmd_new_window_entry = {
"new-window", "neww",
"[-dk] [-n window-name] [-t target-window] [command]",
0, "",
0, 0,
cmd_new_window_init,
cmd_new_window_parse,
cmd_new_window_exec,
@@ -51,7 +51,6 @@ const struct cmd_entry cmd_new_window_entry = {
cmd_new_window_print
};
/* ARGSUSED */
void
cmd_new_window_init(struct cmd *self, unused int arg)
{
@@ -71,7 +70,7 @@ cmd_new_window_parse(struct cmd *self, int argc, char **argv, char **cause)
struct cmd_new_window_data *data;
int opt;
self->entry->init(self, KEYC_NONE);
self->entry->init(self, 0);
data = self->data;
while ((opt = getopt(argc, argv, "dkt:n:")) != -1) {
@@ -129,19 +128,21 @@ cmd_new_window_exec(struct cmd *self, struct cmd_ctx *ctx)
wl = NULL;
if (idx != -1)
wl = winlink_find_by_index(&s->windows, idx);
if (wl != NULL && data->flag_kill) {
/*
* Can't use session_detach as it will destroy session if this
* makes it empty.
*/
session_alert_cancel(s, wl);
winlink_stack_remove(&s->lastw, wl);
winlink_remove(&s->windows, wl);
if (wl != NULL) {
if (data->flag_kill) {
/*
* Can't use session_detach as it will destroy session
* if this makes it empty.
*/
session_alert_cancel(s, wl);
winlink_stack_remove(&s->lastw, wl);
winlink_remove(&s->windows, wl);
/* Force select/redraw if current. */
if (wl == s->curw) {
data->flag_detached = 0;
s->curw = NULL;
/* Force select/redraw if current. */
if (wl == s->curw) {
data->flag_detached = 0;
s->curw = NULL;
}
}
}
@@ -163,9 +164,9 @@ cmd_new_window_exec(struct cmd *self, struct cmd_ctx *ctx)
}
if (!data->flag_detached) {
session_select(s, wl->idx);
server_redraw_session_group(s);
server_redraw_session(s);
} else
server_status_session_group(s);
server_status_session(s);
return (0);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-next-layout.c,v 1.6 2009-11-14 17:56:39 tcunha Exp $ */
/* $Id: cmd-next-layout.c,v 1.5 2009-07-28 22:12:16 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,7 +29,7 @@ int cmd_next_layout_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_next_layout_entry = {
"next-layout", "nextl",
CMD_TARGET_WINDOW_USAGE,
0, "",
0, 0,
cmd_target_init,
cmd_target_parse,
cmd_next_layout_exec,

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-next-window.c,v 1.21 2009-11-14 17:56:39 tcunha Exp $ */
/* $Id: cmd-next-window.c,v 1.20 2009-07-28 22:12:16 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -30,7 +30,7 @@ int cmd_next_window_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_next_window_entry = {
"next-window", "next",
"[-a] " CMD_TARGET_SESSION_USAGE,
0, "a",
0, CMD_CHFLAG('a'),
cmd_next_window_init,
cmd_target_parse,
cmd_next_window_exec,
@@ -47,7 +47,7 @@ cmd_next_window_init(struct cmd *self, int key)
data = self->data;
if (key == ('n' | KEYC_ESCAPE))
cmd_set_flag(&data->chflags, 'a');
data->chflags |= CMD_CHFLAG('a');
}
int
@@ -61,7 +61,7 @@ cmd_next_window_exec(struct cmd *self, struct cmd_ctx *ctx)
return (-1);
activity = 0;
if (cmd_check_flag(data->chflags, 'a'))
if (data->chflags & CMD_CHFLAG('a'))
activity = 1;
if (session_next(s, activity) == 0)

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-paste-buffer.c,v 1.24 2009-12-04 22:14:47 tcunha Exp $ */
/* $Id: cmd-paste-buffer.c,v 1.20 2009-09-07 23:48:54 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -27,12 +27,12 @@
*/
int cmd_paste_buffer_exec(struct cmd *, struct cmd_ctx *);
void cmd_paste_buffer_lf2cr(struct window_pane *, const char *, size_t);
void cmd_paste_buffer_lf2cr(struct buffer *, const char *, size_t);
const struct cmd_entry cmd_paste_buffer_entry = {
"paste-buffer", "pasteb",
"[-dr] " CMD_BUFFER_WINDOW_USAGE,
0, "dr",
0, CMD_CHFLAG('d')|CMD_CHFLAG('r'),
cmd_buffer_init,
cmd_buffer_parse,
cmd_paste_buffer_exec,
@@ -62,39 +62,39 @@ cmd_paste_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
}
}
if (pb != NULL) {
if (pb != NULL && *pb->data != '\0') {
/* -r means raw data without LF->CR conversion. */
if (cmd_check_flag(data->chflags, 'r'))
bufferevent_write(wp->event, pb->data, pb->size);
if (data->chflags & CMD_CHFLAG('r'))
buffer_write(wp->out, pb->data, pb->size);
else
cmd_paste_buffer_lf2cr(wp, pb->data, pb->size);
cmd_paste_buffer_lf2cr(wp->out, pb->data, pb->size);
}
/* Delete the buffer if -d. */
if (cmd_check_flag(data->chflags, 'd')) {
if (data->chflags & CMD_CHFLAG('d')) {
if (data->buffer == -1)
paste_free_top(&s->buffers);
else
paste_free_index(&s->buffers, data->buffer);
}
return (0);
return (0);
}
/* Add bytes to a buffer but change every '\n' to '\r'. */
void
cmd_paste_buffer_lf2cr(struct window_pane *wp, const char *data, size_t size)
cmd_paste_buffer_lf2cr(struct buffer *b, const char *data, size_t size)
{
const char *end = data + size;
const char *lf;
while ((lf = memchr(data, '\n', end - data)) != NULL) {
if (lf != data)
bufferevent_write(wp->event, data, lf - data);
bufferevent_write(wp->event, "\r", 1);
buffer_write(b, data, lf - data);
buffer_write8(b, '\r');
data = lf + 1;
}
if (end != data)
bufferevent_write(wp->event, data, end - data);
buffer_write(b, data, end - data);
}

View File

@@ -1,141 +0,0 @@
/* $Id: cmd-pipe-pane.c,v 1.10 2009-12-04 22:14:47 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <sys/types.h>
#include <sys/socket.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
#include "tmux.h"
/*
* Open pipe to redirect pane output. If already open, close first.
*/
int cmd_pipe_pane_exec(struct cmd *, struct cmd_ctx *);
void cmd_pipe_pane_error_callback(struct bufferevent *, short, void *);
const struct cmd_entry cmd_pipe_pane_entry = {
"pipe-pane", "pipep",
CMD_TARGET_PANE_USAGE "[-o] [command]",
CMD_ARG01, "o",
cmd_target_init,
cmd_target_parse,
cmd_pipe_pane_exec,
cmd_target_free,
cmd_target_print
};
int
cmd_pipe_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_target_data *data = self->data;
struct window_pane *wp;
int old_fd, pipe_fd[2], null_fd, mode;
if (cmd_find_pane(ctx, data->target, NULL, &wp) == NULL)
return (-1);
/* Destroy the old pipe. */
old_fd = wp->pipe_fd;
if (wp->pipe_fd != -1) {
bufferevent_free(wp->pipe_event);
close(wp->pipe_fd);
wp->pipe_fd = -1;
}
/* If no pipe command, that is enough. */
if (data->arg == NULL || *data->arg == '\0')
return (0);
/*
* With -o, only open the new pipe if there was no previous one. This
* allows a pipe to be toggled with a single key, for example:
*
* bind ^p pipep -o 'cat >>~/output'
*/
if (cmd_check_flag(data->chflags, 'o') && old_fd != -1)
return (0);
/* Open the new pipe. */
if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, pipe_fd) != 0) {
ctx->error(ctx, "socketpair error: %s", strerror(errno));
return (-1);
}
/* Fork the child. */
switch (fork()) {
case -1:
ctx->error(ctx, "fork error: %s", strerror(errno));
return (-1);
case 0:
/* Child process. */
close(pipe_fd[0]);
server_signal_clear();
if (dup2(pipe_fd[1], STDIN_FILENO) == -1)
_exit(1);
if (pipe_fd[1] != STDIN_FILENO)
close(pipe_fd[1]);
null_fd = open(_PATH_DEVNULL, O_WRONLY, 0);
if (dup2(null_fd, STDOUT_FILENO) == -1)
_exit(1);
if (dup2(null_fd, STDERR_FILENO) == -1)
_exit(1);
if (null_fd != STDOUT_FILENO && null_fd != STDERR_FILENO)
close(null_fd);
execl(_PATH_BSHELL, "sh", "-c", data->arg, (char *) NULL);
_exit(1);
default:
/* Parent process. */
close(pipe_fd[1]);
wp->pipe_fd = pipe_fd[0];
wp->pipe_off = EVBUFFER_LENGTH(wp->event->input);
wp->pipe_event = bufferevent_new(wp->pipe_fd,
NULL, NULL, cmd_pipe_pane_error_callback, wp);
bufferevent_enable(wp->pipe_event, EV_WRITE);
if ((mode = fcntl(wp->pipe_fd, F_GETFL)) == -1)
fatal("fcntl failed");
if (fcntl(wp->pipe_fd, F_SETFL, mode|O_NONBLOCK) == -1)
fatal("fcntl failed");
if (fcntl(wp->pipe_fd, F_SETFD, FD_CLOEXEC) == -1)
fatal("fcntl failed");
return (0);
}
}
/* ARGSUSED */
void
cmd_pipe_pane_error_callback(
unused struct bufferevent *bufev, unused short what, void *data)
{
struct window_pane *wp = data;
bufferevent_free(wp->pipe_event);
close(wp->pipe_fd);
wp->pipe_fd = -1;
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-previous-layout.c,v 1.6 2009-12-04 22:14:47 tcunha Exp $ */
/* $Id: cmd-previous-layout.c,v 1.4 2009-07-28 22:12:16 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,7 +29,7 @@ int cmd_previous_layout_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_previous_layout_entry = {
"previous-layout", "prevl",
CMD_TARGET_WINDOW_USAGE,
0, "",
0, 0,
cmd_target_init,
cmd_target_parse,
cmd_previous_layout_exec,
@@ -43,7 +43,7 @@ cmd_previous_layout_exec(struct cmd *self, struct cmd_ctx *ctx)
struct cmd_target_data *data = self->data;
struct winlink *wl;
u_int layout;
if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
return (-1);

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-previous-window.c,v 1.21 2009-11-14 17:56:39 tcunha Exp $ */
/* $Id: cmd-previous-window.c,v 1.20 2009-07-28 22:12:16 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -30,7 +30,7 @@ int cmd_previous_window_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_previous_window_entry = {
"previous-window", "prev",
"[-a] " CMD_TARGET_SESSION_USAGE,
0, "a",
0, CMD_CHFLAG('a'),
cmd_previous_window_init,
cmd_target_parse,
cmd_previous_window_exec,
@@ -47,7 +47,7 @@ cmd_previous_window_init(struct cmd *self, int key)
data = self->data;
if (key == ('p' | KEYC_ESCAPE))
cmd_set_flag(&data->chflags, 'a');
data->chflags |= CMD_CHFLAG('a');
}
int
@@ -61,7 +61,7 @@ cmd_previous_window_exec(struct cmd *self, struct cmd_ctx *ctx)
return (-1);
activity = 0;
if (cmd_check_flag(data->chflags, 'a'))
if (data->chflags & CMD_CHFLAG('a'))
activity = 1;
if (session_previous(s, activity) == 0)

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-refresh-client.c,v 1.11 2009-11-14 17:56:39 tcunha Exp $ */
/* $Id: cmd-refresh-client.c,v 1.10 2009-07-28 22:12:16 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,7 +29,7 @@ int cmd_refresh_client_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_refresh_client_entry = {
"refresh-client", "refresh",
CMD_TARGET_CLIENT_USAGE,
0, "",
0, 0,
cmd_target_init,
cmd_target_parse,
cmd_refresh_client_exec,

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-rename-session.c,v 1.19 2009-11-14 17:56:39 tcunha Exp $ */
/* $Id: cmd-rename-session.c,v 1.18 2009-07-28 22:12:16 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -31,7 +31,7 @@ int cmd_rename_session_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_rename_session_entry = {
"rename-session", "rename",
CMD_TARGET_SESSION_USAGE " new-name",
CMD_ARG1, "",
CMD_ARG1, 0,
cmd_target_init,
cmd_target_parse,
cmd_rename_session_exec,

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-rename-window.c,v 1.31 2009-11-14 17:56:39 tcunha Exp $ */
/* $Id: cmd-rename-window.c,v 1.29 2009-07-28 22:12:16 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -31,7 +31,7 @@ int cmd_rename_window_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_rename_window_entry = {
"rename-window", "renamew",
CMD_TARGET_WINDOW_USAGE " new-name",
CMD_ARG1, "",
CMD_ARG1, 0,
cmd_target_init,
cmd_target_parse,
cmd_rename_window_exec,
@@ -53,7 +53,7 @@ cmd_rename_window_exec(struct cmd *self, struct cmd_ctx *ctx)
wl->window->name = xstrdup(data->arg);
options_set_number(&wl->window->options, "automatic-rename", 0);
server_status_window(wl->window);
server_status_session(s);
return (0);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-resize-pane.c,v 1.14 2009-12-04 22:14:47 tcunha Exp $ */
/* $Id: cmd-resize-pane.c,v 1.12 2009-07-30 20:45:20 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -31,8 +31,9 @@ int cmd_resize_pane_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_resize_pane_entry = {
"resize-pane", "resizep",
"[-DLRU] " CMD_TARGET_PANE_USAGE " [adjustment]",
CMD_ARG01, "DLRU",
"[-DU] " CMD_TARGET_PANE_USAGE " [adjustment]",
CMD_ARG01,
CMD_CHFLAG('D')|CMD_CHFLAG('L')|CMD_CHFLAG('R')|CMD_CHFLAG('U'),
cmd_resize_pane_init,
cmd_target_parse,
cmd_resize_pane_exec,
@@ -49,28 +50,28 @@ cmd_resize_pane_init(struct cmd *self, int key)
data = self->data;
if (key == (KEYC_UP | KEYC_CTRL))
cmd_set_flag(&data->chflags, 'U');
data->chflags |= CMD_CHFLAG('U');
if (key == (KEYC_DOWN | KEYC_CTRL))
cmd_set_flag(&data->chflags, 'D');
data->chflags |= CMD_CHFLAG('D');
if (key == (KEYC_LEFT | KEYC_CTRL))
cmd_set_flag(&data->chflags, 'L');
data->chflags |= CMD_CHFLAG('L');
if (key == (KEYC_RIGHT | KEYC_CTRL))
cmd_set_flag(&data->chflags, 'R');
data->chflags |= CMD_CHFLAG('R');
if (key == (KEYC_UP | KEYC_ESCAPE)) {
cmd_set_flag(&data->chflags, 'U');
data->chflags |= CMD_CHFLAG('U');
data->arg = xstrdup("5");
}
if (key == (KEYC_DOWN | KEYC_ESCAPE)) {
cmd_set_flag(&data->chflags, 'D');
data->chflags |= CMD_CHFLAG('D');
data->arg = xstrdup("5");
}
if (key == (KEYC_LEFT | KEYC_ESCAPE)) {
cmd_set_flag(&data->chflags, 'L');
data->chflags |= CMD_CHFLAG('L');
data->arg = xstrdup("5");
}
if (key == (KEYC_RIGHT | KEYC_ESCAPE)) {
cmd_set_flag(&data->chflags, 'R');
data->chflags |= CMD_CHFLAG('R');
data->arg = xstrdup("5");
}
}
@@ -97,14 +98,15 @@ cmd_resize_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
}
}
if (cmd_check_flag(data->chflags, 'L'))
layout_resize_pane(wp, LAYOUT_LEFTRIGHT, -adjust);
else if (cmd_check_flag(data->chflags, 'R'))
if (data->chflags & (CMD_CHFLAG('L')|CMD_CHFLAG('R'))) {
if (data->chflags & CMD_CHFLAG('L'))
adjust = -adjust;
layout_resize_pane(wp, LAYOUT_LEFTRIGHT, adjust);
else if (cmd_check_flag(data->chflags, 'U'))
layout_resize_pane(wp, LAYOUT_TOPBOTTOM, -adjust);
else if (cmd_check_flag(data->chflags, 'D'))
} else {
if (data->chflags & CMD_CHFLAG('U'))
adjust = -adjust;
layout_resize_pane(wp, LAYOUT_TOPBOTTOM, adjust);
}
server_redraw_window(wl->window);
return (0);

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-respawn-window.c,v 1.25 2009-12-04 22:14:47 tcunha Exp $ */
/* $Id: cmd-respawn-window.c,v 1.22 2009-09-16 12:36:27 nicm Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -31,7 +31,7 @@ int cmd_respawn_window_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_respawn_window_entry = {
"respawn-window", "respawnw",
"[-k] " CMD_TARGET_WINDOW_USAGE " [command]",
CMD_ARG01, "k",
CMD_ARG01, CMD_CHFLAG('k'),
cmd_target_init,
cmd_target_parse,
cmd_respawn_window_exec,
@@ -54,7 +54,7 @@ cmd_respawn_window_exec(struct cmd *self, struct cmd_ctx *ctx)
return (-1);
w = wl->window;
if (!cmd_check_flag(data->chflags, 'k')) {
if (!(data->chflags & CMD_CHFLAG('k'))) {
TAILQ_FOREACH(wp, &w->panes, entry) {
if (wp->fd == -1)
continue;
@@ -72,7 +72,7 @@ cmd_respawn_window_exec(struct cmd *self, struct cmd_ctx *ctx)
wp = TAILQ_FIRST(&w->panes);
TAILQ_REMOVE(&w->panes, wp, entry);
layout_free(w);
window_destroy_panes(w);
window_destroy_panes(w);
TAILQ_INSERT_HEAD(&w->panes, wp, entry);
window_pane_resize(wp, w->sx, w->sy);
if (window_pane_spawn(
@@ -80,7 +80,6 @@ cmd_respawn_window_exec(struct cmd *self, struct cmd_ctx *ctx)
ctx->error(ctx, "respawn window failed: %s", cause);
xfree(cause);
environ_free(&env);
server_destroy_pane(wp);
return (-1);
}
layout_init(w);

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-rotate-window.c,v 1.10 2009-11-14 17:56:39 tcunha Exp $ */
/* $Id: cmd-rotate-window.c,v 1.9 2009-07-28 22:12:16 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -30,7 +30,7 @@ int cmd_rotate_window_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_rotate_window_entry = {
"rotate-window", "rotatew",
"[-DU] " CMD_TARGET_WINDOW_USAGE,
0, "DU",
0, CMD_CHFLAG('D')|CMD_CHFLAG('U'),
cmd_rotate_window_init,
cmd_target_parse,
cmd_rotate_window_exec,
@@ -47,7 +47,7 @@ cmd_rotate_window_init(struct cmd *self, int key)
data = self->data;
if (key == ('o' | KEYC_ESCAPE))
cmd_set_flag(&data->chflags, 'D');
data->chflags |= CMD_CHFLAG('D');
}
int
@@ -64,7 +64,7 @@ cmd_rotate_window_exec(struct cmd *self, struct cmd_ctx *ctx)
return (-1);
w = wl->window;
if (cmd_check_flag(data->chflags, 'D')) {
if (data->chflags & CMD_CHFLAG('D')) {
wp = TAILQ_LAST(&w->panes, window_panes);
TAILQ_REMOVE(&w->panes, wp, entry);
TAILQ_INSERT_HEAD(&w->panes, wp, entry);

View File

@@ -1,139 +0,0 @@
/* $Id: cmd-run-shell.c,v 1.6 2009-11-14 17:56:39 tcunha Exp $ */
/*
* Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org>
* Copyright (c) 2009 Nicholas Marriott <nicm@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <sys/types.h>
#include <sys/wait.h>
#include <string.h>
#include "tmux.h"
/*
* Runs a command without a window.
*/
int cmd_run_shell_exec(struct cmd *, struct cmd_ctx *);
void cmd_run_shell_callback(struct job *);
void cmd_run_shell_free(void *);
const struct cmd_entry cmd_run_shell_entry = {
"run-shell", "run",
"command",
CMD_ARG1, "",
cmd_target_init,
cmd_target_parse,
cmd_run_shell_exec,
cmd_target_free,
cmd_target_print
};
struct cmd_run_shell_data {
char *cmd;
struct cmd_ctx ctx;
};
int
cmd_run_shell_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_target_data *data = self->data;
struct cmd_run_shell_data *cdata;
struct job *job;
cdata = xmalloc(sizeof *cdata);
cdata->cmd = xstrdup(data->arg);
memcpy(&cdata->ctx, ctx, sizeof cdata->ctx);
if (ctx->cmdclient != NULL)
ctx->cmdclient->references++;
if (ctx->curclient != NULL)
ctx->curclient->references++;
job = job_add(NULL, 0, NULL,
data->arg, cmd_run_shell_callback, cmd_run_shell_free, cdata);
job_run(job);
return (1); /* don't let client exit */
}
void
cmd_run_shell_callback(struct job *job)
{
struct cmd_run_shell_data *cdata = job->data;
struct cmd_ctx *ctx = &cdata->ctx;
char *cmd, *msg, *line;
size_t size;
int retcode;
u_int lines;
lines = 0;
do {
if ((line = evbuffer_readline(job->event->input)) != NULL) {
ctx->print(ctx, "%s", line);
lines++;
}
} while (line != NULL);
size = EVBUFFER_LENGTH(job->event->input);
if (size != 0) {
line = xmalloc(size + 1);
memcpy(line, EVBUFFER_DATA(job->event->input), size);
line[size] = '\0';
ctx->print(ctx, "%s", line);
lines++;
xfree(line);
}
cmd = cdata->cmd;
msg = NULL;
if (WIFEXITED(job->status)) {
if ((retcode = WEXITSTATUS(job->status)) != 0)
xasprintf(&msg, "'%s' returned %d", cmd, retcode);
} else if (WIFSIGNALED(job->status)) {
retcode = WTERMSIG(job->status);
xasprintf(&msg, "'%s' terminated by signal %d", cmd, retcode);
}
if (msg != NULL) {
if (lines != 0)
ctx->print(ctx, "%s", msg);
else
ctx->info(ctx, "%s", msg);
xfree(msg);
}
}
void
cmd_run_shell_free(void *data)
{
struct cmd_run_shell_data *cdata = data;
struct cmd_ctx *ctx = &cdata->ctx;
if (ctx->cmdclient != NULL) {
ctx->cmdclient->references--;
server_write_client(ctx->cmdclient, MSG_EXIT, NULL, 0);
}
if (ctx->curclient != NULL)
ctx->curclient->references--;
xfree(cdata->cmd);
xfree(cdata);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-save-buffer.c,v 1.10 2009-11-14 17:56:39 tcunha Exp $ */
/* $Id: cmd-save-buffer.c,v 1.8 2009-09-07 23:48:54 tcunha Exp $ */
/*
* Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org>
@@ -33,7 +33,7 @@ int cmd_save_buffer_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_save_buffer_entry = {
"save-buffer", "saveb",
"[-a] " CMD_BUFFER_SESSION_USAGE " path",
CMD_ARG1, "a",
CMD_ARG1, CMD_CHFLAG('a'),
cmd_buffer_init,
cmd_buffer_parse,
cmd_save_buffer_exec,
@@ -66,11 +66,10 @@ cmd_save_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
}
mask = umask(S_IRWXG | S_IRWXO);
if (cmd_check_flag(data->chflags, 'a'))
if (data->chflags & CMD_CHFLAG('a'))
f = fopen(data->arg, "ab");
else
f = fopen(data->arg, "wb");
umask(mask);
if (f == NULL) {
ctx->error(ctx, "%s: %s", data->arg, strerror(errno));
return (-1);
@@ -83,6 +82,7 @@ cmd_save_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
}
fclose(f);
umask(mask);
return (0);
}

View File

@@ -1,7 +1,7 @@
/* $Id: cmd-lock-session.c,v 1.2 2009-11-14 17:56:39 tcunha Exp $ */
/* $Id: cmd-scroll-mode.c,v 1.23 2009-08-20 11:37:46 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -21,33 +21,50 @@
#include "tmux.h"
/*
* Lock all clients attached to a session.
* Enter scroll mode.
*/
int cmd_lock_session_exec(struct cmd *, struct cmd_ctx *);
void cmd_scroll_mode_init(struct cmd *, int);
int cmd_scroll_mode_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_lock_session_entry = {
"lock-session", "locks",
CMD_TARGET_SESSION_USAGE,
0, "",
cmd_target_init,
const struct cmd_entry cmd_scroll_mode_entry = {
"scroll-mode", NULL,
"[-u] " CMD_TARGET_PANE_USAGE,
0, CMD_CHFLAG('u'),
cmd_scroll_mode_init,
cmd_target_parse,
cmd_lock_session_exec,
cmd_scroll_mode_exec,
cmd_target_free,
cmd_target_print
};
void
cmd_scroll_mode_init(struct cmd *self, int key)
{
struct cmd_target_data *data;
cmd_target_init(self, key);
data = self->data;
switch (key) {
case KEYC_PPAGE:
data->chflags |= CMD_CHFLAG('u');
break;
}
}
int
cmd_lock_session_exec(struct cmd *self, struct cmd_ctx *ctx)
cmd_scroll_mode_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_target_data *data = self->data;
struct session *s;
struct window_pane *wp;
if ((s = cmd_find_session(ctx, data->target)) == NULL)
if (cmd_find_pane(ctx, data->target, NULL, &wp) == NULL)
return (-1);
server_lock_session(s);
recalculate_sizes();
window_pane_set_mode(wp, &window_scroll_mode);
if (wp->mode == &window_scroll_mode && data->chflags & CMD_CHFLAG('u'))
window_scroll_pageup(wp);
return (0);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-select-layout.c,v 1.10 2009-12-04 22:14:47 tcunha Exp $ */
/* $Id: cmd-select-layout.c,v 1.8 2009-07-28 23:04:29 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -30,7 +30,7 @@ int cmd_select_layout_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_select_layout_entry = {
"select-layout", "selectl",
CMD_TARGET_WINDOW_USAGE " [layout-name]",
CMD_ARG01, "",
CMD_ARG01, 0,
cmd_select_layout_init,
cmd_target_parse,
cmd_select_layout_exec,
@@ -52,7 +52,7 @@ cmd_select_layout_init(struct cmd *self, int key)
break;
case ('2' | KEYC_ESCAPE):
data->arg = xstrdup("even-vertical");
break;
break;
case ('3' | KEYC_ESCAPE):
data->arg = xstrdup("main-horizontal");
break;
@@ -80,7 +80,7 @@ cmd_select_layout_exec(struct cmd *self, struct cmd_ctx *ctx)
ctx->error(ctx, "unknown layout or ambiguous: %s", data->arg);
return (-1);
}
layout = layout_set_select(wl->window, layout);
ctx->info(ctx, "arranging in: %s", layout_set_name(layout));

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-select-pane.c,v 1.12 2010-01-05 23:52:37 tcunha Exp $ */
/* $Id: cmd-select-pane.c,v 1.10 2009-07-30 20:45:20 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,7 +29,7 @@ int cmd_select_pane_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_select_pane_entry = {
"select-pane", "selectp",
CMD_TARGET_PANE_USAGE,
0, "",
0, 0,
cmd_target_init,
cmd_target_parse,
cmd_select_pane_exec,
@@ -53,7 +53,6 @@ cmd_select_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
}
window_set_active_pane(wl->window, wp);
server_status_window(wl->window);
server_redraw_window_borders(wl->window);
return (0);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-select-prompt.c,v 1.13 2009-11-14 17:56:39 tcunha Exp $ */
/* $Id: cmd-select-prompt.c,v 1.12 2009-08-16 19:29:24 tcunha Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -33,7 +33,7 @@ int cmd_select_prompt_callback(void *, const char *);
const struct cmd_entry cmd_select_prompt_entry = {
"select-prompt", NULL,
CMD_TARGET_CLIENT_USAGE,
0, "",
0, 0,
cmd_target_init,
cmd_target_parse,
cmd_select_prompt_exec,

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-select-window.c,v 1.24 2009-11-14 17:56:39 tcunha Exp $ */
/* $Id: cmd-select-window.c,v 1.23 2009-07-28 22:12:16 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -32,7 +32,7 @@ int cmd_select_window_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_select_window_entry = {
"select-window", "selectw",
CMD_TARGET_WINDOW_USAGE,
0, "",
0, 0,
cmd_select_window_init,
cmd_target_parse,
cmd_select_window_exec,

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-send-keys.c,v 1.24 2009-12-04 22:14:47 tcunha Exp $ */
/* $Id: cmd-send-keys.c,v 1.21 2009-08-20 11:37:46 tcunha Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -33,14 +33,15 @@ size_t cmd_send_keys_print(struct cmd *, char *, size_t);
struct cmd_send_keys_data {
char *target;
u_int nkeys;
int idx;
u_int nkeys;
int *keys;
};
const struct cmd_entry cmd_send_keys_entry = {
"send-keys", "send",
"[-t target-pane] key ...",
0, "",
0, 0,
NULL,
cmd_send_keys_parse,
cmd_send_keys_exec,
@@ -57,6 +58,7 @@ cmd_send_keys_parse(struct cmd *self, int argc, char **argv, char **cause)
self->data = data = xmalloc(sizeof *data);
data->target = NULL;
data->idx = -1;
data->nkeys = 0;
data->keys = NULL;
@@ -141,6 +143,8 @@ cmd_send_keys_print(struct cmd *self, char *buf, size_t len)
return (off);
if (off < len && data->target != NULL)
off += cmd_prarg(buf + off, len - off, " -t ", data->target);
if (off < len && data->idx != -1)
off += xsnprintf(buf + off, len - off, " -i %d", data->idx);
for (i = 0; i < data->nkeys; i++) {
if (off >= len)

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-send-prefix.c,v 1.28 2009-11-14 17:56:39 tcunha Exp $ */
/* $Id: cmd-send-prefix.c,v 1.26 2009-08-20 11:37:46 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,7 +29,7 @@ int cmd_send_prefix_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_send_prefix_entry = {
"send-prefix", NULL,
CMD_TARGET_PANE_USAGE,
0, "",
0, 0,
cmd_target_init,
cmd_target_parse,
cmd_send_prefix_exec,
@@ -43,13 +43,13 @@ cmd_send_prefix_exec(struct cmd *self, struct cmd_ctx *ctx)
struct cmd_target_data *data = self->data;
struct session *s;
struct window_pane *wp;
struct keylist *keylist;
int key;
if (cmd_find_pane(ctx, data->target, &s, &wp) == NULL)
return (-1);
keylist = options_get_data(&s->options, "prefix");
window_pane_key(wp, ctx->curclient, ARRAY_FIRST(keylist));
key = options_get_number(&s->options, "prefix");
window_pane_key(wp, ctx->curclient, key);
return (0);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-server-info.c,v 1.37 2009-12-10 16:59:02 tcunha Exp $ */
/* $Id: cmd-server-info.c,v 1.28 2009-09-07 23:59:19 tcunha Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -35,7 +35,7 @@ int cmd_server_info_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_server_info_entry = {
"server-info", "info",
"",
0, "",
0, 0,
NULL,
NULL,
cmd_server_info_exec,
@@ -43,7 +43,6 @@ const struct cmd_entry cmd_server_info_entry = {
NULL
};
/* ARGSUSED */
int
cmd_server_info_exec(unused struct cmd *self, struct cmd_ctx *ctx)
{
@@ -56,7 +55,6 @@ cmd_server_info_exec(unused struct cmd *self, struct cmd_ctx *ctx)
struct tty_code *code;
struct tty_term_code_entry *ent;
struct utsname un;
struct job *job;
struct grid *gd;
struct grid_line *gl;
u_int i, j, k;
@@ -70,10 +68,11 @@ cmd_server_info_exec(unused struct cmd *self, struct cmd_ctx *ctx)
*strchr(tim, '\n') = '\0';
ctx->print(ctx,
"tmux " BUILD ", pid %ld, started %s", (long) getpid(), tim);
ctx->print(
ctx, "socket path %s, debug level %d", socket_path, debug_level);
if (uname(&un) == 0) {
ctx->print(ctx, "system is %s %s %s %s",
ctx->print(ctx, "socket path %s, debug level %d%s%s",
socket_path, debug_level, be_quiet ? ", quiet" : "",
login_shell ? ", login shell" : "");
if (uname(&un) == 0) {
ctx->print(ctx, "system is %s %s %s %s",
un.sysname, un.release, un.version, un.machine);
}
if (cfg_file != NULL)
@@ -94,19 +93,19 @@ cmd_server_info_exec(unused struct cmd *self, struct cmd_ctx *ctx)
ctx->print(ctx, "%2d: %s (%d, %d): %s [%ux%u %s] "
"[flags=0x%x/0x%x, references=%u]", i, c->tty.path,
c->ibuf.fd, c->tty.fd, c->session->name,
c->tty.sx, c->tty.sy, c->tty.termname, c->flags,
c->tty.sx, c->tty.sy, c->tty.termname, c->flags,
c->tty.flags, c->references);
}
ctx->print(ctx, "%s", "");
ctx->print(ctx, "Sessions: [%zu/%zu]",
ctx->print(ctx, "Sessions: [%zu/%zu]",
sizeof (struct grid_cell), sizeof (struct grid_utf8));
for (i = 0; i < ARRAY_LENGTH(&sessions); i++) {
s = ARRAY_ITEM(&sessions, i);
if (s == NULL)
continue;
t = s->creation_time.tv_sec;
t = s->tv.tv_sec;
tim = ctime(&t);
*strchr(tim, '\n') = '\0';
@@ -148,7 +147,7 @@ cmd_server_info_exec(unused struct cmd *self, struct cmd_ctx *ctx)
}
ctx->print(ctx, "%s", "");
ctx->print(ctx, "Terminals:");
ctx->print(ctx, "Terminals:");
SLIST_FOREACH(term, &tty_terms, entry) {
ctx->print(ctx, "%s [references=%u, flags=0x%x]:",
term->name, term->references, term->flags);
@@ -180,11 +179,5 @@ cmd_server_info_exec(unused struct cmd *self, struct cmd_ctx *ctx)
}
ctx->print(ctx, "%s", "");
ctx->print(ctx, "Jobs:");
SLIST_FOREACH(job, &all_jobs, lentry) {
ctx->print(ctx, "%s [fd=%d, pid=%d, status=%d, flags=0x%x]",
job->cmd, job->fd, job->pid, job->status, job->flags);
}
return (0);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-set-buffer.c,v 1.12 2009-11-28 14:54:12 tcunha Exp $ */
/* $Id: cmd-set-buffer.c,v 1.10 2009-09-07 23:48:54 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -31,7 +31,7 @@ int cmd_set_buffer_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_set_buffer_entry = {
"set-buffer", "setb",
CMD_BUFFER_SESSION_USAGE " data",
CMD_ARG1, "",
CMD_ARG1, 0,
cmd_buffer_init,
cmd_buffer_parse,
cmd_set_buffer_exec,
@@ -45,7 +45,7 @@ cmd_set_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
struct cmd_buffer_data *data = self->data;
struct session *s;
u_int limit;
char *pdata;
u_char *pdata;
size_t psize;
if ((s = cmd_find_session(ctx, data->target)) == NULL)

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-set-environment.c,v 1.3 2009-11-14 17:56:39 tcunha Exp $ */
/* $Id: cmd-set-environment.c,v 1.2 2009-08-11 14:42:59 nicm Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -32,7 +32,7 @@ int cmd_set_environment_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_set_environment_entry = {
"set-environment", "setenv",
"[-gru] " CMD_TARGET_SESSION_USAGE " name [value]",
CMD_ARG12, "gru",
CMD_ARG12, CMD_CHFLAG('g')|CMD_CHFLAG('r')|CMD_CHFLAG('u'),
NULL,
cmd_target_parse,
cmd_set_environment_exec,
@@ -56,7 +56,7 @@ cmd_set_environment_exec(struct cmd *self, struct cmd_ctx *ctx)
return (-1);
}
if (cmd_check_flag(data->chflags, 'g'))
if (data->chflags & CMD_CHFLAG('g'))
env = &global_environ;
else {
if ((s = cmd_find_session(ctx, data->target)) == NULL)
@@ -64,13 +64,13 @@ cmd_set_environment_exec(struct cmd *self, struct cmd_ctx *ctx)
env = &s->environ;
}
if (cmd_check_flag(data->chflags, 'u')) {
if (data->chflags & CMD_CHFLAG('u')) {
if (data->arg2 != NULL) {
ctx->error(ctx, "can't specify a value with -u");
return (-1);
}
environ_unset(env, data->arg);
} else if (cmd_check_flag(data->chflags, 'r')) {
} else if (data->chflags & CMD_CHFLAG('r')) {
if (data->arg2 != NULL) {
ctx->error(ctx, "can't specify a value with -r");
return (-1);

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-set-option.c,v 1.96 2010-02-26 13:31:39 tcunha Exp $ */
/* $Id: cmd-set-option.c,v 1.79 2009-09-19 18:53:01 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,27 +29,10 @@
int cmd_set_option_exec(struct cmd *, struct cmd_ctx *);
const char *cmd_set_option_print(
const struct set_option_entry *, struct options_entry *);
void cmd_set_option_string(struct cmd_ctx *,
struct options *, const struct set_option_entry *, char *, int);
void cmd_set_option_number(struct cmd_ctx *,
struct options *, const struct set_option_entry *, char *);
void cmd_set_option_keys(struct cmd_ctx *,
struct options *, const struct set_option_entry *, char *);
void cmd_set_option_colour(struct cmd_ctx *,
struct options *, const struct set_option_entry *, char *);
void cmd_set_option_attributes(struct cmd_ctx *,
struct options *, const struct set_option_entry *, char *);
void cmd_set_option_flag(struct cmd_ctx *,
struct options *, const struct set_option_entry *, char *);
void cmd_set_option_choice(struct cmd_ctx *,
struct options *, const struct set_option_entry *, char *);
const struct cmd_entry cmd_set_option_entry = {
"set-option", "set",
"[-agsuw] [-t target-session|target-window] option [value]",
CMD_ARG12, "agsuw",
"[-agu] " CMD_TARGET_SESSION_USAGE " option [value]",
CMD_ARG12, CMD_CHFLAG('a')|CMD_CHFLAG('g')|CMD_CHFLAG('u'),
NULL,
cmd_target_parse,
cmd_set_option_exec,
@@ -57,12 +40,6 @@ const struct cmd_entry cmd_set_option_entry = {
cmd_target_print
};
const char *set_option_mode_keys_list[] = {
"emacs", "vi", NULL
};
const char *set_option_clock_mode_style_list[] = {
"12", "24", NULL
};
const char *set_option_status_keys_list[] = {
"emacs", "vi", NULL
};
@@ -72,14 +49,7 @@ const char *set_option_status_justify_list[] = {
const char *set_option_bell_action_list[] = {
"none", "any", "current", NULL
};
const struct set_option_entry set_option_table[] = {
{ "escape-time", SET_OPTION_NUMBER, 0, INT_MAX, NULL },
{ "quiet", SET_OPTION_FLAG, 0, 0, NULL },
{ NULL, 0, 0, 0, NULL }
};
const struct set_option_entry set_session_option_table[] = {
{ "base-index", SET_OPTION_NUMBER, 0, INT_MAX, NULL },
{ "bell-action", SET_OPTION_CHOICE, 0, 0, set_option_bell_action_list },
{ "buffer-limit", SET_OPTION_NUMBER, 1, INT_MAX, NULL },
@@ -88,23 +58,14 @@ const struct set_option_entry set_session_option_table[] = {
{ "default-shell", SET_OPTION_STRING, 0, 0, NULL },
{ "default-terminal", SET_OPTION_STRING, 0, 0, NULL },
{ "display-panes-colour", SET_OPTION_COLOUR, 0, 0, NULL },
{ "display-panes-active-colour", SET_OPTION_COLOUR, 0, 0, NULL },
{ "display-panes-time", SET_OPTION_NUMBER, 1, INT_MAX, NULL },
{ "display-time", SET_OPTION_NUMBER, 1, INT_MAX, NULL },
{ "history-limit", SET_OPTION_NUMBER, 0, INT_MAX, NULL },
{ "lock-after-time", SET_OPTION_NUMBER, 0, INT_MAX, NULL },
{ "lock-command", SET_OPTION_STRING, 0, 0, NULL },
{ "lock-server", SET_OPTION_FLAG, 0, 0, NULL },
{ "message-attr", SET_OPTION_ATTRIBUTES, 0, 0, NULL },
{ "message-bg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "message-fg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "message-limit", SET_OPTION_NUMBER, 0, INT_MAX, NULL },
{ "mouse-select-pane", SET_OPTION_FLAG, 0, 0, NULL },
{ "pane-active-border-bg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "pane-active-border-fg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "pane-border-bg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "pane-border-fg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "prefix", SET_OPTION_KEYS, 0, 0, NULL },
{ "prefix", SET_OPTION_KEY, 0, 0, NULL },
{ "repeat-time", SET_OPTION_NUMBER, 0, SHRT_MAX, NULL },
{ "set-remain-on-exit", SET_OPTION_FLAG, 0, 0, NULL },
{ "set-titles", SET_OPTION_FLAG, 0, 0, NULL },
@@ -114,7 +75,7 @@ const struct set_option_entry set_session_option_table[] = {
{ "status-bg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "status-fg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "status-interval", SET_OPTION_NUMBER, 0, INT_MAX, NULL },
{ "status-justify",
{ "status-justify",
SET_OPTION_CHOICE, 0, 0, set_option_status_justify_list },
{ "status-keys", SET_OPTION_CHOICE, 0, 0, set_option_status_keys_list },
{ "status-left", SET_OPTION_STRING, 0, 0, NULL },
@@ -127,87 +88,31 @@ const struct set_option_entry set_session_option_table[] = {
{ "status-right-bg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "status-right-fg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "status-right-length", SET_OPTION_NUMBER, 0, SHRT_MAX, NULL },
{ "status-utf8", SET_OPTION_FLAG, 0, 0, NULL },
{ "status-utf8", SET_OPTION_FLAG, 0, 0, NULL },
{ "terminal-overrides", SET_OPTION_STRING, 0, 0, NULL },
{ "update-environment", SET_OPTION_STRING, 0, 0, NULL },
{ "visual-activity", SET_OPTION_FLAG, 0, 0, NULL },
{ "visual-bell", SET_OPTION_FLAG, 0, 0, NULL },
{ "visual-bell", SET_OPTION_FLAG, 0, 0, NULL },
{ "visual-content", SET_OPTION_FLAG, 0, 0, NULL },
{ NULL, 0, 0, 0, NULL }
};
const struct set_option_entry set_window_option_table[] = {
{ "aggressive-resize", SET_OPTION_FLAG, 0, 0, NULL },
{ "alternate-screen", SET_OPTION_FLAG, 0, 0, NULL },
{ "automatic-rename", SET_OPTION_FLAG, 0, 0, NULL },
{ "clock-mode-colour", SET_OPTION_COLOUR, 0, 0, NULL },
{ "clock-mode-style",
SET_OPTION_CHOICE, 0, 0, set_option_clock_mode_style_list },
{ "force-height", SET_OPTION_NUMBER, 0, INT_MAX, NULL },
{ "force-width", SET_OPTION_NUMBER, 0, INT_MAX, NULL },
{ "main-pane-height", SET_OPTION_NUMBER, 1, INT_MAX, NULL },
{ "main-pane-width", SET_OPTION_NUMBER, 1, INT_MAX, NULL },
{ "mode-attr", SET_OPTION_ATTRIBUTES, 0, 0, NULL },
{ "mode-bg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "mode-fg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "mode-keys", SET_OPTION_CHOICE, 0, 0, set_option_mode_keys_list },
{ "mode-mouse", SET_OPTION_FLAG, 0, 0, NULL },
{ "monitor-activity", SET_OPTION_FLAG, 0, 0, NULL },
{ "monitor-content", SET_OPTION_STRING, 0, 0, NULL },
{ "remain-on-exit", SET_OPTION_FLAG, 0, 0, NULL },
{ "synchronize-panes", SET_OPTION_FLAG, 0, 0, NULL },
{ "utf8", SET_OPTION_FLAG, 0, 0, NULL },
{ "window-status-attr", SET_OPTION_ATTRIBUTES, 0, 0, NULL },
{ "window-status-bg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "window-status-current-attr", SET_OPTION_ATTRIBUTES, 0, 0, NULL },
{ "window-status-current-bg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "window-status-current-fg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "window-status-current-format", SET_OPTION_STRING, 0, 0, NULL },
{ "window-status-fg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "window-status-format", SET_OPTION_STRING, 0, 0, NULL },
{ "word-separators", SET_OPTION_STRING, 0, 0, NULL },
{ "xterm-keys", SET_OPTION_FLAG, 0, 0, NULL },
{ NULL, 0, 0, 0, NULL }
};
int
cmd_set_option_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_target_data *data = self->data;
const struct set_option_entry *table;
struct session *s;
struct winlink *wl;
struct client *c;
struct options *oo;
const struct set_option_entry *entry, *opt;
struct jobs *jobs;
struct job *job, *nextjob;
u_int i;
int try_again;
if (cmd_check_flag(data->chflags, 's')) {
oo = &global_options;
table = set_option_table;
} else if (cmd_check_flag(data->chflags, 'w')) {
table = set_window_option_table;
if (cmd_check_flag(data->chflags, 'g'))
oo = &global_w_options;
else {
wl = cmd_find_window(ctx, data->target, NULL);
if (wl == NULL)
return (-1);
oo = &wl->window->options;
}
} else {
table = set_session_option_table;
if (cmd_check_flag(data->chflags, 'g'))
oo = &global_s_options;
else {
s = cmd_find_session(ctx, data->target);
if (s == NULL)
return (-1);
oo = &s->options;
}
if (data->chflags & CMD_CHFLAG('g'))
oo = &global_s_options;
else {
if ((s = cmd_find_session(ctx, data->target)) == NULL)
return (-1);
oo = &s->options;
}
if (*data->arg == '\0') {
@@ -216,7 +121,7 @@ cmd_set_option_exec(struct cmd *self, struct cmd_ctx *ctx)
}
entry = NULL;
for (opt = table; opt->name != NULL; opt++) {
for (opt = set_option_table; opt->name != NULL; opt++) {
if (strncmp(opt->name, data->arg, strlen(data->arg)) != 0)
continue;
if (entry != NULL) {
@@ -234,8 +139,8 @@ cmd_set_option_exec(struct cmd *self, struct cmd_ctx *ctx)
return (-1);
}
if (cmd_check_flag(data->chflags, 'u')) {
if (cmd_check_flag(data->chflags, 'g')) {
if (data->chflags & CMD_CHFLAG('u')) {
if (data->chflags & CMD_CHFLAG('g')) {
ctx->error(ctx,
"can't unset global option: %s", entry->name);
return (-1);
@@ -251,26 +156,26 @@ cmd_set_option_exec(struct cmd *self, struct cmd_ctx *ctx)
} else {
switch (entry->type) {
case SET_OPTION_STRING:
cmd_set_option_string(ctx, oo, entry,
data->arg2, cmd_check_flag(data->chflags, 'a'));
set_option_string(ctx, oo, entry,
data->arg2, data->chflags & CMD_CHFLAG('a'));
break;
case SET_OPTION_NUMBER:
cmd_set_option_number(ctx, oo, entry, data->arg2);
set_option_number(ctx, oo, entry, data->arg2);
break;
case SET_OPTION_KEYS:
cmd_set_option_keys(ctx, oo, entry, data->arg2);
case SET_OPTION_KEY:
set_option_key(ctx, oo, entry, data->arg2);
break;
case SET_OPTION_COLOUR:
cmd_set_option_colour(ctx, oo, entry, data->arg2);
set_option_colour(ctx, oo, entry, data->arg2);
break;
case SET_OPTION_ATTRIBUTES:
cmd_set_option_attributes(ctx, oo, entry, data->arg2);
set_option_attributes(ctx, oo, entry, data->arg2);
break;
case SET_OPTION_FLAG:
cmd_set_option_flag(ctx, oo, entry, data->arg2);
set_option_flag(ctx, oo, entry, data->arg2);
break;
case SET_OPTION_CHOICE:
cmd_set_option_choice(ctx, oo, entry, data->arg2);
set_option_choice(ctx, oo, entry, data->arg2);
break;
}
}
@@ -282,277 +187,5 @@ cmd_set_option_exec(struct cmd *self, struct cmd_ctx *ctx)
server_redraw_client(c);
}
/*
* Special-case: kill all persistent jobs if status-left, status-right
* or set-titles-string have changed. Persistent jobs are only used by
* the status line at the moment so this works XXX.
*/
if (strcmp(entry->name, "status-left") == 0 ||
strcmp(entry->name, "status-right") == 0 ||
strcmp(entry->name, "set-titles-string") == 0 ||
strcmp(entry->name, "window-status-format") == 0) {
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
c = ARRAY_ITEM(&clients, i);
if (c == NULL || c->session == NULL)
continue;
jobs = &c->status_jobs;
do {
try_again = 0;
job = RB_ROOT(jobs);
while (job != NULL) {
nextjob = RB_NEXT(jobs, jobs, job);
if (job->flags & JOB_PERSIST) {
job_remove(jobs, job);
try_again = 1;
break;
}
job = nextjob;
}
} while (try_again);
server_redraw_client(c);
}
}
return (0);
}
const char *
cmd_set_option_print(
const struct set_option_entry *entry, struct options_entry *o)
{
static char out[BUFSIZ];
const char *s;
struct keylist *keylist;
u_int i;
*out = '\0';
switch (entry->type) {
case SET_OPTION_STRING:
xsnprintf(out, sizeof out, "\"%s\"", o->str);
break;
case SET_OPTION_NUMBER:
xsnprintf(out, sizeof out, "%lld", o->num);
break;
case SET_OPTION_KEYS:
keylist = o->data;
for (i = 0; i < ARRAY_LENGTH(keylist); i++) {
strlcat(out, key_string_lookup_key(
ARRAY_ITEM(keylist, i)), sizeof out);
if (i != ARRAY_LENGTH(keylist) - 1)
strlcat(out, ",", sizeof out);
}
break;
case SET_OPTION_COLOUR:
s = colour_tostring(o->num);
xsnprintf(out, sizeof out, "%s", s);
break;
case SET_OPTION_ATTRIBUTES:
s = attributes_tostring(o->num);
xsnprintf(out, sizeof out, "%s", s);
break;
case SET_OPTION_FLAG:
if (o->num)
strlcpy(out, "on", sizeof out);
else
strlcpy(out, "off", sizeof out);
break;
case SET_OPTION_CHOICE:
s = entry->choices[o->num];
xsnprintf(out, sizeof out, "%s", s);
break;
}
return (out);
}
void
cmd_set_option_string(struct cmd_ctx *ctx, struct options *oo,
const struct set_option_entry *entry, char *value, int append)
{
struct options_entry *o;
char *oldvalue, *newvalue;
if (value == NULL) {
ctx->error(ctx, "empty value");
return;
}
if (append) {
oldvalue = options_get_string(oo, entry->name);
xasprintf(&newvalue, "%s%s", oldvalue, value);
} else
newvalue = value;
o = options_set_string(oo, entry->name, "%s", newvalue);
ctx->info(ctx,
"set option: %s -> %s", o->name, cmd_set_option_print(entry, o));
if (newvalue != value)
xfree(newvalue);
}
void
cmd_set_option_number(struct cmd_ctx *ctx, struct options *oo,
const struct set_option_entry *entry, char *value)
{
struct options_entry *o;
long long number;
const char *errstr;
if (value == NULL) {
ctx->error(ctx, "empty value");
return;
}
number = strtonum(value, entry->minimum, entry->maximum, &errstr);
if (errstr != NULL) {
ctx->error(ctx, "value is %s: %s", errstr, value);
return;
}
o = options_set_number(oo, entry->name, number);
ctx->info(ctx,
"set option: %s -> %s", o->name, cmd_set_option_print(entry, o));
}
void
cmd_set_option_keys(struct cmd_ctx *ctx, struct options *oo,
const struct set_option_entry *entry, char *value)
{
struct options_entry *o;
struct keylist *keylist;
char *copyvalue, *ptr, *str;
int key;
if (value == NULL) {
ctx->error(ctx, "empty value");
return;
}
keylist = xmalloc(sizeof *keylist);
ARRAY_INIT(keylist);
ptr = copyvalue = xstrdup(value);
while ((str = strsep(&ptr, ",")) != NULL) {
if ((key = key_string_lookup_string(str)) == KEYC_NONE) {
xfree(keylist);
ctx->error(ctx, "unknown key: %s", str);
xfree(copyvalue);
return;
}
ARRAY_ADD(keylist, key);
}
xfree(copyvalue);
o = options_set_data(oo, entry->name, keylist, xfree);
ctx->info(ctx,
"set option: %s -> %s", o->name, cmd_set_option_print(entry, o));
}
void
cmd_set_option_colour(struct cmd_ctx *ctx, struct options *oo,
const struct set_option_entry *entry, char *value)
{
struct options_entry *o;
int colour;
if (value == NULL) {
ctx->error(ctx, "empty value");
return;
}
if ((colour = colour_fromstring(value)) == -1) {
ctx->error(ctx, "bad colour: %s", value);
return;
}
o = options_set_number(oo, entry->name, colour);
ctx->info(ctx,
"set option: %s -> %s", o->name, cmd_set_option_print(entry, o));
}
void
cmd_set_option_attributes(struct cmd_ctx *ctx, struct options *oo,
const struct set_option_entry *entry, char *value)
{
struct options_entry *o;
int attr;
if (value == NULL) {
ctx->error(ctx, "empty value");
return;
}
if ((attr = attributes_fromstring(value)) == -1) {
ctx->error(ctx, "bad attributes: %s", value);
return;
}
o = options_set_number(oo, entry->name, attr);
ctx->info(ctx,
"set option: %s -> %s", o->name, cmd_set_option_print(entry, o));
}
void
cmd_set_option_flag(struct cmd_ctx *ctx, struct options *oo,
const struct set_option_entry *entry, char *value)
{
struct options_entry *o;
int flag;
if (value == NULL || *value == '\0')
flag = !options_get_number(oo, entry->name);
else {
if ((value[0] == '1' && value[1] == '\0') ||
strcasecmp(value, "on") == 0 ||
strcasecmp(value, "yes") == 0)
flag = 1;
else if ((value[0] == '0' && value[1] == '\0') ||
strcasecmp(value, "off") == 0 ||
strcasecmp(value, "no") == 0)
flag = 0;
else {
ctx->error(ctx, "bad value: %s", value);
return;
}
}
o = options_set_number(oo, entry->name, flag);
ctx->info(ctx,
"set option: %s -> %s", o->name, cmd_set_option_print(entry, o));
}
void
cmd_set_option_choice(struct cmd_ctx *ctx, struct options *oo,
const struct set_option_entry *entry, char *value)
{
struct options_entry *o;
const char **choicep;
int n, choice = -1;
if (value == NULL) {
ctx->error(ctx, "empty value");
return;
}
n = 0;
for (choicep = entry->choices; *choicep != NULL; choicep++) {
n++;
if (strncmp(*choicep, value, strlen(value)) != 0)
continue;
if (choice != -1) {
ctx->error(ctx, "ambiguous option value: %s", value);
return;
}
choice = n - 1;
}
if (choice == -1) {
ctx->error(ctx, "unknown option value: %s", value);
return;
}
o = options_set_number(oo, entry->name, choice);
ctx->info(ctx,
"set option: %s -> %s", o->name, cmd_set_option_print(entry, o));
}

145
cmd-set-password.c Normal file
View File

@@ -0,0 +1,145 @@
/* $Id: cmd-set-password.c,v 1.8 2009-07-28 22:12:16 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <sys/types.h>
#include <pwd.h>
#include <unistd.h>
#include "tmux.h"
/*
* Set server password.
*/
int cmd_set_password_parse(struct cmd *, int, char **, char **);
int cmd_set_password_exec(struct cmd *, struct cmd_ctx *);
void cmd_set_password_free(struct cmd *);
void cmd_set_password_init(struct cmd *, int);
size_t cmd_set_password_print(struct cmd *, char *, size_t);
struct cmd_set_password_data {
char *password;
int flag_encrypted;
};
const struct cmd_entry cmd_set_password_entry = {
"set-password", "pass",
"[-c] password",
0, 0,
cmd_set_password_init,
cmd_set_password_parse,
cmd_set_password_exec,
cmd_set_password_free,
cmd_set_password_print
};
void
cmd_set_password_init(struct cmd *self, unused int arg)
{
struct cmd_set_password_data *data;
self->data = data = xmalloc(sizeof *data);
data->password = NULL;
data->flag_encrypted = 0;
}
int
cmd_set_password_parse(struct cmd *self, int argc, char **argv, char **cause)
{
struct cmd_set_password_data *data;
int opt;
char *out;
self->entry->init(self, 0);
data = self->data;
while ((opt = getopt(argc, argv, "c")) != -1) {
switch (opt) {
case 'c':
data->flag_encrypted = 1;
break;
default:
goto usage;
}
}
argc -= optind;
argv += optind;
if (argc != 1)
goto usage;
if (!data->flag_encrypted) {
if ((out = crypt(argv[0], "$1")) != NULL)
data->password = xstrdup(out);
} else
data->password = xstrdup(argv[0]);
return (0);
usage:
xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
self->entry->free(self);
return (-1);
}
int
cmd_set_password_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_set_password_data *data = self->data;
if (data->password == NULL) {
ctx->error(ctx, "failed to encrypt password");
return (-1);
}
if (server_password != NULL)
xfree(server_password);
if (*data->password == '\0')
server_password = NULL;
else
server_password = xstrdup(data->password);
return (0);
}
void
cmd_set_password_free(struct cmd *self)
{
struct cmd_set_password_data *data = self->data;
if (data->password != NULL)
xfree(data->password);
xfree(data);
}
size_t
cmd_set_password_print(struct cmd *self, char *buf, size_t len)
{
struct cmd_set_password_data *data = self->data;
size_t off = 0;
off += xsnprintf(buf, len, "%s", self->entry->name);
if (data == NULL)
return (off);
if (off < len && data->flag_encrypted)
off += xsnprintf(buf + off, len - off, " -c");
if (off < len && data->password != NULL)
off += xsnprintf(buf + off, len - off, " password");
return (off);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-set-window-option.c,v 1.43 2009-12-04 22:11:23 tcunha Exp $ */
/* $Id: cmd-set-window-option.c,v 1.38 2009-08-11 14:42:59 nicm Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -18,10 +18,13 @@
#include <sys/types.h>
#include <stdlib.h>
#include <string.h>
#include "tmux.h"
/*
* Set a window option. This is just an alias for set-option -w.
* Set a window option.
*/
int cmd_set_window_option_exec(struct cmd *, struct cmd_ctx *);
@@ -29,7 +32,7 @@ int cmd_set_window_option_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_set_window_option_entry = {
"set-window-option", "setw",
"[-agu] " CMD_TARGET_WINDOW_USAGE " option [value]",
CMD_ARG12, "agu",
CMD_ARG12, CMD_CHFLAG('a')|CMD_CHFLAG('g')|CMD_CHFLAG('u'),
NULL,
cmd_target_parse,
cmd_set_window_option_exec,
@@ -37,11 +40,130 @@ const struct cmd_entry cmd_set_window_option_entry = {
cmd_target_print
};
const char *set_option_mode_keys_list[] = {
"emacs", "vi", NULL
};
const char *set_option_clock_mode_style_list[] = {
"12", "24", NULL
};
const struct set_option_entry set_window_option_table[] = {
{ "aggressive-resize", SET_OPTION_FLAG, 0, 0, NULL },
{ "automatic-rename", SET_OPTION_FLAG, 0, 0, NULL },
{ "clock-mode-colour", SET_OPTION_COLOUR, 0, 0, NULL },
{ "clock-mode-style",
SET_OPTION_CHOICE, 0, 0, set_option_clock_mode_style_list },
{ "force-height", SET_OPTION_NUMBER, 0, INT_MAX, NULL },
{ "force-width", SET_OPTION_NUMBER, 0, INT_MAX, NULL },
{ "main-pane-height", SET_OPTION_NUMBER, 1, INT_MAX, NULL },
{ "main-pane-width", SET_OPTION_NUMBER, 1, INT_MAX, NULL },
{ "mode-attr", SET_OPTION_ATTRIBUTES, 0, 0, NULL },
{ "mode-bg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "mode-fg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "mode-keys", SET_OPTION_CHOICE, 0, 0, set_option_mode_keys_list },
{ "mode-mouse", SET_OPTION_FLAG, 0, 0, NULL },
{ "monitor-activity", SET_OPTION_FLAG, 0, 0, NULL },
{ "monitor-content", SET_OPTION_STRING, 0, 0, NULL },
{ "remain-on-exit", SET_OPTION_FLAG, 0, 0, NULL },
{ "utf8", SET_OPTION_FLAG, 0, 0, NULL },
{ "window-status-attr", SET_OPTION_ATTRIBUTES, 0, 0, NULL },
{ "window-status-bg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "window-status-current-attr", SET_OPTION_ATTRIBUTES, 0, 0, NULL },
{ "window-status-current-bg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "window-status-current-fg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "window-status-fg", SET_OPTION_COLOUR, 0, 0, NULL },
{ "xterm-keys", SET_OPTION_FLAG, 0, 0, NULL },
{ NULL, 0, 0, 0, NULL }
};
int
cmd_set_window_option_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_target_data *data = self->data;
struct winlink *wl;
struct client *c;
struct options *oo;
const struct set_option_entry *entry, *opt;
u_int i;
cmd_set_flag(&data->chflags, 'w');
return (cmd_set_option_entry.exec(self, ctx));
if (data->chflags & CMD_CHFLAG('g'))
oo = &global_w_options;
else {
if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
return (-1);
oo = &wl->window->options;
}
if (*data->arg == '\0') {
ctx->error(ctx, "invalid option");
return (-1);
}
entry = NULL;
for (opt = set_window_option_table; opt->name != NULL; opt++) {
if (strncmp(opt->name, data->arg, strlen(data->arg)) != 0)
continue;
if (entry != NULL) {
ctx->error(ctx, "ambiguous option: %s", data->arg);
return (-1);
}
entry = opt;
/* Bail now if an exact match. */
if (strcmp(entry->name, data->arg) == 0)
break;
}
if (entry == NULL) {
ctx->error(ctx, "unknown option: %s", data->arg);
return (-1);
}
if (data->chflags & CMD_CHFLAG('u')) {
if (data->chflags & CMD_CHFLAG('g')) {
ctx->error(ctx,
"can't unset global option: %s", entry->name);
return (-1);
}
if (data->arg2 != NULL) {
ctx->error(ctx,
"value passed to unset option: %s", entry->name);
return (-1);
}
options_remove(oo, entry->name);
ctx->info(ctx, "unset option: %s", entry->name);
} else {
switch (entry->type) {
case SET_OPTION_STRING:
set_option_string(ctx, oo, entry,
data->arg2, data->chflags & CMD_CHFLAG('a'));
break;
case SET_OPTION_NUMBER:
set_option_number(ctx, oo, entry, data->arg2);
break;
case SET_OPTION_KEY:
set_option_key(ctx, oo, entry, data->arg2);
break;
case SET_OPTION_COLOUR:
set_option_colour(ctx, oo, entry, data->arg2);
break;
case SET_OPTION_ATTRIBUTES:
set_option_attributes(ctx, oo, entry, data->arg2);
break;
case SET_OPTION_FLAG:
set_option_flag(ctx, oo, entry, data->arg2);
break;
case SET_OPTION_CHOICE:
set_option_choice(ctx, oo, entry, data->arg2);
break;
}
}
recalculate_sizes();
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
c = ARRAY_ITEM(&clients, i);
if (c != NULL && c->session != NULL)
server_redraw_client(c);
}
return (0);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-show-buffer.c,v 1.12 2009-12-04 22:14:47 tcunha Exp $ */
/* $Id: cmd-show-buffer.c,v 1.10 2009-09-07 23:48:54 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,7 +29,7 @@ int cmd_show_buffer_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_show_buffer_entry = {
"show-buffer", "showb",
CMD_BUFFER_SESSION_USAGE,
0, "",
0, 0,
cmd_buffer_init,
cmd_buffer_parse,
cmd_show_buffer_exec,
@@ -71,24 +71,24 @@ cmd_show_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
width = s->sx;
if (ctx->cmdclient != NULL)
width = ctx->cmdclient->tty.sx;
buf = xmalloc(width + 1);
len = 0;
ptr = in;
do {
buf[len++] = *ptr++;
if (len == width || buf[len - 1] == '\n') {
if (buf[len - 1] == '\n')
len--;
buf[len] = '\0';
ctx->print(ctx, "%s", buf);
ctx->print(ctx, "%s", buf);
len = 0;
}
} while (*ptr != '\0');
if (len != 0) {
buf[len] = '\0';
ctx->print(ctx, "%s", buf);

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-show-environment.c,v 1.2 2009-11-14 17:56:39 tcunha Exp $ */
/* $Id: cmd-show-environment.c,v 1.1 2009-08-09 17:48:55 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -32,7 +32,7 @@ int cmd_show_environment_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_show_environment_entry = {
"show-environment", "showenv",
"[-g] " CMD_TARGET_SESSION_USAGE,
0, "g",
0, CMD_CHFLAG('g'),
cmd_target_init,
cmd_target_parse,
cmd_show_environment_exec,
@@ -48,7 +48,7 @@ cmd_show_environment_exec(struct cmd *self, struct cmd_ctx *ctx)
struct environ *env;
struct environ_entry *envent;
if (cmd_check_flag(data->chflags, 'g'))
if (data->chflags & CMD_CHFLAG('g'))
env = &global_environ;
else {
if ((s = cmd_find_session(ctx, data->target)) == NULL)

View File

@@ -1,65 +0,0 @@
/* $Id: cmd-show-messages.c,v 1.2 2009-12-04 22:14:47 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <sys/types.h>
#include <string.h>
#include <time.h>
#include "tmux.h"
/*
* Show client message log.
*/
int cmd_show_messages_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_show_messages_entry = {
"show-messages", "showmsgs",
CMD_TARGET_CLIENT_USAGE,
0, "",
cmd_target_init,
cmd_target_parse,
cmd_show_messages_exec,
cmd_target_free,
cmd_target_print
};
int
cmd_show_messages_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_target_data *data = self->data;
struct client *c;
struct message_entry *msg;
char *tim;
u_int i;
if ((c = cmd_find_client(ctx, data->target)) == NULL)
return (-1);
for (i = 0; i < ARRAY_LENGTH(&c->message_log); i++) {
msg = &ARRAY_ITEM(&c->message_log, i);
tim = ctime(&msg->msg_time);
*strchr(tim, '\n') = '\0';
ctx->print(ctx, "%s %s", tim, msg->msg);
}
return (0);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-show-options.c,v 1.21 2009-12-10 16:59:02 tcunha Exp $ */
/* $Id: cmd-show-options.c,v 1.16 2009-07-28 22:12:16 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -31,8 +31,8 @@ int cmd_show_options_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_show_options_entry = {
"show-options", "show",
"[-gsw] [-t target-session|target-window]",
0, "gsw",
"[-g] " CMD_TARGET_SESSION_USAGE,
0, CMD_CHFLAG('g'),
cmd_target_init,
cmd_target_parse,
cmd_show_options_exec,
@@ -44,44 +44,61 @@ int
cmd_show_options_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_target_data *data = self->data;
const struct set_option_entry *table;
struct session *s;
struct winlink *wl;
struct options *oo;
struct options_entry *o;
const struct set_option_entry *entry;
const char *optval;
char *vs;
long long vn;
if (cmd_check_flag(data->chflags, 's')) {
oo = &global_options;
table = set_option_table;
} else if (cmd_check_flag(data->chflags, 'w')) {
table = set_window_option_table;
if (cmd_check_flag(data->chflags, 'g'))
oo = &global_w_options;
else {
wl = cmd_find_window(ctx, data->target, NULL);
if (wl == NULL)
return (-1);
oo = &wl->window->options;
}
} else {
table = set_session_option_table;
if (cmd_check_flag(data->chflags, 'g'))
oo = &global_s_options;
else {
s = cmd_find_session(ctx, data->target);
if (s == NULL)
return (-1);
oo = &s->options;
}
if (data->chflags & CMD_CHFLAG('g'))
oo = &global_s_options;
else {
if ((s = cmd_find_session(ctx, data->target)) == NULL)
return (-1);
oo = &s->options;
}
for (entry = table; entry->name != NULL; entry++) {
if ((o = options_find1(oo, entry->name)) == NULL)
for (entry = set_option_table; entry->name != NULL; entry++) {
if (options_find1(oo, entry->name) == NULL)
continue;
optval = cmd_set_option_print(entry, o);
ctx->print(ctx, "%s %s", entry->name, optval);
switch (entry->type) {
case SET_OPTION_STRING:
vs = options_get_string(oo, entry->name);
ctx->print(ctx, "%s \"%s\"", entry->name, vs);
break;
case SET_OPTION_NUMBER:
vn = options_get_number(oo, entry->name);
ctx->print(ctx, "%s %lld", entry->name, vn);
break;
case SET_OPTION_KEY:
vn = options_get_number(oo, entry->name);
ctx->print(ctx, "%s %s",
entry->name, key_string_lookup_key(vn));
break;
case SET_OPTION_COLOUR:
vn = options_get_number(oo, entry->name);
ctx->print(ctx, "%s %s",
entry->name, colour_tostring(vn));
break;
case SET_OPTION_ATTRIBUTES:
vn = options_get_number(oo, entry->name);
ctx->print(ctx, "%s %s",
entry->name, attributes_tostring(vn));
break;
case SET_OPTION_FLAG:
vn = options_get_number(oo, entry->name);
if (vn)
ctx->print(ctx, "%s on", entry->name);
else
ctx->print(ctx, "%s off", entry->name);
break;
case SET_OPTION_CHOICE:
vn = options_get_number(oo, entry->name);
ctx->print(ctx, "%s %s",
entry->name, entry->choices[vn]);
break;
}
}
return (0);

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-show-window-options.c,v 1.15 2009-12-04 22:11:23 tcunha Exp $ */
/* $Id: cmd-show-window-options.c,v 1.12 2009-07-28 22:12:16 tcunha Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -24,7 +24,7 @@
#include "tmux.h"
/*
* Show window options. This is an alias for show-options -w.
* Show window options.
*/
int cmd_show_window_options_exec(struct cmd *, struct cmd_ctx *);
@@ -32,7 +32,7 @@ int cmd_show_window_options_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_show_window_options_entry = {
"show-window-options", "showw",
"[-g] " CMD_TARGET_WINDOW_USAGE,
0, "g",
0, CMD_CHFLAG('g'),
cmd_target_init,
cmd_target_parse,
cmd_show_window_options_exec,
@@ -44,7 +44,62 @@ int
cmd_show_window_options_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_target_data *data = self->data;
struct winlink *wl;
struct options *oo;
const struct set_option_entry *entry;
char *vs;
long long vn;
cmd_set_flag(&data->chflags, 'w');
return (cmd_show_options_entry.exec(self, ctx));
if (data->chflags & CMD_CHFLAG('g'))
oo = &global_w_options;
else {
if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
return (-1);
oo = &wl->window->options;
}
for (entry = set_window_option_table; entry->name != NULL; entry++) {
if (options_find1(oo, entry->name) == NULL)
continue;
switch (entry->type) {
case SET_OPTION_STRING:
vs = options_get_string(oo, entry->name);
ctx->print(ctx, "%s \"%s\"", entry->name, vs);
break;
case SET_OPTION_NUMBER:
vn = options_get_number(oo, entry->name);
ctx->print(ctx, "%s %lld", entry->name, vn);
break;
case SET_OPTION_KEY:
vn = options_get_number(oo, entry->name);
ctx->print(ctx, "%s %s",
entry->name, key_string_lookup_key(vn));
break;
case SET_OPTION_COLOUR:
vn = options_get_number(oo, entry->name);
ctx->print(ctx, "%s %s",
entry->name, colour_tostring(vn));
break;
case SET_OPTION_ATTRIBUTES:
vn = options_get_number(oo, entry->name);
ctx->print(ctx, "%s %s",
entry->name, attributes_tostring(vn));
break;
case SET_OPTION_FLAG:
vn = options_get_number(oo, entry->name);
if (vn)
ctx->print(ctx, "%s on", entry->name);
else
ctx->print(ctx, "%s off", entry->name);
break;
case SET_OPTION_CHOICE:
vn = options_get_number(oo, entry->name);
ctx->print(ctx, "%s %s",
entry->name, entry->choices[vn]);
break;
}
}
return (0);
}

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-source-file.c,v 1.13 2010-02-08 18:29:32 tcunha Exp $ */
/* $Id: cmd-source-file.c,v 1.8 2009-08-24 16:27:03 tcunha Exp $ */
/*
* Copyright (c) 2008 Tiago Cunha <me@tiagocunha.org>
@@ -37,7 +37,7 @@ struct cmd_source_file_data {
const struct cmd_entry cmd_source_file_entry = {
"source-file", "source",
"path",
0, "",
0, 0,
cmd_source_file_init,
cmd_source_file_parse,
cmd_source_file_exec,
@@ -45,7 +45,6 @@ const struct cmd_entry cmd_source_file_entry = {
cmd_source_file_print
};
/* ARGSUSED */
void
cmd_source_file_init(struct cmd *self, unused int arg)
{
@@ -61,7 +60,7 @@ cmd_source_file_parse(struct cmd *self, int argc, char **argv, char **cause)
struct cmd_source_file_data *data;
int opt;
self->entry->init(self, KEYC_NONE);
self->entry->init(self, 0);
data = self->data;
while ((opt = getopt(argc, argv, "")) != -1) {
@@ -89,18 +88,12 @@ int
cmd_source_file_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_source_file_data *data = self->data;
struct causelist causes;
char *cause;
u_int i;
ARRAY_INIT(&causes);
if (load_cfg(data->path, ctx, &causes) != 0) {
for (i = 0; i < ARRAY_LENGTH(&causes); i++) {
cause = ARRAY_ITEM(&causes, i);
ctx->print(ctx, "%s", cause);
xfree(cause);
}
ARRAY_FREE(&causes);
if (load_cfg(data->path, ctx, &cause) != 0) {
ctx->error(ctx, "%s", cause);
xfree(cause);
return (-1);
}
return (0);

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-split-window.c,v 1.34 2010-01-08 16:31:35 tcunha Exp $ */
/* $Id: cmd-split-window.c,v 1.27 2009-09-16 12:36:27 nicm Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -44,8 +44,8 @@ struct cmd_split_window_data {
const struct cmd_entry cmd_split_window_entry = {
"split-window", "splitw",
"[-dhv] [-p percentage|-l size] [-t target-pane] [command]",
0, "",
"[-dhv] [-p percentage|-l size] [-t target-window] [command]",
0, 0,
cmd_split_window_init,
cmd_split_window_parse,
cmd_split_window_exec,
@@ -69,7 +69,7 @@ cmd_split_window_init(struct cmd *self, int key)
switch (key) {
case '%':
data->flag_horizontal = 1;
break;
break;
case '"':
data->flag_horizontal = 0;
break;
@@ -83,7 +83,7 @@ cmd_split_window_parse(struct cmd *self, int argc, char **argv, char **cause)
int opt;
const char *errstr;
self->entry->init(self, KEYC_NONE);
self->entry->init(self, 0);
data = self->data;
while ((opt = getopt(argc, argv, "dhl:p:t:v")) != -1) {
@@ -148,16 +148,15 @@ cmd_split_window_exec(struct cmd *self, struct cmd_ctx *ctx)
struct session *s;
struct winlink *wl;
struct window *w;
struct window_pane *wp, *new_wp = NULL;
struct window_pane *wp;
struct environ env;
char *cmd, *cwd, *cause;
const char *shell;
u_int hlimit;
int size;
enum layout_type type;
struct layout_cell *lc;
if ((wl = cmd_find_pane(ctx, data->target, &s, &wp)) == NULL)
if ((wl = cmd_find_window(ctx, data->target, &s)) == NULL)
return (-1);
w = wl->window;
@@ -174,39 +173,33 @@ cmd_split_window_exec(struct cmd *self, struct cmd_ctx *ctx)
else
cwd = ctx->cmdclient->cwd;
type = LAYOUT_TOPBOTTOM;
if (data->flag_horizontal)
type = LAYOUT_LEFTRIGHT;
size = -1;
if (data->size != -1)
size = data->size;
else if (data->percentage != -1) {
if (type == LAYOUT_TOPBOTTOM)
size = (wp->sy * data->percentage) / 100;
else
size = (wp->sx * data->percentage) / 100;
}
else if (data->percentage != -1)
size = (w->active->sy * data->percentage) / 100;
hlimit = options_get_number(&s->options, "history-limit");
type = LAYOUT_TOPBOTTOM;
if (data->flag_horizontal)
type = LAYOUT_LEFTRIGHT;
shell = options_get_string(&s->options, "default-shell");
if (*shell == '\0' || areshell(shell))
shell = _PATH_BSHELL;
if ((lc = layout_split_pane(wp, type, size)) == NULL) {
wp = window_add_pane(w, hlimit);
if (window_pane_spawn(wp, cmd, shell, cwd, &env, s->tio, &cause) != 0)
goto error;
if (layout_split_pane(w->active, type, size, wp) != 0) {
cause = xstrdup("pane too small");
goto error;
}
new_wp = window_add_pane(w, hlimit);
if (window_pane_spawn(
new_wp, cmd, shell, cwd, &env, s->tio, &cause) != 0)
goto error;
layout_assign_pane(lc, new_wp);
server_redraw_window(w);
if (!data->flag_detached) {
window_set_active_pane(w, new_wp);
window_set_active_pane(w, wp);
session_select(s, wl->idx);
server_redraw_session(s);
} else
@@ -217,8 +210,8 @@ cmd_split_window_exec(struct cmd *self, struct cmd_ctx *ctx)
error:
environ_free(&env);
if (new_wp != NULL)
window_remove_pane(w, new_wp);
if (wp != NULL)
window_remove_pane(w, wp);
ctx->error(ctx, "create pane failed: %s", cause);
xfree(cause);
return (-1);

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-start-server.c,v 1.10 2009-11-28 14:50:36 tcunha Exp $ */
/* $Id: cmd-start-server.c,v 1.8 2009-07-28 22:12:16 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,7 +29,7 @@ int cmd_start_server_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_start_server_entry = {
"start-server", "start",
"",
CMD_STARTSERVER, "",
CMD_STARTSERVER, 0,
NULL,
NULL,
cmd_start_server_exec,
@@ -37,7 +37,6 @@ const struct cmd_entry cmd_start_server_entry = {
NULL
};
/* ARGSUSED */
int
cmd_start_server_exec(unused struct cmd *self, unused struct cmd_ctx *ctx)
{

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-string.c,v 1.31 2010-02-26 13:27:38 tcunha Exp $ */
/* $Id: cmd-string.c,v 1.23 2009-08-09 17:48:55 tcunha Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -32,7 +32,7 @@
*/
int cmd_string_getc(const char *, size_t *);
void cmd_string_ungetc(size_t *);
void cmd_string_ungetc(const char *, size_t *);
char *cmd_string_string(const char *, size_t *, char, int);
char *cmd_string_variable(const char *, size_t *);
char *cmd_string_expand_tilde(const char *, size_t *);
@@ -40,15 +40,13 @@ char *cmd_string_expand_tilde(const char *, size_t *);
int
cmd_string_getc(const char *s, size_t *p)
{
const u_char *ucs = s;
if (ucs[*p] == '\0')
if (s[*p] == '\0')
return (EOF);
return (ucs[(*p)++]);
return (s[(*p)++]);
}
void
cmd_string_ungetc(size_t *p)
cmd_string_ungetc(unused const char *s, size_t *p)
{
(*p)--;
}
@@ -61,7 +59,7 @@ int
cmd_string_parse(const char *s, struct cmd_list **cmdlist, char **cause)
{
size_t p;
int ch, i, argc, rval;
int ch, i, argc, rval, have_arg;
char **argv, *buf, *t;
const char *whitespace, *equals;
size_t len;
@@ -72,6 +70,8 @@ cmd_string_parse(const char *s, struct cmd_list **cmdlist, char **cause)
buf = NULL;
len = 0;
have_arg = 0;
*cause = NULL;
*cmdlist = NULL;
@@ -88,6 +88,8 @@ cmd_string_parse(const char *s, struct cmd_list **cmdlist, char **cause)
strlcpy(buf + len, t, strlen(t) + 1);
len += strlen(t);
xfree(t);
have_arg = 1;
break;
case '"':
if ((t = cmd_string_string(s, &p, '"', 1)) == NULL)
@@ -96,6 +98,8 @@ cmd_string_parse(const char *s, struct cmd_list **cmdlist, char **cause)
strlcpy(buf + len, t, strlen(t) + 1);
len += strlen(t);
xfree(t);
have_arg = 1;
break;
case '$':
if ((t = cmd_string_variable(s, &p)) == NULL)
@@ -104,6 +108,8 @@ cmd_string_parse(const char *s, struct cmd_list **cmdlist, char **cause)
strlcpy(buf + len, t, strlen(t) + 1);
len += strlen(t);
xfree(t);
have_arg = 1;
break;
case '#':
/* Comment: discard rest of line. */
@@ -113,7 +119,7 @@ cmd_string_parse(const char *s, struct cmd_list **cmdlist, char **cause)
case EOF:
case ' ':
case '\t':
if (buf != NULL) {
if (have_arg) {
buf = xrealloc(buf, 1, len + 1);
buf[len] = '\0';
@@ -122,19 +128,23 @@ cmd_string_parse(const char *s, struct cmd_list **cmdlist, char **cause)
buf = NULL;
len = 0;
have_arg = 0;
}
if (ch != EOF)
break;
if (argc == 0)
goto out;
while (argc != 0) {
equals = strchr(argv[0], '=');
whitespace = argv[0] + strcspn(argv[0], " \t");
for (i = 0; i < argc; i++) {
equals = strchr(argv[i], '=');
whitespace = argv[i] + strcspn(argv[i], " \t");
if (equals == NULL || equals > whitespace)
break;
environ_put(&global_environ, argv[0]);
environ_put(&global_environ, argv[i]);
memmove(&argv[i], &argv[i + 1], argc - i - 1);
argc--;
memmove(argv, argv + 1, argc * (sizeof *argv));
}
if (argc == 0)
goto out;
@@ -143,10 +153,14 @@ cmd_string_parse(const char *s, struct cmd_list **cmdlist, char **cause)
if (*cmdlist == NULL)
goto out;
do
xfree(argv[argc - 1]);
while (--argc > 0);
rval = 0;
goto out;
case '~':
if (buf == NULL) {
if (have_arg == 0) {
if ((t = cmd_string_expand_tilde(s, &p)) == NULL)
goto error;
buf = xrealloc(buf, 1, len + strlen(t) + 1);
@@ -162,6 +176,8 @@ cmd_string_parse(const char *s, struct cmd_list **cmdlist, char **cause)
buf = xrealloc(buf, 1, len + 1);
buf[len++] = ch;
have_arg = 1;
break;
}
}
@@ -173,11 +189,10 @@ out:
if (buf != NULL)
xfree(buf);
if (argv != NULL) {
for (i = 0; i < argc; i++)
xfree(argv[i]);
while (--argc >= 0)
xfree(argv[argc]);
if (argv != NULL)
xfree(argv);
}
return (rval);
}
@@ -189,33 +204,33 @@ cmd_string_string(const char *s, size_t *p, char endch, int esc)
char *buf, *t;
size_t len;
buf = NULL;
buf = NULL;
len = 0;
while ((ch = cmd_string_getc(s, p)) != endch) {
switch (ch) {
while ((ch = cmd_string_getc(s, p)) != endch) {
switch (ch) {
case EOF:
goto error;
case '\\':
case '\\':
if (!esc)
break;
switch (ch = cmd_string_getc(s, p)) {
switch (ch = cmd_string_getc(s, p)) {
case EOF:
goto error;
case 'e':
ch = '\033';
break;
case 'r':
ch = '\r';
break;
case 'n':
ch = '\n';
break;
case 't':
ch = '\t';
break;
}
break;
case 'r':
ch = '\r';
break;
case 'n':
ch = '\n';
break;
case 't':
ch = '\t';
break;
}
break;
case '$':
if (!esc)
break;
@@ -226,13 +241,13 @@ cmd_string_string(const char *s, size_t *p, char endch, int esc)
len += strlen(t);
xfree(t);
continue;
}
}
if (len >= SIZE_MAX - 2)
goto error;
buf = xrealloc(buf, 1, len + 1);
buf[len++] = ch;
}
buf[len++] = ch;
}
buf = xrealloc(buf, 1, len + 1);
buf[len] = '\0';
@@ -257,7 +272,7 @@ cmd_string_variable(const char *s, size_t *p)
((ch) >= 'a' && (ch) <= 'z') || ((ch) >= 'A' && (ch) <= 'Z') || \
((ch) >= '0' && (ch) <= '9'))
buf = NULL;
buf = NULL;
len = 0;
fch = EOF;
@@ -296,7 +311,7 @@ cmd_string_variable(const char *s, size_t *p)
if (fch == '{' && ch != '}')
goto error;
if (ch != EOF && fch != '{')
cmd_string_ungetc(p); /* ch */
cmd_string_ungetc(s, p); /* ch */
buf = xrealloc(buf, 1, len + 1);
buf[len] = '\0';
@@ -322,17 +337,18 @@ cmd_string_expand_tilde(const char *s, size_t *p)
home = NULL;
if (cmd_string_getc(s, p) == '/') {
if ((home = getenv("HOME")) == NULL || *home == '\0') {
if ((home = getenv("HOME")) == NULL) {
if ((pw = getpwuid(getuid())) != NULL)
home = pw->pw_dir;
}
} else {
cmd_string_ungetc(p);
cmd_string_ungetc(s, p);
if ((username = cmd_string_string(s, p, '/', 0)) == NULL)
return (NULL);
if ((pw = getpwnam(username)) != NULL)
home = pw->pw_dir;
xfree(username);
if (username != NULL)
xfree(username);
}
if (home == NULL)
return (NULL);

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-suspend-client.c,v 1.5 2009-11-14 17:56:39 tcunha Exp $ */
/* $Id: cmd-suspend-client.c,v 1.4 2009-07-28 22:12:16 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -37,7 +37,7 @@ struct cmd_suspend_client_data {
const struct cmd_entry cmd_suspend_client_entry = {
"suspend-client", "suspendc",
"[-c target-client]",
0, "",
0, 0,
cmd_target_init,
cmd_target_parse,
cmd_suspend_client_exec,

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-swap-pane.c,v 1.15 2009-12-04 22:14:47 tcunha Exp $ */
/* $Id: cmd-swap-pane.c,v 1.13 2009-07-30 21:04:40 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -32,7 +32,7 @@ int cmd_swap_pane_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_swap_pane_entry = {
"swap-pane", "swapp",
"[-dDU] " CMD_SRCDST_PANE_USAGE,
0, "dDU",
0, CMD_CHFLAG('d')|CMD_CHFLAG('D')|CMD_CHFLAG('U'),
cmd_swap_pane_init,
cmd_srcdst_parse,
cmd_swap_pane_exec,
@@ -49,12 +49,11 @@ cmd_swap_pane_init(struct cmd *self, int key)
data = self->data;
if (key == '{')
cmd_set_flag(&data->chflags, 'U');
data->chflags |= CMD_CHFLAG('U');
else if (key == '}')
cmd_set_flag(&data->chflags, 'D');
data->chflags |= CMD_CHFLAG('D');
}
int
cmd_swap_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
{
@@ -74,11 +73,11 @@ cmd_swap_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
if (data->src == NULL) {
src_w = dst_w;
if (cmd_check_flag(data->chflags, 'D')) {
if (data->chflags & CMD_CHFLAG('D')) {
src_wp = TAILQ_NEXT(dst_wp, entry);
if (src_wp == NULL)
src_wp = TAILQ_FIRST(&dst_w->panes);
} else if (cmd_check_flag(data->chflags, 'U')) {
} else if (data->chflags & CMD_CHFLAG('U')) {
src_wp = TAILQ_PREV(dst_wp, window_panes, entry);
if (src_wp == NULL)
src_wp = TAILQ_LAST(&dst_w->panes, window_panes);
@@ -110,7 +109,7 @@ cmd_swap_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
dst_wp->layout_cell = src_lc;
dst_lc->wp = src_wp;
src_wp->layout_cell = dst_lc;
src_wp->window = dst_w;
dst_wp->window = src_w;
@@ -121,7 +120,7 @@ cmd_swap_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
dst_wp->xoff = xoff; dst_wp->yoff = yoff;
window_pane_resize(dst_wp, sx, sy);
if (!cmd_check_flag(data->chflags, 'd')) {
if (!(data->chflags & CMD_CHFLAG('d'))) {
if (src_w != dst_w) {
window_set_active_pane(src_w, dst_wp);
window_set_active_pane(dst_w, src_wp);

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-swap-window.c,v 1.19 2009-11-14 17:56:39 tcunha Exp $ */
/* $Id: cmd-swap-window.c,v 1.17 2009-07-28 22:12:16 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -31,7 +31,7 @@ int cmd_swap_window_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_swap_window_entry = {
"swap-window", "swapw",
"[-d] " CMD_SRCDST_WINDOW_USAGE,
0, "d",
0, CMD_CHFLAG('d'),
cmd_srcdst_init,
cmd_srcdst_parse,
cmd_swap_window_exec,
@@ -44,7 +44,6 @@ cmd_swap_window_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_srcdst_data *data = self->data;
struct session *src, *dst;
struct session_group *sg_src, *sg_dst;
struct winlink *wl_src, *wl_dst;
struct window *w;
@@ -53,14 +52,6 @@ cmd_swap_window_exec(struct cmd *self, struct cmd_ctx *ctx)
if ((wl_dst = cmd_find_window(ctx, data->dst, &dst)) == NULL)
return (-1);
sg_src = session_group_find(src);
sg_dst = session_group_find(dst);
if (src != dst &&
sg_src != NULL && sg_dst != NULL && sg_src == sg_dst) {
ctx->error(ctx, "can't move window, sessions are grouped");
return (-1);
}
if (wl_dst->window == wl_src->window)
return (0);
@@ -68,17 +59,14 @@ cmd_swap_window_exec(struct cmd *self, struct cmd_ctx *ctx)
wl_dst->window = wl_src->window;
wl_src->window = w;
if (!cmd_check_flag(data->chflags, 'd')) {
if (!(data->chflags & CMD_CHFLAG('d'))) {
session_select(dst, wl_dst->idx);
if (src != dst)
session_select(src, wl_src->idx);
}
session_group_synchronize_from(src);
server_redraw_session_group(src);
if (src != dst) {
session_group_synchronize_from(dst);
server_redraw_session_group(dst);
}
server_redraw_session(src);
if (src != dst)
server_redraw_session(dst);
recalculate_sizes();
return (0);

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-switch-client.c,v 1.19 2010-01-25 17:12:44 tcunha Exp $ */
/* $Id: cmd-switch-client.c,v 1.17 2009-07-28 22:12:16 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -40,7 +40,7 @@ struct cmd_switch_client_data {
const struct cmd_entry cmd_switch_client_entry = {
"switch-client", "switchc",
"[-c target-client] [-t target-session]",
0, "",
0, 0,
NULL,
cmd_switch_client_parse,
cmd_switch_client_exec,
@@ -61,12 +61,10 @@ cmd_switch_client_parse(struct cmd *self, int argc, char **argv, char **cause)
while ((opt = getopt(argc, argv, "c:t:")) != -1) {
switch (opt) {
case 'c':
if (data->name == NULL)
data->name = xstrdup(optarg);
data->name = xstrdup(optarg);
break;
case 't':
if (data->target == NULL)
data->target = xstrdup(optarg);
data->target = xstrdup(optarg);
break;
default:
goto usage;

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-unbind-key.c,v 1.22 2010-01-25 17:12:44 tcunha Exp $ */
/* $Id: cmd-unbind-key.c,v 1.20 2009-07-28 23:19:06 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -40,7 +40,7 @@ struct cmd_unbind_key_data {
const struct cmd_entry cmd_unbind_key_entry = {
"unbind-key", "unbind",
"[-cn] [-t key-table] key",
0, "",
0, 0,
NULL,
cmd_unbind_key_parse,
cmd_unbind_key_exec,
@@ -67,8 +67,7 @@ cmd_unbind_key_parse(struct cmd *self, int argc, char **argv, char **cause)
no_prefix = 1;
break;
case 't':
if (data->tablename == NULL)
data->tablename = xstrdup(optarg);
data->tablename = xstrdup(optarg);
break;
default:
goto usage;

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-unlink-window.c,v 1.21 2009-12-04 22:14:47 tcunha Exp $ */
/* $Id: cmd-unlink-window.c,v 1.16 2009-07-28 22:12:16 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,7 +29,7 @@ int cmd_unlink_window_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_unlink_window_entry = {
"unlink-window", "unlinkw",
"[-k] " CMD_TARGET_WINDOW_USAGE,
0, "k",
0, CMD_CHFLAG('k'),
cmd_target_init,
cmd_target_parse,
cmd_unlink_window_exec,
@@ -42,29 +42,30 @@ cmd_unlink_window_exec(struct cmd *self, struct cmd_ctx *ctx)
{
struct cmd_target_data *data = self->data;
struct winlink *wl;
struct window *w;
struct session *s, *s2;
struct session_group *sg;
u_int references;
struct session *s;
struct client *c;
u_int i;
int destroyed;
if ((wl = cmd_find_window(ctx, data->target, &s)) == NULL)
return (-1);
w = wl->window;
sg = session_group_find(s);
if (sg != NULL) {
references = 0;
TAILQ_FOREACH(s2, &sg->sessions, gentry)
references++;
} else
references = 1;
if (!cmd_check_flag(data->chflags, 'k') && w->references == references) {
if (!(data->chflags & CMD_CHFLAG('k')) && wl->window->references == 1) {
ctx->error(ctx, "window is only linked to one session");
return (-1);
}
server_unlink_window(s, wl);
destroyed = session_detach(s, wl);
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
c = ARRAY_ITEM(&clients, i);
if (c == NULL || c->session != s)
continue;
if (destroyed) {
c->session = NULL;
server_write_client(c, MSG_EXIT, NULL, 0);
} else
server_redraw_client(c);
}
recalculate_sizes();
return (0);

View File

@@ -1,4 +1,4 @@
/* $Id: cmd-up-pane.c,v 1.14 2010-01-05 23:52:37 tcunha Exp $ */
/* $Id: cmd-up-pane.c,v 1.12 2009-07-28 22:12:16 tcunha Exp $ */
/*
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,7 +29,7 @@ int cmd_up_pane_exec(struct cmd *, struct cmd_ctx *);
const struct cmd_entry cmd_up_pane_entry = {
"up-pane", "upp",
CMD_TARGET_WINDOW_USAGE,
0, "",
0, 0,
cmd_target_init,
cmd_target_parse,
cmd_up_pane_exec,
@@ -54,7 +54,6 @@ cmd_up_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
w->active = TAILQ_LAST(&w->panes, window_panes);
} while (!window_pane_visible(w->active));
server_status_window(wl->window);
server_redraw_window_borders(wl->window);
return (0);
}

269
cmd.c
View File

@@ -1,4 +1,4 @@
/* $Id: cmd.c,v 1.137 2010-01-22 17:28:34 tcunha Exp $ */
/* $Id: cmd.c,v 1.115 2009-08-31 22:30:15 tcunha Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -30,7 +30,6 @@ const struct cmd_entry *cmd_table[] = {
&cmd_attach_session_entry,
&cmd_bind_key_entry,
&cmd_break_pane_entry,
&cmd_capture_pane_entry,
&cmd_choose_client_entry,
&cmd_choose_session_entry,
&cmd_choose_window_entry,
@@ -48,7 +47,6 @@ const struct cmd_entry *cmd_table[] = {
&cmd_find_window_entry,
&cmd_has_session_entry,
&cmd_if_shell_entry,
&cmd_join_pane_entry,
&cmd_kill_pane_entry,
&cmd_kill_server_entry,
&cmd_kill_session_entry,
@@ -59,20 +57,16 @@ const struct cmd_entry *cmd_table[] = {
&cmd_list_clients_entry,
&cmd_list_commands_entry,
&cmd_list_keys_entry,
&cmd_list_panes_entry,
&cmd_list_sessions_entry,
&cmd_list_windows_entry,
&cmd_load_buffer_entry,
&cmd_lock_client_entry,
&cmd_lock_server_entry,
&cmd_lock_session_entry,
&cmd_move_window_entry,
&cmd_new_session_entry,
&cmd_new_window_entry,
&cmd_next_layout_entry,
&cmd_next_window_entry,
&cmd_paste_buffer_entry,
&cmd_pipe_pane_entry,
&cmd_previous_layout_entry,
&cmd_previous_window_entry,
&cmd_refresh_client_entry,
@@ -81,8 +75,8 @@ const struct cmd_entry *cmd_table[] = {
&cmd_resize_pane_entry,
&cmd_respawn_window_entry,
&cmd_rotate_window_entry,
&cmd_run_shell_entry,
&cmd_save_buffer_entry,
&cmd_scroll_mode_entry,
&cmd_select_layout_entry,
&cmd_select_pane_entry,
&cmd_select_prompt_entry,
@@ -93,10 +87,10 @@ const struct cmd_entry *cmd_table[] = {
&cmd_set_buffer_entry,
&cmd_set_environment_entry,
&cmd_set_option_entry,
&cmd_set_password_entry,
&cmd_set_window_option_entry,
&cmd_show_buffer_entry,
&cmd_show_environment_entry,
&cmd_show_messages_entry,
&cmd_show_options_entry,
&cmd_show_window_options_entry,
&cmd_source_file_entry,
@@ -112,8 +106,7 @@ const struct cmd_entry *cmd_table[] = {
NULL
};
struct session *cmd_choose_session(struct sessions *);
struct client *cmd_choose_client(struct clients *);
struct session *cmd_newest_session(struct sessions *);
struct client *cmd_lookup_client(const char *);
struct session *cmd_lookup_session(const char *, int *);
struct winlink *cmd_lookup_window(struct session *, const char *, int *);
@@ -169,7 +162,7 @@ cmd_free_argv(int argc, char **argv)
int i;
if (argc == 0)
return;
return;
for (i = 0; i < argc; i++) {
if (argv[i] != NULL)
xfree(argv[i]);
@@ -181,7 +174,7 @@ struct cmd *
cmd_parse(int argc, char **argv, char **cause)
{
const struct cmd_entry **entryp, *entry;
struct cmd *cmd;
struct cmd *cmd;
char s[BUFSIZ];
int opt, ambiguous = 0;
@@ -265,6 +258,10 @@ usage:
int
cmd_exec(struct cmd *cmd, struct cmd_ctx *ctx)
{
if (server_locked) {
ctx->error(ctx, "server is locked");
return (-1);
}
return (cmd->entry->exec(cmd, ctx));
}
@@ -279,17 +276,17 @@ cmd_free(struct cmd *cmd)
size_t
cmd_print(struct cmd *cmd, char *buf, size_t len)
{
if (cmd->entry->print == NULL)
if (cmd->entry->print == NULL) {
return (xsnprintf(buf, len, "%s", cmd->entry->name));
}
return (cmd->entry->print(cmd, buf, len));
}
/*
* Figure out the current session. Use: 1) the current session, if the command
* context has one; 2) the most recently used session containing the pty of the
* calling client, if any; 3) the session specified in the TMUX variable from
* the environment (as passed from the client); 4) the most recently used
* session from all sessions.
* context has one; 2) the session containing the pty of the calling client, if
* any 3) the session specified in the TMUX variable from the environment (as
* passed from the client); 3) the newest session.
*/
struct session *
cmd_current_session(struct cmd_ctx *ctx)
@@ -331,7 +328,7 @@ cmd_current_session(struct cmd_ctx *ctx)
ARRAY_ADD(&ss, s);
}
s = cmd_choose_session(&ss);
s = cmd_newest_session(&ss);
ARRAY_FREE(&ss);
if (s != NULL)
return (s);
@@ -348,92 +345,29 @@ cmd_current_session(struct cmd_ctx *ctx)
return (s);
}
return (cmd_choose_session(&sessions));
return (cmd_newest_session(&sessions));
}
/* Find the most recently used session from a list. */
/* Find the newest session. */
struct session *
cmd_choose_session(struct sessions *ss)
cmd_newest_session(struct sessions *ss)
{
struct session *s, *sbest;
struct session *s, *snewest;
struct timeval *tv = NULL;
u_int i;
sbest = NULL;
snewest = NULL;
for (i = 0; i < ARRAY_LENGTH(ss); i++) {
if ((s = ARRAY_ITEM(ss, i)) == NULL)
continue;
if (tv == NULL || timercmp(&s->activity_time, tv, >)) {
sbest = s;
tv = &s->activity_time;
if (tv == NULL || timercmp(&s->tv, tv, >)) {
snewest = s;
tv = &s->tv;
}
}
return (sbest);
}
/*
* Find the current client. First try the current client if set, then pick the
* most recently used of the clients attached to the current session if any,
* then of all clients.
*/
struct client *
cmd_current_client(struct cmd_ctx *ctx)
{
struct session *s;
struct client *c;
struct clients cc;
u_int i;
if (ctx->curclient != NULL)
return (ctx->curclient);
/*
* No current client set. Find the current session and return the
* newest of its clients.
*/
s = cmd_current_session(ctx);
if (s != NULL && !(s->flags & SESSION_UNATTACHED)) {
ARRAY_INIT(&cc);
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
if ((c = ARRAY_ITEM(&clients, i)) == NULL)
continue;
if (s == c->session)
ARRAY_ADD(&cc, c);
}
c = cmd_choose_client(&cc);
ARRAY_FREE(&cc);
if (c != NULL)
return (c);
}
return (cmd_choose_client(&clients));
}
/* Choose the most recently used client from a list. */
struct client *
cmd_choose_client(struct clients *cc)
{
struct client *c, *cbest;
struct timeval *tv = NULL;
u_int i;
cbest = NULL;
for (i = 0; i < ARRAY_LENGTH(cc); i++) {
if ((c = ARRAY_ITEM(cc, i)) == NULL)
continue;
if (c->session == NULL)
continue;
if (tv == NULL || timercmp(&c->activity_time, tv, >)) {
cbest = c;
tv = &c->activity_time;
}
}
return (cbest);
return (snewest);
}
/* Find the target client or report an error and return NULL. */
@@ -446,7 +380,7 @@ cmd_find_client(struct cmd_ctx *ctx, const char *arg)
/* A NULL argument means the current client. */
if (arg == NULL)
return (cmd_current_client(ctx));
return (ctx->curclient);
tmparg = xstrdup(arg);
/* Trim a single trailing colon if any. */
@@ -477,8 +411,7 @@ cmd_lookup_client(const char *name)
u_int i;
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
c = ARRAY_ITEM(&clients, i);
if (c == NULL || c->session == NULL)
if ((c = ARRAY_ITEM(&clients, i)) == NULL)
continue;
path = c->tty.path;
@@ -506,25 +439,19 @@ cmd_lookup_session(const char *name, int *ambiguous)
*ambiguous = 0;
/*
* Look for matches. First look for exact matches - session names must
* be unique so an exact match can't be ambigious and can just be
* returned.
*/
for (i = 0; i < ARRAY_LENGTH(&sessions); i++) {
if ((s = ARRAY_ITEM(&sessions, i)) == NULL)
continue;
if (strcmp(name, s->name) == 0)
return (s);
}
/*
* Otherwise look for partial matches, returning early if it is found to
* be ambiguous.
* Look for matches. Session names must be unique so an exact match
* can't be ambigious and can just be returned.
*/
sfound = NULL;
for (i = 0; i < ARRAY_LENGTH(&sessions); i++) {
for (i = 0; i < ARRAY_LENGTH(&sessions); i++) {
if ((s = ARRAY_ITEM(&sessions, i)) == NULL)
continue;
/* Check for an exact match and return it if found. */
if (strcmp(name, s->name) == 0)
return (s);
/* Then check for pattern matches. */
if (strncmp(name, s->name, strlen(name)) == 0 ||
fnmatch(name, s->name, 0) == 0) {
if (sfound != NULL) {
@@ -534,7 +461,8 @@ cmd_lookup_session(const char *name, int *ambiguous)
sfound = s;
}
}
return (sfound);
return (sfound);
}
/*
@@ -558,7 +486,7 @@ cmd_lookup_window(struct session *s, const char *name, int *ambiguous)
if ((wl = winlink_find_by_index(&s->windows, idx)) != NULL)
return (wl);
}
/* Look for exact matches, error if more than one. */
wlfound = NULL;
RB_FOREACH(wl, winlinks, &s->windows) {
@@ -584,7 +512,7 @@ cmd_lookup_window(struct session *s, const char *name, int *ambiguous)
}
wlfound = wl;
}
}
}
if (wlfound != NULL)
return (wlfound);
@@ -701,40 +629,20 @@ cmd_find_window(struct cmd_ctx *ctx, const char *arg, struct session **sp)
/*
* Then work out the window. An empty string is the current window,
* otherwise try special cases then to look it up in the session.
* otherwise try to look it up in the session.
*/
if (*winptr == '\0')
wl = s->curw;
else if (winptr[0] == '!' && winptr[1] == '\0')
wl = TAILQ_FIRST(&s->lastw);
else if (winptr[0] == '+' && winptr[1] == '\0')
wl = winlink_next(s->curw);
else if (winptr[0] == '-' && winptr[1] == '\0')
wl = winlink_previous(s->curw);
else
wl = cmd_lookup_window(s, winptr, &ambiguous);
if (wl == NULL)
else if ((wl = cmd_lookup_window(s, winptr, &ambiguous)) == NULL)
goto not_found;
if (sessptr != NULL)
xfree(sessptr);
return (wl);
no_colon:
/*
* No colon in the string, first try special cases, then as a window
* and lastly as a session.
*/
if (arg[0] == '!' && arg[1] == '\0') {
if ((wl = TAILQ_FIRST(&s->lastw)) == NULL)
goto not_found;
} else if (arg[0] == '+' && arg[1] == '\0') {
if ((wl = winlink_next(s->curw)) == NULL)
goto not_found;
} else if (arg[0] == '-' && arg[1] == '\0') {
if ((wl = winlink_previous(s->curw)) == NULL)
goto not_found;
} else if ((wl = cmd_lookup_window(s, arg, &ambiguous)) == NULL) {
/* No colon in the string, first try as a window then as a session. */
if ((wl = cmd_lookup_window(s, arg, &ambiguous)) == NULL) {
if (ambiguous)
goto not_found;
if ((s = cmd_lookup_session(arg, &ambiguous)) == NULL)
@@ -776,7 +684,6 @@ int
cmd_find_index(struct cmd_ctx *ctx, const char *arg, struct session **sp)
{
struct session *s;
struct winlink *wl;
const char *winptr;
char *sessptr = NULL;
int idx, ambiguous = 0;
@@ -822,48 +729,21 @@ cmd_find_index(struct cmd_ctx *ctx, const char *arg, struct session **sp)
* try to look it up in the session.
*/
if (*winptr == '\0')
idx = -1;
else if (winptr[0] == '!' && winptr[1] == '\0') {
if ((wl = TAILQ_FIRST(&s->lastw)) == NULL)
goto not_found;
idx = wl->idx;
} else if (winptr[0] == '+' && winptr[1] == '\0') {
if (s->curw->idx == INT_MAX)
goto not_found;
idx = s->curw->idx + 1;
} else if (winptr[0] == '-' && winptr[1] == '\0') {
if (s->curw->idx == 0)
goto not_found;
idx = s->curw->idx - 1;
} else if ((idx = cmd_lookup_index(s, winptr, &ambiguous)) == -1) {
idx = -1;
else if ((idx = cmd_lookup_index(s, winptr, &ambiguous)) == -1) {
if (ambiguous)
goto not_found;
ctx->error(ctx, "invalid index: %s", arg);
idx = -2;
}
if (sessptr != NULL)
xfree(sessptr);
return (idx);
no_colon:
/*
* No colon in the string, first try special cases, then as a window
* and lastly as a session.
*/
if (arg[0] == '!' && arg[1] == '\0') {
if ((wl = TAILQ_FIRST(&s->lastw)) == NULL)
goto not_found;
idx = wl->idx;
} else if (arg[0] == '+' && arg[1] == '\0') {
if (s->curw->idx == INT_MAX)
goto not_found;
idx = s->curw->idx + 1;
} else if (arg[0] == '-' && arg[1] == '\0') {
if (s->curw->idx == 0)
goto not_found;
idx = s->curw->idx - 1;
} else if ((idx = cmd_lookup_index(s, arg, &ambiguous)) == -1) {
/* No colon in the string, first try as a window then as a session. */
if ((idx = cmd_lookup_index(s, arg, &ambiguous)) == -1) {
if (ambiguous)
goto not_found;
if ((s = cmd_lookup_session(arg, &ambiguous)) == NULL)
@@ -878,7 +758,7 @@ no_colon:
no_session:
if (ambiguous)
ctx->error(ctx, "multiple sessions: %s", arg);
ctx->error(ctx, "multiple sessions: %s", arg);
else
ctx->error(ctx, "session not found: %s", arg);
if (sessptr != NULL)
@@ -904,16 +784,16 @@ struct winlink *
cmd_find_pane(struct cmd_ctx *ctx,
const char *arg, struct session **sp, struct window_pane **wpp)
{
struct session *s;
struct winlink *wl;
struct layout_cell *lc;
const char *period, *errstr;
char *winptr, *paneptr;
u_int idx;
struct session *s;
struct winlink *wl;
const char *period;
char *winptr, *paneptr;
const char *errstr;
u_int idx;
/* Get the current session. */
if ((s = cmd_current_session(ctx)) == NULL) {
ctx->error(ctx, "can't establish current session");
ctx->error(ctx, "can't establish current session");
return (NULL);
}
if (sp != NULL)
@@ -943,27 +823,20 @@ cmd_find_pane(struct cmd_ctx *ctx,
*wpp = wl->window->active;
else {
idx = strtonum(paneptr, 0, INT_MAX, &errstr);
if (errstr != NULL)
goto lookup_string;
if (errstr != NULL) {
ctx->error(ctx, "pane %s: %s", errstr, paneptr);
goto error;
}
*wpp = window_pane_at_index(wl->window, idx);
if (*wpp == NULL)
goto lookup_string;
if (*wpp == NULL) {
ctx->error(ctx, "no such pane: %u", idx);
goto error;
}
}
xfree(winptr);
return (wl);
lookup_string:
/* Try pane string description. */
if ((lc = layout_find_string(s->curw->window, paneptr)) == NULL) {
ctx->error(ctx, "can't find pane: %s", paneptr);
goto error;
}
*wpp = lc->wp;
xfree(winptr);
return (s->curw);
no_period:
/* Try as a pane number alone. */
idx = strtonum(arg, 0, INT_MAX, &errstr);
@@ -973,21 +846,15 @@ no_period:
/* Try index in the current session and window. */
if ((*wpp = window_pane_at_index(s->curw->window, idx)) == NULL)
goto lookup_window;
return (s->curw);
lookup_window:
/* Try pane string description. */
if ((lc = layout_find_string(s->curw->window, arg)) != NULL) {
*wpp = lc->wp;
return (s->curw);
}
/* Try as a window and use the active pane. */
if ((wl = cmd_find_window(ctx, arg, sp)) != NULL)
*wpp = wl->window->active;
return (wl);
error:
xfree(winptr);
return (NULL);

Some files were not shown because too many files have changed in this diff Show More