├── logo ├── favicon.ico ├── tmux-logo-huge.png ├── tmux-logo-large.png ├── tmux-logo-small.png ├── tmux-logo-medium.png ├── LICENSE └── tmux-logomark.svg ├── presentations ├── tmux_asiabsdcon11.odt ├── tmux_asiabsdcon11.pdf └── tmux_linuxtag_2011.odp ├── .gitignore ├── tools ├── cmp-cvs.sh └── 256colors.pl ├── .travis.yml ├── autogen.sh ├── examples ├── h-boetes.conf ├── vim-keys.conf ├── xterm-keys.vim ├── screen-keys.conf ├── bash_completion_tmux.sh ├── n-marriott.conf └── t-williams.conf ├── COPYING ├── compat ├── cfmakeraw.c ├── setenv.c ├── asprintf.c ├── strlcpy.c ├── openat.c ├── strlcat.c ├── strtonum.c ├── daemon.c ├── forkpty-hpux.c ├── strcasestr.c ├── forkpty-sunos.c ├── strsep.c ├── fgetln.c ├── forkpty-aix.c ├── closefrom.c ├── vis.h └── imsg.h ├── osdep-aix.c ├── osdep-unknown.c ├── osdep-hpux.c ├── cmd-display-panes.c ├── cmd-kill-server.c ├── cmd-clear-history.c ├── grid-cell.c ├── cmd-delete-buffer.c ├── cmd-rename-window.c ├── .mailmap ├── cmd-kill-session.c ├── cmd-list-buffers.c ├── cmd-rename-session.c ├── cmd-kill-pane.c ├── README ├── cmd-lock-server.c ├── osdep-cygwin.c ├── cmd-kill-window.c ├── cmd-list-sessions.c ├── cmd-refresh-client.c ├── osdep-darwin.c ├── cmd-list-clients.c ├── cmd-source-file.c ├── osdep-linux.c ├── cmd-copy-mode.c ├── cmd-paste-buffer.c ├── control.c ├── osdep-sunos.c ├── cmd-swap-window.c ├── cmd-set-environment.c ├── cmd-send-keys.c ├── attributes.c ├── log.c ├── cmd-respawn-pane.c ├── cmd-detach-client.c ├── cmd-choose-buffer.c ├── cmd-move-window.c ├── cmd-set-buffer.c ├── cmd-respawn-window.c ├── cmd-display-message.c ├── names.c ├── cmd-break-pane.c ├── xmalloc.c ├── cmd-list.c ├── cmd-select-layout.c ├── cmd-list-windows.c ├── cmd-show-environment.c ├── cmd-confirm-before.c ├── tty-acs.c ├── osdep-dragonfly.c ├── signal.c ├── cmd-rotate-window.c ├── osdep-netbsd.c ├── cmd-select-window.c ├── cmd-choose-client.c └── array.h /logo/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saitoha/tmux-SIXEL/HEAD/logo/favicon.ico -------------------------------------------------------------------------------- /logo/tmux-logo-huge.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saitoha/tmux-SIXEL/HEAD/logo/tmux-logo-huge.png -------------------------------------------------------------------------------- /logo/tmux-logo-large.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saitoha/tmux-SIXEL/HEAD/logo/tmux-logo-large.png -------------------------------------------------------------------------------- /logo/tmux-logo-small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saitoha/tmux-SIXEL/HEAD/logo/tmux-logo-small.png -------------------------------------------------------------------------------- /logo/tmux-logo-medium.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saitoha/tmux-SIXEL/HEAD/logo/tmux-logo-medium.png -------------------------------------------------------------------------------- /presentations/tmux_asiabsdcon11.odt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saitoha/tmux-SIXEL/HEAD/presentations/tmux_asiabsdcon11.odt -------------------------------------------------------------------------------- /presentations/tmux_asiabsdcon11.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saitoha/tmux-SIXEL/HEAD/presentations/tmux_asiabsdcon11.pdf -------------------------------------------------------------------------------- /presentations/tmux_linuxtag_2011.odp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saitoha/tmux-SIXEL/HEAD/presentations/tmux_linuxtag_2011.odp -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | *~ 3 | *.diff 4 | *.patch 5 | *.core 6 | core 7 | tags 8 | .deps/ 9 | compat/.dirstamp 10 | aclocal.m4 11 | autom4te.cache/ 12 | config.log 13 | config.status 14 | etc/ 15 | tmux 16 | Makefile 17 | Makefile.in 18 | configure 19 | tmux.1.* 20 | -------------------------------------------------------------------------------- /tools/cmp-cvs.sh: -------------------------------------------------------------------------------- 1 | # $Id$ 2 | 3 | rm diff.out 4 | touch diff.out 5 | 6 | for i in *.[ch]; do 7 | diff -u $i /usr/src/usr.bin/tmux/$i >diff.tmp 8 | set -- `wc -l diff.tmp` 9 | [ $1 -eq 8 ] && continue 10 | echo $i 11 | cat diff.tmp >>diff.out 12 | done 13 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: c 2 | matrix: 3 | include: 4 | - compiler: gcc 5 | - compiler: clang 6 | env: CFLAGS="-g -O2" 7 | before_install: 8 | - sudo apt-get update -qq 9 | - sudo apt-get -y install debhelper autotools-dev dh-autoreconf file libncurses5-dev libevent-dev pkg-config libutempter-dev build-essential 10 | script: (CFLAGS= ./autogen.sh) && ./configure --enable-debug && make 11 | -------------------------------------------------------------------------------- /autogen.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | if [ "x$(uname)" = "xOpenBSD" ]; then 4 | [ -z "$AUTOMAKE_VERSION" ] && export AUTOMAKE_VERSION=1.10 5 | [ -z "$AUTOCONF_VERSION" ] && export AUTOCONF_VERSION=2.65 6 | fi 7 | 8 | die() 9 | { 10 | echo "$@" >&2 11 | exit 1 12 | } 13 | 14 | mkdir -p etc 15 | aclocal || die "aclocal failed" 16 | automake --add-missing --force-missing --copy --foreign || die "automake failed" 17 | autoreconf || die "autoreconf failed" 18 | -------------------------------------------------------------------------------- /logo/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015, Jason Long 2 | 3 | Permission to use, copy, modify, and/or distribute this software for any 4 | purpose with or without fee is hereby granted, provided that the above 5 | copyright notice and this permission notice appear in all copies. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 8 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 9 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 10 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 11 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 12 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 13 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 | -------------------------------------------------------------------------------- /examples/h-boetes.conf: -------------------------------------------------------------------------------- 1 | # $Id: h-boetes.conf,v 1.2 2009-10-25 21:45:26 nicm Exp $ 2 | # 3 | # From Han Boetes. 4 | 5 | set -g default-command zsh 6 | set -g status-right "#(uptime|awk '{print $11}') #(date)" 7 | 8 | # Statusbar properties. 9 | set -g display-time 3000 10 | set -g status-bg black 11 | set -g status-fg cyan 12 | set-window-option -g window-status-current-attr bright,reverse 13 | set-window-option -g window-status-current-bg cyan 14 | set-window-option -g window-status-current-fg black 15 | 16 | # Use c-t instead of c-b as the prefix 17 | unbind C-b 18 | set -g prefix C-t 19 | bind C-t send-prefix 20 | bind t send-prefix 21 | 22 | # Bind function keys. 23 | bind -n F1 select-window -t 1 24 | bind -n F2 select-window -t 2 25 | bind -n F3 select-window -t 3 26 | bind -n F4 select-window -t 4 27 | bind -n F5 select-window -t 5 28 | bind -n F6 select-window -t 6 29 | bind -n F7 select-window -t 7 30 | bind -n F8 select-window -t 8 31 | 32 | # All new windows started at startup. 33 | new emacs 34 | neww irssi 35 | neww mutt 36 | neww 37 | neww 38 | neww 39 | neww 40 | neww 41 | 42 | select-window -t 1 43 | -------------------------------------------------------------------------------- /COPYING: -------------------------------------------------------------------------------- 1 | THIS IS FOR INFORMATION ONLY, CODE IS UNDER THE LICENCE AT THE TOP OF ITS FILE. 2 | 3 | The README, CHANGES, FAQ and TODO files are licensed under the ISC 4 | license. Files under examples/ remain copyright their authors unless otherwise 5 | stated in the file but permission has been received to distribute them with 6 | tmux. All other files have a license and copyright notice at their start, 7 | typically: 8 | 9 | Copyright (c) 10 | 11 | Permission to use, copy, modify, and distribute this software for any 12 | purpose with or without fee is hereby granted, provided that the above 13 | copyright notice and this permission notice appear in all copies. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 16 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 17 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 18 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 19 | WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER 20 | IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 21 | OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 22 | -------------------------------------------------------------------------------- /examples/vim-keys.conf: -------------------------------------------------------------------------------- 1 | # $Id: vim-keys.conf,v 1.2 2010-09-18 09:36:15 nicm Exp $ 2 | # 3 | # vim-keys.conf, v1.2 2010/09/12 4 | # 5 | # By Daniel Thau. Public domain. 6 | # 7 | # This configuration file binds many vi- and vim-like bindings to the 8 | # appropriate tmux key bindings. Note that for many key bindings there is no 9 | # tmux analogue. This is intended for tmux 1.3, which handles pane selection 10 | # differently from the previous versions 11 | 12 | # split windows like vim 13 | # vim's definition of a horizontal/vertical split is reversed from tmux's 14 | bind s split-window -v 15 | bind v split-window -h 16 | 17 | # move around panes with hjkl, as one would in vim after pressing ctrl-w 18 | bind h select-pane -L 19 | bind j select-pane -D 20 | bind k select-pane -U 21 | bind l select-pane -R 22 | 23 | # resize panes like vim 24 | # feel free to change the "1" to however many lines you want to resize by, only 25 | # one at a time can be slow 26 | bind < resize-pane -L 1 27 | bind > resize-pane -R 1 28 | bind - resize-pane -D 1 29 | bind + resize-pane -U 1 30 | 31 | # bind : to command-prompt like vim 32 | # this is the default in tmux already 33 | bind : command-prompt 34 | 35 | # vi-style controls for copy mode 36 | setw -g mode-keys vi 37 | -------------------------------------------------------------------------------- /compat/cfmakeraw.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013 Dagobert Michelsen 3 | * Copyright (c) 2013 Nicholas Marriott 4 | * 5 | * Permission to use, copy, modify, and distribute this software for any 6 | * purpose with or without fee is hereby granted, provided that the above 7 | * copyright notice and this permission notice appear in all copies. 8 | * 9 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 | * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER 14 | * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 15 | * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 | */ 17 | 18 | #include 19 | 20 | #include "tmux.h" 21 | 22 | void 23 | cfmakeraw(struct termios *tio) 24 | { 25 | tio->c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON); 26 | tio->c_oflag &= ~OPOST; 27 | tio->c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN); 28 | tio->c_cflag &= ~(CSIZE|PARENB); 29 | tio->c_cflag |= CS8; 30 | } 31 | -------------------------------------------------------------------------------- /osdep-aix.c: -------------------------------------------------------------------------------- 1 | /* $OpenBSD$ */ 2 | 3 | /* 4 | * Copyright (c) 2011 Nicholas Marriott 5 | * 6 | * Permission to use, copy, modify, and distribute this software for any 7 | * purpose with or without fee is hereby granted, provided that the above 8 | * copyright notice and this permission notice appear in all copies. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 | * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER 15 | * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 16 | * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 | */ 18 | 19 | #include 20 | 21 | #include 22 | 23 | #include "tmux.h" 24 | 25 | char * 26 | osdep_get_name(unused int fd, unused char *tty) 27 | { 28 | return (NULL); 29 | } 30 | 31 | char * 32 | osdep_get_cwd(unused int fd) 33 | { 34 | return (NULL); 35 | } 36 | 37 | struct event_base * 38 | osdep_event_init(void) 39 | { 40 | return (event_init()); 41 | } 42 | -------------------------------------------------------------------------------- /osdep-unknown.c: -------------------------------------------------------------------------------- 1 | /* $OpenBSD$ */ 2 | 3 | /* 4 | * Copyright (c) 2009 Nicholas Marriott 5 | * 6 | * Permission to use, copy, modify, and distribute this software for any 7 | * purpose with or without fee is hereby granted, provided that the above 8 | * copyright notice and this permission notice appear in all copies. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 | * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER 15 | * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 16 | * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 | */ 18 | 19 | #include 20 | 21 | #include 22 | 23 | #include "tmux.h" 24 | 25 | char * 26 | osdep_get_name(unused int fd, unused char *tty) 27 | { 28 | return (NULL); 29 | } 30 | 31 | char * 32 | osdep_get_cwd(int fd) 33 | { 34 | return (NULL); 35 | } 36 | 37 | struct event_base * 38 | osdep_event_init(void) 39 | { 40 | return (event_init()); 41 | } 42 | -------------------------------------------------------------------------------- /osdep-hpux.c: -------------------------------------------------------------------------------- 1 | /* $OpenBSD$ */ 2 | 3 | /* 4 | * Copyright (c) 2009 Nicholas Marriott 5 | * 6 | * Permission to use, copy, modify, and distribute this software for any 7 | * purpose with or without fee is hereby granted, provided that the above 8 | * copyright notice and this permission notice appear in all copies. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 | * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER 15 | * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 16 | * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 | */ 18 | 19 | #include 20 | 21 | #include 22 | 23 | #include "tmux.h" 24 | 25 | char * 26 | osdep_get_name(unused int fd, unused char *tty) 27 | { 28 | return (NULL); 29 | } 30 | 31 | char * 32 | osdep_get_cwd(unused int fd) 33 | { 34 | return (NULL); 35 | } 36 | 37 | struct event_base * 38 | osdep_event_init(void) 39 | { 40 | return (event_init()); 41 | } 42 | -------------------------------------------------------------------------------- /logo/tmux-logomark.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | logomark copy 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /examples/xterm-keys.vim: -------------------------------------------------------------------------------- 1 | " tmux.vim - Set xterm input codes passed by tmux 2 | " Author: Mark Oteiza 3 | " License: Public domain 4 | " Description: Simple plugin that assigns some xterm(1)-style keys to escape 5 | " sequences passed by tmux when "xterm-keys" is set to "on". Inspired by an 6 | " example given by Chris Johnsen at: 7 | " https://stackoverflow.com/a/15471820 8 | " 9 | " Documentation: help:xterm-modifier-keys man:tmux(1) 10 | 11 | if exists("g:loaded_tmux") || &cp 12 | finish 13 | endif 14 | let g:loaded_tmux = 1 15 | 16 | function! s:SetXtermCapabilities() 17 | set ttymouse=sgr 18 | 19 | execute "set =\e[1;*A" 20 | execute "set =\e[1;*B" 21 | execute "set =\e[1;*C" 22 | execute "set =\e[1;*D" 23 | 24 | execute "set =\e[1;*H" 25 | execute "set =\e[1;*F" 26 | 27 | execute "set =\e[2;*~" 28 | execute "set =\e[3;*~" 29 | execute "set =\e[5;*~" 30 | execute "set =\e[6;*~" 31 | 32 | execute "set =\e[1;*P" 33 | execute "set =\e[1;*Q" 34 | execute "set =\e[1;*R" 35 | execute "set =\e[1;*S" 36 | 37 | execute "set =\e[15;*~" 38 | execute "set =\e[17;*~" 39 | execute "set =\e[18;*~" 40 | execute "set =\e[19;*~" 41 | execute "set =\e[20;*~" 42 | execute "set =\e[21;*~" 43 | execute "set =\e[23;*~" 44 | execute "set =\e[24;*~" 45 | endfunction 46 | 47 | if exists('$TMUX') 48 | call s:SetXtermCapabilities() 49 | endif 50 | -------------------------------------------------------------------------------- /compat/setenv.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010 Dagobert Michelsen 3 | * Copyright (c) 2010 Nicholas Marriott 4 | * 5 | * Permission to use, copy, modify, and distribute this software for any 6 | * purpose with or without fee is hereby granted, provided that the above 7 | * copyright notice and this permission notice appear in all copies. 8 | * 9 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 | * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER 14 | * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 15 | * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 | */ 17 | 18 | #include 19 | #include 20 | 21 | #include "tmux.h" 22 | 23 | int 24 | setenv(const char *name, const char *value, unused int overwrite) 25 | { 26 | char *newval; 27 | 28 | xasprintf(&newval, "%s=%s", name, value); 29 | return (putenv(newval)); 30 | } 31 | 32 | int 33 | unsetenv(const char *name) 34 | { 35 | char **envptr; 36 | int namelen; 37 | 38 | namelen = strlen(name); 39 | for (envptr = environ; *envptr != NULL; envptr++) { 40 | if (strncmp(name, *envptr, namelen) == 0 && 41 | ((*envptr)[namelen] == '=' || (*envptr)[namelen] == '\0')) 42 | break; 43 | } 44 | for (; *envptr != NULL; envptr++) 45 | *envptr = *(envptr + 1); 46 | return (0); 47 | } 48 | -------------------------------------------------------------------------------- /cmd-display-panes.c: -------------------------------------------------------------------------------- 1 | /* $OpenBSD$ */ 2 | 3 | /* 4 | * Copyright (c) 2009 Nicholas Marriott 5 | * 6 | * Permission to use, copy, modify, and distribute this software for any 7 | * purpose with or without fee is hereby granted, provided that the above 8 | * copyright notice and this permission notice appear in all copies. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 | * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER 15 | * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 16 | * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 | */ 18 | 19 | #include 20 | 21 | #include "tmux.h" 22 | 23 | /* 24 | * Display panes on a client. 25 | */ 26 | 27 | enum cmd_retval cmd_display_panes_exec(struct cmd *, struct cmd_q *); 28 | 29 | const struct cmd_entry cmd_display_panes_entry = { 30 | "display-panes", "displayp", 31 | "t:", 0, 0, 32 | CMD_TARGET_CLIENT_USAGE, 33 | 0, 34 | cmd_display_panes_exec 35 | }; 36 | 37 | enum cmd_retval 38 | cmd_display_panes_exec(struct cmd *self, struct cmd_q *cmdq) 39 | { 40 | struct args *args = self->args; 41 | struct client *c; 42 | 43 | if ((c = cmd_find_client(cmdq, args_get(args, 't'), 0)) == NULL) 44 | return (CMD_RETURN_ERROR); 45 | 46 | server_set_identify(c); 47 | 48 | return (CMD_RETURN_NORMAL); 49 | } 50 | -------------------------------------------------------------------------------- /cmd-kill-server.c: -------------------------------------------------------------------------------- 1 | /* $OpenBSD$ */ 2 | 3 | /* 4 | * Copyright (c) 2007 Nicholas Marriott 5 | * 6 | * Permission to use, copy, modify, and distribute this software for any 7 | * purpose with or without fee is hereby granted, provided that the above 8 | * copyright notice and this permission notice appear in all copies. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 | * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER 15 | * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 16 | * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 | */ 18 | 19 | #include 20 | 21 | #include 22 | #include 23 | 24 | #include "tmux.h" 25 | 26 | /* 27 | * Kill the server and do nothing else. 28 | */ 29 | 30 | enum cmd_retval cmd_kill_server_exec(struct cmd *, struct cmd_q *); 31 | 32 | const struct cmd_entry cmd_kill_server_entry = { 33 | "kill-server", NULL, 34 | "", 0, 0, 35 | "", 36 | 0, 37 | cmd_kill_server_exec 38 | }; 39 | 40 | const struct cmd_entry cmd_start_server_entry = { 41 | "start-server", "start", 42 | "", 0, 0, 43 | "", 44 | CMD_STARTSERVER, 45 | cmd_kill_server_exec 46 | }; 47 | 48 | enum cmd_retval 49 | cmd_kill_server_exec(struct cmd *self, unused struct cmd_q *cmdq) 50 | { 51 | if (self->entry == &cmd_kill_server_entry) 52 | kill(getpid(), SIGTERM); 53 | 54 | return (CMD_RETURN_NORMAL); 55 | } 56 | -------------------------------------------------------------------------------- /cmd-clear-history.c: -------------------------------------------------------------------------------- 1 | /* $OpenBSD$ */ 2 | 3 | /* 4 | * Copyright (c) 2009 Nicholas Marriott 5 | * 6 | * Permission to use, copy, modify, and distribute this software for any 7 | * purpose with or without fee is hereby granted, provided that the above 8 | * copyright notice and this permission notice appear in all copies. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 | * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER 15 | * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 16 | * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 | */ 18 | 19 | #include 20 | 21 | #include "tmux.h" 22 | 23 | /* 24 | * Clear pane history. 25 | */ 26 | 27 | enum cmd_retval cmd_clear_history_exec(struct cmd *, struct cmd_q *); 28 | 29 | const struct cmd_entry cmd_clear_history_entry = { 30 | "clear-history", "clearhist", 31 | "t:", 0, 0, 32 | CMD_TARGET_PANE_USAGE, 33 | 0, 34 | cmd_clear_history_exec 35 | }; 36 | 37 | enum cmd_retval 38 | cmd_clear_history_exec(struct cmd *self, struct cmd_q *cmdq) 39 | { 40 | struct args *args = self->args; 41 | struct window_pane *wp; 42 | struct grid *gd; 43 | 44 | if (cmd_find_pane(cmdq, args_get(args, 't'), NULL, &wp) == NULL) 45 | return (CMD_RETURN_ERROR); 46 | gd = wp->base.grid; 47 | 48 | grid_move_lines(gd, 0, gd->hsize, gd->sy); 49 | gd->hsize = 0; 50 | 51 | return (CMD_RETURN_NORMAL); 52 | } 53 | -------------------------------------------------------------------------------- /grid-cell.c: -------------------------------------------------------------------------------- 1 | /* $OpenBSD$ */ 2 | 3 | /* 4 | * Copyright (c) 2012 Nicholas Marriott 5 | * 6 | * Permission to use, copy, modify, and distribute this software for any 7 | * purpose with or without fee is hereby granted, provided that the above 8 | * copyright notice and this permission notice appear in all copies. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 | * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER 15 | * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 16 | * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 | */ 18 | 19 | #include 20 | 21 | #include 22 | 23 | #include "tmux.h" 24 | 25 | /* Get cell width. */ 26 | u_int 27 | grid_cell_width(const struct grid_cell *gc) 28 | { 29 | return (gc->xstate >> 4); 30 | } 31 | 32 | /* Get cell data. */ 33 | void 34 | grid_cell_get(const struct grid_cell *gc, struct utf8_data *ud) 35 | { 36 | ud->size = gc->xstate & 0xf; 37 | ud->width = gc->xstate >> 4; 38 | memcpy(ud->data, gc->xdata, ud->size); 39 | } 40 | 41 | /* Set cell data. */ 42 | void 43 | grid_cell_set(struct grid_cell *gc, const struct utf8_data *ud) 44 | { 45 | memcpy(gc->xdata, ud->data, ud->size); 46 | gc->xstate = (ud->width << 4) | ud->size; 47 | } 48 | 49 | /* Set a single character as cell data. */ 50 | void 51 | grid_cell_one(struct grid_cell *gc, u_char ch) 52 | { 53 | *gc->xdata = ch; 54 | gc->xstate = (1 << 4) | 1; 55 | } 56 | -------------------------------------------------------------------------------- /compat/asprintf.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2006 Nicholas Marriott 3 | * 4 | * Permission to use, copy, modify, and distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER 13 | * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 14 | * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #include 18 | #include 19 | #ifdef HAVE_STDINT_H 20 | #include 21 | #else 22 | #include 23 | #endif 24 | #include 25 | 26 | #include "tmux.h" 27 | 28 | int 29 | asprintf(char **ret, const char *fmt, ...) 30 | { 31 | va_list ap; 32 | int n; 33 | 34 | va_start(ap, fmt); 35 | n = vasprintf(ret, fmt, ap); 36 | va_end(ap); 37 | 38 | return (n); 39 | } 40 | 41 | int 42 | vasprintf(char **ret, const char *fmt, va_list ap) 43 | { 44 | int n; 45 | va_list ap2; 46 | 47 | va_copy(ap2, ap); 48 | 49 | if ((n = vsnprintf(NULL, 0, fmt, ap)) < 0) 50 | goto error; 51 | 52 | *ret = xmalloc(n + 1); 53 | if ((n = vsnprintf(*ret, n + 1, fmt, ap2)) < 0) { 54 | free(*ret); 55 | goto error; 56 | } 57 | va_end(ap2); 58 | 59 | return (n); 60 | 61 | error: 62 | va_end(ap2); 63 | *ret = NULL; 64 | return (-1); 65 | } 66 | -------------------------------------------------------------------------------- /cmd-delete-buffer.c: -------------------------------------------------------------------------------- 1 | /* $OpenBSD$ */ 2 | 3 | /* 4 | * Copyright (c) 2007 Nicholas Marriott 5 | * 6 | * Permission to use, copy, modify, and distribute this software for any 7 | * purpose with or without fee is hereby granted, provided that the above 8 | * copyright notice and this permission notice appear in all copies. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 | * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER 15 | * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 16 | * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 | */ 18 | 19 | #include 20 | 21 | #include 22 | 23 | #include "tmux.h" 24 | 25 | /* 26 | * Delete a paste buffer. 27 | */ 28 | 29 | enum cmd_retval cmd_delete_buffer_exec(struct cmd *, struct cmd_q *); 30 | 31 | const struct cmd_entry cmd_delete_buffer_entry = { 32 | "delete-buffer", "deleteb", 33 | "b:", 0, 0, 34 | CMD_BUFFER_USAGE, 35 | 0, 36 | cmd_delete_buffer_exec 37 | }; 38 | 39 | enum cmd_retval 40 | cmd_delete_buffer_exec(struct cmd *self, struct cmd_q *cmdq) 41 | { 42 | struct args *args = self->args; 43 | const char *bufname; 44 | 45 | if (!args_has(args, 'b')) { 46 | paste_free_top(); 47 | return (CMD_RETURN_NORMAL); 48 | } 49 | bufname = args_get(args, 'b'); 50 | 51 | if (paste_free_name(bufname) != 0) { 52 | cmdq_error(cmdq, "no buffer %s", bufname); 53 | return (CMD_RETURN_ERROR); 54 | } 55 | 56 | return (CMD_RETURN_NORMAL); 57 | } 58 | -------------------------------------------------------------------------------- /compat/strlcpy.c: -------------------------------------------------------------------------------- 1 | /* $OpenBSD: strlcpy.c,v 1.10 2005/08/08 08:05:37 espie Exp $ */ 2 | 3 | /* 4 | * Copyright (c) 1998 Todd C. Miller 5 | * 6 | * Permission to use, copy, modify, and distribute this software for any 7 | * purpose with or without fee is hereby granted, provided that the above 8 | * copyright notice and this permission notice appear in all copies. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 | */ 18 | 19 | #include 20 | #include 21 | 22 | #include "tmux.h" 23 | 24 | /* 25 | * Copy src to string dst of size siz. At most siz-1 characters 26 | * will be copied. Always NUL terminates (unless siz == 0). 27 | * Returns strlen(src); if retval >= siz, truncation occurred. 28 | */ 29 | size_t 30 | strlcpy(char *dst, const char *src, size_t siz) 31 | { 32 | char *d = dst; 33 | const char *s = src; 34 | size_t n = siz; 35 | 36 | /* Copy as many bytes as will fit */ 37 | if (n != 0 && --n != 0) { 38 | do { 39 | if ((*d++ = *s++) == 0) 40 | break; 41 | } while (--n != 0); 42 | } 43 | 44 | /* Not enough room in dst, add NUL and traverse rest of src */ 45 | if (n == 0) { 46 | if (siz != 0) 47 | *d = '\0'; /* NUL-terminate dst */ 48 | while (*s++) 49 | ; 50 | } 51 | 52 | return(s - src - 1); /* count does not include NUL */ 53 | } 54 | -------------------------------------------------------------------------------- /cmd-rename-window.c: -------------------------------------------------------------------------------- 1 | /* $OpenBSD$ */ 2 | 3 | /* 4 | * Copyright (c) 2007 Nicholas Marriott 5 | * 6 | * Permission to use, copy, modify, and distribute this software for any 7 | * purpose with or without fee is hereby granted, provided that the above 8 | * copyright notice and this permission notice appear in all copies. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 | * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER 15 | * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 16 | * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 | */ 18 | 19 | #include 20 | 21 | #include 22 | 23 | #include "tmux.h" 24 | 25 | /* 26 | * Rename a window. 27 | */ 28 | 29 | enum cmd_retval cmd_rename_window_exec(struct cmd *, struct cmd_q *); 30 | 31 | const struct cmd_entry cmd_rename_window_entry = { 32 | "rename-window", "renamew", 33 | "t:", 1, 1, 34 | CMD_TARGET_WINDOW_USAGE " new-name", 35 | 0, 36 | cmd_rename_window_exec 37 | }; 38 | 39 | enum cmd_retval 40 | cmd_rename_window_exec(struct cmd *self, struct cmd_q *cmdq) 41 | { 42 | struct args *args = self->args; 43 | struct session *s; 44 | struct winlink *wl; 45 | 46 | if ((wl = cmd_find_window(cmdq, args_get(args, 't'), &s)) == NULL) 47 | return (CMD_RETURN_ERROR); 48 | 49 | window_set_name(wl->window, args->argv[0]); 50 | options_set_number(&wl->window->options, "automatic-rename", 0); 51 | 52 | server_status_window(wl->window); 53 | 54 | return (CMD_RETURN_NORMAL); 55 | } 56 | -------------------------------------------------------------------------------- /compat/openat.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013 Nicholas Marriott 3 | * 4 | * Permission to use, copy, modify, and distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER 13 | * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 14 | * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | #include "tmux.h" 23 | 24 | int 25 | openat(int fd, const char *path, int flags, ...) 26 | { 27 | mode_t mode; 28 | va_list ap; 29 | int dotfd, retval, saved_errno; 30 | 31 | if (flags & O_CREAT) { 32 | va_start(ap, flags); 33 | mode = va_arg(ap, mode_t); 34 | va_end(ap); 35 | } else 36 | mode = 0; 37 | 38 | dotfd = -1; 39 | if (fd != AT_FDCWD) { 40 | dotfd = open(".", O_RDONLY); 41 | if (dotfd == -1) 42 | return (-1); 43 | if (fchdir(fd) != 0) { 44 | saved_errno = errno; 45 | close(dotfd); 46 | errno = saved_errno; 47 | return (-1); 48 | } 49 | } 50 | 51 | retval = open(path, flags, mode); 52 | 53 | if (dotfd != -1) { 54 | if (fchdir(dotfd) != 0) { 55 | saved_errno = errno; 56 | close(retval); 57 | close(dotfd); 58 | errno = saved_errno; 59 | return (-1); 60 | } 61 | close(dotfd); 62 | } 63 | 64 | return (retval); 65 | } 66 | -------------------------------------------------------------------------------- /tools/256colors.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | # Author: Todd Larason 3 | # $XFree86: xc/programs/xterm/vttests/256colors2.pl,v 1.2 2002/03/26 01:46:43 dickey Exp $ 4 | 5 | # use the resources for colors 0-15 - usually more-or-less a 6 | # reproduction of the standard ANSI colors, but possibly more 7 | # pleasing shades 8 | 9 | # colors 16-231 are a 6x6x6 color cube 10 | for ($red = 0; $red < 6; $red++) { 11 | for ($green = 0; $green < 6; $green++) { 12 | for ($blue = 0; $blue < 6; $blue++) { 13 | printf("\x1b]4;%d;rgb:%2.2x/%2.2x/%2.2x\x1b\\", 14 | 16 + ($red * 36) + ($green * 6) + $blue, 15 | ($red ? ($red * 40 + 55) : 0), 16 | ($green ? ($green * 40 + 55) : 0), 17 | ($blue ? ($blue * 40 + 55) : 0)); 18 | } 19 | } 20 | } 21 | 22 | # colors 232-255 are a grayscale ramp, intentionally leaving out 23 | # black and white 24 | for ($gray = 0; $gray < 24; $gray++) { 25 | $level = ($gray * 10) + 8; 26 | printf("\x1b]4;%d;rgb:%2.2x/%2.2x/%2.2x\x1b\\", 27 | 232 + $gray, $level, $level, $level); 28 | } 29 | 30 | 31 | # display the colors 32 | 33 | # first the system ones: 34 | print "System colors:\n"; 35 | for ($color = 0; $color < 8; $color++) { 36 | print "\x1b[48;5;${color}m "; 37 | } 38 | print "\x1b[0m\n"; 39 | for ($color = 8; $color < 16; $color++) { 40 | print "\x1b[48;5;${color}m "; 41 | } 42 | print "\x1b[0m\n\n"; 43 | 44 | # now the color cube 45 | print "Color cube, 6x6x6:\n"; 46 | for ($green = 0; $green < 6; $green++) { 47 | for ($red = 0; $red < 6; $red++) { 48 | for ($blue = 0; $blue < 6; $blue++) { 49 | $color = 16 + ($red * 36) + ($green * 6) + $blue; 50 | print "\x1b[48;5;${color}m "; 51 | } 52 | print "\x1b[0m "; 53 | } 54 | print "\n"; 55 | } 56 | 57 | 58 | # now the grayscale ramp 59 | print "Grayscale ramp:\n"; 60 | for ($color = 232; $color < 256; $color++) { 61 | print "\x1b[48;5;${color}m "; 62 | } 63 | print "\x1b[0m\n"; 64 | -------------------------------------------------------------------------------- /compat/strlcat.c: -------------------------------------------------------------------------------- 1 | /* $OpenBSD: strlcat.c,v 1.13 2005/08/08 08:05:37 espie Exp $ */ 2 | 3 | /* 4 | * Copyright (c) 1998 Todd C. Miller 5 | * 6 | * Permission to use, copy, modify, and distribute this software for any 7 | * purpose with or without fee is hereby granted, provided that the above 8 | * copyright notice and this permission notice appear in all copies. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 | */ 18 | 19 | #include 20 | #include 21 | 22 | #include "tmux.h" 23 | 24 | /* 25 | * Appends src to string dst of size siz (unlike strncat, siz is the 26 | * full size of dst, not space left). At most siz-1 characters 27 | * will be copied. Always NUL terminates (unless siz <= strlen(dst)). 28 | * Returns strlen(src) + MIN(siz, strlen(initial dst)). 29 | * If retval >= siz, truncation occurred. 30 | */ 31 | size_t 32 | strlcat(char *dst, const char *src, size_t siz) 33 | { 34 | char *d = dst; 35 | const char *s = src; 36 | size_t n = siz; 37 | size_t dlen; 38 | 39 | /* Find the end of dst and adjust bytes left but don't go past end */ 40 | while (n-- != 0 && *d != '\0') 41 | d++; 42 | dlen = d - dst; 43 | n = siz - dlen; 44 | 45 | if (n == 0) 46 | return(dlen + strlen(s)); 47 | while (*s != '\0') { 48 | if (n != 1) { 49 | *d++ = *s; 50 | n--; 51 | } 52 | s++; 53 | } 54 | *d = '\0'; 55 | 56 | return(dlen + (s - src)); /* count does not include NUL */ 57 | } 58 | -------------------------------------------------------------------------------- /.mailmap: -------------------------------------------------------------------------------- 1 | Bob Beck beck 2 | Igor Sobrado sobrado 3 | Ingo Schwarze schwarze 4 | Jacek Masiulaniec jacekm 5 | Jason McIntyre jmc 6 | Jason McIntyre jcm 7 | Joel Sing jsing 8 | Jonathan Gray jsg 9 | Kenneth R Westerback krw 10 | Marc Espie espie 11 | Matthew Dempsky matthew 12 | Matthias Kilian kili 13 | Matthieu Herrb matthieu 14 | Miod Vallat miod 15 | Nicholas Marriott Nicholas Marriott 16 | Nicholas Marriott nicm 17 | Nicholas Marriott no_author 18 | Okan Demirmen okan 19 | Philip Guenther guenther 20 | Pierre-Yves Ritschard pyr 21 | Ray Lai ray 22 | Ryan McBride mcbride 23 | Sebastian Benoit benno 24 | Stefan Sperling stsp 25 | Stuart Henderson sthen 26 | Ted Unangst tedu 27 | Theo de Raadt deraadt 28 | Theo de Raadt Theo Deraadt 29 | Thomas Adam Thomas 30 | Thomas Adam n6tadam 31 | Thomas Adam Thomas Adam 32 | Tobias Stoeckmann tobias 33 | Todd C Miller millert 34 | William Yodlowsky william 35 | -------------------------------------------------------------------------------- /cmd-kill-session.c: -------------------------------------------------------------------------------- 1 | /* $OpenBSD$ */ 2 | 3 | /* 4 | * Copyright (c) 2007 Nicholas Marriott 5 | * 6 | * Permission to use, copy, modify, and distribute this software for any 7 | * purpose with or without fee is hereby granted, provided that the above 8 | * copyright notice and this permission notice appear in all copies. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 | * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER 15 | * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 16 | * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 | */ 18 | 19 | #include 20 | 21 | #include "tmux.h" 22 | 23 | /* 24 | * Destroy session, detaching all clients attached to it and destroying any 25 | * windows linked only to this session. 26 | * 27 | * Note this deliberately has no alias to make it hard to hit by accident. 28 | */ 29 | 30 | enum cmd_retval cmd_kill_session_exec(struct cmd *, struct cmd_q *); 31 | 32 | const struct cmd_entry cmd_kill_session_entry = { 33 | "kill-session", NULL, 34 | "at:", 0, 0, 35 | "[-a] " CMD_TARGET_SESSION_USAGE, 36 | 0, 37 | cmd_kill_session_exec 38 | }; 39 | 40 | enum cmd_retval 41 | cmd_kill_session_exec(struct cmd *self, struct cmd_q *cmdq) 42 | { 43 | struct args *args = self->args; 44 | struct session *s, *s2, *s3; 45 | 46 | if ((s = cmd_find_session(cmdq, args_get(args, 't'), 0)) == NULL) 47 | return (CMD_RETURN_ERROR); 48 | 49 | if (args_has(args, 'a')) { 50 | RB_FOREACH_SAFE(s2, sessions, &sessions, s3) { 51 | if (s != s2) { 52 | server_destroy_session(s2); 53 | session_destroy(s2); 54 | } 55 | } 56 | } else { 57 | server_destroy_session(s); 58 | session_destroy(s); 59 | } 60 | return (CMD_RETURN_NORMAL); 61 | } 62 | -------------------------------------------------------------------------------- /compat/strtonum.c: -------------------------------------------------------------------------------- 1 | /* $OpenBSD: strtonum.c,v 1.6 2004/08/03 19:38:01 millert Exp $ */ 2 | 3 | /* 4 | * Copyright (c) 2004 Ted Unangst and Todd Miller 5 | * All rights reserved. 6 | * 7 | * Permission to use, copy, modify, and distribute this software for any 8 | * purpose with or without fee is hereby granted, provided that the above 9 | * copyright notice and this permission notice appear in all copies. 10 | * 11 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 12 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 13 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 14 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 15 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 16 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 17 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 18 | */ 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | #include "tmux.h" 25 | 26 | #define INVALID 1 27 | #define TOOSMALL 2 28 | #define TOOLARGE 3 29 | 30 | long long 31 | strtonum(const char *numstr, long long minval, long long maxval, 32 | const char **errstrp) 33 | { 34 | long long ll = 0; 35 | char *ep; 36 | int error = 0; 37 | struct errval { 38 | const char *errstr; 39 | int err; 40 | } ev[4] = { 41 | { NULL, 0 }, 42 | { "invalid", EINVAL }, 43 | { "too small", ERANGE }, 44 | { "too large", ERANGE }, 45 | }; 46 | 47 | ev[0].err = errno; 48 | errno = 0; 49 | if (minval > maxval) 50 | error = INVALID; 51 | else { 52 | ll = strtoll(numstr, &ep, 10); 53 | if (numstr == ep || *ep != '\0') 54 | error = INVALID; 55 | else if ((ll == LLONG_MIN && errno == ERANGE) || ll < minval) 56 | error = TOOSMALL; 57 | else if ((ll == LLONG_MAX && errno == ERANGE) || ll > maxval) 58 | error = TOOLARGE; 59 | } 60 | if (errstrp != NULL) 61 | *errstrp = ev[error].errstr; 62 | errno = ev[error].err; 63 | if (error) 64 | ll = 0; 65 | 66 | return (ll); 67 | } 68 | -------------------------------------------------------------------------------- /cmd-list-buffers.c: -------------------------------------------------------------------------------- 1 | /* $OpenBSD$ */ 2 | 3 | /* 4 | * Copyright (c) 2007 Nicholas Marriott 5 | * 6 | * Permission to use, copy, modify, and distribute this software for any 7 | * purpose with or without fee is hereby granted, provided that the above 8 | * copyright notice and this permission notice appear in all copies. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 | * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER 15 | * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 16 | * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 | */ 18 | 19 | #include 20 | 21 | #include 22 | #include 23 | 24 | #include "tmux.h" 25 | 26 | /* 27 | * List paste buffers. 28 | */ 29 | 30 | #define LIST_BUFFERS_TEMPLATE \ 31 | "#{buffer_name}: #{buffer_size} bytes: \"#{buffer_sample}\"" 32 | 33 | enum cmd_retval cmd_list_buffers_exec(struct cmd *, struct cmd_q *); 34 | 35 | const struct cmd_entry cmd_list_buffers_entry = { 36 | "list-buffers", "lsb", 37 | "F:", 0, 0, 38 | "[-F format]", 39 | 0, 40 | cmd_list_buffers_exec 41 | }; 42 | 43 | enum cmd_retval 44 | cmd_list_buffers_exec(unused struct cmd *self, struct cmd_q *cmdq) 45 | { 46 | struct args *args = self->args; 47 | struct paste_buffer *pb; 48 | struct format_tree *ft; 49 | char *line; 50 | const char *template; 51 | 52 | if ((template = args_get(args, 'F')) == NULL) 53 | template = LIST_BUFFERS_TEMPLATE; 54 | 55 | pb = NULL; 56 | while ((pb = paste_walk(pb)) != NULL) { 57 | ft = format_create(); 58 | format_defaults_paste_buffer(ft, pb, 0); 59 | 60 | line = format_expand(ft, template); 61 | cmdq_print(cmdq, "%s", line); 62 | free(line); 63 | 64 | format_free(ft); 65 | } 66 | 67 | return (CMD_RETURN_NORMAL); 68 | } 69 | -------------------------------------------------------------------------------- /cmd-rename-session.c: -------------------------------------------------------------------------------- 1 | /* $OpenBSD$ */ 2 | 3 | /* 4 | * Copyright (c) 2007 Nicholas Marriott 5 | * 6 | * Permission to use, copy, modify, and distribute this software for any 7 | * purpose with or without fee is hereby granted, provided that the above 8 | * copyright notice and this permission notice appear in all copies. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 | * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER 15 | * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 16 | * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 | */ 18 | 19 | #include 20 | 21 | #include 22 | 23 | #include "tmux.h" 24 | 25 | /* 26 | * Change session name. 27 | */ 28 | 29 | enum cmd_retval cmd_rename_session_exec(struct cmd *, struct cmd_q *); 30 | 31 | const struct cmd_entry cmd_rename_session_entry = { 32 | "rename-session", "rename", 33 | "t:", 1, 1, 34 | CMD_TARGET_SESSION_USAGE " new-name", 35 | 0, 36 | cmd_rename_session_exec 37 | }; 38 | 39 | enum cmd_retval 40 | cmd_rename_session_exec(struct cmd *self, struct cmd_q *cmdq) 41 | { 42 | struct args *args = self->args; 43 | struct session *s; 44 | const char *newname; 45 | 46 | newname = args->argv[0]; 47 | if (!session_check_name(newname)) { 48 | cmdq_error(cmdq, "bad session name: %s", newname); 49 | return (CMD_RETURN_ERROR); 50 | } 51 | if (session_find(newname) != NULL) { 52 | cmdq_error(cmdq, "duplicate session: %s", newname); 53 | return (CMD_RETURN_ERROR); 54 | } 55 | 56 | if ((s = cmd_find_session(cmdq, args_get(args, 't'), 0)) == NULL) 57 | return (CMD_RETURN_ERROR); 58 | 59 | RB_REMOVE(sessions, &sessions, s); 60 | free(s->name); 61 | s->name = xstrdup(newname); 62 | RB_INSERT(sessions, &sessions, s); 63 | 64 | server_status_session(s); 65 | notify_session_renamed(s); 66 | 67 | return (CMD_RETURN_NORMAL); 68 | } 69 | -------------------------------------------------------------------------------- /cmd-kill-pane.c: -------------------------------------------------------------------------------- 1 | /* $OpenBSD$ */ 2 | 3 | /* 4 | * Copyright (c) 2009 Nicholas Marriott 5 | * 6 | * Permission to use, copy, modify, and distribute this software for any 7 | * purpose with or without fee is hereby granted, provided that the above 8 | * copyright notice and this permission notice appear in all copies. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 | * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER 15 | * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 16 | * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 | */ 18 | 19 | #include 20 | 21 | #include 22 | 23 | #include "tmux.h" 24 | 25 | /* 26 | * Kill pane. 27 | */ 28 | 29 | enum cmd_retval cmd_kill_pane_exec(struct cmd *, struct cmd_q *); 30 | 31 | const struct cmd_entry cmd_kill_pane_entry = { 32 | "kill-pane", "killp", 33 | "at:", 0, 0, 34 | "[-a] " CMD_TARGET_PANE_USAGE, 35 | 0, 36 | cmd_kill_pane_exec 37 | }; 38 | 39 | enum cmd_retval 40 | cmd_kill_pane_exec(struct cmd *self, struct cmd_q *cmdq) 41 | { 42 | struct args *args = self->args; 43 | struct winlink *wl; 44 | struct window_pane *loopwp, *tmpwp, *wp; 45 | 46 | if ((wl = cmd_find_pane(cmdq, args_get(args, 't'), NULL, &wp)) == NULL) 47 | return (CMD_RETURN_ERROR); 48 | server_unzoom_window(wl->window); 49 | 50 | if (window_count_panes(wl->window) == 1) { 51 | /* Only one pane, kill the window. */ 52 | server_kill_window(wl->window); 53 | recalculate_sizes(); 54 | return (CMD_RETURN_NORMAL); 55 | } 56 | 57 | if (args_has(self->args, 'a')) { 58 | TAILQ_FOREACH_SAFE(loopwp, &wl->window->panes, entry, tmpwp) { 59 | if (loopwp == wp) 60 | continue; 61 | layout_close_pane(loopwp); 62 | window_remove_pane(wl->window, loopwp); 63 | } 64 | } else { 65 | layout_close_pane(wp); 66 | window_remove_pane(wl->window, wp); 67 | } 68 | server_redraw_window(wl->window); 69 | 70 | return (CMD_RETURN_NORMAL); 71 | } 72 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | Welcome to tmux! 2 | 3 | tmux is a "terminal multiplexer", it enables a number of terminals (or windows) 4 | to be accessed and controlled from a single terminal. tmux is intended to be a 5 | simple, modern, BSD-licensed alternative to programs such as GNU screen. 6 | 7 | This release runs on OpenBSD, FreeBSD, NetBSD, Linux, OS X and Solaris. 8 | 9 | tmux depends on libevent 2.x. Download it from: 10 | 11 | http://www.monkey.org/~provos/libevent/ 12 | 13 | To build tmux from a release tarball, do: 14 | 15 | $ ./configure && make 16 | $ sudo make install 17 | 18 | To get and build the latest from version control: 19 | 20 | $ git clone https://github.com/tmux/tmux.git 21 | $ cd tmux 22 | $ sh autogen.sh 23 | $ ./configure && make 24 | 25 | For more information see http://git-scm.com. Patches should be sent by email to 26 | the mailing list at tmux-users@googlegroups.com. 27 | 28 | For documentation on using tmux, see the tmux.1 manpage. It can be viewed from 29 | the source tree with: 30 | 31 | $ nroff -mdoc tmux.1|less 32 | 33 | Some common questions are answered in the FAQ file and a more extensive (but 34 | slightly out of date) guide is available in the OpenBSD FAQ at 35 | http://www.openbsd.org/faq/faq7.html#tmux. A rough todo list is in the TODO 36 | file and some example configurations and a Vim syntax file are in the examples 37 | directory. 38 | 39 | For debugging, running tmux with -v or -vv will generate server and client log 40 | files in the current directory. 41 | 42 | tmux mailing lists are available. For general discussion and bug reports: 43 | 44 | https://groups.google.com/forum/#!forum/tmux-users 45 | 46 | And for Git commit emails: 47 | 48 | https://groups.google.com/forum/#!forum/tmux-git 49 | 50 | Bug reports, feature suggestions and especially code contributions are most 51 | welcome. Please send by email to: 52 | 53 | tmux-users@googlegroups.com 54 | 55 | This file and the CHANGES, FAQ, SYNCING and TODO files are licensed under 56 | the ISC license. Files under examples/ remain copyright their authors unless 57 | otherwise stated in the file but permission has been received to distribute 58 | them with tmux. All other files have a license and copyright notice at their 59 | start. 60 | 61 | -- Nicholas Marriott 62 | -------------------------------------------------------------------------------- /cmd-lock-server.c: -------------------------------------------------------------------------------- 1 | /* $OpenBSD$ */ 2 | 3 | /* 4 | * Copyright (c) 2008 Nicholas Marriott 5 | * 6 | * Permission to use, copy, modify, and distribute this software for any 7 | * purpose with or without fee is hereby granted, provided that the above 8 | * copyright notice and this permission notice appear in all copies. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 | * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER 15 | * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 16 | * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 | */ 18 | 19 | #include 20 | 21 | #include "tmux.h" 22 | 23 | /* 24 | * Lock commands. 25 | */ 26 | 27 | enum cmd_retval cmd_lock_server_exec(struct cmd *, struct cmd_q *); 28 | 29 | const struct cmd_entry cmd_lock_server_entry = { 30 | "lock-server", "lock", 31 | "", 0, 0, 32 | "", 33 | 0, 34 | cmd_lock_server_exec 35 | }; 36 | 37 | const struct cmd_entry cmd_lock_session_entry = { 38 | "lock-session", "locks", 39 | "t:", 0, 0, 40 | CMD_TARGET_SESSION_USAGE, 41 | 0, 42 | cmd_lock_server_exec 43 | }; 44 | 45 | const struct cmd_entry cmd_lock_client_entry = { 46 | "lock-client", "lockc", 47 | "t:", 0, 0, 48 | CMD_TARGET_CLIENT_USAGE, 49 | 0, 50 | cmd_lock_server_exec 51 | }; 52 | 53 | enum cmd_retval 54 | cmd_lock_server_exec(struct cmd *self, unused struct cmd_q *cmdq) 55 | { 56 | struct args *args = self->args; 57 | struct client *c; 58 | struct session *s; 59 | 60 | if (self->entry == &cmd_lock_server_entry) 61 | server_lock(); 62 | else if (self->entry == &cmd_lock_session_entry) { 63 | s = cmd_find_session(cmdq, args_get(args, 't'), 0); 64 | if (s == NULL) 65 | return (CMD_RETURN_ERROR); 66 | server_lock_session(s); 67 | } else { 68 | c = cmd_find_client(cmdq, args_get(args, 't'), 0); 69 | if (c == NULL) 70 | return (CMD_RETURN_ERROR); 71 | server_lock_client(c); 72 | } 73 | recalculate_sizes(); 74 | 75 | return (CMD_RETURN_NORMAL); 76 | } 77 | -------------------------------------------------------------------------------- /osdep-cygwin.c: -------------------------------------------------------------------------------- 1 | /* $OpenBSD$ */ 2 | 3 | /* 4 | * Copyright (c) 2009 Nicholas Marriott 5 | * 6 | * Permission to use, copy, modify, and distribute this software for any 7 | * purpose with or without fee is hereby granted, provided that the above 8 | * copyright notice and this permission notice appear in all copies. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 | * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER 15 | * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 16 | * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 | */ 18 | 19 | #include 20 | #include 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | #include "tmux.h" 28 | 29 | char * 30 | osdep_get_name(int fd, unused char *tty) 31 | { 32 | FILE *f; 33 | char *path, *buf; 34 | size_t len; 35 | int ch; 36 | pid_t pgrp; 37 | 38 | if ((pgrp = tcgetpgrp(fd)) == -1) 39 | return (NULL); 40 | 41 | xasprintf(&path, "/proc/%lld/cmdline", (long long) pgrp); 42 | if ((f = fopen(path, "r")) == NULL) { 43 | free(path); 44 | return (NULL); 45 | } 46 | free(path); 47 | 48 | len = 0; 49 | buf = NULL; 50 | while ((ch = fgetc(f)) != EOF) { 51 | if (ch == '\0') 52 | break; 53 | buf = xrealloc(buf, len + 2); 54 | buf[len++] = ch; 55 | } 56 | if (buf != NULL) 57 | buf[len] = '\0'; 58 | 59 | fclose(f); 60 | return (buf); 61 | } 62 | 63 | char * 64 | osdep_get_cwd(int fd) 65 | { 66 | static char target[MAXPATHLEN + 1]; 67 | char *path; 68 | pid_t pgrp; 69 | ssize_t n; 70 | 71 | if ((pgrp = tcgetpgrp(fd)) == -1) 72 | return (NULL); 73 | 74 | xasprintf(&path, "/proc/%lld/cwd", (long long) pgrp); 75 | n = readlink(path, target, MAXPATHLEN); 76 | free(path); 77 | if (n > 0) { 78 | target[n] = '\0'; 79 | return (target); 80 | } 81 | return (NULL); 82 | } 83 | 84 | struct event_base * 85 | osdep_event_init(void) 86 | { 87 | return (event_init()); 88 | } 89 | -------------------------------------------------------------------------------- /examples/screen-keys.conf: -------------------------------------------------------------------------------- 1 | # $Id: screen-keys.conf,v 1.7 2010-07-31 11:39:13 nicm Exp $ 2 | # 3 | # By Nicholas Marriott. Public domain. 4 | # 5 | # This configuration file binds many of the common GNU screen key bindings to 6 | # appropriate tmux key bindings. Note that for some key bindings there is no 7 | # tmux analogue and also that this set omits binding some commands available in 8 | # tmux but not in screen. 9 | # 10 | # Note this is only a selection of key bindings and they are in addition to the 11 | # normal tmux key bindings. This is intended as an example not as to be used 12 | # as-is. 13 | 14 | # Set the prefix to ^A. 15 | unbind C-b 16 | set -g prefix ^A 17 | bind a send-prefix 18 | 19 | # Bind appropriate commands similar to screen. 20 | # lockscreen ^X x 21 | unbind ^X 22 | bind ^X lock-server 23 | unbind x 24 | bind x lock-server 25 | 26 | # screen ^C c 27 | unbind ^C 28 | bind ^C new-window 29 | unbind c 30 | bind c new-window 31 | 32 | # detach ^D d 33 | unbind ^D 34 | bind ^D detach 35 | 36 | # displays * 37 | unbind * 38 | bind * list-clients 39 | 40 | # next ^@ ^N sp n 41 | unbind ^@ 42 | bind ^@ next-window 43 | unbind ^N 44 | bind ^N next-window 45 | unbind " " 46 | bind " " next-window 47 | unbind n 48 | bind n next-window 49 | 50 | # title A 51 | unbind A 52 | bind A command-prompt "rename-window %%" 53 | 54 | # other ^A 55 | unbind ^A 56 | bind ^A last-window 57 | 58 | # prev ^H ^P p ^? 59 | unbind ^H 60 | bind ^H previous-window 61 | unbind ^P 62 | bind ^P previous-window 63 | unbind p 64 | bind p previous-window 65 | unbind BSpace 66 | bind BSpace previous-window 67 | 68 | # windows ^W w 69 | unbind ^W 70 | bind ^W list-windows 71 | unbind w 72 | bind w list-windows 73 | 74 | # quit \ 75 | unbind '\' 76 | bind '\' confirm-before "kill-server" 77 | 78 | # kill K k 79 | unbind K 80 | bind K confirm-before "kill-window" 81 | unbind k 82 | bind k confirm-before "kill-window" 83 | 84 | # redisplay ^L l 85 | unbind ^L 86 | bind ^L refresh-client 87 | unbind l 88 | bind l refresh-client 89 | 90 | # split -v | 91 | unbind | 92 | bind | split-window 93 | 94 | # :kB: focus up 95 | unbind Tab 96 | bind Tab select-pane -t:.+ 97 | unbind BTab 98 | bind BTab select-pane -t:.- 99 | 100 | # " windowlist -b 101 | unbind '"' 102 | bind '"' choose-window 103 | -------------------------------------------------------------------------------- /cmd-kill-window.c: -------------------------------------------------------------------------------- 1 | /* $OpenBSD$ */ 2 | 3 | /* 4 | * Copyright (c) 2007 Nicholas Marriott 5 | * 6 | * Permission to use, copy, modify, and distribute this software for any 7 | * purpose with or without fee is hereby granted, provided that the above 8 | * copyright notice and this permission notice appear in all copies. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 | * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER 15 | * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 16 | * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 | */ 18 | 19 | #include 20 | 21 | #include "tmux.h" 22 | 23 | /* 24 | * Destroy window. 25 | */ 26 | 27 | enum cmd_retval cmd_kill_window_exec(struct cmd *, struct cmd_q *); 28 | 29 | const struct cmd_entry cmd_kill_window_entry = { 30 | "kill-window", "killw", 31 | "at:", 0, 0, 32 | "[-a] " CMD_TARGET_WINDOW_USAGE, 33 | 0, 34 | cmd_kill_window_exec 35 | }; 36 | 37 | const struct cmd_entry cmd_unlink_window_entry = { 38 | "unlink-window", "unlinkw", 39 | "kt:", 0, 0, 40 | "[-k] " CMD_TARGET_WINDOW_USAGE, 41 | 0, 42 | cmd_kill_window_exec 43 | }; 44 | 45 | enum cmd_retval 46 | cmd_kill_window_exec(struct cmd *self, struct cmd_q *cmdq) 47 | { 48 | struct args *args = self->args; 49 | struct winlink *wl, *wl2, *wl3; 50 | struct window *w; 51 | struct session *s; 52 | 53 | if ((wl = cmd_find_window(cmdq, args_get(args, 't'), &s)) == NULL) 54 | return (CMD_RETURN_ERROR); 55 | w = wl->window; 56 | 57 | if (self->entry == &cmd_unlink_window_entry) { 58 | if (!args_has(self->args, 'k') && !session_is_linked(s, w)) { 59 | cmdq_error(cmdq, "window only linked to one session"); 60 | return (CMD_RETURN_ERROR); 61 | } 62 | server_unlink_window(s, wl); 63 | } else { 64 | if (args_has(args, 'a')) { 65 | RB_FOREACH_SAFE(wl2, winlinks, &s->windows, wl3) { 66 | if (wl != wl2) 67 | server_kill_window(wl2->window); 68 | } 69 | } else 70 | server_kill_window(wl->window); 71 | } 72 | 73 | recalculate_sizes(); 74 | return (CMD_RETURN_NORMAL); 75 | } 76 | -------------------------------------------------------------------------------- /cmd-list-sessions.c: -------------------------------------------------------------------------------- 1 | /* $OpenBSD$ */ 2 | 3 | /* 4 | * Copyright (c) 2007 Nicholas Marriott 5 | * 6 | * Permission to use, copy, modify, and distribute this software for any 7 | * purpose with or without fee is hereby granted, provided that the above 8 | * copyright notice and this permission notice appear in all copies. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 | * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER 15 | * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 16 | * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 | */ 18 | 19 | #include 20 | 21 | #include 22 | #include 23 | #include 24 | 25 | #include "tmux.h" 26 | 27 | /* 28 | * List all sessions. 29 | */ 30 | 31 | #define LIST_SESSIONS_TEMPLATE \ 32 | "#{session_name}: #{session_windows} windows " \ 33 | "(created #{session_created_string}) " \ 34 | "[#{session_width}x#{session_height}]" \ 35 | "#{?session_grouped, (group ,}" \ 36 | "#{session_group}#{?session_grouped,),}" \ 37 | "#{?session_attached, (attached),}" 38 | 39 | enum cmd_retval cmd_list_sessions_exec(struct cmd *, struct cmd_q *); 40 | 41 | const struct cmd_entry cmd_list_sessions_entry = { 42 | "list-sessions", "ls", 43 | "F:", 0, 0, 44 | "[-F format]", 45 | 0, 46 | cmd_list_sessions_exec 47 | }; 48 | 49 | enum cmd_retval 50 | cmd_list_sessions_exec(struct cmd *self, struct cmd_q *cmdq) 51 | { 52 | struct args *args = self->args; 53 | struct session *s; 54 | u_int n; 55 | struct format_tree *ft; 56 | const char *template; 57 | char *line; 58 | 59 | if ((template = args_get(args, 'F')) == NULL) 60 | template = LIST_SESSIONS_TEMPLATE; 61 | 62 | n = 0; 63 | RB_FOREACH(s, sessions, &sessions) { 64 | ft = format_create(); 65 | format_add(ft, "line", "%u", n); 66 | format_defaults(ft, NULL, s, NULL, NULL); 67 | 68 | line = format_expand(ft, template); 69 | cmdq_print(cmdq, "%s", line); 70 | free(line); 71 | 72 | format_free(ft); 73 | n++; 74 | } 75 | 76 | return (CMD_RETURN_NORMAL); 77 | } 78 | -------------------------------------------------------------------------------- /compat/daemon.c: -------------------------------------------------------------------------------- 1 | /* $OpenBSD: daemon.c,v 1.6 2005/08/08 08:05:33 espie Exp $ */ 2 | /*- 3 | * Copyright (c) 1990, 1993 4 | * The Regents of the University of California. All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 1. Redistributions of source code must retain the above copyright 10 | * notice, this list of conditions and the following disclaimer. 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 3. Neither the name of the University nor the names of its contributors 15 | * may be used to endorse or promote products derived from this software 16 | * without specific prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 19 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 22 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 | * SUCH DAMAGE. 29 | */ 30 | 31 | #include 32 | #include 33 | #include 34 | 35 | #include "tmux.h" 36 | 37 | int 38 | daemon(int nochdir, int noclose) 39 | { 40 | int fd; 41 | 42 | switch (fork()) { 43 | case -1: 44 | return (-1); 45 | case 0: 46 | break; 47 | default: 48 | _exit(0); 49 | } 50 | 51 | if (setsid() == -1) 52 | return (-1); 53 | 54 | if (!nochdir) 55 | (void)chdir("/"); 56 | 57 | if (!noclose && (fd = open(_PATH_DEVNULL, O_RDWR, 0)) != -1) { 58 | (void)dup2(fd, STDIN_FILENO); 59 | (void)dup2(fd, STDOUT_FILENO); 60 | (void)dup2(fd, STDERR_FILENO); 61 | if (fd > 2) 62 | (void)close (fd); 63 | } 64 | return (0); 65 | } 66 | -------------------------------------------------------------------------------- /cmd-refresh-client.c: -------------------------------------------------------------------------------- 1 | /* $OpenBSD$ */ 2 | 3 | /* 4 | * Copyright (c) 2007 Nicholas Marriott 5 | * 6 | * Permission to use, copy, modify, and distribute this software for any 7 | * purpose with or without fee is hereby granted, provided that the above 8 | * copyright notice and this permission notice appear in all copies. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 | * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER 15 | * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 16 | * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 | */ 18 | 19 | #include 20 | 21 | #include "tmux.h" 22 | 23 | /* 24 | * Refresh client. 25 | */ 26 | 27 | enum cmd_retval cmd_refresh_client_exec(struct cmd *, struct cmd_q *); 28 | 29 | const struct cmd_entry cmd_refresh_client_entry = { 30 | "refresh-client", "refresh", 31 | "C:St:", 0, 0, 32 | "[-S] [-C size] " CMD_TARGET_CLIENT_USAGE, 33 | 0, 34 | cmd_refresh_client_exec 35 | }; 36 | 37 | enum cmd_retval 38 | cmd_refresh_client_exec(struct cmd *self, struct cmd_q *cmdq) 39 | { 40 | struct args *args = self->args; 41 | struct client *c; 42 | const char *size; 43 | u_int w, h; 44 | 45 | if ((c = cmd_find_client(cmdq, args_get(args, 't'), 0)) == NULL) 46 | return (CMD_RETURN_ERROR); 47 | 48 | if (args_has(args, 'C')) { 49 | if ((size = args_get(args, 'C')) == NULL) { 50 | cmdq_error(cmdq, "missing size"); 51 | return (CMD_RETURN_ERROR); 52 | } 53 | if (sscanf(size, "%u,%u", &w, &h) != 2) { 54 | cmdq_error(cmdq, "bad size argument"); 55 | return (CMD_RETURN_ERROR); 56 | } 57 | if (w < PANE_MINIMUM || w > 5000 || 58 | h < PANE_MINIMUM || h > 5000) { 59 | cmdq_error(cmdq, "size too small or too big"); 60 | return (CMD_RETURN_ERROR); 61 | } 62 | if (!(c->flags & CLIENT_CONTROL)) { 63 | cmdq_error(cmdq, "not a control client"); 64 | return (CMD_RETURN_ERROR); 65 | } 66 | if (tty_set_size(&c->tty, w, h)) 67 | recalculate_sizes(); 68 | } else if (args_has(args, 'S')) 69 | server_status_client(c); 70 | else 71 | server_redraw_client(c); 72 | 73 | return (CMD_RETURN_NORMAL); 74 | } 75 | -------------------------------------------------------------------------------- /osdep-darwin.c: -------------------------------------------------------------------------------- 1 | /* $OpenBSD$ */ 2 | 3 | /* 4 | * Copyright (c) 2009 Joshua Elsasser 5 | * 6 | * Permission to use, copy, modify, and distribute this software for any 7 | * purpose with or without fee is hereby granted, provided that the above 8 | * copyright notice and this permission notice appear in all copies. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 | * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER 15 | * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 16 | * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 | */ 18 | 19 | #include 20 | 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | char *osdep_get_name(int, char *); 28 | char *osdep_get_cwd(int); 29 | struct event_base *osdep_event_init(void); 30 | 31 | #define unused __attribute__ ((unused)) 32 | 33 | char * 34 | osdep_get_name(int fd, unused char *tty) 35 | { 36 | struct proc_bsdinfo bsdinfo; 37 | pid_t pgrp; 38 | int ret; 39 | 40 | if ((pgrp = tcgetpgrp(fd)) == -1) 41 | return (NULL); 42 | 43 | ret = proc_pidinfo(pgrp, PROC_PIDTBSDINFO, 0, 44 | &bsdinfo, sizeof bsdinfo); 45 | if (ret == sizeof bsdinfo && *bsdinfo.pbi_comm != '\0') 46 | return (strdup(bsdinfo.pbi_comm)); 47 | return (NULL); 48 | } 49 | 50 | char * 51 | osdep_get_cwd(int fd) 52 | { 53 | static char wd[PATH_MAX]; 54 | struct proc_vnodepathinfo pathinfo; 55 | pid_t pgrp; 56 | int ret; 57 | 58 | if ((pgrp = tcgetpgrp(fd)) == -1) 59 | return (NULL); 60 | 61 | ret = proc_pidinfo(pgrp, PROC_PIDVNODEPATHINFO, 0, 62 | &pathinfo, sizeof pathinfo); 63 | if (ret == sizeof pathinfo) { 64 | strlcpy(wd, pathinfo.pvi_cdir.vip_path, sizeof wd); 65 | return (wd); 66 | } 67 | return (NULL); 68 | } 69 | 70 | struct event_base * 71 | osdep_event_init(void) 72 | { 73 | /* 74 | * On OS X, kqueue and poll are both completely broken and don't 75 | * work on anything except socket file descriptors (yes, really). 76 | */ 77 | setenv("EVENT_NOKQUEUE", "1", 1); 78 | setenv("EVENT_NOPOLL", "1", 1); 79 | return (event_init()); 80 | } 81 | -------------------------------------------------------------------------------- /compat/forkpty-hpux.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2008 Nicholas Marriott 3 | * 4 | * Permission to use, copy, modify, and distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER 13 | * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 14 | * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #include 18 | #include 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | #include "tmux.h" 26 | 27 | pid_t 28 | forkpty(int *master, char *name, struct termios *tio, struct winsize *ws) 29 | { 30 | int slave = -1; 31 | char *path; 32 | pid_t pid; 33 | 34 | if ((*master = open("/dev/ptmx", O_RDWR|O_NOCTTY)) == -1) 35 | return (-1); 36 | if (grantpt(*master) != 0) 37 | goto out; 38 | if (unlockpt(*master) != 0) 39 | goto out; 40 | 41 | if ((path = ptsname(*master)) == NULL) 42 | goto out; 43 | if (name != NULL) 44 | strlcpy(name, path, TTY_NAME_MAX); 45 | if ((slave = open(path, O_RDWR|O_NOCTTY)) == -1) 46 | goto out; 47 | 48 | switch (pid = fork()) { 49 | case -1: 50 | goto out; 51 | case 0: 52 | close(*master); 53 | 54 | setsid(); 55 | #ifdef TIOCSCTTY 56 | if (ioctl(slave, TIOCSCTTY, NULL) == -1) 57 | fatal("ioctl failed"); 58 | #endif 59 | 60 | if (ioctl(slave, I_PUSH, "ptem") == -1) 61 | fatal("ioctl failed"); 62 | if (ioctl(slave, I_PUSH, "ldterm") == -1) 63 | fatal("ioctl failed"); 64 | 65 | if (tio != NULL && tcsetattr(slave, TCSAFLUSH, tio) == -1) 66 | fatal("tcsetattr failed"); 67 | if (ioctl(slave, TIOCSWINSZ, ws) == -1) 68 | fatal("ioctl failed"); 69 | 70 | dup2(slave, 0); 71 | dup2(slave, 1); 72 | dup2(slave, 2); 73 | if (slave > 2) 74 | close(slave); 75 | return (0); 76 | } 77 | 78 | close(slave); 79 | return (pid); 80 | 81 | out: 82 | if (*master != -1) 83 | close(*master); 84 | if (slave != -1) 85 | close(slave); 86 | return (-1); 87 | } 88 | -------------------------------------------------------------------------------- /compat/strcasestr.c: -------------------------------------------------------------------------------- 1 | /* $OpenBSD: strcasestr.c,v 1.3 2006/03/31 05:34:55 deraadt Exp $ */ 2 | /* $NetBSD: strcasestr.c,v 1.2 2005/02/09 21:35:47 kleink Exp $ */ 3 | 4 | /*- 5 | * Copyright (c) 1990, 1993 6 | * The Regents of the University of California. All rights reserved. 7 | * 8 | * This code is derived from software contributed to Berkeley by 9 | * Chris Torek. 10 | * 11 | * Redistribution and use in source and binary forms, with or without 12 | * modification, are permitted provided that the following conditions 13 | * are met: 14 | * 1. Redistributions of source code must retain the above copyright 15 | * notice, this list of conditions and the following disclaimer. 16 | * 2. Redistributions in binary form must reproduce the above copyright 17 | * notice, this list of conditions and the following disclaimer in the 18 | * documentation and/or other materials provided with the distribution. 19 | * 3. Neither the name of the University nor the names of its contributors 20 | * may be used to endorse or promote products derived from this software 21 | * without specific prior written permission. 22 | * 23 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 24 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 27 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 | * SUCH DAMAGE. 34 | */ 35 | 36 | #include 37 | #include 38 | 39 | /* 40 | * Find the first occurrence of find in s, ignore case. 41 | */ 42 | char * 43 | strcasestr(const char *s, const char *find) 44 | { 45 | char c, sc; 46 | size_t len; 47 | 48 | if ((c = *find++) != 0) { 49 | c = (char)tolower((unsigned char)c); 50 | len = strlen(find); 51 | do { 52 | do { 53 | if ((sc = *s++) == 0) 54 | return (NULL); 55 | } while ((char)tolower((unsigned char)sc) != c); 56 | } while (strncasecmp(s, find, len) != 0); 57 | s--; 58 | } 59 | return ((char *)s); 60 | } 61 | -------------------------------------------------------------------------------- /compat/forkpty-sunos.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2008 Nicholas Marriott 3 | * 4 | * Permission to use, copy, modify, and distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER 13 | * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 14 | * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #include 18 | #include 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | #include "tmux.h" 27 | 28 | pid_t 29 | forkpty(int *master, char *name, struct termios *tio, struct winsize *ws) 30 | { 31 | int slave = -1; 32 | char *path; 33 | pid_t pid; 34 | 35 | if ((*master = open("/dev/ptmx", O_RDWR|O_NOCTTY)) == -1) 36 | return (-1); 37 | if (grantpt(*master) != 0) 38 | goto out; 39 | if (unlockpt(*master) != 0) 40 | goto out; 41 | 42 | if ((path = ptsname(*master)) == NULL) 43 | goto out; 44 | if (name != NULL) 45 | strlcpy(name, path, TTY_NAME_MAX); 46 | if ((slave = open(path, O_RDWR|O_NOCTTY)) == -1) 47 | goto out; 48 | 49 | switch (pid = fork()) { 50 | case -1: 51 | goto out; 52 | case 0: 53 | close(*master); 54 | 55 | setsid(); 56 | #ifdef TIOCSCTTY 57 | if (ioctl(slave, TIOCSCTTY, NULL) == -1) 58 | fatal("ioctl failed"); 59 | #endif 60 | 61 | if (ioctl(slave, I_PUSH, "ptem") == -1) 62 | fatal("ioctl failed"); 63 | if (ioctl(slave, I_PUSH, "ldterm") == -1) 64 | fatal("ioctl failed"); 65 | 66 | if (tio != NULL && tcsetattr(slave, TCSAFLUSH, tio) == -1) 67 | fatal("tcsetattr failed"); 68 | if (ioctl(slave, TIOCSWINSZ, ws) == -1) 69 | fatal("ioctl failed"); 70 | 71 | dup2(slave, 0); 72 | dup2(slave, 1); 73 | dup2(slave, 2); 74 | if (slave > 2) 75 | close(slave); 76 | return (0); 77 | } 78 | 79 | close(slave); 80 | return (pid); 81 | 82 | out: 83 | if (*master != -1) 84 | close(*master); 85 | if (slave != -1) 86 | close(slave); 87 | return (-1); 88 | } 89 | -------------------------------------------------------------------------------- /examples/bash_completion_tmux.sh: -------------------------------------------------------------------------------- 1 | # START tmux completion 2 | # This file is in the public domain 3 | # See: http://www.debian-administration.org/articles/317 for how to write more. 4 | # Usage: Put "source bash_completion_tmux.sh" into your .bashrc 5 | _tmux() 6 | { 7 | local cur prev opts 8 | COMPREPLY=() 9 | cur="${COMP_WORDS[COMP_CWORD]}" 10 | prev="${COMP_WORDS[COMP_CWORD-1]}" 11 | 12 | opts=" \ 13 | attach-session \ 14 | bind-key \ 15 | break-pane \ 16 | capture-pane \ 17 | choose-client \ 18 | choose-session \ 19 | choose-window \ 20 | clear-history \ 21 | clock-mode \ 22 | command-prompt \ 23 | confirm-before \ 24 | copy-buffer \ 25 | copy-mode \ 26 | delete-buffer \ 27 | detach-client \ 28 | display-message \ 29 | display-panes \ 30 | down-pane \ 31 | find-window \ 32 | has-session \ 33 | if-shell \ 34 | join-pane \ 35 | kill-pane \ 36 | kill-server \ 37 | kill-session \ 38 | kill-window \ 39 | last-window \ 40 | link-window \ 41 | list-buffers \ 42 | list-clients \ 43 | list-commands \ 44 | list-keys \ 45 | list-panes \ 46 | list-sessions \ 47 | list-windows \ 48 | load-buffer \ 49 | lock-client \ 50 | lock-server \ 51 | lock-session \ 52 | move-window \ 53 | new-session \ 54 | new-window \ 55 | next-layout \ 56 | next-window \ 57 | paste-buffer \ 58 | pipe-pane \ 59 | previous-layout \ 60 | previous-window \ 61 | refresh-client \ 62 | rename-session \ 63 | rename-window \ 64 | resize-pane \ 65 | respawn-window \ 66 | rotate-window \ 67 | run-shell \ 68 | save-buffer \ 69 | select-layout \ 70 | select-pane \ 71 | select-prompt \ 72 | select-window \ 73 | send-keys \ 74 | send-prefix \ 75 | server-info \ 76 | set-buffer \ 77 | set-environment \ 78 | set-option \ 79 | set-window-option \ 80 | show-buffer \ 81 | show-environment \ 82 | show-messages \ 83 | show-options \ 84 | show-window-options \ 85 | source-file \ 86 | split-window \ 87 | start-server \ 88 | suspend-client \ 89 | swap-pane \ 90 | swap-window \ 91 | switch-client \ 92 | unbind-key \ 93 | unlink-window \ 94 | up-pane" 95 | 96 | COMPREPLY=($(compgen -W "${opts}" -- ${cur})) 97 | return 0 98 | 99 | } 100 | complete -F _tmux tmux 101 | 102 | # END tmux completion 103 | 104 | 105 | 106 | -------------------------------------------------------------------------------- /cmd-list-clients.c: -------------------------------------------------------------------------------- 1 | /* $OpenBSD$ */ 2 | 3 | /* 4 | * Copyright (c) 2007 Nicholas Marriott 5 | * 6 | * Permission to use, copy, modify, and distribute this software for any 7 | * purpose with or without fee is hereby granted, provided that the above 8 | * copyright notice and this permission notice appear in all copies. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 | * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER 15 | * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 16 | * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 | */ 18 | 19 | #include 20 | 21 | #include 22 | #include 23 | #include 24 | 25 | #include "tmux.h" 26 | 27 | /* 28 | * List all clients. 29 | */ 30 | 31 | #define LIST_CLIENTS_TEMPLATE \ 32 | "#{client_tty}: #{session_name} " \ 33 | "[#{client_width}x#{client_height} #{client_termname}]" \ 34 | "#{?client_utf8, (utf8),} #{?client_readonly, (ro),}" 35 | 36 | enum cmd_retval cmd_list_clients_exec(struct cmd *, struct cmd_q *); 37 | 38 | const struct cmd_entry cmd_list_clients_entry = { 39 | "list-clients", "lsc", 40 | "F:t:", 0, 0, 41 | "[-F format] " CMD_TARGET_SESSION_USAGE, 42 | CMD_READONLY, 43 | cmd_list_clients_exec 44 | }; 45 | 46 | enum cmd_retval 47 | cmd_list_clients_exec(struct cmd *self, struct cmd_q *cmdq) 48 | { 49 | struct args *args = self->args; 50 | struct client *c; 51 | struct session *s; 52 | struct format_tree *ft; 53 | const char *template; 54 | u_int idx; 55 | char *line; 56 | 57 | if (args_has(args, 't')) { 58 | s = cmd_find_session(cmdq, args_get(args, 't'), 0); 59 | if (s == NULL) 60 | return (CMD_RETURN_ERROR); 61 | } else 62 | s = NULL; 63 | 64 | if ((template = args_get(args, 'F')) == NULL) 65 | template = LIST_CLIENTS_TEMPLATE; 66 | 67 | idx = 0; 68 | TAILQ_FOREACH(c, &clients, entry) { 69 | if (c->session == NULL || (s != NULL && s != c->session)) 70 | continue; 71 | 72 | ft = format_create(); 73 | format_add(ft, "line", "%u", idx); 74 | format_defaults(ft, c, NULL, NULL, NULL); 75 | 76 | line = format_expand(ft, template); 77 | cmdq_print(cmdq, "%s", line); 78 | free(line); 79 | 80 | format_free(ft); 81 | 82 | idx++; 83 | } 84 | 85 | return (CMD_RETURN_NORMAL); 86 | } 87 | -------------------------------------------------------------------------------- /cmd-source-file.c: -------------------------------------------------------------------------------- 1 | /* $OpenBSD$ */ 2 | 3 | /* 4 | * Copyright (c) 2008 Tiago Cunha 5 | * 6 | * Permission to use, copy, modify, and distribute this software for any 7 | * purpose with or without fee is hereby granted, provided that the above 8 | * copyright notice and this permission notice appear in all copies. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 | * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER 15 | * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 16 | * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 | */ 18 | 19 | #include 20 | 21 | #include 22 | 23 | #include "tmux.h" 24 | 25 | /* 26 | * Sources a configuration file. 27 | */ 28 | 29 | enum cmd_retval cmd_source_file_exec(struct cmd *, struct cmd_q *); 30 | 31 | void cmd_source_file_done(struct cmd_q *); 32 | 33 | const struct cmd_entry cmd_source_file_entry = { 34 | "source-file", "source", 35 | "", 1, 1, 36 | "path", 37 | 0, 38 | cmd_source_file_exec 39 | }; 40 | 41 | enum cmd_retval 42 | cmd_source_file_exec(struct cmd *self, struct cmd_q *cmdq) 43 | { 44 | struct args *args = self->args; 45 | struct cmd_q *cmdq1; 46 | char *cause; 47 | 48 | cmdq1 = cmdq_new(NULL); 49 | cmdq1->client = cmdq->client; 50 | cmdq1->emptyfn = cmd_source_file_done; 51 | cmdq1->data = cmdq; 52 | 53 | switch (load_cfg(args->argv[0], cmdq1, &cause)) { 54 | case -1: 55 | if (cfg_references == 0) { 56 | cmdq_free(cmdq1); 57 | cmdq_error(cmdq, "%s", cause); 58 | free(cause); 59 | return (CMD_RETURN_ERROR); 60 | } 61 | cfg_add_cause("%s", cause); 62 | free(cause); 63 | /* FALLTHROUGH */ 64 | case 0: 65 | if (cfg_references == 0) 66 | cfg_print_causes(cmdq); 67 | cmdq_free(cmdq1); 68 | return (CMD_RETURN_NORMAL); 69 | } 70 | 71 | cmdq->references++; 72 | cfg_references++; 73 | 74 | cmdq_continue(cmdq1); 75 | return (CMD_RETURN_WAIT); 76 | } 77 | 78 | void 79 | cmd_source_file_done(struct cmd_q *cmdq1) 80 | { 81 | struct cmd_q *cmdq = cmdq1->data; 82 | 83 | if (cmdq1->client_exit >= 0) 84 | cmdq->client_exit = cmdq1->client_exit; 85 | 86 | cmdq_free(cmdq1); 87 | 88 | cfg_references--; 89 | 90 | if (cmdq_free(cmdq)) 91 | return; 92 | 93 | if (cfg_references == 0) 94 | cfg_print_causes(cmdq); 95 | cmdq_continue(cmdq); 96 | } 97 | -------------------------------------------------------------------------------- /osdep-linux.c: -------------------------------------------------------------------------------- 1 | /* $OpenBSD$ */ 2 | 3 | /* 4 | * Copyright (c) 2009 Nicholas Marriott 5 | * 6 | * Permission to use, copy, modify, and distribute this software for any 7 | * purpose with or without fee is hereby granted, provided that the above 8 | * copyright notice and this permission notice appear in all copies. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 | * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER 15 | * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 16 | * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 | */ 18 | 19 | #include 20 | #include 21 | #include 22 | 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | #include "tmux.h" 29 | 30 | char * 31 | osdep_get_name(int fd, unused char *tty) 32 | { 33 | FILE *f; 34 | char *path, *buf; 35 | size_t len; 36 | int ch; 37 | pid_t pgrp; 38 | 39 | if ((pgrp = tcgetpgrp(fd)) == -1) 40 | return (NULL); 41 | 42 | xasprintf(&path, "/proc/%lld/cmdline", (long long) pgrp); 43 | if ((f = fopen(path, "r")) == NULL) { 44 | free(path); 45 | return (NULL); 46 | } 47 | free(path); 48 | 49 | len = 0; 50 | buf = NULL; 51 | while ((ch = fgetc(f)) != EOF) { 52 | if (ch == '\0') 53 | break; 54 | buf = xrealloc(buf, len + 2); 55 | buf[len++] = ch; 56 | } 57 | if (buf != NULL) 58 | buf[len] = '\0'; 59 | 60 | fclose(f); 61 | return (buf); 62 | } 63 | 64 | char * 65 | osdep_get_cwd(int fd) 66 | { 67 | static char target[MAXPATHLEN + 1]; 68 | char *path; 69 | pid_t pgrp, sid; 70 | ssize_t n; 71 | 72 | if ((pgrp = tcgetpgrp(fd)) == -1) 73 | return (NULL); 74 | 75 | xasprintf(&path, "/proc/%lld/cwd", (long long) pgrp); 76 | n = readlink(path, target, MAXPATHLEN); 77 | free(path); 78 | 79 | if (n == -1 && ioctl(fd, TIOCGSID, &sid) != -1) { 80 | xasprintf(&path, "/proc/%lld/cwd", (long long) sid); 81 | n = readlink(path, target, MAXPATHLEN); 82 | free(path); 83 | } 84 | 85 | if (n > 0) { 86 | target[n] = '\0'; 87 | return (target); 88 | } 89 | return (NULL); 90 | } 91 | 92 | struct event_base * 93 | osdep_event_init(void) 94 | { 95 | /* On Linux, epoll doesn't work on /dev/null (yes, really). */ 96 | setenv("EVENT_NOEPOLL", "1", 1); 97 | return (event_init()); 98 | } 99 | -------------------------------------------------------------------------------- /cmd-copy-mode.c: -------------------------------------------------------------------------------- 1 | /* $OpenBSD$ */ 2 | 3 | /* 4 | * Copyright (c) 2007 Nicholas Marriott 5 | * 6 | * Permission to use, copy, modify, and distribute this software for any 7 | * purpose with or without fee is hereby granted, provided that the above 8 | * copyright notice and this permission notice appear in all copies. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 | * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER 15 | * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 16 | * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 | */ 18 | 19 | #include 20 | 21 | #include "tmux.h" 22 | 23 | /* 24 | * Enter copy or clock mode. 25 | */ 26 | 27 | enum cmd_retval cmd_copy_mode_exec(struct cmd *, struct cmd_q *); 28 | 29 | const struct cmd_entry cmd_copy_mode_entry = { 30 | "copy-mode", NULL, 31 | "Mt:u", 0, 0, 32 | "[-Mu] " CMD_TARGET_PANE_USAGE, 33 | 0, 34 | cmd_copy_mode_exec 35 | }; 36 | 37 | const struct cmd_entry cmd_clock_mode_entry = { 38 | "clock-mode", NULL, 39 | "t:", 0, 0, 40 | CMD_TARGET_PANE_USAGE, 41 | 0, 42 | cmd_copy_mode_exec 43 | }; 44 | 45 | enum cmd_retval 46 | cmd_copy_mode_exec(struct cmd *self, struct cmd_q *cmdq) 47 | { 48 | struct args *args = self->args; 49 | struct client *c = cmdq->client; 50 | struct session *s; 51 | struct window_pane *wp; 52 | 53 | if (args_has(args, 'M')) { 54 | if ((wp = cmd_mouse_pane(&cmdq->item->mouse, &s, NULL)) == NULL) 55 | return (CMD_RETURN_NORMAL); 56 | if (c == NULL || c->session != s) 57 | return (CMD_RETURN_NORMAL); 58 | } else if (cmd_find_pane(cmdq, args_get(args, 't'), NULL, &wp) == NULL) 59 | return (CMD_RETURN_ERROR); 60 | 61 | if (self->entry == &cmd_clock_mode_entry) { 62 | window_pane_set_mode(wp, &window_clock_mode); 63 | return (CMD_RETURN_NORMAL); 64 | } 65 | 66 | if (wp->mode != &window_copy_mode) { 67 | if (window_pane_set_mode(wp, &window_copy_mode) != 0) 68 | return (CMD_RETURN_NORMAL); 69 | window_copy_init_from_pane(wp); 70 | } 71 | if (args_has(args, 'M')) { 72 | if (wp->mode != NULL && wp->mode != &window_copy_mode) 73 | return (CMD_RETURN_NORMAL); 74 | window_copy_start_drag(c, &cmdq->item->mouse); 75 | } 76 | if (wp->mode == &window_copy_mode && args_has(self->args, 'u')) 77 | window_copy_pageup(wp); 78 | 79 | return (CMD_RETURN_NORMAL); 80 | } 81 | -------------------------------------------------------------------------------- /cmd-paste-buffer.c: -------------------------------------------------------------------------------- 1 | /* $OpenBSD$ */ 2 | 3 | /* 4 | * Copyright (c) 2007 Nicholas Marriott 5 | * 6 | * Permission to use, copy, modify, and distribute this software for any 7 | * purpose with or without fee is hereby granted, provided that the above 8 | * copyright notice and this permission notice appear in all copies. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 | * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER 15 | * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 16 | * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 | */ 18 | 19 | #include 20 | 21 | #include 22 | #include 23 | 24 | #include "tmux.h" 25 | 26 | /* 27 | * Paste paste buffer if present. 28 | */ 29 | 30 | enum cmd_retval cmd_paste_buffer_exec(struct cmd *, struct cmd_q *); 31 | 32 | void cmd_paste_buffer_filter(struct window_pane *, 33 | const char *, size_t, const char *, int); 34 | 35 | const struct cmd_entry cmd_paste_buffer_entry = { 36 | "paste-buffer", "pasteb", 37 | "db:prs:t:", 0, 0, 38 | "[-dpr] [-s separator] " CMD_BUFFER_USAGE " " CMD_TARGET_PANE_USAGE, 39 | 0, 40 | cmd_paste_buffer_exec 41 | }; 42 | 43 | enum cmd_retval 44 | cmd_paste_buffer_exec(struct cmd *self, struct cmd_q *cmdq) 45 | { 46 | struct args *args = self->args; 47 | struct window_pane *wp; 48 | struct session *s; 49 | struct paste_buffer *pb; 50 | const char *sepstr, *bufname; 51 | 52 | if (cmd_find_pane(cmdq, args_get(args, 't'), &s, &wp) == NULL) 53 | return (CMD_RETURN_ERROR); 54 | 55 | bufname = NULL; 56 | if (args_has(args, 'b')) 57 | bufname = args_get(args, 'b'); 58 | 59 | if (bufname == NULL) 60 | pb = paste_get_top(); 61 | else { 62 | pb = paste_get_name(bufname); 63 | if (pb == NULL) { 64 | cmdq_error(cmdq, "no buffer %s", bufname); 65 | return (CMD_RETURN_ERROR); 66 | } 67 | } 68 | 69 | if (pb != NULL) { 70 | sepstr = args_get(args, 's'); 71 | if (sepstr == NULL) { 72 | if (args_has(args, 'r')) 73 | sepstr = "\n"; 74 | else 75 | sepstr = "\r"; 76 | } 77 | paste_send_pane(pb, wp, sepstr, args_has(args, 'p')); 78 | } 79 | 80 | /* Delete the buffer if -d. */ 81 | if (args_has(args, 'd')) { 82 | if (bufname == NULL) 83 | paste_free_top(); 84 | else 85 | paste_free_name(bufname); 86 | } 87 | 88 | return (CMD_RETURN_NORMAL); 89 | } 90 | -------------------------------------------------------------------------------- /control.c: -------------------------------------------------------------------------------- 1 | /* $OpenBSD$ */ 2 | 3 | /* 4 | * Copyright (c) 2012 Nicholas Marriott 5 | * Copyright (c) 2012 George Nachman 6 | * 7 | * Permission to use, copy, modify, and distribute this software for any 8 | * purpose with or without fee is hereby granted, provided that the above 9 | * copyright notice and this permission notice appear in all copies. 10 | * 11 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 12 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 13 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 14 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 15 | * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER 16 | * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 17 | * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 18 | */ 19 | 20 | #include 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | #include "tmux.h" 28 | 29 | /* Write a line. */ 30 | void 31 | control_write(struct client *c, const char *fmt, ...) 32 | { 33 | va_list ap; 34 | 35 | va_start(ap, fmt); 36 | evbuffer_add_vprintf(c->stdout_data, fmt, ap); 37 | va_end(ap); 38 | 39 | evbuffer_add(c->stdout_data, "\n", 1); 40 | server_push_stdout(c); 41 | } 42 | 43 | /* Write a buffer, adding a terminal newline. Empties buffer. */ 44 | void 45 | control_write_buffer(struct client *c, struct evbuffer *buffer) 46 | { 47 | evbuffer_add_buffer(c->stdout_data, buffer); 48 | evbuffer_add(c->stdout_data, "\n", 1); 49 | server_push_stdout(c); 50 | } 51 | 52 | /* Control input callback. Read lines and fire commands. */ 53 | void 54 | control_callback(struct client *c, int closed, unused void *data) 55 | { 56 | char *line, *cause; 57 | struct cmd_list *cmdlist; 58 | struct cmd *cmd; 59 | 60 | if (closed) 61 | c->flags |= CLIENT_EXIT; 62 | 63 | for (;;) { 64 | line = evbuffer_readln(c->stdin_data, NULL, EVBUFFER_EOL_LF); 65 | if (line == NULL) 66 | break; 67 | if (*line == '\0') { /* empty line exit */ 68 | c->flags |= CLIENT_EXIT; 69 | break; 70 | } 71 | 72 | if (cmd_string_parse(line, &cmdlist, NULL, 0, &cause) != 0) { 73 | c->cmdq->time = time(NULL); 74 | c->cmdq->number++; 75 | 76 | cmdq_guard(c->cmdq, "begin", 1); 77 | control_write(c, "parse error: %s", cause); 78 | cmdq_guard(c->cmdq, "error", 1); 79 | 80 | free(cause); 81 | } else { 82 | TAILQ_FOREACH(cmd, &cmdlist->list, qentry) 83 | cmd->flags |= CMD_CONTROL; 84 | cmdq_run(c->cmdq, cmdlist, NULL); 85 | cmd_list_free(cmdlist); 86 | } 87 | 88 | free(line); 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /osdep-sunos.c: -------------------------------------------------------------------------------- 1 | /* $OpenBSD$ */ 2 | 3 | /* 4 | * Copyright (c) 2009 Todd Carson 5 | * 6 | * Permission to use, copy, modify, and distribute this software for any 7 | * purpose with or without fee is hereby granted, provided that the above 8 | * copyright notice and this permission notice appear in all copies. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 | * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER 15 | * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 16 | * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 | */ 18 | 19 | #include 20 | #include 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | #include "tmux.h" 30 | 31 | char * 32 | osdep_get_name(int fd, char *tty) 33 | { 34 | struct psinfo p; 35 | struct stat st; 36 | char *path; 37 | ssize_t bytes; 38 | int f; 39 | pid_t pgrp; 40 | 41 | if ((f = open(tty, O_RDONLY)) < 0) 42 | return (NULL); 43 | 44 | if (fstat(f, &st) != 0 || ioctl(f, TIOCGPGRP, &pgrp) != 0) { 45 | close(f); 46 | return (NULL); 47 | } 48 | close(f); 49 | 50 | xasprintf(&path, "/proc/%u/psinfo", (u_int) pgrp); 51 | f = open(path, O_RDONLY); 52 | free(path); 53 | if (f < 0) 54 | return (NULL); 55 | 56 | bytes = read(f, &p, sizeof(p)); 57 | close(f); 58 | if (bytes != sizeof(p)) 59 | return (NULL); 60 | 61 | if (p.pr_ttydev != st.st_rdev) 62 | return (NULL); 63 | 64 | return (xstrdup(p.pr_fname)); 65 | } 66 | 67 | char * 68 | osdep_get_cwd(int fd) 69 | { 70 | static char target[MAXPATHLEN + 1]; 71 | char *path; 72 | const char *ttypath; 73 | ssize_t n; 74 | pid_t pgrp; 75 | int retval, ttyfd; 76 | 77 | if ((ttypath = ptsname(fd)) == NULL) 78 | return (NULL); 79 | if ((ttyfd = open(ttypath, O_RDONLY|O_NOCTTY)) == -1) 80 | return (NULL); 81 | 82 | retval = ioctl(ttyfd, TIOCGPGRP, &pgrp); 83 | close(ttyfd); 84 | if (retval == -1) 85 | return (NULL); 86 | 87 | xasprintf(&path, "/proc/%u/path/cwd", (u_int) pgrp); 88 | n = readlink(path, target, MAXPATHLEN); 89 | free(path); 90 | if (n > 0) { 91 | target[n] = '\0'; 92 | return (target); 93 | } 94 | return (NULL); 95 | } 96 | 97 | struct event_base * 98 | osdep_event_init(void) 99 | { 100 | return (event_init()); 101 | } 102 | -------------------------------------------------------------------------------- /cmd-swap-window.c: -------------------------------------------------------------------------------- 1 | /* $OpenBSD$ */ 2 | 3 | /* 4 | * Copyright (c) 2007 Nicholas Marriott 5 | * 6 | * Permission to use, copy, modify, and distribute this software for any 7 | * purpose with or without fee is hereby granted, provided that the above 8 | * copyright notice and this permission notice appear in all copies. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 | * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER 15 | * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 16 | * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 | */ 18 | 19 | #include 20 | 21 | #include 22 | 23 | #include "tmux.h" 24 | 25 | /* 26 | * Swap one window with another. 27 | */ 28 | 29 | enum cmd_retval cmd_swap_window_exec(struct cmd *, struct cmd_q *); 30 | 31 | const struct cmd_entry cmd_swap_window_entry = { 32 | "swap-window", "swapw", 33 | "ds:t:", 0, 0, 34 | "[-d] " CMD_SRCDST_WINDOW_USAGE, 35 | 0, 36 | cmd_swap_window_exec 37 | }; 38 | 39 | enum cmd_retval 40 | cmd_swap_window_exec(struct cmd *self, struct cmd_q *cmdq) 41 | { 42 | struct args *args = self->args; 43 | const char *target_src, *target_dst; 44 | struct session *src, *dst; 45 | struct session_group *sg_src, *sg_dst; 46 | struct winlink *wl_src, *wl_dst; 47 | struct window *w; 48 | 49 | target_src = args_get(args, 's'); 50 | if ((wl_src = cmd_find_window_marked(cmdq, target_src, &src)) == NULL) 51 | return (CMD_RETURN_ERROR); 52 | target_dst = args_get(args, 't'); 53 | if ((wl_dst = cmd_find_window(cmdq, target_dst, &dst)) == NULL) 54 | return (CMD_RETURN_ERROR); 55 | 56 | sg_src = session_group_find(src); 57 | sg_dst = session_group_find(dst); 58 | if (src != dst && 59 | sg_src != NULL && sg_dst != NULL && sg_src == sg_dst) { 60 | cmdq_error(cmdq, "can't move window, sessions are grouped"); 61 | return (CMD_RETURN_ERROR); 62 | } 63 | 64 | if (wl_dst->window == wl_src->window) 65 | return (CMD_RETURN_NORMAL); 66 | 67 | w = wl_dst->window; 68 | wl_dst->window = wl_src->window; 69 | wl_src->window = w; 70 | 71 | if (!args_has(self->args, 'd')) { 72 | session_select(dst, wl_dst->idx); 73 | if (src != dst) 74 | session_select(src, wl_src->idx); 75 | } 76 | session_group_synchronize_from(src); 77 | server_redraw_session_group(src); 78 | if (src != dst) { 79 | session_group_synchronize_from(dst); 80 | server_redraw_session_group(dst); 81 | } 82 | recalculate_sizes(); 83 | 84 | return (CMD_RETURN_NORMAL); 85 | } 86 | -------------------------------------------------------------------------------- /compat/strsep.c: -------------------------------------------------------------------------------- 1 | /* $OpenBSD: strsep.c,v 1.6 2005/08/08 08:05:37 espie Exp $ */ 2 | 3 | /*- 4 | * Copyright (c) 1990, 1993 5 | * The Regents of the University of California. All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions 9 | * are met: 10 | * 1. Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * 2. Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer in the 14 | * documentation and/or other materials provided with the distribution. 15 | * 3. Neither the name of the University nor the names of its contributors 16 | * may be used to endorse or promote products derived from this software 17 | * without specific prior written permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 20 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 | * SUCH DAMAGE. 30 | */ 31 | 32 | #include 33 | #include 34 | 35 | /* 36 | * Get next token from string *stringp, where tokens are possibly-empty 37 | * strings separated by characters from delim. 38 | * 39 | * Writes NULs into the string at *stringp to end tokens. 40 | * delim need not remain constant from call to call. 41 | * On return, *stringp points past the last NUL written (if there might 42 | * be further tokens), or is NULL (if there are definitely no more tokens). 43 | * 44 | * If *stringp is NULL, strsep returns NULL. 45 | */ 46 | char * 47 | strsep(char **stringp, const char *delim) 48 | { 49 | char *s; 50 | const char *spanp; 51 | int c, sc; 52 | char *tok; 53 | 54 | if ((s = *stringp) == NULL) 55 | return (NULL); 56 | for (tok = s;;) { 57 | c = *s++; 58 | spanp = delim; 59 | do { 60 | if ((sc = *spanp++) == c) { 61 | if (c == 0) 62 | s = NULL; 63 | else 64 | s[-1] = 0; 65 | *stringp = s; 66 | return (tok); 67 | } 68 | } while (sc != 0); 69 | } 70 | /* NOTREACHED */ 71 | } 72 | -------------------------------------------------------------------------------- /cmd-set-environment.c: -------------------------------------------------------------------------------- 1 | /* $OpenBSD$ */ 2 | 3 | /* 4 | * Copyright (c) 2009 Nicholas Marriott 5 | * 6 | * Permission to use, copy, modify, and distribute this software for any 7 | * purpose with or without fee is hereby granted, provided that the above 8 | * copyright notice and this permission notice appear in all copies. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 | * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER 15 | * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 16 | * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 | */ 18 | 19 | #include 20 | 21 | #include 22 | #include 23 | 24 | #include "tmux.h" 25 | 26 | /* 27 | * Set an environment variable. 28 | */ 29 | 30 | enum cmd_retval cmd_set_environment_exec(struct cmd *, struct cmd_q *); 31 | 32 | const struct cmd_entry cmd_set_environment_entry = { 33 | "set-environment", "setenv", 34 | "grt:u", 1, 2, 35 | "[-gru] " CMD_TARGET_SESSION_USAGE " name [value]", 36 | 0, 37 | cmd_set_environment_exec 38 | }; 39 | 40 | enum cmd_retval 41 | cmd_set_environment_exec(struct cmd *self, struct cmd_q *cmdq) 42 | { 43 | struct args *args = self->args; 44 | struct session *s; 45 | struct environ *env; 46 | const char *name, *value; 47 | 48 | name = args->argv[0]; 49 | if (*name == '\0') { 50 | cmdq_error(cmdq, "empty variable name"); 51 | return (CMD_RETURN_ERROR); 52 | } 53 | if (strchr(name, '=') != NULL) { 54 | cmdq_error(cmdq, "variable name contains ="); 55 | return (CMD_RETURN_ERROR); 56 | } 57 | 58 | if (args->argc < 2) 59 | value = NULL; 60 | else 61 | value = args->argv[1]; 62 | 63 | if (args_has(self->args, 'g')) 64 | env = &global_environ; 65 | else { 66 | if ((s = cmd_find_session(cmdq, args_get(args, 't'), 0)) == NULL) 67 | return (CMD_RETURN_ERROR); 68 | env = &s->environ; 69 | } 70 | 71 | if (args_has(self->args, 'u')) { 72 | if (value != NULL) { 73 | cmdq_error(cmdq, "can't specify a value with -u"); 74 | return (CMD_RETURN_ERROR); 75 | } 76 | environ_unset(env, name); 77 | } else if (args_has(self->args, 'r')) { 78 | if (value != NULL) { 79 | cmdq_error(cmdq, "can't specify a value with -r"); 80 | return (CMD_RETURN_ERROR); 81 | } 82 | environ_set(env, name, NULL); 83 | } else { 84 | if (value == NULL) { 85 | cmdq_error(cmdq, "no value specified"); 86 | return (CMD_RETURN_ERROR); 87 | } 88 | environ_set(env, name, value); 89 | } 90 | 91 | return (CMD_RETURN_NORMAL); 92 | } 93 | -------------------------------------------------------------------------------- /compat/fgetln.c: -------------------------------------------------------------------------------- 1 | /* $NetBSD: fgetln.c,v 1.3 2007/08/07 02:06:58 lukem Exp $ */ 2 | 3 | /*- 4 | * Copyright (c) 1998 The NetBSD Foundation, Inc. 5 | * All rights reserved. 6 | * 7 | * This code is derived from software contributed to The NetBSD Foundation 8 | * by Christos Zoulas. 9 | * 10 | * Redistribution and use in source and binary forms, with or without 11 | * modification, are permitted provided that the following conditions 12 | * are met: 13 | * 1. Redistributions of source code must retain the above copyright 14 | * notice, this list of conditions and the following disclaimer. 15 | * 2. Redistributions in binary form must reproduce the above copyright 16 | * notice, this list of conditions and the following disclaimer in the 17 | * documentation and/or other materials provided with the distribution. 18 | * 3. Neither the name of The NetBSD Foundation nor the names of its 19 | * contributors may be used to endorse or promote products derived 20 | * from this software without specific prior written permission. 21 | * 22 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 23 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 24 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 25 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 26 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 27 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 28 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 29 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 30 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 31 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 32 | * POSSIBILITY OF SUCH DAMAGE. 33 | */ 34 | 35 | #include 36 | 37 | #include 38 | #include 39 | #include 40 | #include 41 | 42 | #include "tmux.h" 43 | 44 | char * 45 | fgetln(FILE *fp, size_t *len) 46 | { 47 | static char *buf = NULL; 48 | static size_t bufsiz = 0; 49 | char *ptr; 50 | 51 | 52 | if (buf == NULL) { 53 | bufsiz = BUFSIZ; 54 | if ((buf = malloc(bufsiz)) == NULL) 55 | return NULL; 56 | } 57 | 58 | if (fgets(buf, bufsiz, fp) == NULL) 59 | return NULL; 60 | 61 | *len = 0; 62 | while ((ptr = strchr(&buf[*len], '\n')) == NULL) { 63 | size_t nbufsiz = bufsiz + BUFSIZ; 64 | char *nbuf = realloc(buf, nbufsiz); 65 | 66 | if (nbuf == NULL) { 67 | int oerrno = errno; 68 | free(buf); 69 | errno = oerrno; 70 | buf = NULL; 71 | return NULL; 72 | } else 73 | buf = nbuf; 74 | 75 | *len = bufsiz; 76 | if (fgets(&buf[bufsiz], BUFSIZ, fp) == NULL) 77 | return buf; 78 | 79 | bufsiz = nbufsiz; 80 | } 81 | 82 | *len = (ptr - buf) + 1; 83 | return buf; 84 | } 85 | 86 | -------------------------------------------------------------------------------- /cmd-send-keys.c: -------------------------------------------------------------------------------- 1 | /* $OpenBSD$ */ 2 | 3 | /* 4 | * Copyright (c) 2008 Nicholas Marriott 5 | * 6 | * Permission to use, copy, modify, and distribute this software for any 7 | * purpose with or without fee is hereby granted, provided that the above 8 | * copyright notice and this permission notice appear in all copies. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 | * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER 15 | * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 16 | * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 | */ 18 | 19 | #include 20 | 21 | #include 22 | #include 23 | 24 | #include "tmux.h" 25 | 26 | /* 27 | * Send keys to client. 28 | */ 29 | 30 | enum cmd_retval cmd_send_keys_exec(struct cmd *, struct cmd_q *); 31 | 32 | const struct cmd_entry cmd_send_keys_entry = { 33 | "send-keys", "send", 34 | "lRMt:", 0, -1, 35 | "[-lRM] " CMD_TARGET_PANE_USAGE " key ...", 36 | 0, 37 | cmd_send_keys_exec 38 | }; 39 | 40 | const struct cmd_entry cmd_send_prefix_entry = { 41 | "send-prefix", NULL, 42 | "2t:", 0, 0, 43 | "[-2] " CMD_TARGET_PANE_USAGE, 44 | 0, 45 | cmd_send_keys_exec 46 | }; 47 | 48 | enum cmd_retval 49 | cmd_send_keys_exec(struct cmd *self, struct cmd_q *cmdq) 50 | { 51 | struct args *args = self->args; 52 | struct mouse_event *m = &cmdq->item->mouse; 53 | struct window_pane *wp; 54 | struct session *s; 55 | const u_char *str; 56 | int i, key; 57 | 58 | if (args_has(args, 'M')) { 59 | wp = cmd_mouse_pane(m, &s, NULL); 60 | if (wp == NULL) { 61 | cmdq_error(cmdq, "no mouse target"); 62 | return (CMD_RETURN_ERROR); 63 | } 64 | window_pane_key(wp, NULL, s, m->key, m); 65 | return (CMD_RETURN_NORMAL); 66 | } 67 | 68 | if (cmd_find_pane(cmdq, args_get(args, 't'), &s, &wp) == NULL) 69 | return (CMD_RETURN_ERROR); 70 | 71 | if (self->entry == &cmd_send_prefix_entry) { 72 | if (args_has(args, '2')) 73 | key = options_get_number(&s->options, "prefix2"); 74 | else 75 | key = options_get_number(&s->options, "prefix"); 76 | window_pane_key(wp, NULL, s, key, NULL); 77 | return (CMD_RETURN_NORMAL); 78 | } 79 | 80 | if (args_has(args, 'R')) 81 | input_reset(wp); 82 | 83 | for (i = 0; i < args->argc; i++) { 84 | str = args->argv[i]; 85 | 86 | if (!args_has(args, 'l') && 87 | (key = key_string_lookup_string(str)) != KEYC_NONE) { 88 | window_pane_key(wp, NULL, s, key, NULL); 89 | } else { 90 | for (; *str != '\0'; str++) 91 | window_pane_key(wp, NULL, s, *str, NULL); 92 | } 93 | } 94 | 95 | return (CMD_RETURN_NORMAL); 96 | } 97 | -------------------------------------------------------------------------------- /examples/n-marriott.conf: -------------------------------------------------------------------------------- 1 | # $Id: n-marriott.conf,v 1.11 2009-11-24 19:03:59 nicm Exp $ 2 | # 3 | # By Nicholas Marriott. Public domain. 4 | 5 | # Default global options. 6 | set -g status-bg green 7 | set -g status-right "%H:%M" # %d-%b-%y 8 | set -g bell-action none 9 | set -g lock-after-time 1800 10 | 11 | # Default global window options. 12 | setw -g remain-on-exit on 13 | setw -g window-status-current-attr "underscore" 14 | #setw -g xterm-keys on 15 | 16 | # Prefix key. 17 | set -g prefix C-a 18 | unbind C-b 19 | bind C-a send-prefix 20 | 21 | # Keys to switch session. 22 | bind Q switchc -t0 23 | bind W switchc -t1 24 | bind E switchc -t2 25 | 26 | # Other key bindings. 27 | bind F1 selectw -t:10 28 | bind F2 selectw -t:11 29 | bind F3 selectw -t:12 30 | bind F4 selectw -t:13 31 | bind F5 selectw -t:14 32 | bind F6 selectw -t:15 33 | bind F7 selectw -t:16 34 | bind F8 selectw -t:17 35 | bind F9 selectw -t:18 36 | bind F10 selectw -t:19 37 | bind F11 selectw -t:20 38 | bind F12 selectw -t:21 39 | 40 | bind m setw monitor-activity 41 | 42 | bind y setw force-width 81 43 | bind u setw force-width 0 44 | 45 | bind -n F1 run-shell 'mpc toggle >/dev/null 2>&1' 46 | bind -n F2 run-shell 'mpc' 47 | bind -n F3 run-shell 'mpc prev >/dev/null 2>&1' 48 | bind -n F4 run-shell 'mpc next >/dev/null 2>&1' 49 | bind -n F5 run-shell 'mpc volume -5 >/dev/null 2>&1' 50 | bind -n F6 run-shell 'mpc volume +5 >/dev/null 2>&1' 51 | 52 | # Hide and show window name from status line 53 | bind '-' setw window-status-format '#I'\; setw window-status-current-format '#I' 54 | bind '+' setw window-status-format '#I:#W#F'\; setw window-status-current-format '#I:#W#F' 55 | 56 | # First session. 57 | new -d -s0 -nirssi 'exec ssh -t natalya exec sh ~/bin/tmux-start' 58 | setw -t0:0 monitor-activity on 59 | setw -t0:0 aggressive-resize on 60 | set -t0 status-bg green 61 | neww -d -ntodo 'exec emacs ~/TODO' 62 | setw -t0:1 aggressive-resize on 63 | neww -d -ntodo2 'exec emacs ~/TODO2' 64 | setw -t0:2 aggressive-resize on 65 | neww -d -nncmpc 'exec ncmpc -f ~/.ncmpc.conf' 66 | setw -t0:3 aggressive-resize on 67 | neww -d -nmutt 'exec mutt' 68 | setw -t0:4 aggressive-resize on 69 | neww -d 70 | neww -d 71 | neww -d 72 | neww -d 73 | neww -d 74 | neww -d 75 | neww -d 76 | neww -d 77 | neww -d 78 | neww -d 79 | neww -d 80 | neww -d 81 | 82 | # Second session. 83 | new -d -s1 84 | set -t1 status-bg cyan 85 | linkw -dk -t0 -s0:0 86 | linkw -dk -t1 -s0:1 87 | linkw -dk -t2 -s0:2 88 | linkw -dk -t3 -s0:3 89 | linkw -dk -t4 -s0:4 90 | neww -d 91 | neww -d 92 | neww -d 93 | neww -d 94 | neww -d 95 | neww -d 96 | 97 | # Third session. 98 | new -d -s2 99 | set -t2 status-bg yellow 100 | linkw -dk -t0 -s0:0 101 | linkw -dk -t1 -s0:1 102 | linkw -dk -t2 -s0:2 103 | linkw -dk -t3 -s0:3 104 | linkw -dk -t4 -s0:4 105 | neww -d 106 | neww -d 107 | neww -d 108 | neww -d 109 | neww -d 110 | neww -d 111 | -------------------------------------------------------------------------------- /attributes.c: -------------------------------------------------------------------------------- 1 | /* $OpenBSD$ */ 2 | 3 | /* 4 | * Copyright (c) 2009 Joshua Elsasser 5 | * 6 | * Permission to use, copy, modify, and distribute this software for any 7 | * purpose with or without fee is hereby granted, provided that the above 8 | * copyright notice and this permission notice appear in all copies. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 | * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER 15 | * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 16 | * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 | */ 18 | 19 | #include 20 | 21 | #include 22 | 23 | #include "tmux.h" 24 | 25 | const char * 26 | attributes_tostring(u_char attr) 27 | { 28 | static char buf[128]; 29 | size_t len; 30 | 31 | if (attr == 0) 32 | return ("none"); 33 | 34 | len = xsnprintf(buf, sizeof buf, "%s%s%s%s%s%s%s", 35 | attr & GRID_ATTR_BRIGHT ? "bright," : "", 36 | attr & GRID_ATTR_DIM ? "dim," : "", 37 | attr & GRID_ATTR_UNDERSCORE ? "underscore," : "", 38 | attr & GRID_ATTR_BLINK ? "blink," : "", 39 | attr & GRID_ATTR_REVERSE ? "reverse," : "", 40 | attr & GRID_ATTR_HIDDEN ? "hidden," : "", 41 | attr & GRID_ATTR_ITALICS ? "italics," : ""); 42 | if (len > 0) 43 | buf[len - 1] = '\0'; 44 | 45 | return (buf); 46 | } 47 | 48 | int 49 | attributes_fromstring(const char *str) 50 | { 51 | const char delimiters[] = " ,|"; 52 | u_char attr; 53 | size_t end; 54 | 55 | if (*str == '\0' || strcspn(str, delimiters) == 0) 56 | return (-1); 57 | if (strchr(delimiters, str[strlen(str) - 1]) != NULL) 58 | return (-1); 59 | 60 | if (strcasecmp(str, "default") == 0 || strcasecmp(str, "none") == 0) 61 | return (0); 62 | 63 | attr = 0; 64 | do { 65 | end = strcspn(str, delimiters); 66 | if ((end == 6 && strncasecmp(str, "bright", end) == 0) || 67 | (end == 4 && strncasecmp(str, "bold", end) == 0)) 68 | attr |= GRID_ATTR_BRIGHT; 69 | else if (end == 3 && strncasecmp(str, "dim", end) == 0) 70 | attr |= GRID_ATTR_DIM; 71 | else if (end == 10 && strncasecmp(str, "underscore", end) == 0) 72 | attr |= GRID_ATTR_UNDERSCORE; 73 | else if (end == 5 && strncasecmp(str, "blink", end) == 0) 74 | attr |= GRID_ATTR_BLINK; 75 | else if (end == 7 && strncasecmp(str, "reverse", end) == 0) 76 | attr |= GRID_ATTR_REVERSE; 77 | else if (end == 6 && strncasecmp(str, "hidden", end) == 0) 78 | attr |= GRID_ATTR_HIDDEN; 79 | else if (end == 7 && strncasecmp(str, "italics", end) == 0) 80 | attr |= GRID_ATTR_ITALICS; 81 | else 82 | return (-1); 83 | str += end + strspn(str + end, delimiters); 84 | } while (*str != '\0'); 85 | 86 | return (attr); 87 | } 88 | -------------------------------------------------------------------------------- /log.c: -------------------------------------------------------------------------------- 1 | /* $OpenBSD$ */ 2 | 3 | /* 4 | * Copyright (c) 2007 Nicholas Marriott 5 | * 6 | * Permission to use, copy, modify, and distribute this software for any 7 | * purpose with or without fee is hereby granted, provided that the above 8 | * copyright notice and this permission notice appear in all copies. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 | * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER 15 | * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 16 | * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 | */ 18 | 19 | #include 20 | #include 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | #include "tmux.h" 28 | 29 | FILE *log_file; 30 | 31 | void log_event_cb(int, const char *); 32 | void log_vwrite(const char *, va_list); 33 | 34 | /* Log callback for libevent. */ 35 | void 36 | log_event_cb(unused int severity, const char *msg) 37 | { 38 | log_debug("%s", msg); 39 | } 40 | 41 | /* Open logging to file. */ 42 | void 43 | log_open(const char *path) 44 | { 45 | log_file = fopen(path, "w"); 46 | if (log_file == NULL) 47 | return; 48 | 49 | setvbuf(log_file, NULL, _IOLBF, 0); 50 | event_set_log_callback(log_event_cb); 51 | 52 | tzset(); 53 | } 54 | 55 | /* Close logging. */ 56 | void 57 | log_close(void) 58 | { 59 | if (log_file != NULL) 60 | fclose(log_file); 61 | log_file = NULL; 62 | 63 | event_set_log_callback(NULL); 64 | } 65 | 66 | /* Write a log message. */ 67 | void 68 | log_vwrite(const char *msg, va_list ap) 69 | { 70 | char *fmt; 71 | 72 | if (log_file == NULL) 73 | return; 74 | 75 | if (asprintf(&fmt, "%s\n", msg) == -1) 76 | exit(1); 77 | if (vfprintf(log_file, fmt, ap) == -1) 78 | exit(1); 79 | fflush(log_file); 80 | free(fmt); 81 | } 82 | 83 | /* Log a debug message. */ 84 | void 85 | log_debug(const char *msg, ...) 86 | { 87 | va_list ap; 88 | 89 | va_start(ap, msg); 90 | log_vwrite(msg, ap); 91 | va_end(ap); 92 | } 93 | 94 | /* Log a critical error with error string and die. */ 95 | __dead void 96 | log_fatal(const char *msg, ...) 97 | { 98 | char *fmt; 99 | va_list ap; 100 | 101 | va_start(ap, msg); 102 | if (asprintf(&fmt, "fatal: %s: %s", msg, strerror(errno)) == -1) 103 | exit(1); 104 | log_vwrite(fmt, ap); 105 | exit(1); 106 | } 107 | 108 | /* Log a critical error and die. */ 109 | __dead void 110 | log_fatalx(const char *msg, ...) 111 | { 112 | char *fmt; 113 | va_list ap; 114 | 115 | va_start(ap, msg); 116 | if (asprintf(&fmt, "fatal: %s", msg) == -1) 117 | exit(1); 118 | log_vwrite(fmt, ap); 119 | exit(1); 120 | } 121 | -------------------------------------------------------------------------------- /compat/forkpty-aix.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009 Nicholas Marriott 3 | * 4 | * Permission to use, copy, modify, and distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER 13 | * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 14 | * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #include 18 | #include 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | #include "tmux.h" 27 | 28 | pid_t 29 | forkpty(int *master, unused char *name, struct termios *tio, struct winsize *ws) 30 | { 31 | int slave = -1, fd, pipe_fd[2]; 32 | char *path, dummy; 33 | pid_t pid; 34 | 35 | if (pipe(pipe_fd) == -1) 36 | return (-1); 37 | 38 | if ((*master = open("/dev/ptc", O_RDWR|O_NOCTTY)) == -1) 39 | goto out; 40 | 41 | if ((path = ttyname(*master)) == NULL) 42 | goto out; 43 | if ((slave = open(path, O_RDWR|O_NOCTTY)) == -1) 44 | goto out; 45 | 46 | switch (pid = fork()) { 47 | case -1: 48 | goto out; 49 | case 0: 50 | close(*master); 51 | 52 | close(pipe_fd[1]); 53 | while (read(pipe_fd[0], &dummy, 1) == -1) { 54 | if (errno != EINTR) 55 | break; 56 | } 57 | close(pipe_fd[0]); 58 | 59 | fd = open(_PATH_TTY, O_RDWR|O_NOCTTY); 60 | if (fd >= 0) { 61 | ioctl(fd, TIOCNOTTY, NULL); 62 | close(fd); 63 | } 64 | 65 | if (setsid() < 0) 66 | fatal("setsid"); 67 | 68 | fd = open(_PATH_TTY, O_RDWR|O_NOCTTY); 69 | if (fd >= 0) 70 | fatalx("open succeeded (failed to disconnect)"); 71 | 72 | fd = open(path, O_RDWR); 73 | if (fd < 0) 74 | fatal("open failed"); 75 | close(fd); 76 | 77 | fd = open("/dev/tty", O_WRONLY); 78 | if (fd < 0) 79 | fatal("open failed"); 80 | close(fd); 81 | 82 | if (tio != NULL && tcsetattr(slave, TCSAFLUSH, tio) == -1) 83 | fatal("tcsetattr failed"); 84 | if (ioctl(slave, TIOCSWINSZ, ws) == -1) 85 | fatal("ioctl failed"); 86 | 87 | dup2(slave, 0); 88 | dup2(slave, 1); 89 | dup2(slave, 2); 90 | if (slave > 2) 91 | close(slave); 92 | 93 | return (0); 94 | } 95 | 96 | close(slave); 97 | 98 | close(pipe_fd[0]); 99 | close(pipe_fd[1]); 100 | return (pid); 101 | 102 | out: 103 | if (*master != -1) 104 | close(*master); 105 | if (slave != -1) 106 | close(slave); 107 | 108 | close(pipe_fd[0]); 109 | close(pipe_fd[1]); 110 | return (-1); 111 | } 112 | -------------------------------------------------------------------------------- /cmd-respawn-pane.c: -------------------------------------------------------------------------------- 1 | /* $OpenBSD$ */ 2 | 3 | /* 4 | * Copyright (c) 2008 Nicholas Marriott 5 | * Copyright (c) 2011 Marcel P. Partap 6 | * 7 | * Permission to use, copy, modify, and distribute this software for any 8 | * purpose with or without fee is hereby granted, provided that the above 9 | * copyright notice and this permission notice appear in all copies. 10 | * 11 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 12 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 13 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 14 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 15 | * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER 16 | * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 17 | * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 18 | */ 19 | 20 | #include 21 | 22 | #include 23 | #include 24 | 25 | #include "tmux.h" 26 | 27 | /* 28 | * Respawn a pane (restart the command). Kill existing if -k given. 29 | */ 30 | 31 | enum cmd_retval cmd_respawn_pane_exec(struct cmd *, struct cmd_q *); 32 | 33 | const struct cmd_entry cmd_respawn_pane_entry = { 34 | "respawn-pane", "respawnp", 35 | "kt:", 0, -1, 36 | "[-k] " CMD_TARGET_PANE_USAGE " [command]", 37 | 0, 38 | cmd_respawn_pane_exec 39 | }; 40 | 41 | enum cmd_retval 42 | cmd_respawn_pane_exec(struct cmd *self, struct cmd_q *cmdq) 43 | { 44 | struct args *args = self->args; 45 | struct winlink *wl; 46 | struct window *w; 47 | struct window_pane *wp; 48 | struct session *s; 49 | struct environ env; 50 | const char *path; 51 | char *cause; 52 | u_int idx; 53 | struct environ_entry *envent; 54 | 55 | if ((wl = cmd_find_pane(cmdq, args_get(args, 't'), &s, &wp)) == NULL) 56 | return (CMD_RETURN_ERROR); 57 | w = wl->window; 58 | 59 | if (!args_has(self->args, 'k') && wp->fd != -1) { 60 | if (window_pane_index(wp, &idx) != 0) 61 | fatalx("index not found"); 62 | cmdq_error(cmdq, "pane still active: %s:%d.%u", 63 | s->name, wl->idx, idx); 64 | return (CMD_RETURN_ERROR); 65 | } 66 | 67 | environ_init(&env); 68 | environ_copy(&global_environ, &env); 69 | environ_copy(&s->environ, &env); 70 | server_fill_environ(s, &env); 71 | 72 | window_pane_reset_mode(wp); 73 | screen_reinit(&wp->base); 74 | input_init(wp); 75 | 76 | path = NULL; 77 | if (cmdq->client != NULL && cmdq->client->session == NULL) 78 | envent = environ_find(&cmdq->client->environ, "PATH"); 79 | else 80 | envent = environ_find(&s->environ, "PATH"); 81 | if (envent != NULL) 82 | path = envent->value; 83 | 84 | if (window_pane_spawn(wp, args->argc, args->argv, path, NULL, -1, &env, 85 | s->tio, &cause) != 0) { 86 | cmdq_error(cmdq, "respawn pane failed: %s", cause); 87 | free(cause); 88 | environ_free(&env); 89 | return (CMD_RETURN_ERROR); 90 | } 91 | wp->flags |= PANE_REDRAW; 92 | server_status_window(w); 93 | 94 | environ_free(&env); 95 | return (CMD_RETURN_NORMAL); 96 | } 97 | -------------------------------------------------------------------------------- /cmd-detach-client.c: -------------------------------------------------------------------------------- 1 | /* $OpenBSD$ */ 2 | 3 | /* 4 | * Copyright (c) 2007 Nicholas Marriott 5 | * 6 | * Permission to use, copy, modify, and distribute this software for any 7 | * purpose with or without fee is hereby granted, provided that the above 8 | * copyright notice and this permission notice appear in all copies. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 | * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER 15 | * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 16 | * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 | */ 18 | 19 | #include 20 | 21 | #include 22 | 23 | #include "tmux.h" 24 | 25 | /* 26 | * Detach a client. 27 | */ 28 | 29 | enum cmd_retval cmd_detach_client_exec(struct cmd *, struct cmd_q *); 30 | 31 | const struct cmd_entry cmd_detach_client_entry = { 32 | "detach-client", "detach", 33 | "as:t:P", 0, 0, 34 | "[-P] [-a] [-s target-session] " CMD_TARGET_CLIENT_USAGE, 35 | CMD_READONLY, 36 | cmd_detach_client_exec 37 | }; 38 | 39 | const struct cmd_entry cmd_suspend_client_entry = { 40 | "suspend-client", "suspendc", 41 | "t:", 0, 0, 42 | CMD_TARGET_CLIENT_USAGE, 43 | 0, 44 | cmd_detach_client_exec 45 | }; 46 | 47 | enum cmd_retval 48 | cmd_detach_client_exec(struct cmd *self, struct cmd_q *cmdq) 49 | { 50 | struct args *args = self->args; 51 | struct client *c, *cloop; 52 | struct session *s; 53 | enum msgtype msgtype; 54 | 55 | if (self->entry == &cmd_suspend_client_entry) { 56 | if ((c = cmd_find_client(cmdq, args_get(args, 't'), 0)) == NULL) 57 | return (CMD_RETURN_ERROR); 58 | tty_stop_tty(&c->tty); 59 | c->flags |= CLIENT_SUSPENDED; 60 | server_write_client(c, MSG_SUSPEND, NULL, 0); 61 | return (CMD_RETURN_NORMAL); 62 | } 63 | 64 | if (args_has(args, 'P')) 65 | msgtype = MSG_DETACHKILL; 66 | else 67 | msgtype = MSG_DETACH; 68 | 69 | if (args_has(args, 's')) { 70 | s = cmd_find_session(cmdq, args_get(args, 's'), 0); 71 | if (s == NULL) 72 | return (CMD_RETURN_ERROR); 73 | 74 | TAILQ_FOREACH(cloop, &clients, entry) { 75 | if (cloop->session != s) 76 | continue; 77 | server_write_client(cloop, msgtype, 78 | cloop->session->name, 79 | strlen(cloop->session->name) + 1); 80 | } 81 | return (CMD_RETURN_STOP); 82 | } 83 | 84 | c = cmd_find_client(cmdq, args_get(args, 't'), 0); 85 | if (c == NULL) 86 | return (CMD_RETURN_ERROR); 87 | 88 | if (args_has(args, 'a')) { 89 | TAILQ_FOREACH(cloop, &clients, entry) { 90 | if (cloop->session == NULL || cloop == c) 91 | continue; 92 | server_write_client(cloop, msgtype, 93 | cloop->session->name, 94 | strlen(cloop->session->name) + 1); 95 | } 96 | return (CMD_RETURN_NORMAL); 97 | } 98 | 99 | server_write_client(c, msgtype, c->session->name, 100 | strlen(c->session->name) + 1); 101 | return (CMD_RETURN_STOP); 102 | } 103 | -------------------------------------------------------------------------------- /cmd-choose-buffer.c: -------------------------------------------------------------------------------- 1 | /* $OpenBSD$ */ 2 | 3 | /* 4 | * Copyright (c) 2010 Nicholas Marriott 5 | * 6 | * Permission to use, copy, modify, and distribute this software for any 7 | * purpose with or without fee is hereby granted, provided that the above 8 | * copyright notice and this permission notice appear in all copies. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 | * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER 15 | * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 16 | * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 | */ 18 | 19 | #include 20 | 21 | #include 22 | #include 23 | 24 | #include "tmux.h" 25 | 26 | /* 27 | * Enter choice mode to choose a buffer. 28 | */ 29 | 30 | #define CHOOSE_BUFFER_TEMPLATE \ 31 | "#{buffer_name}: #{buffer_size} bytes: #{buffer_sample}" 32 | 33 | enum cmd_retval cmd_choose_buffer_exec(struct cmd *, struct cmd_q *); 34 | 35 | const struct cmd_entry cmd_choose_buffer_entry = { 36 | "choose-buffer", NULL, 37 | "F:t:", 0, 1, 38 | CMD_TARGET_WINDOW_USAGE " [-F format] [template]", 39 | 0, 40 | cmd_choose_buffer_exec 41 | }; 42 | 43 | enum cmd_retval 44 | cmd_choose_buffer_exec(struct cmd *self, struct cmd_q *cmdq) 45 | { 46 | struct args *args = self->args; 47 | struct client *c; 48 | struct window_choose_data *cdata; 49 | struct winlink *wl; 50 | struct paste_buffer *pb; 51 | char *action, *action_data; 52 | const char *template; 53 | u_int idx; 54 | int utf8flag; 55 | 56 | if ((c = cmd_find_client(cmdq, NULL, 1)) == NULL) { 57 | cmdq_error(cmdq, "no client available"); 58 | return (CMD_RETURN_ERROR); 59 | } 60 | 61 | if ((template = args_get(args, 'F')) == NULL) 62 | template = CHOOSE_BUFFER_TEMPLATE; 63 | 64 | if ((wl = cmd_find_window(cmdq, args_get(args, 't'), NULL)) == NULL) 65 | return (CMD_RETURN_ERROR); 66 | utf8flag = options_get_number(&wl->window->options, "utf8"); 67 | 68 | if (paste_get_top() == NULL) 69 | return (CMD_RETURN_NORMAL); 70 | 71 | if (window_pane_set_mode(wl->window->active, &window_choose_mode) != 0) 72 | return (CMD_RETURN_NORMAL); 73 | 74 | if (args->argc != 0) 75 | action = xstrdup(args->argv[0]); 76 | else 77 | action = xstrdup("paste-buffer -b '%%'"); 78 | 79 | idx = 0; 80 | pb = NULL; 81 | while ((pb = paste_walk(pb)) != NULL) { 82 | cdata = window_choose_data_create(TREE_OTHER, c, c->session); 83 | cdata->idx = idx; 84 | 85 | cdata->ft_template = xstrdup(template); 86 | format_defaults_paste_buffer(cdata->ft, pb, utf8flag); 87 | 88 | xasprintf(&action_data, "%s", pb->name); 89 | cdata->command = cmd_template_replace(action, action_data, 1); 90 | free(action_data); 91 | 92 | window_choose_add(wl->window->active, cdata); 93 | idx++; 94 | } 95 | free(action); 96 | 97 | window_choose_ready(wl->window->active, 0, NULL); 98 | 99 | return (CMD_RETURN_NORMAL); 100 | } 101 | -------------------------------------------------------------------------------- /examples/t-williams.conf: -------------------------------------------------------------------------------- 1 | # $Id: t-williams.conf,v 1.1 2009-11-02 18:59:28 nicm Exp $ 2 | # 3 | # ~/.tmux.conf - tmux terminal multiplexer config 4 | # Thayer Williams (http://cinderwick.ca) 5 | # "Feel free to do whatever you like with it." 6 | 7 | # I typically start tmux from ~/.xinitrc with the following: 8 | # 9 | # urxvt -e bash -c "tmux attach -d -t mysession" & 10 | # 11 | # and recall it any time thereafter with xbindkeys (Mod4+s): 12 | # 13 | # "urxvt -e bash -c 'tmux attach -d -t mysession'" 14 | # m:0x50 + c:39 15 | 16 | 17 | # set prefix key to ctrl+a until I have time to adapt 18 | unbind C-b 19 | set -g prefix C-a 20 | 21 | # send the prefix to client inside window (ala nested sessions) 22 | bind-key a send-prefix 23 | 24 | # toggle last window like screen 25 | bind-key C-a last-window 26 | 27 | # confirm before killing a window or the server 28 | bind-key k confirm kill-window 29 | bind-key K confirm kill-server 30 | 31 | # toggle statusbar 32 | bind-key b set-option status 33 | 34 | # ctrl+left/right cycles thru windows 35 | bind-key -n C-right next 36 | bind-key -n C-left prev 37 | 38 | # open a man page in new window 39 | bind / command-prompt "split-window 'exec man %%'" 40 | 41 | # quick view of processes 42 | bind '~' split-window "exec htop" 43 | 44 | # scrollback buffer n lines 45 | set -g history-limit 5000 46 | 47 | # listen for activity on all windows 48 | set -g bell-action any 49 | 50 | # on-screen time for display-panes in ms 51 | set -g display-panes-time 2000 52 | 53 | # start window indexing at one instead of zero 54 | set -g base-index 1 55 | 56 | # enable wm window titles 57 | set -g set-titles on 58 | 59 | # wm window title string (uses statusbar variables) 60 | set -g set-titles-string "tmux.#I.#W" 61 | 62 | # session initialization 63 | new -s mysession mutt 64 | neww -t 2 65 | neww -d -t 3 66 | neww -d -t 5 mocp 67 | neww -d -t 6 rtorrent 68 | selectw -t 1 69 | 70 | # statusbar -------------------------------------------------------------- 71 | 72 | set -g display-time 2000 73 | 74 | # default statusbar colors 75 | set -g status-fg white 76 | set -g status-bg default 77 | set -g status-attr default 78 | 79 | # default window title colors 80 | set-window-option -g window-status-fg cyan 81 | set-window-option -g window-status-bg default 82 | set-window-option -g window-status-attr dim 83 | 84 | # active window title colors 85 | set-window-option -g window-status-current-fg white 86 | set-window-option -g window-status-current-bg default 87 | set-window-option -g window-status-current-attr bright 88 | 89 | # command/message line colors 90 | set -g message-fg white 91 | set -g message-bg black 92 | set -g message-attr bright 93 | 94 | # center align the window list 95 | set -g status-justify centre 96 | 97 | # show some useful stats but only when tmux is started 98 | # outside of Xorg, otherwise dwm statusbar shows these already 99 | set -g status-right "" 100 | set -g status-left "" 101 | if '[ -z "$DISPLAY" ]' 'set -g status-left "[#[fg=green] #H #[default]]"' 102 | if '[ -z "$DISPLAY" ]' 'set -g status-right "[ #[fg=magenta]#(cat /proc/loadavg | cut -d \" \" -f 1,2,3)#[default] ][ #[fg=cyan,bright]%a %Y-%m-%d %H:%M #[default]]"' 103 | if '[ -z "$DISPLAY" ]' 'set -g status-right-length 50' 104 | 105 | -------------------------------------------------------------------------------- /cmd-move-window.c: -------------------------------------------------------------------------------- 1 | /* $OpenBSD$ */ 2 | 3 | /* 4 | * Copyright (c) 2008 Nicholas Marriott 5 | * 6 | * Permission to use, copy, modify, and distribute this software for any 7 | * purpose with or without fee is hereby granted, provided that the above 8 | * copyright notice and this permission notice appear in all copies. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 | * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER 15 | * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 16 | * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 | */ 18 | 19 | #include 20 | 21 | #include 22 | 23 | #include "tmux.h" 24 | 25 | /* 26 | * Move a window. 27 | */ 28 | 29 | enum cmd_retval cmd_move_window_exec(struct cmd *, struct cmd_q *); 30 | 31 | const struct cmd_entry cmd_move_window_entry = { 32 | "move-window", "movew", 33 | "adkrs:t:", 0, 0, 34 | "[-dkr] " CMD_SRCDST_WINDOW_USAGE, 35 | 0, 36 | cmd_move_window_exec 37 | }; 38 | 39 | const struct cmd_entry cmd_link_window_entry = { 40 | "link-window", "linkw", 41 | "adks:t:", 0, 0, 42 | "[-dk] " CMD_SRCDST_WINDOW_USAGE, 43 | 0, 44 | cmd_move_window_exec 45 | }; 46 | 47 | enum cmd_retval 48 | cmd_move_window_exec(struct cmd *self, struct cmd_q *cmdq) 49 | { 50 | struct args *args = self->args; 51 | struct session *src, *dst, *s; 52 | struct winlink *wl; 53 | char *cause; 54 | int idx, kflag, dflag, sflag; 55 | 56 | if (args_has(args, 'r')) { 57 | s = cmd_find_session(cmdq, args_get(args, 't'), 0); 58 | if (s == NULL) 59 | return (CMD_RETURN_ERROR); 60 | 61 | session_renumber_windows(s); 62 | recalculate_sizes(); 63 | 64 | return (CMD_RETURN_NORMAL); 65 | } 66 | 67 | if ((wl = cmd_find_window(cmdq, args_get(args, 's'), &src)) == NULL) 68 | return (CMD_RETURN_ERROR); 69 | if ((idx = cmd_find_index(cmdq, args_get(args, 't'), &dst)) == -2) 70 | return (CMD_RETURN_ERROR); 71 | 72 | kflag = args_has(self->args, 'k'); 73 | dflag = args_has(self->args, 'd'); 74 | sflag = args_has(self->args, 's'); 75 | 76 | if (args_has(self->args, 'a')) { 77 | s = cmd_find_session(cmdq, args_get(args, 't'), 0); 78 | if (s == NULL) 79 | return (CMD_RETURN_ERROR); 80 | if ((idx = winlink_shuffle_up(s, s->curw)) == -1) 81 | return (CMD_RETURN_ERROR); 82 | } 83 | 84 | if (server_link_window(src, wl, dst, idx, kflag, !dflag, 85 | &cause) != 0) { 86 | cmdq_error(cmdq, "can't link window: %s", cause); 87 | free(cause); 88 | return (CMD_RETURN_ERROR); 89 | } 90 | if (self->entry == &cmd_move_window_entry) 91 | server_unlink_window(src, wl); 92 | 93 | /* 94 | * Renumber the winlinks in the src session only, the destination 95 | * session already has the correct winlink id to us, either 96 | * automatically or specified by -s. 97 | */ 98 | if (!sflag && options_get_number(&src->options, "renumber-windows")) 99 | session_renumber_windows(src); 100 | 101 | recalculate_sizes(); 102 | 103 | return (CMD_RETURN_NORMAL); 104 | } 105 | -------------------------------------------------------------------------------- /cmd-set-buffer.c: -------------------------------------------------------------------------------- 1 | /* $OpenBSD$ */ 2 | 3 | /* 4 | * Copyright (c) 2007 Nicholas Marriott 5 | * 6 | * Permission to use, copy, modify, and distribute this software for any 7 | * purpose with or without fee is hereby granted, provided that the above 8 | * copyright notice and this permission notice appear in all copies. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 | * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER 15 | * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 16 | * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 | */ 18 | 19 | #include 20 | 21 | #include 22 | #include 23 | 24 | #include "tmux.h" 25 | 26 | /* 27 | * Add, set, or append to a paste buffer. 28 | */ 29 | 30 | enum cmd_retval cmd_set_buffer_exec(struct cmd *, struct cmd_q *); 31 | 32 | const struct cmd_entry cmd_set_buffer_entry = { 33 | "set-buffer", "setb", 34 | "ab:n:", 0, 1, 35 | "[-a] " CMD_BUFFER_USAGE " [-n new-buffer-name] data", 36 | 0, 37 | cmd_set_buffer_exec 38 | }; 39 | 40 | enum cmd_retval 41 | cmd_set_buffer_exec(struct cmd *self, struct cmd_q *cmdq) 42 | { 43 | struct args *args = self->args; 44 | struct paste_buffer *pb; 45 | char *pdata, *cause; 46 | const char *bufname; 47 | size_t psize, newsize; 48 | 49 | bufname = NULL; 50 | 51 | if (args_has(args, 'n')) { 52 | if (args->argc > 0) { 53 | cmdq_error(cmdq, "don't provide data with n flag"); 54 | return (CMD_RETURN_ERROR); 55 | } 56 | 57 | if (args_has(args, 'b')) 58 | bufname = args_get(args, 'b'); 59 | 60 | if (bufname == NULL) { 61 | pb = paste_get_top(); 62 | if (pb == NULL) { 63 | cmdq_error(cmdq, "no buffer"); 64 | return (CMD_RETURN_ERROR); 65 | } 66 | bufname = pb->name; 67 | } 68 | 69 | if (paste_rename(bufname, args_get(args, 'n'), &cause) != 0) { 70 | cmdq_error(cmdq, "%s", cause); 71 | free(cause); 72 | return (CMD_RETURN_ERROR); 73 | } 74 | 75 | return (CMD_RETURN_NORMAL); 76 | } 77 | 78 | if (args->argc != 1) { 79 | cmdq_error(cmdq, "no data specified"); 80 | return (CMD_RETURN_ERROR); 81 | } 82 | 83 | psize = 0; 84 | pdata = NULL; 85 | 86 | pb = NULL; 87 | 88 | if ((newsize = strlen(args->argv[0])) == 0) 89 | return (CMD_RETURN_NORMAL); 90 | 91 | if (args_has(args, 'b')) { 92 | bufname = args_get(args, 'b'); 93 | pb = paste_get_name(bufname); 94 | } else if (args_has(args, 'a')) { 95 | pb = paste_get_top(); 96 | if (pb != NULL) 97 | bufname = pb->name; 98 | } 99 | 100 | if (args_has(args, 'a') && pb != NULL) { 101 | psize = pb->size; 102 | pdata = xmalloc(psize); 103 | memcpy(pdata, pb->data, psize); 104 | } 105 | 106 | pdata = xrealloc(pdata, psize + newsize); 107 | memcpy(pdata + psize, args->argv[0], newsize); 108 | psize += newsize; 109 | 110 | if (paste_set(pdata, psize, bufname, &cause) != 0) { 111 | cmdq_error(cmdq, "%s", cause); 112 | free(pdata); 113 | free(cause); 114 | return (CMD_RETURN_ERROR); 115 | } 116 | 117 | return (CMD_RETURN_NORMAL); 118 | } 119 | -------------------------------------------------------------------------------- /cmd-respawn-window.c: -------------------------------------------------------------------------------- 1 | /* $OpenBSD$ */ 2 | 3 | /* 4 | * Copyright (c) 2008 Nicholas Marriott 5 | * 6 | * Permission to use, copy, modify, and distribute this software for any 7 | * purpose with or without fee is hereby granted, provided that the above 8 | * copyright notice and this permission notice appear in all copies. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 | * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER 15 | * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 16 | * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 | */ 18 | 19 | #include 20 | 21 | #include 22 | #include 23 | 24 | #include "tmux.h" 25 | 26 | /* 27 | * Respawn a window (restart the command). Kill existing if -k given. 28 | */ 29 | 30 | enum cmd_retval cmd_respawn_window_exec(struct cmd *, struct cmd_q *); 31 | 32 | const struct cmd_entry cmd_respawn_window_entry = { 33 | "respawn-window", "respawnw", 34 | "kt:", 0, -1, 35 | "[-k] " CMD_TARGET_WINDOW_USAGE " [command]", 36 | 0, 37 | cmd_respawn_window_exec 38 | }; 39 | 40 | enum cmd_retval 41 | cmd_respawn_window_exec(struct cmd *self, struct cmd_q *cmdq) 42 | { 43 | struct args *args = self->args; 44 | struct winlink *wl; 45 | struct window *w; 46 | struct window_pane *wp; 47 | struct session *s; 48 | struct environ env; 49 | const char *path; 50 | char *cause; 51 | struct environ_entry *envent; 52 | 53 | if ((wl = cmd_find_window(cmdq, args_get(args, 't'), &s)) == NULL) 54 | return (CMD_RETURN_ERROR); 55 | w = wl->window; 56 | 57 | if (!args_has(self->args, 'k')) { 58 | TAILQ_FOREACH(wp, &w->panes, entry) { 59 | if (wp->fd == -1) 60 | continue; 61 | cmdq_error(cmdq, 62 | "window still active: %s:%d", s->name, wl->idx); 63 | return (CMD_RETURN_ERROR); 64 | } 65 | } 66 | 67 | environ_init(&env); 68 | environ_copy(&global_environ, &env); 69 | environ_copy(&s->environ, &env); 70 | server_fill_environ(s, &env); 71 | 72 | wp = TAILQ_FIRST(&w->panes); 73 | TAILQ_REMOVE(&w->panes, wp, entry); 74 | layout_free(w); 75 | window_destroy_panes(w); 76 | TAILQ_INSERT_HEAD(&w->panes, wp, entry); 77 | window_pane_resize(wp, w->sx, w->sy); 78 | 79 | path = NULL; 80 | if (cmdq->client != NULL && cmdq->client->session == NULL) 81 | envent = environ_find(&cmdq->client->environ, "PATH"); 82 | else 83 | envent = environ_find(&s->environ, "PATH"); 84 | if (envent != NULL) 85 | path = envent->value; 86 | 87 | if (window_pane_spawn(wp, args->argc, args->argv, path, NULL, -1, &env, 88 | s->tio, &cause) != 0) { 89 | cmdq_error(cmdq, "respawn window failed: %s", cause); 90 | free(cause); 91 | environ_free(&env); 92 | server_destroy_pane(wp); 93 | return (CMD_RETURN_ERROR); 94 | } 95 | layout_init(w, wp); 96 | window_pane_reset_mode(wp); 97 | screen_reinit(&wp->base); 98 | input_init(wp); 99 | window_set_active_pane(w, wp); 100 | 101 | recalculate_sizes(); 102 | server_redraw_window(w); 103 | 104 | environ_free(&env); 105 | return (CMD_RETURN_NORMAL); 106 | } 107 | -------------------------------------------------------------------------------- /cmd-display-message.c: -------------------------------------------------------------------------------- 1 | /* $OpenBSD$ */ 2 | 3 | /* 4 | * Copyright (c) 2009 Tiago Cunha 5 | * 6 | * Permission to use, copy, modify, and distribute this software for any 7 | * purpose with or without fee is hereby granted, provided that the above 8 | * copyright notice and this permission notice appear in all copies. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 | * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER 15 | * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 16 | * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 | */ 18 | 19 | #include 20 | 21 | #include 22 | #include 23 | 24 | #include "tmux.h" 25 | 26 | /* 27 | * Displays a message in the status line. 28 | */ 29 | 30 | #define DISPLAY_MESSAGE_TEMPLATE \ 31 | "[#{session_name}] #{window_index}:" \ 32 | "#{window_name}, current pane #{pane_index} " \ 33 | "- (%H:%M %d-%b-%y)" 34 | 35 | enum cmd_retval cmd_display_message_exec(struct cmd *, struct cmd_q *); 36 | 37 | const struct cmd_entry cmd_display_message_entry = { 38 | "display-message", "display", 39 | "c:pt:F:", 0, 1, 40 | "[-p] [-c target-client] [-F format] " CMD_TARGET_PANE_USAGE 41 | " [message]", 42 | 0, 43 | cmd_display_message_exec 44 | }; 45 | 46 | enum cmd_retval 47 | cmd_display_message_exec(struct cmd *self, struct cmd_q *cmdq) 48 | { 49 | struct args *args = self->args; 50 | struct client *c; 51 | struct session *s; 52 | struct winlink *wl; 53 | struct window_pane *wp; 54 | const char *template; 55 | char *msg; 56 | struct format_tree *ft; 57 | char out[BUFSIZ]; 58 | time_t t; 59 | size_t len; 60 | 61 | if (args_has(args, 't')) { 62 | wl = cmd_find_pane(cmdq, args_get(args, 't'), &s, &wp); 63 | if (wl == NULL) 64 | return (CMD_RETURN_ERROR); 65 | } else { 66 | wl = cmd_find_pane(cmdq, NULL, &s, &wp); 67 | if (wl == NULL) 68 | return (CMD_RETURN_ERROR); 69 | } 70 | 71 | if (args_has(args, 'F') && args->argc != 0) { 72 | cmdq_error(cmdq, "only one of -F or argument must be given"); 73 | return (CMD_RETURN_ERROR); 74 | } 75 | 76 | if (args_has(args, 'c')) { 77 | c = cmd_find_client(cmdq, args_get(args, 'c'), 0); 78 | if (c == NULL) 79 | return (CMD_RETURN_ERROR); 80 | } else { 81 | c = cmd_find_client(cmdq, NULL, 1); 82 | if (c == NULL && !args_has(self->args, 'p')) { 83 | cmdq_error(cmdq, "no client available"); 84 | return (CMD_RETURN_ERROR); 85 | } 86 | } 87 | 88 | template = args_get(args, 'F'); 89 | if (args->argc != 0) 90 | template = args->argv[0]; 91 | if (template == NULL) 92 | template = DISPLAY_MESSAGE_TEMPLATE; 93 | 94 | ft = format_create(); 95 | format_defaults(ft, c, s, wl, wp); 96 | 97 | t = time(NULL); 98 | len = strftime(out, sizeof out, template, localtime(&t)); 99 | out[len] = '\0'; 100 | 101 | msg = format_expand(ft, out); 102 | if (args_has(self->args, 'p')) 103 | cmdq_print(cmdq, "%s", msg); 104 | else 105 | status_message_set(c, "%s", msg); 106 | free(msg); 107 | format_free(ft); 108 | 109 | return (CMD_RETURN_NORMAL); 110 | } 111 | -------------------------------------------------------------------------------- /compat/closefrom.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2004-2005 Todd C. Miller 3 | * 4 | * Permission to use, copy, modify, and distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 | */ 16 | 17 | #include "tmux.h" 18 | 19 | #ifndef HAVE_CLOSEFROM 20 | 21 | #include 22 | #include 23 | #include 24 | #include 25 | #ifdef HAVE_FCNTL_H 26 | # include 27 | #endif 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #ifdef HAVE_DIRENT_H 34 | # include 35 | # define NAMLEN(dirent) strlen((dirent)->d_name) 36 | #else 37 | # define dirent direct 38 | # define NAMLEN(dirent) (dirent)->d_namlen 39 | # ifdef HAVE_SYS_NDIR_H 40 | # include 41 | # endif 42 | # ifdef HAVE_SYS_DIR_H 43 | # include 44 | # endif 45 | # ifdef HAVE_NDIR_H 46 | # include 47 | # endif 48 | #endif 49 | 50 | #ifndef OPEN_MAX 51 | # define OPEN_MAX 256 52 | #endif 53 | 54 | #if 0 55 | __unused static const char rcsid[] = "$Sudo: closefrom.c,v 1.11 2006/08/17 15:26:54 millert Exp $"; 56 | #endif /* lint */ 57 | 58 | /* 59 | * Close all file descriptors greater than or equal to lowfd. 60 | */ 61 | #ifdef HAVE_FCNTL_CLOSEM 62 | void 63 | closefrom(int lowfd) 64 | { 65 | (void) fcntl(lowfd, F_CLOSEM, 0); 66 | } 67 | #else 68 | void 69 | closefrom(int lowfd) 70 | { 71 | long fd, maxfd; 72 | #if defined(HAVE_DIRFD) && defined(HAVE_PROC_PID) 73 | char fdpath[PATH_MAX], *endp; 74 | struct dirent *dent; 75 | DIR *dirp; 76 | int len; 77 | 78 | /* Check for a /proc/$$/fd directory. */ 79 | len = snprintf(fdpath, sizeof(fdpath), "/proc/%ld/fd", (long)getpid()); 80 | if (len > 0 && (size_t)len <= sizeof(fdpath) && (dirp = opendir(fdpath))) { 81 | while ((dent = readdir(dirp)) != NULL) { 82 | fd = strtol(dent->d_name, &endp, 10); 83 | if (dent->d_name != endp && *endp == '\0' && 84 | fd >= 0 && fd < INT_MAX && fd >= lowfd && fd != dirfd(dirp)) 85 | (void) close((int) fd); 86 | } 87 | (void) closedir(dirp); 88 | } else 89 | #endif 90 | { 91 | /* 92 | * Fall back on sysconf() or getdtablesize(). We avoid checking 93 | * resource limits since it is possible to open a file descriptor 94 | * and then drop the rlimit such that it is below the open fd. 95 | */ 96 | #ifdef HAVE_SYSCONF 97 | maxfd = sysconf(_SC_OPEN_MAX); 98 | #else 99 | maxfd = getdtablesize(); 100 | #endif /* HAVE_SYSCONF */ 101 | if (maxfd < 0) 102 | maxfd = OPEN_MAX; 103 | 104 | for (fd = lowfd; fd < maxfd; fd++) 105 | (void) close((int) fd); 106 | } 107 | } 108 | #endif /* !HAVE_FCNTL_CLOSEM */ 109 | #endif /* HAVE_CLOSEFROM */ 110 | -------------------------------------------------------------------------------- /compat/vis.h: -------------------------------------------------------------------------------- 1 | /* $OpenBSD: vis.h,v 1.11 2005/08/09 19:38:31 millert Exp $ */ 2 | /* $NetBSD: vis.h,v 1.4 1994/10/26 00:56:41 cgd Exp $ */ 3 | 4 | /*- 5 | * Copyright (c) 1990 The Regents of the University of California. 6 | * All rights reserved. 7 | * 8 | * Redistribution and use in source and binary forms, with or without 9 | * modification, are permitted provided that the following conditions 10 | * are met: 11 | * 1. Redistributions of source code must retain the above copyright 12 | * notice, this list of conditions and the following disclaimer. 13 | * 2. Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 3. Neither the name of the University nor the names of its contributors 17 | * may be used to endorse or promote products derived from this software 18 | * without specific prior written permission. 19 | * 20 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 21 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 24 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 | * SUCH DAMAGE. 31 | * 32 | * @(#)vis.h 5.9 (Berkeley) 4/3/91 33 | */ 34 | 35 | #ifndef _VIS_H_ 36 | #define _VIS_H_ 37 | 38 | /* 39 | * to select alternate encoding format 40 | */ 41 | #define VIS_OCTAL 0x01 /* use octal \ddd format */ 42 | #define VIS_CSTYLE 0x02 /* use \[nrft0..] where appropriate */ 43 | 44 | /* 45 | * to alter set of characters encoded (default is to encode all 46 | * non-graphic except space, tab, and newline). 47 | */ 48 | #define VIS_SP 0x04 /* also encode space */ 49 | #define VIS_TAB 0x08 /* also encode tab */ 50 | #define VIS_NL 0x10 /* also encode newline */ 51 | #define VIS_WHITE (VIS_SP | VIS_TAB | VIS_NL) 52 | #define VIS_SAFE 0x20 /* only encode "unsafe" characters */ 53 | 54 | /* 55 | * other 56 | */ 57 | #define VIS_NOSLASH 0x40 /* inhibit printing '\' */ 58 | #define VIS_GLOB 0x100 /* encode glob(3) magics and '#' */ 59 | 60 | /* 61 | * unvis return codes 62 | */ 63 | #define UNVIS_VALID 1 /* character valid */ 64 | #define UNVIS_VALIDPUSH 2 /* character valid, push back passed char */ 65 | #define UNVIS_NOCHAR 3 /* valid sequence, no character produced */ 66 | #define UNVIS_SYNBAD -1 /* unrecognized escape sequence */ 67 | #define UNVIS_ERROR -2 /* decoder in unknown state (unrecoverable) */ 68 | 69 | /* 70 | * unvis flags 71 | */ 72 | #define UNVIS_END 1 /* no more characters */ 73 | 74 | char *vis(char *, int, int, int); 75 | int strvis(char *, const char *, int); 76 | int strnvis(char *, const char *, size_t, int); 77 | int strvisx(char *, const char *, size_t, int); 78 | int strunvis(char *, const char *); 79 | int unvis(char *, char, int *, int); 80 | ssize_t strnunvis(char *, const char *, size_t); 81 | 82 | #endif /* !_VIS_H_ */ 83 | -------------------------------------------------------------------------------- /names.c: -------------------------------------------------------------------------------- 1 | /* $OpenBSD$ */ 2 | 3 | /* 4 | * Copyright (c) 2009 Nicholas Marriott 5 | * 6 | * Permission to use, copy, modify, and distribute this software for any 7 | * purpose with or without fee is hereby granted, provided that the above 8 | * copyright notice and this permission notice appear in all copies. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 | * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER 15 | * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 16 | * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 | */ 18 | 19 | #include 20 | 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | #include "tmux.h" 27 | 28 | void window_name_callback(unused int, unused short, void *); 29 | 30 | void 31 | queue_window_name(struct window *w) 32 | { 33 | struct timeval tv; 34 | 35 | tv.tv_sec = 0; 36 | tv.tv_usec = NAME_INTERVAL * 1000L; 37 | 38 | if (event_initialized(&w->name_timer)) 39 | evtimer_del(&w->name_timer); 40 | evtimer_set(&w->name_timer, window_name_callback, w); 41 | evtimer_add(&w->name_timer, &tv); 42 | } 43 | 44 | void 45 | window_name_callback(unused int fd, unused short events, void *data) 46 | { 47 | struct window *w = data; 48 | char *name; 49 | 50 | if (w->active == NULL) 51 | return; 52 | 53 | if (!options_get_number(&w->options, "automatic-rename")) { 54 | if (event_initialized(&w->name_timer)) 55 | event_del(&w->name_timer); 56 | return; 57 | } 58 | queue_window_name(w); 59 | 60 | name = format_window_name(w); 61 | if (strcmp(name, w->name) != 0) { 62 | window_set_name(w, name); 63 | server_status_window(w); 64 | } 65 | free(name); 66 | } 67 | 68 | char * 69 | default_window_name(struct window *w) 70 | { 71 | char *cmd, *s; 72 | 73 | cmd = cmd_stringify_argv(w->active->argc, w->active->argv); 74 | if (cmd != NULL && *cmd != '\0') 75 | s = parse_window_name(cmd); 76 | else 77 | s = parse_window_name(w->active->shell); 78 | free(cmd); 79 | return (s); 80 | } 81 | 82 | char * 83 | format_window_name(struct window *w) 84 | { 85 | struct format_tree *ft; 86 | char *fmt, *name; 87 | 88 | ft = format_create(); 89 | format_defaults_window(ft, w); 90 | format_defaults_pane(ft, w->active); 91 | 92 | fmt = options_get_string(&w->options, "automatic-rename-format"); 93 | name = format_expand(ft, fmt); 94 | 95 | format_free(ft); 96 | return (name); 97 | } 98 | 99 | char * 100 | parse_window_name(const char *in) 101 | { 102 | char *copy, *name, *ptr; 103 | 104 | name = copy = xstrdup(in); 105 | if (strncmp(name, "exec ", (sizeof "exec ") - 1) == 0) 106 | name = name + (sizeof "exec ") - 1; 107 | 108 | while (*name == ' ' || *name == '-') 109 | name++; 110 | if ((ptr = strchr(name, ' ')) != NULL) 111 | *ptr = '\0'; 112 | 113 | if (*name != '\0') { 114 | ptr = name + strlen(name) - 1; 115 | while (ptr > name && !isalnum((u_char)*ptr)) 116 | *ptr-- = '\0'; 117 | } 118 | 119 | if (*name == '/') 120 | name = basename(name); 121 | name = xstrdup(name); 122 | free(copy); 123 | return (name); 124 | } 125 | -------------------------------------------------------------------------------- /cmd-break-pane.c: -------------------------------------------------------------------------------- 1 | /* $OpenBSD$ */ 2 | 3 | /* 4 | * Copyright (c) 2009 Nicholas Marriott 5 | * 6 | * Permission to use, copy, modify, and distribute this software for any 7 | * purpose with or without fee is hereby granted, provided that the above 8 | * copyright notice and this permission notice appear in all copies. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 | * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER 15 | * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 16 | * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 | */ 18 | 19 | #include 20 | 21 | #include 22 | 23 | #include "tmux.h" 24 | 25 | /* 26 | * Break pane off into a window. 27 | */ 28 | 29 | #define BREAK_PANE_TEMPLATE "#{session_name}:#{window_index}.#{pane_index}" 30 | 31 | enum cmd_retval cmd_break_pane_exec(struct cmd *, struct cmd_q *); 32 | 33 | const struct cmd_entry cmd_break_pane_entry = { 34 | "break-pane", "breakp", 35 | "dPF:s:t:", 0, 0, 36 | "[-dP] [-F format] " CMD_SRCDST_PANE_USAGE, 37 | 0, 38 | cmd_break_pane_exec 39 | }; 40 | 41 | enum cmd_retval 42 | cmd_break_pane_exec(struct cmd *self, struct cmd_q *cmdq) 43 | { 44 | struct args *args = self->args; 45 | struct winlink *wl; 46 | struct session *s; 47 | struct window_pane *wp; 48 | struct window *w; 49 | char *name; 50 | char *cause; 51 | int idx; 52 | struct format_tree *ft; 53 | const char *template; 54 | char *cp; 55 | 56 | if ((wl = cmd_find_pane(cmdq, args_get(args, 's'), &s, &wp)) == NULL) 57 | return (CMD_RETURN_ERROR); 58 | if ((idx = cmd_find_index(cmdq, args_get(args, 't'), &s)) == -2) 59 | return (CMD_RETURN_ERROR); 60 | if (idx != -1 && winlink_find_by_index(&s->windows, idx) != NULL) { 61 | cmdq_error(cmdq, "index %d already in use", idx); 62 | return (CMD_RETURN_ERROR); 63 | } 64 | 65 | if (window_count_panes(wl->window) == 1) { 66 | cmdq_error(cmdq, "can't break with only one pane"); 67 | return (CMD_RETURN_ERROR); 68 | } 69 | 70 | w = wl->window; 71 | server_unzoom_window(w); 72 | 73 | TAILQ_REMOVE(&w->panes, wp, entry); 74 | window_lost_pane(w, wp); 75 | layout_close_pane(wp); 76 | 77 | w = wp->window = window_create1(s->sx, s->sy); 78 | TAILQ_INSERT_HEAD(&w->panes, wp, entry); 79 | w->active = wp; 80 | name = default_window_name(w); 81 | window_set_name(w, name); 82 | free(name); 83 | layout_init(w, wp); 84 | 85 | if (idx == -1) 86 | idx = -1 - options_get_number(&s->options, "base-index"); 87 | wl = session_attach(s, w, idx, &cause); /* can't fail */ 88 | if (!args_has(self->args, 'd')) 89 | session_select(s, wl->idx); 90 | 91 | server_redraw_session(s); 92 | server_status_session_group(s); 93 | 94 | if (args_has(args, 'P')) { 95 | if ((template = args_get(args, 'F')) == NULL) 96 | template = BREAK_PANE_TEMPLATE; 97 | 98 | ft = format_create(); 99 | format_defaults(ft, cmd_find_client(cmdq, NULL, 1), s, wl, wp); 100 | 101 | cp = format_expand(ft, template); 102 | cmdq_print(cmdq, "%s", cp); 103 | free(cp); 104 | 105 | format_free(ft); 106 | } 107 | return (CMD_RETURN_NORMAL); 108 | } 109 | -------------------------------------------------------------------------------- /xmalloc.c: -------------------------------------------------------------------------------- 1 | /* $OpenBSD$ */ 2 | 3 | /* 4 | * Copyright (c) 2004 Nicholas Marriott 5 | * 6 | * Permission to use, copy, modify, and distribute this software for any 7 | * purpose with or without fee is hereby granted, provided that the above 8 | * copyright notice and this permission notice appear in all copies. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 | * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER 15 | * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 16 | * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 | */ 18 | 19 | #include 20 | 21 | #include 22 | #include 23 | #include 24 | 25 | #include "tmux.h" 26 | 27 | char * 28 | xstrdup(const char *s) 29 | { 30 | char *ptr; 31 | size_t len; 32 | 33 | len = strlen(s) + 1; 34 | ptr = xmalloc(len); 35 | 36 | strlcpy(ptr, s, len); 37 | return (ptr); 38 | } 39 | 40 | void * 41 | xcalloc(size_t nmemb, size_t size) 42 | { 43 | void *ptr; 44 | 45 | if (size == 0 || nmemb == 0) 46 | fatalx("zero size"); 47 | if (SIZE_MAX / nmemb < size) 48 | fatalx("nmemb * size > SIZE_MAX"); 49 | if ((ptr = calloc(nmemb, size)) == NULL) 50 | fatal("xcalloc failed"); 51 | 52 | return (ptr); 53 | } 54 | 55 | void * 56 | xmalloc(size_t size) 57 | { 58 | void *ptr; 59 | 60 | if (size == 0) 61 | fatalx("zero size"); 62 | if ((ptr = malloc(size)) == NULL) 63 | fatal("xmalloc failed"); 64 | 65 | return (ptr); 66 | } 67 | 68 | void * 69 | xrealloc(void *oldptr, size_t newsize) 70 | { 71 | void *newptr; 72 | 73 | if (newsize == 0) 74 | fatalx("zero size"); 75 | if ((newptr = realloc(oldptr, newsize)) == NULL) 76 | fatal("xrealloc failed"); 77 | 78 | return (newptr); 79 | } 80 | 81 | void * 82 | xreallocarray(void *oldptr, size_t nmemb, size_t size) 83 | { 84 | size_t newsize = nmemb * size; 85 | void *newptr; 86 | 87 | if (newsize == 0) 88 | fatalx("zero size"); 89 | if (SIZE_MAX / nmemb < size) 90 | fatalx("nmemb * size > SIZE_MAX"); 91 | if ((newptr = realloc(oldptr, newsize)) == NULL) 92 | fatal("xreallocarray failed"); 93 | 94 | return (newptr); 95 | } 96 | 97 | int 98 | xasprintf(char **ret, const char *fmt, ...) 99 | { 100 | va_list ap; 101 | int i; 102 | 103 | va_start(ap, fmt); 104 | i = xvasprintf(ret, fmt, ap); 105 | va_end(ap); 106 | 107 | return (i); 108 | } 109 | 110 | int 111 | xvasprintf(char **ret, const char *fmt, va_list ap) 112 | { 113 | int i; 114 | 115 | i = vasprintf(ret, fmt, ap); 116 | if (i < 0 || *ret == NULL) 117 | fatal("xvasprintf failed"); 118 | 119 | return (i); 120 | } 121 | 122 | int 123 | xsnprintf(char *buf, size_t len, const char *fmt, ...) 124 | { 125 | va_list ap; 126 | int i; 127 | 128 | va_start(ap, fmt); 129 | i = xvsnprintf(buf, len, fmt, ap); 130 | va_end(ap); 131 | 132 | return (i); 133 | } 134 | 135 | int 136 | xvsnprintf(char *buf, size_t len, const char *fmt, va_list ap) 137 | { 138 | int i; 139 | 140 | if (len > INT_MAX) 141 | fatalx("len > INT_MAX"); 142 | 143 | i = vsnprintf(buf, len, fmt, ap); 144 | if (i < 0) 145 | fatal("vsnprintf failed"); 146 | 147 | return (i); 148 | } 149 | -------------------------------------------------------------------------------- /cmd-list.c: -------------------------------------------------------------------------------- 1 | /* $OpenBSD$ */ 2 | 3 | /* 4 | * Copyright (c) 2009 Nicholas Marriott 5 | * 6 | * Permission to use, copy, modify, and distribute this software for any 7 | * purpose with or without fee is hereby granted, provided that the above 8 | * copyright notice and this permission notice appear in all copies. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 | * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER 15 | * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 16 | * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 | */ 18 | 19 | #include 20 | 21 | #include 22 | #include 23 | 24 | #include "tmux.h" 25 | 26 | struct cmd_list * 27 | cmd_list_parse(int argc, char **argv, const char *file, u_int line, 28 | char **cause) 29 | { 30 | struct cmd_list *cmdlist; 31 | struct cmd *cmd; 32 | int i, lastsplit; 33 | size_t arglen, new_argc; 34 | char **copy_argv, **new_argv; 35 | 36 | copy_argv = cmd_copy_argv(argc, argv); 37 | 38 | cmdlist = xcalloc(1, sizeof *cmdlist); 39 | cmdlist->references = 1; 40 | TAILQ_INIT(&cmdlist->list); 41 | 42 | lastsplit = 0; 43 | for (i = 0; i < argc; i++) { 44 | arglen = strlen(copy_argv[i]); 45 | if (arglen == 0 || copy_argv[i][arglen - 1] != ';') 46 | continue; 47 | copy_argv[i][arglen - 1] = '\0'; 48 | 49 | if (arglen > 1 && copy_argv[i][arglen - 2] == '\\') { 50 | copy_argv[i][arglen - 2] = ';'; 51 | continue; 52 | } 53 | 54 | new_argc = i - lastsplit; 55 | new_argv = copy_argv + lastsplit; 56 | if (arglen != 1) 57 | new_argc++; 58 | 59 | cmd = cmd_parse(new_argc, new_argv, file, line, cause); 60 | if (cmd == NULL) 61 | goto bad; 62 | TAILQ_INSERT_TAIL(&cmdlist->list, cmd, qentry); 63 | 64 | lastsplit = i + 1; 65 | } 66 | 67 | if (lastsplit != argc) { 68 | cmd = cmd_parse(argc - lastsplit, copy_argv + lastsplit, 69 | file, line, cause); 70 | if (cmd == NULL) 71 | goto bad; 72 | TAILQ_INSERT_TAIL(&cmdlist->list, cmd, qentry); 73 | } 74 | 75 | cmd_free_argv(argc, copy_argv); 76 | return (cmdlist); 77 | 78 | bad: 79 | cmd_list_free(cmdlist); 80 | cmd_free_argv(argc, copy_argv); 81 | return (NULL); 82 | } 83 | 84 | void 85 | cmd_list_free(struct cmd_list *cmdlist) 86 | { 87 | struct cmd *cmd, *cmd1; 88 | 89 | if (--cmdlist->references != 0) 90 | return; 91 | 92 | TAILQ_FOREACH_SAFE(cmd, &cmdlist->list, qentry, cmd1) { 93 | TAILQ_REMOVE(&cmdlist->list, cmd, qentry); 94 | args_free(cmd->args); 95 | free(cmd->file); 96 | free(cmd); 97 | } 98 | 99 | free(cmdlist); 100 | } 101 | 102 | size_t 103 | cmd_list_print(struct cmd_list *cmdlist, char *buf, size_t len) 104 | { 105 | struct cmd *cmd; 106 | size_t off, used; 107 | 108 | off = 0; 109 | TAILQ_FOREACH(cmd, &cmdlist->list, qentry) { 110 | if (off >= len) 111 | break; 112 | off += cmd_print(cmd, buf + off, len - off); 113 | if (off >= len) 114 | break; 115 | if (TAILQ_NEXT(cmd, qentry) != NULL) { 116 | used = xsnprintf(buf + off, len - off, " ; "); 117 | if (used > len - off) 118 | used = len - off; 119 | off += used; 120 | } 121 | } 122 | return (off); 123 | } 124 | -------------------------------------------------------------------------------- /cmd-select-layout.c: -------------------------------------------------------------------------------- 1 | /* $OpenBSD$ */ 2 | 3 | /* 4 | * Copyright (c) 2009 Nicholas Marriott 5 | * 6 | * Permission to use, copy, modify, and distribute this software for any 7 | * purpose with or without fee is hereby granted, provided that the above 8 | * copyright notice and this permission notice appear in all copies. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 | * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER 15 | * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 16 | * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 | */ 18 | 19 | #include 20 | 21 | #include 22 | 23 | #include "tmux.h" 24 | 25 | /* 26 | * Switch window to selected layout. 27 | */ 28 | 29 | enum cmd_retval cmd_select_layout_exec(struct cmd *, struct cmd_q *); 30 | 31 | const struct cmd_entry cmd_select_layout_entry = { 32 | "select-layout", "selectl", 33 | "nopt:", 0, 1, 34 | "[-nop] " CMD_TARGET_WINDOW_USAGE " [layout-name]", 35 | 0, 36 | cmd_select_layout_exec 37 | }; 38 | 39 | const struct cmd_entry cmd_next_layout_entry = { 40 | "next-layout", "nextl", 41 | "t:", 0, 0, 42 | CMD_TARGET_WINDOW_USAGE, 43 | 0, 44 | cmd_select_layout_exec 45 | }; 46 | 47 | const struct cmd_entry cmd_previous_layout_entry = { 48 | "previous-layout", "prevl", 49 | "t:", 0, 0, 50 | CMD_TARGET_WINDOW_USAGE, 51 | 0, 52 | cmd_select_layout_exec 53 | }; 54 | 55 | enum cmd_retval 56 | cmd_select_layout_exec(struct cmd *self, struct cmd_q *cmdq) 57 | { 58 | struct args *args = self->args; 59 | struct winlink *wl; 60 | struct window *w; 61 | const char *layoutname; 62 | char *oldlayout; 63 | int next, previous, layout; 64 | 65 | if ((wl = cmd_find_window(cmdq, args_get(args, 't'), NULL)) == NULL) 66 | return (CMD_RETURN_ERROR); 67 | w = wl->window; 68 | 69 | server_unzoom_window(w); 70 | 71 | next = self->entry == &cmd_next_layout_entry; 72 | if (args_has(args, 'n')) 73 | next = 1; 74 | previous = self->entry == &cmd_previous_layout_entry; 75 | if (args_has(args, 'p')) 76 | previous = 1; 77 | 78 | oldlayout = w->old_layout; 79 | w->old_layout = layout_dump(w->layout_root); 80 | 81 | if (next || previous) { 82 | if (next) 83 | layout_set_next(w); 84 | else 85 | layout_set_previous(w); 86 | goto changed; 87 | } 88 | 89 | if (!args_has(args, 'o')) { 90 | if (args->argc == 0) 91 | layout = w->lastlayout; 92 | else 93 | layout = layout_set_lookup(args->argv[0]); 94 | if (layout != -1) { 95 | layout_set_select(w, layout); 96 | goto changed; 97 | } 98 | } 99 | 100 | if (args->argc != 0) 101 | layoutname = args->argv[0]; 102 | else if (args_has(args, 'o')) 103 | layoutname = oldlayout; 104 | else 105 | layoutname = NULL; 106 | 107 | if (layoutname != NULL) { 108 | if (layout_parse(w, layoutname) == -1) { 109 | cmdq_error(cmdq, "can't set layout: %s", layoutname); 110 | goto error; 111 | } 112 | goto changed; 113 | } 114 | 115 | free(oldlayout); 116 | return (CMD_RETURN_NORMAL); 117 | 118 | changed: 119 | free(oldlayout); 120 | server_redraw_window(w); 121 | return (CMD_RETURN_NORMAL); 122 | 123 | error: 124 | free(w->old_layout); 125 | w->old_layout = oldlayout; 126 | return (CMD_RETURN_ERROR); 127 | } 128 | -------------------------------------------------------------------------------- /compat/imsg.h: -------------------------------------------------------------------------------- 1 | /* $OpenBSD: imsg.h,v 1.3 2013/12/26 17:32:33 eric Exp $ */ 2 | 3 | /* 4 | * Copyright (c) 2006, 2007 Pierre-Yves Ritschard 5 | * Copyright (c) 2006, 2007, 2008 Reyk Floeter 6 | * Copyright (c) 2003, 2004 Henning Brauer 7 | * 8 | * Permission to use, copy, modify, and distribute this software for any 9 | * purpose with or without fee is hereby granted, provided that the above 10 | * copyright notice and this permission notice appear in all copies. 11 | * 12 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 13 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 14 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 15 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 16 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 17 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 18 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 19 | */ 20 | 21 | #include "tmux.h" 22 | 23 | #ifndef _IMSG_H_ 24 | #define _IMSG_H_ 25 | 26 | #define IBUF_READ_SIZE 65535 27 | #define IMSG_HEADER_SIZE sizeof(struct imsg_hdr) 28 | #define MAX_IMSGSIZE 16384 29 | 30 | struct ibuf { 31 | TAILQ_ENTRY(ibuf) entry; 32 | u_char *buf; 33 | size_t size; 34 | size_t max; 35 | size_t wpos; 36 | size_t rpos; 37 | int fd; 38 | }; 39 | 40 | struct msgbuf { 41 | TAILQ_HEAD(, ibuf) bufs; 42 | u_int32_t queued; 43 | int fd; 44 | }; 45 | 46 | struct ibuf_read { 47 | u_char buf[IBUF_READ_SIZE]; 48 | u_char *rptr; 49 | size_t wpos; 50 | }; 51 | 52 | struct imsg_fd { 53 | TAILQ_ENTRY(imsg_fd) entry; 54 | int fd; 55 | }; 56 | 57 | struct imsgbuf { 58 | TAILQ_HEAD(, imsg_fd) fds; 59 | struct ibuf_read r; 60 | struct msgbuf w; 61 | int fd; 62 | pid_t pid; 63 | }; 64 | 65 | #define IMSGF_HASFD 1 66 | 67 | struct imsg_hdr { 68 | u_int32_t type; 69 | u_int16_t len; 70 | u_int16_t flags; 71 | u_int32_t peerid; 72 | u_int32_t pid; 73 | }; 74 | 75 | struct imsg { 76 | struct imsg_hdr hdr; 77 | int fd; 78 | void *data; 79 | }; 80 | 81 | 82 | /* buffer.c */ 83 | struct ibuf *ibuf_open(size_t); 84 | struct ibuf *ibuf_dynamic(size_t, size_t); 85 | int ibuf_add(struct ibuf *, const void *, size_t); 86 | void *ibuf_reserve(struct ibuf *, size_t); 87 | void *ibuf_seek(struct ibuf *, size_t, size_t); 88 | size_t ibuf_size(struct ibuf *); 89 | size_t ibuf_left(struct ibuf *); 90 | void ibuf_close(struct msgbuf *, struct ibuf *); 91 | int ibuf_write(struct msgbuf *); 92 | void ibuf_free(struct ibuf *); 93 | void msgbuf_init(struct msgbuf *); 94 | void msgbuf_clear(struct msgbuf *); 95 | int msgbuf_write(struct msgbuf *); 96 | void msgbuf_drain(struct msgbuf *, size_t); 97 | 98 | /* imsg.c */ 99 | void imsg_init(struct imsgbuf *, int); 100 | ssize_t imsg_read(struct imsgbuf *); 101 | ssize_t imsg_get(struct imsgbuf *, struct imsg *); 102 | int imsg_compose(struct imsgbuf *, u_int32_t, u_int32_t, pid_t, 103 | int, const void *, u_int16_t); 104 | int imsg_composev(struct imsgbuf *, u_int32_t, u_int32_t, pid_t, 105 | int, const struct iovec *, int); 106 | struct ibuf *imsg_create(struct imsgbuf *, u_int32_t, u_int32_t, pid_t, 107 | u_int16_t); 108 | int imsg_add(struct ibuf *, const void *, u_int16_t); 109 | void imsg_close(struct imsgbuf *, struct ibuf *); 110 | void imsg_free(struct imsg *); 111 | int imsg_flush(struct imsgbuf *); 112 | void imsg_clear(struct imsgbuf *); 113 | 114 | #endif 115 | -------------------------------------------------------------------------------- /cmd-list-windows.c: -------------------------------------------------------------------------------- 1 | /* $OpenBSD$ */ 2 | 3 | /* 4 | * Copyright (c) 2007 Nicholas Marriott 5 | * 6 | * Permission to use, copy, modify, and distribute this software for any 7 | * purpose with or without fee is hereby granted, provided that the above 8 | * copyright notice and this permission notice appear in all copies. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 | * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER 15 | * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 16 | * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 | */ 18 | 19 | #include 20 | 21 | #include 22 | #include 23 | 24 | #include "tmux.h" 25 | 26 | /* 27 | * List windows on given session. 28 | */ 29 | 30 | #define LIST_WINDOWS_TEMPLATE \ 31 | "#{window_index}: #{window_name}#{window_flags} " \ 32 | "(#{window_panes} panes) " \ 33 | "[#{window_width}x#{window_height}] " \ 34 | "[layout #{window_layout}] #{window_id}" \ 35 | "#{?window_active, (active),}"; 36 | #define LIST_WINDOWS_WITH_SESSION_TEMPLATE \ 37 | "#{session_name}:" \ 38 | "#{window_index}: #{window_name}#{window_flags} " \ 39 | "(#{window_panes} panes) " \ 40 | "[#{window_width}x#{window_height}] " 41 | 42 | enum cmd_retval cmd_list_windows_exec(struct cmd *, struct cmd_q *); 43 | 44 | void cmd_list_windows_server(struct cmd *, struct cmd_q *); 45 | void cmd_list_windows_session(struct cmd *, struct session *, 46 | struct cmd_q *, int); 47 | 48 | const struct cmd_entry cmd_list_windows_entry = { 49 | "list-windows", "lsw", 50 | "F:at:", 0, 0, 51 | "[-a] [-F format] " CMD_TARGET_SESSION_USAGE, 52 | 0, 53 | cmd_list_windows_exec 54 | }; 55 | 56 | enum cmd_retval 57 | cmd_list_windows_exec(struct cmd *self, struct cmd_q *cmdq) 58 | { 59 | struct args *args = self->args; 60 | struct session *s; 61 | 62 | if (args_has(args, 'a')) 63 | cmd_list_windows_server(self, cmdq); 64 | else { 65 | s = cmd_find_session(cmdq, args_get(args, 't'), 0); 66 | if (s == NULL) 67 | return (CMD_RETURN_ERROR); 68 | cmd_list_windows_session(self, s, cmdq, 0); 69 | } 70 | 71 | return (CMD_RETURN_NORMAL); 72 | } 73 | 74 | void 75 | cmd_list_windows_server(struct cmd *self, struct cmd_q *cmdq) 76 | { 77 | struct session *s; 78 | 79 | RB_FOREACH(s, sessions, &sessions) 80 | cmd_list_windows_session(self, s, cmdq, 1); 81 | } 82 | 83 | void 84 | cmd_list_windows_session( 85 | struct cmd *self, struct session *s, struct cmd_q *cmdq, int type) 86 | { 87 | struct args *args = self->args; 88 | struct winlink *wl; 89 | u_int n; 90 | struct format_tree *ft; 91 | const char *template; 92 | char *line; 93 | 94 | template = args_get(args, 'F'); 95 | if (template == NULL) { 96 | switch (type) { 97 | case 0: 98 | template = LIST_WINDOWS_TEMPLATE; 99 | break; 100 | case 1: 101 | template = LIST_WINDOWS_WITH_SESSION_TEMPLATE; 102 | break; 103 | } 104 | } 105 | 106 | n = 0; 107 | RB_FOREACH(wl, winlinks, &s->windows) { 108 | ft = format_create(); 109 | format_add(ft, "line", "%u", n); 110 | format_defaults(ft, NULL, s, wl, NULL); 111 | 112 | line = format_expand(ft, template); 113 | cmdq_print(cmdq, "%s", line); 114 | free(line); 115 | 116 | format_free(ft); 117 | n++; 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /cmd-show-environment.c: -------------------------------------------------------------------------------- 1 | /* $OpenBSD$ */ 2 | 3 | /* 4 | * Copyright (c) 2009 Nicholas Marriott 5 | * 6 | * Permission to use, copy, modify, and distribute this software for any 7 | * purpose with or without fee is hereby granted, provided that the above 8 | * copyright notice and this permission notice appear in all copies. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 | * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER 15 | * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 16 | * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 | */ 18 | 19 | #include 20 | 21 | #include 22 | #include 23 | 24 | #include "tmux.h" 25 | 26 | /* 27 | * Show environment. 28 | */ 29 | 30 | enum cmd_retval cmd_show_environment_exec(struct cmd *, struct cmd_q *); 31 | 32 | char *cmd_show_environment_escape(struct environ_entry *); 33 | void cmd_show_environment_print(struct cmd *, struct cmd_q *, 34 | struct environ_entry *); 35 | 36 | const struct cmd_entry cmd_show_environment_entry = { 37 | "show-environment", "showenv", 38 | "gst:", 0, 1, 39 | "[-gs] " CMD_TARGET_SESSION_USAGE " [name]", 40 | 0, 41 | cmd_show_environment_exec 42 | }; 43 | 44 | char * 45 | cmd_show_environment_escape(struct environ_entry *envent) 46 | { 47 | const char *value = envent->value; 48 | char c, *out, *ret; 49 | 50 | out = ret = xmalloc(strlen(value) * 2 + 1); /* at most twice the size */ 51 | while ((c = *value++) != '\0') { 52 | /* POSIX interprets $ ` " and \ in double quotes. */ 53 | if (c == '$' || c == '`' || c == '"' || c == '\\') 54 | *out++ = '\\'; 55 | *out++ = c; 56 | } 57 | *out = '\0'; 58 | 59 | return ret; 60 | } 61 | 62 | void 63 | cmd_show_environment_print(struct cmd *self, struct cmd_q *cmdq, 64 | struct environ_entry *envent) 65 | { 66 | char *escaped; 67 | 68 | if (!args_has(self->args, 's')) { 69 | if (envent->value != NULL) 70 | cmdq_print(cmdq, "%s=%s", envent->name, envent->value); 71 | else 72 | cmdq_print(cmdq, "-%s", envent->name); 73 | return; 74 | } 75 | 76 | if (envent->value != NULL) { 77 | escaped = cmd_show_environment_escape(envent); 78 | cmdq_print(cmdq, "%s=\"%s\"; export %s;", envent->name, escaped, 79 | envent->name); 80 | free(escaped); 81 | } else 82 | cmdq_print(cmdq, "unset %s;", envent->name); 83 | } 84 | 85 | enum cmd_retval 86 | cmd_show_environment_exec(struct cmd *self, struct cmd_q *cmdq) 87 | { 88 | struct args *args = self->args; 89 | struct session *s; 90 | struct environ *env; 91 | struct environ_entry *envent; 92 | 93 | if (args_has(self->args, 'g')) 94 | env = &global_environ; 95 | else { 96 | s = cmd_find_session(cmdq, args_get(args, 't'), 0); 97 | if (s == NULL) 98 | return (CMD_RETURN_ERROR); 99 | env = &s->environ; 100 | } 101 | 102 | if (args->argc != 0) { 103 | envent = environ_find(env, args->argv[0]); 104 | if (envent == NULL) { 105 | cmdq_error(cmdq, "unknown variable: %s", args->argv[0]); 106 | return (CMD_RETURN_ERROR); 107 | } 108 | cmd_show_environment_print(self, cmdq, envent); 109 | return (CMD_RETURN_NORMAL); 110 | } 111 | 112 | RB_FOREACH(envent, environ, env) 113 | cmd_show_environment_print(self, cmdq, envent); 114 | return (CMD_RETURN_NORMAL); 115 | } 116 | -------------------------------------------------------------------------------- /cmd-confirm-before.c: -------------------------------------------------------------------------------- 1 | /* $OpenBSD$ */ 2 | 3 | /* 4 | * Copyright (c) 2009 Tiago Cunha 5 | * 6 | * Permission to use, copy, modify, and distribute this software for any 7 | * purpose with or without fee is hereby granted, provided that the above 8 | * copyright notice and this permission notice appear in all copies. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 | * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER 15 | * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 16 | * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 | */ 18 | 19 | #include 20 | 21 | #include 22 | #include 23 | #include 24 | 25 | #include "tmux.h" 26 | 27 | /* 28 | * Asks for confirmation before executing a command. 29 | */ 30 | 31 | enum cmd_retval cmd_confirm_before_exec(struct cmd *, struct cmd_q *); 32 | 33 | int cmd_confirm_before_callback(void *, const char *); 34 | void cmd_confirm_before_free(void *); 35 | 36 | const struct cmd_entry cmd_confirm_before_entry = { 37 | "confirm-before", "confirm", 38 | "p:t:", 1, 1, 39 | "[-p prompt] " CMD_TARGET_CLIENT_USAGE " command", 40 | 0, 41 | cmd_confirm_before_exec 42 | }; 43 | 44 | struct cmd_confirm_before_data { 45 | char *cmd; 46 | struct client *client; 47 | }; 48 | 49 | enum cmd_retval 50 | cmd_confirm_before_exec(struct cmd *self, struct cmd_q *cmdq) 51 | { 52 | struct args *args = self->args; 53 | struct cmd_confirm_before_data *cdata; 54 | struct client *c; 55 | char *cmd, *copy, *new_prompt, *ptr; 56 | const char *prompt; 57 | 58 | if ((c = cmd_find_client(cmdq, args_get(args, 't'), 0)) == NULL) 59 | return (CMD_RETURN_ERROR); 60 | 61 | if ((prompt = args_get(args, 'p')) != NULL) 62 | xasprintf(&new_prompt, "%s ", prompt); 63 | else { 64 | ptr = copy = xstrdup(args->argv[0]); 65 | cmd = strsep(&ptr, " \t"); 66 | xasprintf(&new_prompt, "Confirm '%s'? (y/n) ", cmd); 67 | free(copy); 68 | } 69 | 70 | cdata = xmalloc(sizeof *cdata); 71 | cdata->cmd = xstrdup(args->argv[0]); 72 | 73 | cdata->client = c; 74 | cdata->client->references++; 75 | 76 | status_prompt_set(c, new_prompt, NULL, 77 | cmd_confirm_before_callback, cmd_confirm_before_free, cdata, 78 | PROMPT_SINGLE); 79 | 80 | free(new_prompt); 81 | return (CMD_RETURN_NORMAL); 82 | } 83 | 84 | int 85 | cmd_confirm_before_callback(void *data, const char *s) 86 | { 87 | struct cmd_confirm_before_data *cdata = data; 88 | struct client *c = cdata->client; 89 | struct cmd_list *cmdlist; 90 | char *cause; 91 | 92 | if (c->flags & CLIENT_DEAD) 93 | return (0); 94 | 95 | if (s == NULL || *s == '\0') 96 | return (0); 97 | if (tolower((u_char) s[0]) != 'y' || s[1] != '\0') 98 | return (0); 99 | 100 | if (cmd_string_parse(cdata->cmd, &cmdlist, NULL, 0, &cause) != 0) { 101 | if (cause != NULL) { 102 | cmdq_error(c->cmdq, "%s", cause); 103 | free(cause); 104 | } 105 | return (0); 106 | } 107 | 108 | cmdq_run(c->cmdq, cmdlist, NULL); 109 | cmd_list_free(cmdlist); 110 | 111 | return (0); 112 | } 113 | 114 | void 115 | cmd_confirm_before_free(void *data) 116 | { 117 | struct cmd_confirm_before_data *cdata = data; 118 | struct client *c = cdata->client; 119 | 120 | server_client_unref(c); 121 | 122 | free(cdata->cmd); 123 | free(cdata); 124 | } 125 | -------------------------------------------------------------------------------- /tty-acs.c: -------------------------------------------------------------------------------- 1 | /* $OpenBSD$ */ 2 | 3 | /* 4 | * Copyright (c) 2010 Nicholas Marriott 5 | * 6 | * Permission to use, copy, modify, and distribute this software for any 7 | * purpose with or without fee is hereby granted, provided that the above 8 | * copyright notice and this permission notice appear in all copies. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 | * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER 15 | * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 16 | * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 | */ 18 | 19 | #include 20 | 21 | #include 22 | 23 | #include "tmux.h" 24 | 25 | int tty_acs_cmp(const void *, const void *); 26 | 27 | /* Table mapping ACS entries to UTF-8. */ 28 | struct tty_acs_entry { 29 | u_char key; 30 | const char *string; 31 | }; 32 | const struct tty_acs_entry tty_acs_table[] = { 33 | { '+', "\342\206\222" }, /* arrow pointing right */ 34 | { ',', "\342\206\220" }, /* arrow pointing left */ 35 | { '-', "\342\206\221" }, /* arrow pointing up */ 36 | { '.', "\342\206\223" }, /* arrow pointing down */ 37 | { '0', "\342\226\256" }, /* solid square block */ 38 | { '`', "\342\227\206" }, /* diamond */ 39 | { 'a', "\342\226\222" }, /* checker board (stipple) */ 40 | { 'f', "\302\260" }, /* degree symbol */ 41 | { 'g', "\302\261" }, /* plus/minus */ 42 | { 'h', "\342\226\222" }, /* board of squares */ 43 | { 'i', "\342\230\203" }, /* lantern symbol */ 44 | { 'j', "\342\224\230" }, /* lower right corner */ 45 | { 'k', "\342\224\220" }, /* upper right corner */ 46 | { 'l', "\342\224\214" }, /* upper left corner */ 47 | { 'm', "\342\224\224" }, /* lower left corner */ 48 | { 'n', "\342\224\274" }, /* large plus or crossover */ 49 | { 'o', "\342\216\272" }, /* scan line 1 */ 50 | { 'p', "\342\216\273" }, /* scan line 3 */ 51 | { 'q', "\342\224\200" }, /* horizontal line */ 52 | { 'r', "\342\216\274" }, /* scan line 7 */ 53 | { 's', "\342\216\275" }, /* scan line 9 */ 54 | { 't', "\342\224\234" }, /* tee pointing right */ 55 | { 'u', "\342\224\244" }, /* tee pointing left */ 56 | { 'v', "\342\224\264" }, /* tee pointing up */ 57 | { 'w', "\342\224\254" }, /* tee pointing down */ 58 | { 'x', "\342\224\202" }, /* vertical line */ 59 | { 'y', "\342\211\244" }, /* less-than-or-equal-to */ 60 | { 'z', "\342\211\245" }, /* greater-than-or-equal-to */ 61 | { '{', "\317\200" }, /* greek pi */ 62 | { '|', "\342\211\240" }, /* not-equal */ 63 | { '}', "\302\243" }, /* UK pound sign */ 64 | { '~', "\302\267" } /* bullet */ 65 | }; 66 | 67 | int 68 | tty_acs_cmp(const void *key, const void *value) 69 | { 70 | const struct tty_acs_entry *entry = value; 71 | u_char ch; 72 | 73 | ch = *(u_char *) key; 74 | return (ch - entry->key); 75 | } 76 | 77 | /* Retrieve ACS to output as a string. */ 78 | const char * 79 | tty_acs_get(struct tty *tty, u_char ch) 80 | { 81 | struct tty_acs_entry *entry; 82 | 83 | /* If not a UTF-8 terminal, use the ACS set. */ 84 | if (tty != NULL && !(tty->flags & TTY_UTF8)) { 85 | if (tty->term->acs[ch][0] == '\0') 86 | return (NULL); 87 | return (&tty->term->acs[ch][0]); 88 | } 89 | 90 | /* Otherwise look up the UTF-8 translation. */ 91 | entry = bsearch(&ch, 92 | tty_acs_table, nitems(tty_acs_table), sizeof tty_acs_table[0], 93 | tty_acs_cmp); 94 | if (entry == NULL) 95 | return (NULL); 96 | return (entry->string); 97 | } 98 | -------------------------------------------------------------------------------- /osdep-dragonfly.c: -------------------------------------------------------------------------------- 1 | /* $OpenBSD$ */ 2 | 3 | /* 4 | * Copyright (c) 2009 Nicholas Marriott 5 | * 6 | * Permission to use, copy, modify, and distribute this software for any 7 | * purpose with or without fee is hereby granted, provided that the above 8 | * copyright notice and this permission notice appear in all copies. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 | * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER 15 | * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 16 | * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 | */ 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | 32 | struct kinfo_proc *cmp_procs(struct kinfo_proc *, struct kinfo_proc *); 33 | char *osdep_get_name(int, char *); 34 | char *osdep_get_cwd(int); 35 | struct event_base *osdep_event_init(void); 36 | 37 | #ifndef nitems 38 | #define nitems(_a) (sizeof((_a)) / sizeof((_a)[0])) 39 | #endif 40 | 41 | #define is_runnable(p) \ 42 | ((p)->kp_stat == SACTIVE || (p)->kp_stat == SIDL) 43 | #define is_stopped(p) \ 44 | ((p)->kp_stat == SSTOP || (p)->kp_stat == SZOMB) 45 | 46 | struct kinfo_proc * 47 | cmp_procs(struct kinfo_proc *p1, struct kinfo_proc *p2) 48 | { 49 | if (is_runnable(p1) && !is_runnable(p2)) 50 | return (p1); 51 | if (!is_runnable(p1) && is_runnable(p2)) 52 | return (p2); 53 | 54 | if (is_stopped(p1) && !is_stopped(p2)) 55 | return (p1); 56 | if (!is_stopped(p1) && is_stopped(p2)) 57 | return (p2); 58 | 59 | if (strcmp(p1->kp_comm, p2->kp_comm) < 0) 60 | return (p1); 61 | if (strcmp(p1->kp_comm, p2->kp_comm) > 0) 62 | return (p2); 63 | 64 | if (p1->kp_pid > p2->kp_pid) 65 | return (p1); 66 | return (p2); 67 | } 68 | 69 | char * 70 | osdep_get_name(int fd, char *tty) 71 | { 72 | int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PGRP, 0 }; 73 | struct stat sb; 74 | size_t len; 75 | struct kinfo_proc *buf, *newbuf, *bestp; 76 | u_int i; 77 | char *name; 78 | 79 | buf = NULL; 80 | 81 | if (stat(tty, &sb) == -1) 82 | return (NULL); 83 | if ((mib[3] = tcgetpgrp(fd)) == -1) 84 | return (NULL); 85 | 86 | retry: 87 | if (sysctl(mib, nitems(mib), NULL, &len, NULL, 0) == -1) 88 | return (NULL); 89 | len = (len * 5) / 4; 90 | 91 | if ((newbuf = realloc(buf, len)) == NULL) 92 | goto error; 93 | buf = newbuf; 94 | 95 | if (sysctl(mib, nitems(mib), buf, &len, NULL, 0) == -1) { 96 | if (errno == ENOMEM) 97 | goto retry; 98 | goto error; 99 | } 100 | 101 | bestp = NULL; 102 | for (i = 0; i < len / sizeof (struct kinfo_proc); i++) { 103 | if (buf[i].kp_tdev != sb.st_rdev) 104 | continue; 105 | if (bestp == NULL) 106 | bestp = &buf[i]; 107 | else 108 | bestp = cmp_procs(&buf[i], bestp); 109 | } 110 | 111 | name = NULL; 112 | if (bestp != NULL) 113 | name = strdup(bestp->kp_comm); 114 | 115 | free(buf); 116 | return (name); 117 | 118 | error: 119 | free(buf); 120 | return (NULL); 121 | } 122 | 123 | char * 124 | osdep_get_cwd(int fd) 125 | { 126 | return (NULL); 127 | } 128 | 129 | struct event_base * 130 | osdep_event_init(void) 131 | { 132 | return (event_init()); 133 | } 134 | -------------------------------------------------------------------------------- /signal.c: -------------------------------------------------------------------------------- 1 | /* $OpenBSD$ */ 2 | 3 | /* 4 | * Copyright (c) 2007 Nicholas Marriott 5 | * Copyright (c) 2010 Romain Francoise 6 | * 7 | * Permission to use, copy, modify, and distribute this software for any 8 | * purpose with or without fee is hereby granted, provided that the above 9 | * copyright notice and this permission notice appear in all copies. 10 | * 11 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 12 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 13 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 14 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 15 | * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER 16 | * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 17 | * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 18 | */ 19 | 20 | #include 21 | 22 | #include 23 | #include 24 | 25 | #include "tmux.h" 26 | 27 | struct event ev_sighup; 28 | struct event ev_sigchld; 29 | struct event ev_sigcont; 30 | struct event ev_sigterm; 31 | struct event ev_sigusr1; 32 | struct event ev_sigwinch; 33 | 34 | void 35 | set_signals(void(*handler)(int, short, unused void *)) 36 | { 37 | struct sigaction sigact; 38 | 39 | memset(&sigact, 0, sizeof sigact); 40 | sigemptyset(&sigact.sa_mask); 41 | sigact.sa_flags = SA_RESTART; 42 | sigact.sa_handler = SIG_IGN; 43 | if (sigaction(SIGINT, &sigact, NULL) != 0) 44 | fatal("sigaction failed"); 45 | if (sigaction(SIGPIPE, &sigact, NULL) != 0) 46 | fatal("sigaction failed"); 47 | if (sigaction(SIGUSR2, &sigact, NULL) != 0) 48 | fatal("sigaction failed"); 49 | if (sigaction(SIGTSTP, &sigact, NULL) != 0) 50 | fatal("sigaction failed"); 51 | 52 | signal_set(&ev_sighup, SIGHUP, handler, NULL); 53 | signal_add(&ev_sighup, NULL); 54 | signal_set(&ev_sigchld, SIGCHLD, handler, NULL); 55 | signal_add(&ev_sigchld, NULL); 56 | signal_set(&ev_sigcont, SIGCONT, handler, NULL); 57 | signal_add(&ev_sigcont, NULL); 58 | signal_set(&ev_sigterm, SIGTERM, handler, NULL); 59 | signal_add(&ev_sigterm, NULL); 60 | signal_set(&ev_sigusr1, SIGUSR1, handler, NULL); 61 | signal_add(&ev_sigusr1, NULL); 62 | signal_set(&ev_sigwinch, SIGWINCH, handler, NULL); 63 | signal_add(&ev_sigwinch, NULL); 64 | } 65 | 66 | void 67 | clear_signals(int after_fork) 68 | { 69 | struct sigaction sigact; 70 | 71 | memset(&sigact, 0, sizeof sigact); 72 | sigemptyset(&sigact.sa_mask); 73 | sigact.sa_flags = SA_RESTART; 74 | sigact.sa_handler = SIG_DFL; 75 | if (sigaction(SIGINT, &sigact, NULL) != 0) 76 | fatal("sigaction failed"); 77 | if (sigaction(SIGPIPE, &sigact, NULL) != 0) 78 | fatal("sigaction failed"); 79 | if (sigaction(SIGUSR2, &sigact, NULL) != 0) 80 | fatal("sigaction failed"); 81 | if (sigaction(SIGTSTP, &sigact, NULL) != 0) 82 | fatal("sigaction failed"); 83 | 84 | if (after_fork) { 85 | if (sigaction(SIGHUP, &sigact, NULL) != 0) 86 | fatal("sigaction failed"); 87 | if (sigaction(SIGCHLD, &sigact, NULL) != 0) 88 | fatal("sigaction failed"); 89 | if (sigaction(SIGCONT, &sigact, NULL) != 0) 90 | fatal("sigaction failed"); 91 | if (sigaction(SIGTERM, &sigact, NULL) != 0) 92 | fatal("sigaction failed"); 93 | if (sigaction(SIGUSR1, &sigact, NULL) != 0) 94 | fatal("sigaction failed"); 95 | if (sigaction(SIGWINCH, &sigact, NULL) != 0) 96 | fatal("sigaction failed"); 97 | } else { 98 | event_del(&ev_sighup); 99 | event_del(&ev_sigchld); 100 | event_del(&ev_sigcont); 101 | event_del(&ev_sigterm); 102 | event_del(&ev_sigusr1); 103 | event_del(&ev_sigwinch); 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /cmd-rotate-window.c: -------------------------------------------------------------------------------- 1 | /* $OpenBSD$ */ 2 | 3 | /* 4 | * Copyright (c) 2009 Nicholas Marriott 5 | * 6 | * Permission to use, copy, modify, and distribute this software for any 7 | * purpose with or without fee is hereby granted, provided that the above 8 | * copyright notice and this permission notice appear in all copies. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 | * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER 15 | * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 16 | * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 | */ 18 | 19 | #include 20 | 21 | #include "tmux.h" 22 | 23 | /* 24 | * Rotate the panes in a window. 25 | */ 26 | 27 | enum cmd_retval cmd_rotate_window_exec(struct cmd *, struct cmd_q *); 28 | 29 | const struct cmd_entry cmd_rotate_window_entry = { 30 | "rotate-window", "rotatew", 31 | "Dt:U", 0, 0, 32 | "[-DU] " CMD_TARGET_WINDOW_USAGE, 33 | 0, 34 | cmd_rotate_window_exec 35 | }; 36 | 37 | enum cmd_retval 38 | cmd_rotate_window_exec(struct cmd *self, struct cmd_q *cmdq) 39 | { 40 | struct args *args = self->args; 41 | struct winlink *wl; 42 | struct window *w; 43 | struct window_pane *wp, *wp2; 44 | struct layout_cell *lc; 45 | u_int sx, sy, xoff, yoff; 46 | 47 | if ((wl = cmd_find_window(cmdq, args_get(args, 't'), NULL)) == NULL) 48 | return (CMD_RETURN_ERROR); 49 | w = wl->window; 50 | 51 | if (args_has(self->args, 'D')) { 52 | wp = TAILQ_LAST(&w->panes, window_panes); 53 | TAILQ_REMOVE(&w->panes, wp, entry); 54 | TAILQ_INSERT_HEAD(&w->panes, wp, entry); 55 | 56 | lc = wp->layout_cell; 57 | xoff = wp->xoff; yoff = wp->yoff; 58 | sx = wp->sx; sy = wp->sy; 59 | TAILQ_FOREACH(wp, &w->panes, entry) { 60 | if ((wp2 = TAILQ_NEXT(wp, entry)) == NULL) 61 | break; 62 | wp->layout_cell = wp2->layout_cell; 63 | if (wp->layout_cell != NULL) 64 | wp->layout_cell->wp = wp; 65 | wp->xoff = wp2->xoff; wp->yoff = wp2->yoff; 66 | window_pane_resize(wp, wp2->sx, wp2->sy); 67 | } 68 | wp->layout_cell = lc; 69 | if (wp->layout_cell != NULL) 70 | wp->layout_cell->wp = wp; 71 | wp->xoff = xoff; wp->yoff = yoff; 72 | window_pane_resize(wp, sx, sy); 73 | 74 | if ((wp = TAILQ_PREV(w->active, window_panes, entry)) == NULL) 75 | wp = TAILQ_LAST(&w->panes, window_panes); 76 | window_set_active_pane(w, wp); 77 | server_redraw_window(w); 78 | } else { 79 | wp = TAILQ_FIRST(&w->panes); 80 | TAILQ_REMOVE(&w->panes, wp, entry); 81 | TAILQ_INSERT_TAIL(&w->panes, wp, entry); 82 | 83 | lc = wp->layout_cell; 84 | xoff = wp->xoff; yoff = wp->yoff; 85 | sx = wp->sx; sy = wp->sy; 86 | TAILQ_FOREACH_REVERSE(wp, &w->panes, window_panes, entry) { 87 | if ((wp2 = TAILQ_PREV(wp, window_panes, entry)) == NULL) 88 | break; 89 | wp->layout_cell = wp2->layout_cell; 90 | if (wp->layout_cell != NULL) 91 | wp->layout_cell->wp = wp; 92 | wp->xoff = wp2->xoff; wp->yoff = wp2->yoff; 93 | window_pane_resize(wp, wp2->sx, wp2->sy); 94 | } 95 | wp->layout_cell = lc; 96 | if (wp->layout_cell != NULL) 97 | wp->layout_cell->wp = wp; 98 | wp->xoff = xoff; wp->yoff = yoff; 99 | window_pane_resize(wp, sx, sy); 100 | 101 | if ((wp = TAILQ_NEXT(w->active, entry)) == NULL) 102 | wp = TAILQ_FIRST(&w->panes); 103 | window_set_active_pane(w, wp); 104 | server_redraw_window(w); 105 | } 106 | 107 | return (CMD_RETURN_NORMAL); 108 | } 109 | -------------------------------------------------------------------------------- /osdep-netbsd.c: -------------------------------------------------------------------------------- 1 | /* $OpenBSD$ */ 2 | 3 | /* 4 | * Copyright (c) 2009 Nicholas Marriott 5 | * 6 | * Permission to use, copy, modify, and distribute this software for any 7 | * purpose with or without fee is hereby granted, provided that the above 8 | * copyright notice and this permission notice appear in all copies. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 | * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER 15 | * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 16 | * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 | */ 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | #define is_runnable(p) \ 31 | ((p)->p_stat == LSRUN || (p)->p_stat == SIDL) 32 | #define is_stopped(p) \ 33 | ((p)->p_stat == SSTOP || (p)->p_stat == SZOMB) 34 | 35 | struct kinfo_proc2 *cmp_procs(struct kinfo_proc2 *, struct kinfo_proc2 *); 36 | char *osdep_get_name(int, char *); 37 | char *osdep_get_cwd(int); 38 | struct event_base *osdep_event_init(void); 39 | 40 | struct kinfo_proc2 * 41 | cmp_procs(struct kinfo_proc2 *p1, struct kinfo_proc2 *p2) 42 | { 43 | if (is_runnable(p1) && !is_runnable(p2)) 44 | return (p1); 45 | if (!is_runnable(p1) && is_runnable(p2)) 46 | return (p2); 47 | 48 | if (is_stopped(p1) && !is_stopped(p2)) 49 | return (p1); 50 | if (!is_stopped(p1) && is_stopped(p2)) 51 | return (p2); 52 | 53 | if (p1->p_estcpu > p2->p_estcpu) 54 | return (p1); 55 | if (p1->p_estcpu < p2->p_estcpu) 56 | return (p2); 57 | 58 | if (p1->p_slptime < p2->p_slptime) 59 | return (p1); 60 | if (p1->p_slptime > p2->p_slptime) 61 | return (p2); 62 | 63 | if (p1->p_pid > p2->p_pid) 64 | return (p1); 65 | return (p2); 66 | } 67 | 68 | char * 69 | osdep_get_name(int fd, __unused char *tty) 70 | { 71 | int mib[6]; 72 | struct stat sb; 73 | size_t len, i; 74 | struct kinfo_proc2 *buf, *newbuf, *bestp; 75 | char *name; 76 | 77 | if (stat(tty, &sb) == -1) 78 | return (NULL); 79 | if ((mib[3] = tcgetpgrp(fd)) == -1) 80 | return (NULL); 81 | 82 | buf = NULL; 83 | len = sizeof(bestp); 84 | mib[0] = CTL_KERN; 85 | mib[1] = KERN_PROC2; 86 | mib[2] = KERN_PROC_PGRP; 87 | mib[4] = sizeof (*buf); 88 | mib[5] = 0; 89 | 90 | retry: 91 | if (sysctl(mib, __arraycount(mib), NULL, &len, NULL, 0) == -1) 92 | return (NULL); 93 | 94 | if ((newbuf = realloc(buf, len * sizeof (*buf))) == NULL) 95 | goto error; 96 | buf = newbuf; 97 | 98 | mib[5] = len / sizeof(*buf); 99 | if (sysctl(mib, __arraycount(mib), buf, &len, NULL, 0) == -1) { 100 | if (errno == ENOMEM) 101 | goto retry; /* possible infinite loop? */ 102 | goto error; 103 | } 104 | 105 | bestp = NULL; 106 | for (i = 0; i < len / sizeof (*buf); i++) { 107 | if (buf[i].p_tdev != sb.st_rdev) 108 | continue; 109 | if (bestp == NULL) 110 | bestp = &buf[i]; 111 | else 112 | bestp = cmp_procs(&buf[i], bestp); 113 | } 114 | 115 | name = NULL; 116 | if (bestp != NULL) 117 | name = strdup(bestp->p_comm); 118 | 119 | free(buf); 120 | return (name); 121 | 122 | error: 123 | free(buf); 124 | return (NULL); 125 | } 126 | 127 | char * 128 | osdep_get_cwd(int fd) 129 | { 130 | return (NULL); 131 | } 132 | 133 | struct event_base * 134 | osdep_event_init(void) 135 | { 136 | return (event_init()); 137 | } 138 | -------------------------------------------------------------------------------- /cmd-select-window.c: -------------------------------------------------------------------------------- 1 | /* $OpenBSD$ */ 2 | 3 | /* 4 | * Copyright (c) 2007 Nicholas Marriott 5 | * 6 | * Permission to use, copy, modify, and distribute this software for any 7 | * purpose with or without fee is hereby granted, provided that the above 8 | * copyright notice and this permission notice appear in all copies. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 | * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER 15 | * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 16 | * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 | */ 18 | 19 | #include 20 | 21 | #include 22 | 23 | #include "tmux.h" 24 | 25 | /* 26 | * Select window by index. 27 | */ 28 | 29 | enum cmd_retval cmd_select_window_exec(struct cmd *, struct cmd_q *); 30 | 31 | const struct cmd_entry cmd_select_window_entry = { 32 | "select-window", "selectw", 33 | "lnpTt:", 0, 0, 34 | "[-lnpT] " CMD_TARGET_WINDOW_USAGE, 35 | 0, 36 | cmd_select_window_exec 37 | }; 38 | 39 | const struct cmd_entry cmd_next_window_entry = { 40 | "next-window", "next", 41 | "at:", 0, 0, 42 | "[-a] " CMD_TARGET_SESSION_USAGE, 43 | 0, 44 | cmd_select_window_exec 45 | }; 46 | 47 | const struct cmd_entry cmd_previous_window_entry = { 48 | "previous-window", "prev", 49 | "at:", 0, 0, 50 | "[-a] " CMD_TARGET_SESSION_USAGE, 51 | 0, 52 | cmd_select_window_exec 53 | }; 54 | 55 | const struct cmd_entry cmd_last_window_entry = { 56 | "last-window", "last", 57 | "t:", 0, 0, 58 | CMD_TARGET_SESSION_USAGE, 59 | 0, 60 | cmd_select_window_exec 61 | }; 62 | 63 | enum cmd_retval 64 | cmd_select_window_exec(struct cmd *self, struct cmd_q *cmdq) 65 | { 66 | struct args *args = self->args; 67 | struct winlink *wl; 68 | struct session *s; 69 | int next, previous, last, activity; 70 | 71 | next = self->entry == &cmd_next_window_entry; 72 | if (args_has(self->args, 'n')) 73 | next = 1; 74 | previous = self->entry == &cmd_previous_window_entry; 75 | if (args_has(self->args, 'p')) 76 | previous = 1; 77 | last = self->entry == &cmd_last_window_entry; 78 | if (args_has(self->args, 'l')) 79 | last = 1; 80 | 81 | if (next || previous || last) { 82 | s = cmd_find_session(cmdq, args_get(args, 't'), 0); 83 | if (s == NULL) 84 | return (CMD_RETURN_ERROR); 85 | 86 | activity = args_has(self->args, 'a'); 87 | if (next) { 88 | if (session_next(s, activity) != 0) { 89 | cmdq_error(cmdq, "no next window"); 90 | return (CMD_RETURN_ERROR); 91 | } 92 | } else if (previous) { 93 | if (session_previous(s, activity) != 0) { 94 | cmdq_error(cmdq, "no previous window"); 95 | return (CMD_RETURN_ERROR); 96 | } 97 | } else { 98 | if (session_last(s) != 0) { 99 | cmdq_error(cmdq, "no last window"); 100 | return (CMD_RETURN_ERROR); 101 | } 102 | } 103 | 104 | server_redraw_session(s); 105 | } else { 106 | wl = cmd_find_window(cmdq, args_get(args, 't'), &s); 107 | if (wl == NULL) 108 | return (CMD_RETURN_ERROR); 109 | 110 | /* 111 | * If -T and select-window is invoked on same window as 112 | * current, switch to previous window. 113 | */ 114 | if (args_has(self->args, 'T') && wl == s->curw) { 115 | if (session_last(s) != 0) { 116 | cmdq_error(cmdq, "no last window"); 117 | return (-1); 118 | } 119 | server_redraw_session(s); 120 | } else if (session_select(s, wl->idx) == 0) 121 | server_redraw_session(s); 122 | } 123 | recalculate_sizes(); 124 | 125 | return (CMD_RETURN_NORMAL); 126 | } 127 | -------------------------------------------------------------------------------- /cmd-choose-client.c: -------------------------------------------------------------------------------- 1 | /* $OpenBSD$ */ 2 | 3 | /* 4 | * Copyright (c) 2009 Nicholas Marriott 5 | * 6 | * Permission to use, copy, modify, and distribute this software for any 7 | * purpose with or without fee is hereby granted, provided that the above 8 | * copyright notice and this permission notice appear in all copies. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 | * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER 15 | * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 16 | * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 | */ 18 | 19 | #include 20 | 21 | #include 22 | #include 23 | 24 | #include "tmux.h" 25 | 26 | /* 27 | * Enter choice mode to choose a client. 28 | */ 29 | 30 | #define CHOOSE_CLIENT_TEMPLATE \ 31 | "#{client_tty}: #{session_name} " \ 32 | "[#{client_width}x#{client_height} #{client_termname}]" \ 33 | "#{?client_utf8, (utf8),}#{?client_readonly, (ro),} " \ 34 | "(last used #{client_activity_string})" 35 | 36 | enum cmd_retval cmd_choose_client_exec(struct cmd *, struct cmd_q *); 37 | 38 | void cmd_choose_client_callback(struct window_choose_data *); 39 | 40 | const struct cmd_entry cmd_choose_client_entry = { 41 | "choose-client", NULL, 42 | "F:t:", 0, 1, 43 | CMD_TARGET_WINDOW_USAGE " [-F format] [template]", 44 | 0, 45 | cmd_choose_client_exec 46 | }; 47 | 48 | struct cmd_choose_client_data { 49 | struct client *client; 50 | }; 51 | 52 | enum cmd_retval 53 | cmd_choose_client_exec(struct cmd *self, struct cmd_q *cmdq) 54 | { 55 | struct args *args = self->args; 56 | struct client *c; 57 | struct client *c1; 58 | struct window_choose_data *cdata; 59 | struct winlink *wl; 60 | const char *template; 61 | char *action; 62 | u_int idx, cur; 63 | 64 | if ((c = cmd_find_client(cmdq, NULL, 1)) == NULL) { 65 | cmdq_error(cmdq, "no client available"); 66 | return (CMD_RETURN_ERROR); 67 | } 68 | 69 | if ((wl = cmd_find_window(cmdq, args_get(args, 't'), NULL)) == NULL) 70 | return (CMD_RETURN_ERROR); 71 | 72 | if (window_pane_set_mode(wl->window->active, &window_choose_mode) != 0) 73 | return (CMD_RETURN_NORMAL); 74 | 75 | if ((template = args_get(args, 'F')) == NULL) 76 | template = CHOOSE_CLIENT_TEMPLATE; 77 | 78 | if (args->argc != 0) 79 | action = xstrdup(args->argv[0]); 80 | else 81 | action = xstrdup("detach-client -t '%%'"); 82 | 83 | cur = idx = 0; 84 | TAILQ_FOREACH(c1, &clients, entry) { 85 | if (c1->session == NULL || c1->tty.path == NULL) 86 | continue; 87 | if (c1 == cmdq->client) 88 | cur = idx; 89 | 90 | cdata = window_choose_data_create(TREE_OTHER, c, c->session); 91 | cdata->idx = idx; 92 | 93 | cdata->ft_template = xstrdup(template); 94 | format_add(cdata->ft, "line", "%u", idx); 95 | format_defaults(cdata->ft, c1, NULL, NULL, NULL); 96 | 97 | cdata->command = cmd_template_replace(action, c1->tty.path, 1); 98 | 99 | window_choose_add(wl->window->active, cdata); 100 | 101 | idx++; 102 | } 103 | free(action); 104 | 105 | window_choose_ready(wl->window->active, cur, 106 | cmd_choose_client_callback); 107 | 108 | return (CMD_RETURN_NORMAL); 109 | } 110 | 111 | void 112 | cmd_choose_client_callback(struct window_choose_data *cdata) 113 | { 114 | struct client *c; 115 | u_int idx; 116 | 117 | if (cdata == NULL) 118 | return; 119 | if (cdata->start_client->flags & CLIENT_DEAD) 120 | return; 121 | 122 | idx = 0; 123 | TAILQ_FOREACH(c, &clients, entry) { 124 | if (idx == cdata->idx) 125 | break; 126 | idx++; 127 | } 128 | if (c == NULL || c->session == NULL) 129 | return; 130 | 131 | window_choose_data_run(cdata); 132 | } 133 | -------------------------------------------------------------------------------- /array.h: -------------------------------------------------------------------------------- 1 | /* $OpenBSD$ */ 2 | 3 | /* 4 | * Copyright (c) 2006 Nicholas Marriott 5 | * 6 | * Permission to use, copy, modify, and distribute this software for any 7 | * purpose with or without fee is hereby granted, provided that the above 8 | * copyright notice and this permission notice appear in all copies. 9 | * 10 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 | * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER 15 | * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 16 | * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 | */ 18 | 19 | #ifndef ARRAY_H 20 | #define ARRAY_H 21 | 22 | #define ARRAY_INITIALIZER { NULL, 0, 0 } 23 | 24 | #define ARRAY_DECL(n, c) \ 25 | struct n { \ 26 | c *list; \ 27 | u_int num; \ 28 | size_t space; \ 29 | } 30 | 31 | #define ARRAY_ITEM(a, i) ((a)->list[i]) 32 | #define ARRAY_ITEMSIZE(a) (sizeof *(a)->list) 33 | #define ARRAY_INITIALSPACE(a) (10 * ARRAY_ITEMSIZE(a)) 34 | 35 | #define ARRAY_ENSURE(a, n) do { \ 36 | if (UINT_MAX - (n) < (a)->num) \ 37 | fatalx("number too big"); \ 38 | if (SIZE_MAX / ((a)->num + (n)) < ARRAY_ITEMSIZE(a)) \ 39 | fatalx("size too big"); \ 40 | if ((a)->space == 0) { \ 41 | (a)->space = ARRAY_INITIALSPACE(a); \ 42 | (a)->list = xrealloc((a)->list, (a)->space); \ 43 | } \ 44 | while ((a)->space <= ((a)->num + (n)) * ARRAY_ITEMSIZE(a)) { \ 45 | (a)->list = xreallocarray((a)->list, 2, (a)->space); \ 46 | (a)->space *= 2; \ 47 | } \ 48 | } while (0) 49 | 50 | #define ARRAY_EMPTY(a) (((void *) (a)) == NULL || (a)->num == 0) 51 | #define ARRAY_LENGTH(a) ((a)->num) 52 | #define ARRAY_DATA(a) ((a)->list) 53 | 54 | #define ARRAY_FIRST(a) ARRAY_ITEM(a, 0) 55 | #define ARRAY_LAST(a) ARRAY_ITEM(a, (a)->num - 1) 56 | 57 | #define ARRAY_INIT(a) do { \ 58 | (a)->num = 0; \ 59 | (a)->list = NULL; \ 60 | (a)->space = 0; \ 61 | } while (0) 62 | #define ARRAY_CLEAR(a) do { \ 63 | (a)->num = 0; \ 64 | } while (0) 65 | 66 | #define ARRAY_SET(a, i, s) do { \ 67 | (a)->list[i] = s; \ 68 | } while (0) 69 | 70 | #define ARRAY_ADD(a, s) do { \ 71 | ARRAY_ENSURE(a, 1); \ 72 | (a)->list[(a)->num] = s; \ 73 | (a)->num++; \ 74 | } while (0) 75 | #define ARRAY_INSERT(a, i, s) do { \ 76 | ARRAY_ENSURE(a, 1); \ 77 | if ((i) < (a)->num) { \ 78 | memmove((a)->list + (i) + 1, (a)->list + (i), \ 79 | ARRAY_ITEMSIZE(a) * ((a)->num - (i))); \ 80 | } \ 81 | (a)->list[i] = s; \ 82 | (a)->num++; \ 83 | } while (0) 84 | #define ARRAY_REMOVE(a, i) do { \ 85 | if ((i) < (a)->num - 1) { \ 86 | memmove((a)->list + (i), (a)->list + (i) + 1, \ 87 | ARRAY_ITEMSIZE(a) * ((a)->num - (i) - 1)); \ 88 | } \ 89 | (a)->num--; \ 90 | if ((a)->num == 0) \ 91 | ARRAY_FREE(a); \ 92 | } while (0) 93 | 94 | #define ARRAY_EXPAND(a, n) do { \ 95 | ARRAY_ENSURE(a, n); \ 96 | (a)->num += n; \ 97 | } while (0) 98 | #define ARRAY_TRUNC(a, n) do { \ 99 | if ((a)->num > n) \ 100 | (a)->num -= n; \ 101 | else \ 102 | ARRAY_FREE(a); \ 103 | } while (0) 104 | 105 | #define ARRAY_CONCAT(a, b) do { \ 106 | ARRAY_ENSURE(a, (b)->num); \ 107 | memcpy((a)->list + (a)->num, (b)->list, (b)->num * ARRAY_ITEMSIZE(a)); \ 108 | (a)->num += (b)->num; \ 109 | } while (0) 110 | 111 | #define ARRAY_FREE(a) do { \ 112 | free((a)->list); \ 113 | ARRAY_INIT(a); \ 114 | } while (0) 115 | #define ARRAY_FREEALL(a) do { \ 116 | ARRAY_FREE(a); \ 117 | free(a); \ 118 | } while (0) 119 | 120 | #endif 121 | --------------------------------------------------------------------------------