├── .github ├── FUNDING.yml └── workflows │ ├── DragonflyBSD.yml │ ├── FreeBSD.yml │ ├── MacOS.yml │ ├── NetBSD.yml │ ├── OpenBSD.yml │ └── Ubuntu.yml ├── .gitignore ├── .mailmap ├── .travis.yml ├── CHANGES ├── COPYING ├── Dockerfile ├── FAQ ├── Makefile.am ├── README ├── README-tmux ├── README.md ├── SYNCING ├── TODO ├── alerts.c ├── arguments.c ├── array.h ├── attributes.c ├── autogen.sh ├── build_static_release.sh ├── cfg.c ├── client.c ├── cmd-attach-session.c ├── cmd-bind-key.c ├── cmd-break-pane.c ├── cmd-capture-pane.c ├── cmd-choose-buffer.c ├── cmd-choose-client.c ├── cmd-choose-tree.c ├── cmd-clear-history.c ├── cmd-command-prompt.c ├── cmd-confirm-before.c ├── cmd-copy-mode.c ├── cmd-detach-client.c ├── cmd-display-message.c ├── cmd-display-panes.c ├── cmd-find-window.c ├── cmd-find.c ├── cmd-if-shell.c ├── cmd-join-pane.c ├── cmd-kill-pane.c ├── cmd-kill-server.c ├── cmd-kill-session.c ├── cmd-kill-window.c ├── cmd-list-buffers.c ├── cmd-list-clients.c ├── cmd-list-keys.c ├── cmd-list-panes.c ├── cmd-list-sessions.c ├── cmd-list-windows.c ├── cmd-list.c ├── cmd-load-buffer.c ├── cmd-lock-server.c ├── cmd-move-window.c ├── cmd-new-session.c ├── cmd-new-window.c ├── cmd-paste-buffer.c ├── cmd-pipe-pane.c ├── cmd-queue.c ├── cmd-refresh-client.c ├── cmd-rename-session.c ├── cmd-rename-window.c ├── cmd-resize-pane.c ├── cmd-respawn-pane.c ├── cmd-respawn-window.c ├── cmd-rotate-window.c ├── cmd-run-shell.c ├── cmd-save-buffer.c ├── cmd-select-layout.c ├── cmd-select-pane.c ├── cmd-select-window.c ├── cmd-send-keys.c ├── cmd-set-buffer.c ├── cmd-set-environment.c ├── cmd-set-hook.c ├── cmd-set-option.c ├── cmd-show-environment.c ├── cmd-show-messages.c ├── cmd-show-options.c ├── cmd-source-file.c ├── cmd-split-window.c ├── cmd-string.c ├── cmd-swap-pane.c ├── cmd-swap-window.c ├── cmd-switch-client.c ├── cmd-unbind-key.c ├── cmd-wait-for.c ├── cmd.c ├── colour.c ├── compat.h ├── compat ├── asprintf.c ├── b64_ntop.c ├── bitstring.h ├── cfmakeraw.c ├── closefrom.c ├── daemon.c ├── fgetln.c ├── forkpty-aix.c ├── forkpty-hpux.c ├── forkpty-sunos.c ├── fparseln.c ├── getopt.c ├── imsg-buffer.c ├── imsg.c ├── imsg.h ├── openat.c ├── queue.h ├── reallocarray.c ├── setenv.c ├── strcasestr.c ├── strlcat.c ├── strlcpy.c ├── strsep.c ├── strtonum.c ├── tree.h ├── unvis.c ├── vis.c └── vis.h ├── configure.ac ├── control-notify.c ├── control.c ├── environ.c ├── example_tmux.conf ├── format.c ├── grid-view.c ├── grid.c ├── hooks.c ├── input-keys.c ├── input.c ├── job.c ├── key-bindings.c ├── key-string.c ├── layout-custom.c ├── layout-set.c ├── layout.c ├── log.c ├── logo ├── LICENSE ├── favicon.ico ├── tmux-logo-1-color.eps ├── tmux-logo-1-color.svg ├── tmux-logo-huge.png ├── tmux-logo-large.png ├── tmux-logo-medium.png ├── tmux-logo-small.png ├── tmux-logo.eps ├── tmux-logo.svg ├── tmux-logomark.eps └── tmux-logomark.svg ├── mdoc2man.awk ├── mode-key.c ├── names.c ├── notify.c ├── options-table.c ├── options.c ├── osdep-aix.c ├── osdep-cygwin.c ├── osdep-darwin.c ├── osdep-dragonfly.c ├── osdep-freebsd.c ├── osdep-hpux.c ├── osdep-linux.c ├── osdep-netbsd.c ├── osdep-openbsd.c ├── osdep-sunos.c ├── osdep-unknown.c ├── paste.c ├── presentations ├── tmux_asiabsdcon11.odt ├── tmux_asiabsdcon11.pdf └── tmux_linuxtag_2011.odp ├── proc.c ├── resize.c ├── screen-redraw.c ├── screen-write.c ├── screen.c ├── server-client.c ├── server-fn.c ├── server.c ├── session.c ├── signal.c ├── status.c ├── style.c ├── tmate-debug.c ├── tmate-decoder.c ├── tmate-encoder.c ├── tmate-env.c ├── tmate-msg.c ├── tmate-msgpack.c ├── tmate-protocol.h ├── tmate-session.c ├── tmate-ssh-client.c ├── tmate.1 ├── tmate.h ├── tmux.1 ├── tmux.c ├── tmux.h ├── tools ├── 256colors.pl ├── UTF-8-demo.txt ├── ansicode.txt └── cmp-cvs.sh ├── tty-acs.c ├── tty-keys.c ├── tty-term.c ├── tty.c ├── utf8.c ├── window-choose.c ├── window-clock.c ├── window-copy.c ├── window-copy.h ├── window.c ├── xmalloc.c ├── xmalloc.h └── xterm-keys.c /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: nviennot 2 | -------------------------------------------------------------------------------- /.github/workflows/DragonflyBSD.yml: -------------------------------------------------------------------------------- 1 | name: DragonflyBSD 2 | on: 3 | push: 4 | branches: 5 | - '*' 6 | paths: 7 | - '**.c' 8 | - '**.h' 9 | - 'compat/*' 10 | - '.github/workflows/DragonflyBSD.yml' 11 | pull_request: 12 | branches: 13 | - '*' 14 | paths: 15 | - '**.c' 16 | - '**.h' 17 | - 'compat/*' 18 | - '.github/workflows/DragonflyBSD.yml' 19 | 20 | 21 | 22 | jobs: 23 | DragonflyBSD: 24 | runs-on: macos-12 25 | steps: 26 | - uses: actions/checkout@v2 27 | - uses: vmactions/dragonflybsd-vm@v0 28 | with: 29 | prepare: | 30 | pkg install -y automake autoconf libtool pkgconf libevent msgpack libssh gsed 31 | usesh: true 32 | run: | 33 | gsed -i "s/OK/0/g" tty-term.c 34 | autoupdate 35 | ./autogen.sh 36 | ./configure 37 | make 38 | make install 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /.github/workflows/FreeBSD.yml: -------------------------------------------------------------------------------- 1 | name: FreeBSD 2 | on: 3 | push: 4 | branches: 5 | - '*' 6 | paths: 7 | - '**.c' 8 | - '**.h' 9 | - 'compat/*' 10 | - '.github/workflows/FreeBSD.yml' 11 | pull_request: 12 | branches: 13 | - '*' 14 | paths: 15 | - '**.c' 16 | - '**.h' 17 | - 'compat/*' 18 | - '.github/workflows/FreeBSD.yml' 19 | 20 | 21 | 22 | jobs: 23 | FreeBSD: 24 | runs-on: macos-12 25 | steps: 26 | - uses: actions/checkout@v2 27 | - uses: vmactions/freebsd-vm@v0 28 | with: 29 | prepare: | 30 | pkg install -y automake autoconf libtool pkgconf libevent msgpack libssh 31 | usesh: true 32 | run: | 33 | autoupdate 34 | ./autogen.sh 35 | ./configure 36 | make 37 | make install 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /.github/workflows/MacOS.yml: -------------------------------------------------------------------------------- 1 | name: MacOS 2 | on: 3 | push: 4 | branches: 5 | - '*' 6 | paths: 7 | - '**.c' 8 | - '**.h' 9 | - 'compat/*' 10 | - '.github/workflows/MacOS.yml' 11 | pull_request: 12 | branches: 13 | - '*' 14 | paths: 15 | - '**.c' 16 | - '**.h' 17 | - 'compat/*' 18 | - '.github/workflows/MacOS.yml' 19 | 20 | 21 | 22 | jobs: 23 | MacOS: 24 | runs-on: macos-latest 25 | steps: 26 | - uses: actions/checkout@v2 27 | - run: | 28 | brew install automake msgpack libssh 29 | autoupdate 30 | ./autogen.sh 31 | ./configure 32 | make 33 | make install 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /.github/workflows/NetBSD.yml: -------------------------------------------------------------------------------- 1 | name: NetBSD 2 | on: 3 | push: 4 | branches: 5 | - '*' 6 | paths: 7 | - '**.c' 8 | - '**.h' 9 | - 'compat/*' 10 | - '.github/workflows/NetBSD.yml' 11 | pull_request: 12 | branches: 13 | - '*' 14 | paths: 15 | - '**.c' 16 | - '**.h' 17 | - 'compat/*' 18 | - '.github/workflows/NetBSD.yml' 19 | 20 | 21 | 22 | jobs: 23 | NetBSD: 24 | runs-on: macos-12 25 | steps: 26 | - uses: actions/checkout@v2 27 | - uses: vmactions/netbsd-vm@v0 28 | with: 29 | prepare: | 30 | pkg_add automake autoconf libtool pkgconf libevent msgpack libssh 31 | usesh: true 32 | run: | 33 | autoupdate 34 | ./autogen.sh 35 | ./configure 36 | make 37 | make install 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /.github/workflows/OpenBSD.yml: -------------------------------------------------------------------------------- 1 | name: OpenBSD 2 | on: 3 | push: 4 | branches: 5 | - '*' 6 | paths: 7 | - '**.c' 8 | - '**.h' 9 | - 'compat/*' 10 | - '.github/workflows/OpenBSD.yml' 11 | pull_request: 12 | branches: 13 | - '*' 14 | paths: 15 | - '**.c' 16 | - '**.h' 17 | - 'compat/*' 18 | - '.github/workflows/OpenBSD.yml' 19 | 20 | 21 | 22 | jobs: 23 | OpenBSD: 24 | runs-on: macos-12 25 | steps: 26 | - uses: actions/checkout@v2 27 | - uses: vmactions/openbsd-vm@v0 28 | with: 29 | prepare: | 30 | pkg_add automake-1.16.3 autoconf-2.71 libtool pkgconf libevent msgpack libssh curl 31 | usesh: true 32 | run: | 33 | sed -i 's,,,' *.[ch] 34 | curl https://raw.githubusercontent.com/openbsd/ports/master/sysutils/tmate/patches/patch-Makefile_am | patch 35 | curl https://raw.githubusercontent.com/openbsd/ports/master/sysutils/tmate/patches/patch-server_c | patch 36 | curl https://raw.githubusercontent.com/openbsd/ports/master/sysutils/tmate/patches/patch-tmate-debug_c | patch 37 | curl https://raw.githubusercontent.com/openbsd/ports/master/sysutils/tmate/patches/patch-tmate_h | patch 38 | curl https://raw.githubusercontent.com/openbsd/ports/master/sysutils/tmate/patches/patch-tmux_c | patch 39 | curl https://raw.githubusercontent.com/openbsd/ports/master/sysutils/tmate/patches/patch-tmux_h | patch 40 | curl https://raw.githubusercontent.com/openbsd/ports/master/sysutils/tmate/patches/patch-osdep-openbsd_c | patch 41 | export AUTOMAKE_VERSION=1.16 42 | export AUTOCONF_VERSION=2.71 43 | autoupdate 44 | ./autogen.sh 45 | ./configure 46 | make 47 | make install 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /.github/workflows/Ubuntu.yml: -------------------------------------------------------------------------------- 1 | name: Ubuntu 2 | on: 3 | push: 4 | branches: 5 | - '*' 6 | paths: 7 | - '**.c' 8 | - '**.h' 9 | - 'compat/*' 10 | - '.github/workflows/Ubuntu.yml' 11 | pull_request: 12 | branches: 13 | - '*' 14 | paths: 15 | - '**.c' 16 | - '**.h' 17 | - 'compat/*' 18 | - '.github/workflows/Ubuntu.yml' 19 | 20 | 21 | 22 | jobs: 23 | Ubuntu: 24 | runs-on: ubuntu-latest 25 | steps: 26 | - uses: actions/checkout@v2 27 | - run: | 28 | sudo apt-get install -y build-essential automake libtool libevent-dev libncurses5-dev libmsgpack-dev libssh-dev pkg-config 29 | autoupdate 30 | ACLOCAL_PATH=/usr/share/aclocal ./autogen.sh 31 | ./configure 32 | make 33 | sudo make install 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /.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 | tmate 20 | cscope.* 21 | ctags 22 | *.log 23 | tmate.1.* 24 | downloads/ 25 | ext/ 26 | libssh-*/ 27 | msgpack-*/ 28 | releases/ 29 | -------------------------------------------------------------------------------- /.mailmap: -------------------------------------------------------------------------------- 1 | Bob Beck beck 2 | Claudio Jeker claudio 3 | Igor Sobrado sobrado 4 | Ingo Schwarze schwarze 5 | Jacek Masiulaniec jacekm 6 | Jason McIntyre jmc 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 | Michael McConville mmcc 15 | Miod Vallat miod 16 | Nicholas Marriott Nicholas Marriott 17 | Nicholas Marriott nicm 18 | Nicholas Marriott no_author 19 | Okan Demirmen okan 20 | Philip Guenther guenther 21 | Pierre-Yves Ritschard pyr 22 | Ray Lai ray 23 | Ryan McBride mcbride 24 | Sebastian Benoit benno 25 | Stefan Sperling stsp 26 | Stuart Henderson sthen 27 | Ted Unangst tedu 28 | Theo de Raadt Theo Deraadt 29 | Theo de Raadt deraadt 30 | Thomas Adam Thomas 31 | Thomas Adam Thomas Adam 32 | Thomas Adam n6tadam 33 | Tim van der Molen tim 34 | Tobias Stoeckmann tobias 35 | Todd C Miller millert 36 | William Yodlowsky william 37 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: c 2 | services: 3 | - docker 4 | 5 | matrix: 6 | include: 7 | - arch: amd64 8 | env: PLATFORM=amd64 9 | - arch: amd64 10 | env: PLATFORM=i386 11 | - arch: arm64 12 | env: PLATFORM=arm32v6 13 | - arch: arm64 14 | env: PLATFORM=arm32v7 15 | - arch: arm64 16 | env: PLATFORM=arm64v8 17 | - arch: s390x 18 | env: PLATFORM=s390x 19 | - arch: ppc64le 20 | env: PLATFORM=ppc64le 21 | 22 | script: 23 | - 'docker build . --tag local-$PLATFORM/tmate-build --build-arg PLATFORM=$PLATFORM' 24 | # On arch=arm64, some directories are not setup correctly, and 'ruby -S gem 25 | # install dpl' required by the release push scripts fails. 26 | - 'if [ "$TRAVIS_TAG" ]; then sudo chown -R $USER: /var/lib/gems /usr/local/bin; fi' 27 | - 'if [ "$TRAVIS_TAG" ]; then ./build_static_release.sh $TRAVIS_TAG $PLATFORM; fi' 28 | 29 | deploy: 30 | provider: releases 31 | api_key: 32 | secure: T2109tjjOsrVLEpJZK/uxmO0AuDGXYFdN4AAsNTmVwu/W5dcX57Kk2TCgqDuLfD21iGGXP0U/OYHM06IfBDODBWCA9P8ASHYsenS7wIiFnvCEMbfzoAFyBMrXN2kNdM2+ho3aqc0xE2lQKOKDLxpGm5FZrzujscXXzxQjWBU5Hk= 33 | skip_cleanup: true 34 | overwrite: true 35 | file_glob: true 36 | file: releases/*.tar.* 37 | on: 38 | repo: tmate-io/tmate 39 | branch: master 40 | tags: true 41 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | ARG PLATFORM=amd64 2 | FROM ${PLATFORM}/alpine:3.10 AS build 3 | 4 | WORKDIR /build 5 | 6 | RUN apk add --no-cache wget cmake make gcc g++ linux-headers zlib-dev openssl-dev \ 7 | automake autoconf libevent-dev ncurses-dev msgpack-c-dev libexecinfo-dev \ 8 | ncurses-static libexecinfo-static libevent-static msgpack-c ncurses-libs \ 9 | libevent libexecinfo openssl zlib 10 | 11 | RUN set -ex; \ 12 | mkdir -p /src/libssh/build; \ 13 | cd /src; \ 14 | wget -O libssh.tar.xz https://www.libssh.org/files/0.9/libssh-0.9.0.tar.xz; \ 15 | tar -xf libssh.tar.xz -C /src/libssh --strip-components=1; \ 16 | cd /src/libssh/build; \ 17 | cmake -DCMAKE_INSTALL_PREFIX:PATH=/usr \ 18 | -DWITH_SFTP=OFF -DWITH_SERVER=OFF -DWITH_PCAP=OFF \ 19 | -DWITH_STATIC_LIB=ON -DWITH_GSSAPI=OFF ..; \ 20 | make -j $(nproc); \ 21 | make install 22 | 23 | COPY compat ./compat 24 | COPY *.c *.h autogen.sh Makefile.am configure.ac ./ 25 | 26 | RUN ./autogen.sh && ./configure --enable-static 27 | RUN make -j $(nproc) 28 | RUN objcopy --only-keep-debug tmate tmate.symbols && chmod -x tmate.symbols && strip tmate 29 | RUN ./tmate -V 30 | 31 | FROM alpine:3.9 32 | 33 | RUN apk --no-cache add bash 34 | RUN mkdir /build 35 | ENV PATH=/build:$PATH 36 | COPY --from=build /build/tmate.symbols /build 37 | COPY --from=build /build/tmate /build 38 | -------------------------------------------------------------------------------- /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://libevent.org 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 an example configuration in example_tmux.conf. 37 | 38 | A vim(1) syntax file is available at: 39 | 40 | https://github.com/keith/tmux.vim 41 | https://raw.githubusercontent.com/keith/tmux.vim/master/syntax/tmux.vim 42 | 43 | And a bash(1) completion file at: 44 | 45 | https://github.com/przepompownia/tmux-bash-completion 46 | 47 | For debugging, running tmux with -v or -vv will generate server and client log 48 | files in the current directory. 49 | 50 | tmux mailing lists are available. For general discussion and bug reports: 51 | 52 | https://groups.google.com/forum/#!forum/tmux-users 53 | 54 | And for Git commit emails: 55 | 56 | https://groups.google.com/forum/#!forum/tmux-git 57 | 58 | Bug reports, feature suggestions and especially code contributions are most 59 | welcome. Please send by email to: 60 | 61 | tmux-users@googlegroups.com 62 | 63 | This file and the CHANGES, FAQ, SYNCING and TODO files are licensed under the 64 | ISC license. All other files have a license and copyright notice at their start. 65 | 66 | -- Nicholas Marriott 67 | -------------------------------------------------------------------------------- /README-tmux: -------------------------------------------------------------------------------- 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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | tmate 2 | ===== 3 | 4 | What is it? 5 | ----------- 6 | 7 | Tmate is a fork of tmux. It provides an instant pairing solution. 8 | 9 | License 10 | ------- 11 | 12 | tmate is built on top of tmux. tmux and tmate are BSD-licensed. 13 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /build_static_release.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -eux 3 | 4 | # This is invoked by .travis.yml 5 | 6 | VERSION=$1 7 | PLATFORM=$2 8 | 9 | SRC_VERSION=`cat configure.ac | grep AC_INIT | sed -E 's/^AC_INIT\(tmate, (.+)\)$/\1/'` 10 | 11 | if [ $SRC_VERSION != $VERSION ]; then 12 | echo "Version mismatch: $SRC_VERSION != $VERSION" 13 | exit 1 14 | fi 15 | 16 | RELEASE_NAME=tmate-$VERSION-static-linux-$PLATFORM 17 | echo "Building $RELEASE_NAME" 18 | 19 | docker build . --tag local-$PLATFORM/tmate-build --build-arg PLATFORM=$PLATFORM 20 | 21 | mkdir -p releases 22 | cd releases 23 | 24 | rm -rf $RELEASE_NAME 25 | mkdir -p $RELEASE_NAME 26 | docker run --rm local-$PLATFORM/tmate-build cat /build/tmate > $RELEASE_NAME/tmate 27 | chmod +x $RELEASE_NAME/tmate 28 | tar -cf - $RELEASE_NAME | xz > tmate-$VERSION-static-linux-$PLATFORM.tar.xz 29 | 30 | rm -rf $RELEASE_NAME-symbols 31 | mkdir -p $RELEASE_NAME-symbols 32 | docker run --rm local-$PLATFORM/tmate-build cat /build/tmate.symbols > $RELEASE_NAME-symbols/tmate.symbols 33 | tar -cf - $RELEASE_NAME-symbols | xz > dbg-symbols-tmate-$VERSION-static-linux-$PLATFORM.tar.xz 34 | -------------------------------------------------------------------------------- /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 | .name = "break-pane", 35 | .alias = "breakp", 36 | 37 | .args = { "dPF:s:t:", 0, 0 }, 38 | .usage = "[-dP] [-F format] [-s src-pane] [-t dst-window]", 39 | 40 | .sflag = CMD_PANE, 41 | .tflag = CMD_WINDOW_INDEX, 42 | 43 | .flags = 0, 44 | .exec = cmd_break_pane_exec 45 | }; 46 | 47 | enum cmd_retval 48 | cmd_break_pane_exec(struct cmd *self, struct cmd_q *cmdq) 49 | { 50 | #ifdef TMATE 51 | cmdq_error(cmdq, "break pane is not supported with tmate"); 52 | return (CMD_RETURN_ERROR); 53 | #else 54 | struct args *args = self->args; 55 | struct winlink *wl = cmdq->state.sflag.wl; 56 | struct session *src_s = cmdq->state.sflag.s; 57 | struct session *dst_s = cmdq->state.tflag.s; 58 | struct window_pane *wp = cmdq->state.sflag.wp; 59 | struct window *w = wl->window; 60 | char *name; 61 | char *cause; 62 | int idx = cmdq->state.tflag.idx; 63 | struct format_tree *ft; 64 | const char *template; 65 | char *cp; 66 | 67 | if (idx != -1 && winlink_find_by_index(&dst_s->windows, idx) != NULL) { 68 | cmdq_error(cmdq, "index %d already in use", idx); 69 | return (CMD_RETURN_ERROR); 70 | } 71 | 72 | if (window_count_panes(w) == 1) { 73 | cmdq_error(cmdq, "can't break with only one pane"); 74 | return (CMD_RETURN_ERROR); 75 | } 76 | server_unzoom_window(w); 77 | 78 | TAILQ_REMOVE(&w->panes, wp, entry); 79 | window_lost_pane(w, wp); 80 | layout_close_pane(wp); 81 | 82 | w = wp->window = window_create1(dst_s->sx, dst_s->sy); 83 | TAILQ_INSERT_HEAD(&w->panes, wp, entry); 84 | w->active = wp; 85 | name = default_window_name(w); 86 | window_set_name(w, name); 87 | free(name); 88 | layout_init(w, wp); 89 | wp->flags |= PANE_CHANGED; 90 | 91 | if (idx == -1) 92 | idx = -1 - options_get_number(dst_s->options, "base-index"); 93 | wl = session_attach(dst_s, w, idx, &cause); /* can't fail */ 94 | if (!args_has(self->args, 'd')) 95 | session_select(dst_s, wl->idx); 96 | 97 | server_redraw_session(src_s); 98 | if (src_s != dst_s) 99 | server_redraw_session(dst_s); 100 | server_status_session_group(src_s); 101 | if (src_s != dst_s) 102 | server_status_session_group(dst_s); 103 | 104 | if (args_has(args, 'P')) { 105 | if ((template = args_get(args, 'F')) == NULL) 106 | template = BREAK_PANE_TEMPLATE; 107 | 108 | ft = format_create(cmdq, 0); 109 | format_defaults(ft, cmdq->state.c, dst_s, wl, wp); 110 | 111 | cp = format_expand(ft, template); 112 | cmdq_print(cmdq, "%s", cp); 113 | free(cp); 114 | 115 | format_free(ft); 116 | } 117 | return (CMD_RETURN_NORMAL); 118 | #endif 119 | } 120 | -------------------------------------------------------------------------------- /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 | .name = "choose-buffer", 37 | .alias = NULL, 38 | 39 | .args = { "F:t:", 0, 1 }, 40 | .usage = CMD_TARGET_WINDOW_USAGE " [-F format] [template]", 41 | 42 | .tflag = CMD_WINDOW, 43 | 44 | .flags = 0, 45 | .exec = cmd_choose_buffer_exec 46 | }; 47 | 48 | enum cmd_retval 49 | cmd_choose_buffer_exec(struct cmd *self, struct cmd_q *cmdq) 50 | { 51 | struct args *args = self->args; 52 | struct client *c = cmdq->state.c; 53 | struct winlink *wl = cmdq->state.tflag.wl; 54 | struct window_choose_data *cdata; 55 | struct paste_buffer *pb; 56 | char *action, *action_data; 57 | const char *template; 58 | u_int idx; 59 | 60 | if (c == NULL) { 61 | cmdq_error(cmdq, "no client available"); 62 | return (CMD_RETURN_ERROR); 63 | } 64 | 65 | if ((template = args_get(args, 'F')) == NULL) 66 | template = CHOOSE_BUFFER_TEMPLATE; 67 | 68 | if (paste_get_top(NULL) == 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); 87 | 88 | xasprintf(&action_data, "%s", paste_buffer_name(pb)); 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 | -------------------------------------------------------------------------------- /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 #{t:client_activity})" 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 | .name = "choose-client", 42 | .alias = NULL, 43 | 44 | .args = { "F:t:", 0, 1 }, 45 | .usage = CMD_TARGET_WINDOW_USAGE " [-F format] [template]", 46 | 47 | .tflag = CMD_WINDOW, 48 | 49 | .flags = 0, 50 | .exec = cmd_choose_client_exec 51 | }; 52 | 53 | struct cmd_choose_client_data { 54 | struct client *client; 55 | }; 56 | 57 | enum cmd_retval 58 | cmd_choose_client_exec(struct cmd *self, struct cmd_q *cmdq) 59 | { 60 | struct args *args = self->args; 61 | struct client *c = cmdq->state.c; 62 | struct client *c1; 63 | struct window_choose_data *cdata; 64 | struct winlink *wl = cmdq->state.tflag.wl; 65 | const char *template; 66 | char *action; 67 | u_int idx, cur; 68 | 69 | if (c == NULL) { 70 | cmdq_error(cmdq, "no client available"); 71 | return (CMD_RETURN_ERROR); 72 | } 73 | 74 | if (window_pane_set_mode(wl->window->active, &window_choose_mode) != 0) 75 | return (CMD_RETURN_NORMAL); 76 | 77 | if ((template = args_get(args, 'F')) == NULL) 78 | template = CHOOSE_CLIENT_TEMPLATE; 79 | 80 | if (args->argc != 0) 81 | action = xstrdup(args->argv[0]); 82 | else 83 | action = xstrdup("detach-client -t '%%'"); 84 | 85 | cur = idx = 0; 86 | TAILQ_FOREACH(c1, &clients, entry) { 87 | if (c1->session == NULL || c1->tty.path == NULL) 88 | continue; 89 | if (c1 == cmdq->client) 90 | cur = idx; 91 | 92 | cdata = window_choose_data_create(TREE_OTHER, c, c->session); 93 | cdata->idx = idx; 94 | 95 | cdata->ft_template = xstrdup(template); 96 | format_add(cdata->ft, "line", "%u", idx); 97 | format_defaults(cdata->ft, c1, NULL, NULL, NULL); 98 | 99 | cdata->command = cmd_template_replace(action, c1->tty.path, 1); 100 | 101 | window_choose_add(wl->window->active, cdata); 102 | 103 | idx++; 104 | } 105 | free(action); 106 | 107 | window_choose_ready(wl->window->active, cur, 108 | cmd_choose_client_callback); 109 | 110 | return (CMD_RETURN_NORMAL); 111 | } 112 | 113 | void 114 | cmd_choose_client_callback(struct window_choose_data *cdata) 115 | { 116 | struct client *c; 117 | u_int idx; 118 | 119 | if (cdata == NULL) 120 | return; 121 | if (cdata->start_client->flags & CLIENT_DEAD) 122 | return; 123 | 124 | idx = 0; 125 | TAILQ_FOREACH(c, &clients, entry) { 126 | if (idx == cdata->idx) 127 | break; 128 | idx++; 129 | } 130 | if (c == NULL || c->session == NULL) 131 | return; 132 | 133 | window_choose_data_run(cdata); 134 | } 135 | -------------------------------------------------------------------------------- /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 | .name = "clear-history", 31 | .alias = "clearhist", 32 | 33 | .args = { "t:", 0, 0 }, 34 | .usage = CMD_TARGET_PANE_USAGE, 35 | 36 | .tflag = CMD_PANE, 37 | 38 | .flags = 0, 39 | .exec = cmd_clear_history_exec 40 | }; 41 | 42 | enum cmd_retval 43 | cmd_clear_history_exec(__unused struct cmd *self, struct cmd_q *cmdq) 44 | { 45 | struct window_pane *wp = cmdq->state.tflag.wp; 46 | struct grid *gd; 47 | 48 | gd = cmdq->state.tflag.wp->base.grid; 49 | 50 | if (wp->mode == &window_copy_mode) 51 | window_pane_reset_mode(wp); 52 | grid_clear_history(gd); 53 | 54 | return (CMD_RETURN_NORMAL); 55 | } 56 | -------------------------------------------------------------------------------- /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 | .name = "confirm-before", 38 | .alias = "confirm", 39 | 40 | .args = { "p:t:", 1, 1 }, 41 | .usage = "[-p prompt] " CMD_TARGET_CLIENT_USAGE " command", 42 | 43 | .tflag = CMD_CLIENT, 44 | 45 | .flags = 0, 46 | .exec = cmd_confirm_before_exec 47 | }; 48 | 49 | struct cmd_confirm_before_data { 50 | char *cmd; 51 | struct client *client; 52 | }; 53 | 54 | enum cmd_retval 55 | cmd_confirm_before_exec(struct cmd *self, struct cmd_q *cmdq) 56 | { 57 | struct args *args = self->args; 58 | struct cmd_confirm_before_data *cdata; 59 | struct client *c = cmdq->state.c; 60 | char *cmd, *copy, *new_prompt, *ptr; 61 | const char *prompt; 62 | 63 | if ((prompt = args_get(args, 'p')) != NULL) 64 | xasprintf(&new_prompt, "%s ", prompt); 65 | else { 66 | ptr = copy = xstrdup(args->argv[0]); 67 | cmd = strsep(&ptr, " \t"); 68 | xasprintf(&new_prompt, "Confirm '%s'? (y/n) ", cmd); 69 | free(copy); 70 | } 71 | 72 | cdata = xmalloc(sizeof *cdata); 73 | cdata->cmd = xstrdup(args->argv[0]); 74 | 75 | cdata->client = c; 76 | cdata->client->references++; 77 | 78 | status_prompt_set(c, new_prompt, NULL, 79 | cmd_confirm_before_callback, cmd_confirm_before_free, cdata, 80 | PROMPT_SINGLE); 81 | 82 | free(new_prompt); 83 | return (CMD_RETURN_NORMAL); 84 | } 85 | 86 | int 87 | cmd_confirm_before_callback(void *data, const char *s) 88 | { 89 | struct cmd_confirm_before_data *cdata = data; 90 | struct client *c = cdata->client; 91 | struct cmd_list *cmdlist; 92 | char *cause; 93 | 94 | if (c->flags & CLIENT_DEAD) 95 | return (0); 96 | 97 | if (s == NULL || *s == '\0') 98 | return (0); 99 | if (tolower((u_char) s[0]) != 'y' || s[1] != '\0') 100 | return (0); 101 | 102 | if (cmd_string_parse(cdata->cmd, &cmdlist, NULL, 0, &cause) != 0) { 103 | if (cause != NULL) { 104 | cmdq_error(c->cmdq, "%s", cause); 105 | free(cause); 106 | } 107 | return (0); 108 | } 109 | 110 | cmdq_run(c->cmdq, cmdlist, NULL); 111 | cmd_list_free(cmdlist); 112 | 113 | return (0); 114 | } 115 | 116 | void 117 | cmd_confirm_before_free(void *data) 118 | { 119 | struct cmd_confirm_before_data *cdata = data; 120 | struct client *c = cdata->client; 121 | 122 | server_client_unref(c); 123 | 124 | free(cdata->cmd); 125 | free(cdata); 126 | } 127 | -------------------------------------------------------------------------------- /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 | .name = "copy-mode", 31 | .alias = NULL, 32 | 33 | .args = { "Met:u", 0, 0 }, 34 | .usage = "[-Mu] " CMD_TARGET_PANE_USAGE, 35 | 36 | .tflag = CMD_PANE, 37 | 38 | .flags = 0, 39 | .exec = cmd_copy_mode_exec 40 | }; 41 | 42 | const struct cmd_entry cmd_clock_mode_entry = { 43 | .name = "clock-mode", 44 | .alias = NULL, 45 | 46 | .args = { "t:", 0, 0 }, 47 | .usage = CMD_TARGET_PANE_USAGE, 48 | 49 | .tflag = CMD_PANE, 50 | 51 | .flags = 0, 52 | .exec = cmd_copy_mode_exec 53 | }; 54 | 55 | enum cmd_retval 56 | cmd_copy_mode_exec(struct cmd *self, struct cmd_q *cmdq) 57 | { 58 | struct args *args = self->args; 59 | struct client *c = cmdq->client; 60 | struct session *s; 61 | struct window_pane *wp = cmdq->state.tflag.wp; 62 | 63 | if (args_has(args, 'M')) { 64 | if ((wp = cmd_mouse_pane(&cmdq->item->mouse, &s, NULL)) == NULL) 65 | return (CMD_RETURN_NORMAL); 66 | if (c == NULL || c->session != s) 67 | return (CMD_RETURN_NORMAL); 68 | } 69 | 70 | if (self->entry == &cmd_clock_mode_entry) { 71 | window_pane_set_mode(wp, &window_clock_mode); 72 | return (CMD_RETURN_NORMAL); 73 | } 74 | 75 | if (wp->mode != &window_copy_mode) { 76 | if (window_pane_set_mode(wp, &window_copy_mode) != 0) 77 | return (CMD_RETURN_NORMAL); 78 | window_copy_init_from_pane(wp, args_has(self->args, 'e')); 79 | } 80 | if (args_has(args, 'M')) { 81 | if (wp->mode != NULL && wp->mode != &window_copy_mode) 82 | return (CMD_RETURN_NORMAL); 83 | window_copy_start_drag(c, &cmdq->item->mouse); 84 | } 85 | if (wp->mode == &window_copy_mode && args_has(self->args, 'u')) 86 | window_copy_pageup(wp); 87 | 88 | return (CMD_RETURN_NORMAL); 89 | } 90 | -------------------------------------------------------------------------------- /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 | .name = "detach-client", 33 | .alias = "detach", 34 | 35 | .args = { "as:t:P", 0, 0 }, 36 | .usage = "[-P] [-a] [-s target-session] " CMD_TARGET_CLIENT_USAGE, 37 | 38 | .sflag = CMD_SESSION, 39 | .tflag = CMD_CLIENT, 40 | 41 | .flags = CMD_READONLY, 42 | .exec = cmd_detach_client_exec 43 | }; 44 | 45 | const struct cmd_entry cmd_suspend_client_entry = { 46 | .name = "suspend-client", 47 | .alias = "suspendc", 48 | 49 | .args = { "t:", 0, 0 }, 50 | .usage = CMD_TARGET_CLIENT_USAGE, 51 | 52 | .tflag = CMD_CLIENT, 53 | 54 | .flags = 0, 55 | .exec = cmd_detach_client_exec 56 | }; 57 | 58 | enum cmd_retval 59 | cmd_detach_client_exec(struct cmd *self, struct cmd_q *cmdq) 60 | { 61 | struct args *args = self->args; 62 | struct client *c = cmdq->state.c, *cloop; 63 | struct session *s; 64 | enum msgtype msgtype; 65 | 66 | if (self->entry == &cmd_suspend_client_entry) { 67 | tty_stop_tty(&c->tty); 68 | c->flags |= CLIENT_SUSPENDED; 69 | proc_send(c->peer, MSG_SUSPEND, -1, NULL, 0); 70 | return (CMD_RETURN_NORMAL); 71 | } 72 | 73 | if (args_has(args, 'P')) 74 | msgtype = MSG_DETACHKILL; 75 | else 76 | msgtype = MSG_DETACH; 77 | 78 | if (args_has(args, 's')) { 79 | s = cmdq->state.sflag.s; 80 | TAILQ_FOREACH(cloop, &clients, entry) { 81 | if (cloop->session == s) 82 | server_client_detach(cloop, msgtype); 83 | } 84 | return (CMD_RETURN_STOP); 85 | } 86 | 87 | if (args_has(args, 'a')) { 88 | TAILQ_FOREACH(cloop, &clients, entry) { 89 | if (cloop->session != NULL && cloop != c) 90 | server_client_detach(cloop, msgtype); 91 | } 92 | return (CMD_RETURN_NORMAL); 93 | } 94 | 95 | server_client_detach(c, msgtype); 96 | return (CMD_RETURN_STOP); 97 | } 98 | -------------------------------------------------------------------------------- /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 | .name = "display-message", 39 | .alias = "display", 40 | 41 | .args = { "c:pt:F:", 0, 1 }, 42 | .usage = "[-p] [-c target-client] [-F format] " 43 | CMD_TARGET_PANE_USAGE " [message]", 44 | 45 | .cflag = CMD_CLIENT_CANFAIL, 46 | .tflag = CMD_PANE, 47 | 48 | .flags = 0, 49 | .exec = cmd_display_message_exec 50 | }; 51 | 52 | enum cmd_retval 53 | cmd_display_message_exec(struct cmd *self, struct cmd_q *cmdq) 54 | { 55 | struct args *args = self->args; 56 | struct client *c = cmdq->state.c; 57 | struct session *s = cmdq->state.tflag.s; 58 | struct winlink *wl = cmdq->state.tflag.wl; 59 | struct window_pane *wp = cmdq->state.tflag.wp; 60 | const char *template; 61 | char *msg; 62 | struct format_tree *ft; 63 | 64 | if (args_has(args, 'F') && args->argc != 0) { 65 | cmdq_error(cmdq, "only one of -F or argument must be given"); 66 | return (CMD_RETURN_ERROR); 67 | } 68 | 69 | template = args_get(args, 'F'); 70 | if (args->argc != 0) 71 | template = args->argv[0]; 72 | if (template == NULL) 73 | template = DISPLAY_MESSAGE_TEMPLATE; 74 | 75 | ft = format_create(cmdq, 0); 76 | format_defaults(ft, c, s, wl, wp); 77 | 78 | msg = format_expand_time(ft, template, time(NULL)); 79 | if (args_has(self->args, 'p')) 80 | cmdq_print(cmdq, "%s", msg); 81 | else 82 | status_message_set(c, "%s", msg); 83 | free(msg); 84 | format_free(ft); 85 | 86 | return (CMD_RETURN_NORMAL); 87 | } 88 | -------------------------------------------------------------------------------- /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 | .name = "display-panes", 31 | .alias = "displayp", 32 | 33 | .args = { "t:", 0, 0 }, 34 | .usage = CMD_TARGET_CLIENT_USAGE, 35 | 36 | .tflag = CMD_CLIENT, 37 | 38 | .flags = 0, 39 | .exec = cmd_display_panes_exec 40 | }; 41 | 42 | enum cmd_retval 43 | cmd_display_panes_exec(__unused struct cmd *self, struct cmd_q *cmdq) 44 | { 45 | server_set_identify(cmdq->state.c); 46 | 47 | return (CMD_RETURN_NORMAL); 48 | } 49 | -------------------------------------------------------------------------------- /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 | .name = "kill-pane", 33 | .alias = "killp", 34 | 35 | .args = { "at:", 0, 0 }, 36 | .usage = "[-a] " CMD_TARGET_PANE_USAGE, 37 | 38 | .tflag = CMD_PANE, 39 | 40 | .flags = 0, 41 | .exec = cmd_kill_pane_exec 42 | }; 43 | 44 | enum cmd_retval 45 | cmd_kill_pane_exec(struct cmd *self, struct cmd_q *cmdq) 46 | { 47 | struct winlink *wl = cmdq->state.tflag.wl; 48 | struct window_pane *loopwp, *tmpwp, *wp = cmdq->state.tflag.wp; 49 | 50 | server_unzoom_window(wl->window); 51 | 52 | if (window_count_panes(wl->window) == 1) { 53 | /* Only one pane, kill the window. */ 54 | server_kill_window(wl->window); 55 | recalculate_sizes(); 56 | return (CMD_RETURN_NORMAL); 57 | } 58 | 59 | if (args_has(self->args, 'a')) { 60 | TAILQ_FOREACH_SAFE(loopwp, &wl->window->panes, entry, tmpwp) { 61 | if (loopwp == wp) 62 | continue; 63 | layout_close_pane(loopwp); 64 | window_remove_pane(wl->window, loopwp); 65 | } 66 | } else { 67 | layout_close_pane(wp); 68 | window_remove_pane(wl->window, wp); 69 | } 70 | server_redraw_window(wl->window); 71 | 72 | return (CMD_RETURN_NORMAL); 73 | } 74 | -------------------------------------------------------------------------------- /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 | .name = "kill-server", 34 | .alias = NULL, 35 | 36 | .args = { "", 0, 0 }, 37 | .usage = "", 38 | 39 | .flags = 0, 40 | .exec = cmd_kill_server_exec 41 | }; 42 | 43 | const struct cmd_entry cmd_start_server_entry = { 44 | .name = "start-server", 45 | .alias = "start", 46 | 47 | .args = { "", 0, 0 }, 48 | .usage = "", 49 | 50 | .flags = CMD_STARTSERVER, 51 | .exec = cmd_kill_server_exec 52 | }; 53 | 54 | enum cmd_retval 55 | cmd_kill_server_exec(struct cmd *self, __unused struct cmd_q *cmdq) 56 | { 57 | if (self->entry == &cmd_kill_server_entry) 58 | kill(getpid(), SIGTERM); 59 | 60 | return (CMD_RETURN_NORMAL); 61 | } 62 | -------------------------------------------------------------------------------- /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 | .name = "kill-session", 34 | .alias = NULL, 35 | 36 | .args = { "aCt:", 0, 0 }, 37 | .usage = "[-aC] " CMD_TARGET_SESSION_USAGE, 38 | 39 | .tflag = CMD_SESSION, 40 | 41 | .flags = 0, 42 | .exec = cmd_kill_session_exec 43 | }; 44 | 45 | enum cmd_retval 46 | cmd_kill_session_exec(struct cmd *self, struct cmd_q *cmdq) 47 | { 48 | struct args *args = self->args; 49 | struct session *s, *sloop, *stmp; 50 | struct winlink *wl; 51 | 52 | s = cmdq->state.tflag.s; 53 | 54 | if (args_has(args, 'C')) { 55 | RB_FOREACH(wl, winlinks, &s->windows) { 56 | wl->window->flags &= ~WINDOW_ALERTFLAGS; 57 | wl->flags &= ~WINLINK_ALERTFLAGS; 58 | } 59 | server_redraw_session(s); 60 | } else if (args_has(args, 'a')) { 61 | RB_FOREACH_SAFE(sloop, sessions, &sessions, stmp) { 62 | if (sloop != s) { 63 | server_destroy_session(sloop); 64 | session_destroy(sloop); 65 | } 66 | } 67 | } else { 68 | server_destroy_session(s); 69 | session_destroy(s); 70 | } 71 | return (CMD_RETURN_NORMAL); 72 | } 73 | -------------------------------------------------------------------------------- /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 | .name = "kill-window", 31 | .alias = "killw", 32 | 33 | .args = { "at:", 0, 0 }, 34 | .usage = "[-a] " CMD_TARGET_WINDOW_USAGE, 35 | 36 | .tflag = CMD_WINDOW, 37 | 38 | .flags = 0, 39 | .exec = cmd_kill_window_exec 40 | }; 41 | 42 | const struct cmd_entry cmd_unlink_window_entry = { 43 | .name = "unlink-window", 44 | .alias = "unlinkw", 45 | 46 | .args = { "kt:", 0, 0 }, 47 | .usage = "[-k] " CMD_TARGET_WINDOW_USAGE, 48 | 49 | .tflag = CMD_WINDOW, 50 | 51 | .flags = 0, 52 | .exec = cmd_kill_window_exec 53 | }; 54 | 55 | enum cmd_retval 56 | cmd_kill_window_exec(struct cmd *self, struct cmd_q *cmdq) 57 | { 58 | struct args *args = self->args; 59 | struct winlink *wl = cmdq->state.tflag.wl, *wl2, *wl3; 60 | struct window *w = wl->window; 61 | struct session *s = cmdq->state.tflag.s; 62 | 63 | if (self->entry == &cmd_unlink_window_entry) { 64 | if (!args_has(self->args, 'k') && !session_is_linked(s, w)) { 65 | cmdq_error(cmdq, "window only linked to one session"); 66 | return (CMD_RETURN_ERROR); 67 | } 68 | server_unlink_window(s, wl); 69 | } else { 70 | if (args_has(args, 'a')) { 71 | RB_FOREACH_SAFE(wl2, winlinks, &s->windows, wl3) { 72 | if (wl != wl2) 73 | server_kill_window(wl2->window); 74 | } 75 | } else 76 | server_kill_window(wl->window); 77 | } 78 | 79 | recalculate_sizes(); 80 | return (CMD_RETURN_NORMAL); 81 | } 82 | -------------------------------------------------------------------------------- /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 | .name = "list-buffers", 37 | .alias = "lsb", 38 | 39 | .args = { "F:", 0, 0 }, 40 | .usage = "[-F format]", 41 | 42 | .flags = 0, 43 | .exec = cmd_list_buffers_exec 44 | }; 45 | 46 | enum cmd_retval 47 | cmd_list_buffers_exec(struct cmd *self, struct cmd_q *cmdq) 48 | { 49 | struct args *args = self->args; 50 | struct paste_buffer *pb; 51 | struct format_tree *ft; 52 | char *line; 53 | const char *template; 54 | 55 | if ((template = args_get(args, 'F')) == NULL) 56 | template = LIST_BUFFERS_TEMPLATE; 57 | 58 | pb = NULL; 59 | while ((pb = paste_walk(pb)) != NULL) { 60 | ft = format_create(cmdq, 0); 61 | format_defaults_paste_buffer(ft, pb); 62 | 63 | line = format_expand(ft, template); 64 | cmdq_print(cmdq, "%s", line); 65 | free(line); 66 | 67 | format_free(ft); 68 | } 69 | 70 | return (CMD_RETURN_NORMAL); 71 | } 72 | -------------------------------------------------------------------------------- /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 | .name = "list-clients", 40 | .alias = "lsc", 41 | 42 | .args = { "F:t:", 0, 0 }, 43 | .usage = "[-F format] " CMD_TARGET_SESSION_USAGE, 44 | 45 | .tflag = CMD_SESSION, 46 | 47 | .flags = CMD_READONLY, 48 | .exec = cmd_list_clients_exec 49 | }; 50 | 51 | enum cmd_retval 52 | cmd_list_clients_exec(struct cmd *self, struct cmd_q *cmdq) 53 | { 54 | struct args *args = self->args; 55 | struct client *c; 56 | struct session *s; 57 | struct format_tree *ft; 58 | const char *template; 59 | u_int idx; 60 | char *line; 61 | 62 | if (args_has(args, 't')) 63 | s = cmdq->state.tflag.s; 64 | else 65 | s = NULL; 66 | 67 | if ((template = args_get(args, 'F')) == NULL) 68 | template = LIST_CLIENTS_TEMPLATE; 69 | 70 | idx = 0; 71 | TAILQ_FOREACH(c, &clients, entry) { 72 | if (c->session == NULL || (s != NULL && s != c->session)) 73 | continue; 74 | 75 | ft = format_create(cmdq, 0); 76 | format_add(ft, "line", "%u", idx); 77 | format_defaults(ft, c, NULL, NULL, NULL); 78 | 79 | line = format_expand(ft, template); 80 | cmdq_print(cmdq, "%s", line); 81 | free(line); 82 | 83 | format_free(ft); 84 | 85 | idx++; 86 | } 87 | 88 | return (CMD_RETURN_NORMAL); 89 | } 90 | -------------------------------------------------------------------------------- /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 #{t:session_created}) " \ 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 | .name = "list-sessions", 43 | .alias = "ls", 44 | 45 | .args = { "F:", 0, 0 }, 46 | .usage = "[-F format]", 47 | 48 | .flags = 0, 49 | .exec = cmd_list_sessions_exec 50 | }; 51 | 52 | enum cmd_retval 53 | cmd_list_sessions_exec(struct cmd *self, struct cmd_q *cmdq) 54 | { 55 | struct args *args = self->args; 56 | struct session *s; 57 | u_int n; 58 | struct format_tree *ft; 59 | const char *template; 60 | char *line; 61 | 62 | if ((template = args_get(args, 'F')) == NULL) 63 | template = LIST_SESSIONS_TEMPLATE; 64 | 65 | n = 0; 66 | RB_FOREACH(s, sessions, &sessions) { 67 | ft = format_create(cmdq, 0); 68 | format_add(ft, "line", "%u", n); 69 | format_defaults(ft, NULL, s, NULL, NULL); 70 | 71 | line = format_expand(ft, template); 72 | cmdq_print(cmdq, "%s", line); 73 | free(line); 74 | 75 | format_free(ft); 76 | n++; 77 | } 78 | 79 | return (CMD_RETURN_NORMAL); 80 | } 81 | -------------------------------------------------------------------------------- /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 | .name = "list-windows", 50 | .alias = "lsw", 51 | 52 | .args = { "F:at:", 0, 0 }, 53 | .usage = "[-a] [-F format] " CMD_TARGET_SESSION_USAGE, 54 | 55 | .tflag = CMD_SESSION, 56 | 57 | .flags = 0, 58 | .exec = cmd_list_windows_exec 59 | }; 60 | 61 | enum cmd_retval 62 | cmd_list_windows_exec(struct cmd *self, struct cmd_q *cmdq) 63 | { 64 | struct args *args = self->args; 65 | 66 | if (args_has(args, 'a')) 67 | cmd_list_windows_server(self, cmdq); 68 | else 69 | cmd_list_windows_session(self, cmdq->state.tflag.s, cmdq, 0); 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(struct cmd *self, struct session *s, 85 | 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(cmdq, 0); 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-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 | char * 103 | cmd_list_print(struct cmd_list *cmdlist) 104 | { 105 | struct cmd *cmd; 106 | char *buf, *this; 107 | size_t len; 108 | 109 | len = 1; 110 | buf = xcalloc(1, len); 111 | 112 | TAILQ_FOREACH(cmd, &cmdlist->list, qentry) { 113 | this = cmd_print(cmd); 114 | 115 | len += strlen(this) + 3; 116 | buf = xrealloc(buf, len); 117 | 118 | strlcat(buf, this, len); 119 | if (TAILQ_NEXT(cmd, qentry) != NULL) 120 | strlcat(buf, " ; ", len); 121 | 122 | free(this); 123 | } 124 | 125 | return (buf); 126 | } 127 | -------------------------------------------------------------------------------- /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 | .name = "lock-server", 31 | .alias = "lock", 32 | 33 | .args = { "", 0, 0 }, 34 | .usage = "", 35 | 36 | .flags = 0, 37 | .exec = cmd_lock_server_exec 38 | }; 39 | 40 | const struct cmd_entry cmd_lock_session_entry = { 41 | .name = "lock-session", 42 | .alias = "locks", 43 | 44 | .args = { "t:", 0, 0 }, 45 | .usage = CMD_TARGET_SESSION_USAGE, 46 | 47 | .tflag = CMD_SESSION, 48 | 49 | .flags = 0, 50 | .exec = cmd_lock_server_exec 51 | }; 52 | 53 | const struct cmd_entry cmd_lock_client_entry = { 54 | .name = "lock-client", 55 | .alias = "lockc", 56 | 57 | .args = { "t:", 0, 0 }, 58 | .usage = CMD_TARGET_CLIENT_USAGE, 59 | 60 | .tflag = CMD_CLIENT, 61 | 62 | .flags = 0, 63 | .exec = cmd_lock_server_exec 64 | }; 65 | 66 | enum cmd_retval 67 | cmd_lock_server_exec(struct cmd *self, __unused struct cmd_q *cmdq) 68 | { 69 | if (self->entry == &cmd_lock_server_entry) 70 | server_lock(); 71 | else if (self->entry == &cmd_lock_session_entry) 72 | server_lock_session(cmdq->state.tflag.s); 73 | else 74 | server_lock_client(cmdq->state.c); 75 | 76 | recalculate_sizes(); 77 | 78 | return (CMD_RETURN_NORMAL); 79 | } 80 | -------------------------------------------------------------------------------- /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 | .name = "move-window", 33 | .alias = "movew", 34 | 35 | .args = { "adkrs:t:", 0, 0 }, 36 | .usage = "[-dkr] " CMD_SRCDST_WINDOW_USAGE, 37 | 38 | .sflag = CMD_WINDOW, 39 | .tflag = CMD_MOVEW_R, 40 | 41 | .flags = 0, 42 | .exec = cmd_move_window_exec 43 | }; 44 | 45 | const struct cmd_entry cmd_link_window_entry = { 46 | .name = "link-window", 47 | .alias = "linkw", 48 | 49 | .args = { "adks:t:", 0, 0 }, 50 | .usage = "[-dk] " CMD_SRCDST_WINDOW_USAGE, 51 | 52 | .sflag = CMD_WINDOW, 53 | .tflag = CMD_WINDOW_INDEX, 54 | 55 | .flags = 0, 56 | .exec = cmd_move_window_exec 57 | }; 58 | 59 | enum cmd_retval 60 | cmd_move_window_exec(struct cmd *self, struct cmd_q *cmdq) 61 | { 62 | #ifdef TMATE 63 | cmdq_error(cmdq, "move window is not supported with tmate"); 64 | return (CMD_RETURN_ERROR); 65 | #else 66 | struct args *args = self->args; 67 | struct session *src = cmdq->state.sflag.s; 68 | struct session *dst = cmdq->state.tflag.s; 69 | struct winlink *wl = cmdq->state.sflag.wl; 70 | char *cause; 71 | int idx = cmdq->state.tflag.idx, kflag, dflag, sflag; 72 | 73 | kflag = args_has(self->args, 'k'); 74 | dflag = args_has(self->args, 'd'); 75 | 76 | if (args_has(args, 'r')) { 77 | session_renumber_windows(dst); 78 | recalculate_sizes(); 79 | 80 | return (CMD_RETURN_NORMAL); 81 | } 82 | 83 | kflag = args_has(self->args, 'k'); 84 | dflag = args_has(self->args, 'd'); 85 | sflag = args_has(self->args, 's'); 86 | 87 | if (args_has(self->args, 'a')) { 88 | if ((idx = winlink_shuffle_up(dst, dst->curw)) == -1) 89 | return (CMD_RETURN_ERROR); 90 | } 91 | 92 | if (server_link_window(src, wl, dst, idx, kflag, !dflag, 93 | &cause) != 0) { 94 | cmdq_error(cmdq, "can't link window: %s", cause); 95 | free(cause); 96 | return (CMD_RETURN_ERROR); 97 | } 98 | if (self->entry == &cmd_move_window_entry) 99 | server_unlink_window(src, wl); 100 | 101 | /* 102 | * Renumber the winlinks in the src session only, the destination 103 | * session already has the correct winlink id to us, either 104 | * automatically or specified by -s. 105 | */ 106 | if (!sflag && options_get_number(src->options, "renumber-windows")) 107 | session_renumber_windows(src); 108 | 109 | recalculate_sizes(); 110 | 111 | return (CMD_RETURN_NORMAL); 112 | #endif 113 | } 114 | -------------------------------------------------------------------------------- /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 | .name = "paste-buffer", 37 | .alias = "pasteb", 38 | 39 | .args = { "db:prs:t:", 0, 0 }, 40 | .usage = "[-dpr] [-s separator] " CMD_BUFFER_USAGE " " 41 | CMD_TARGET_PANE_USAGE, 42 | 43 | .tflag = CMD_PANE, 44 | 45 | .flags = 0, 46 | .exec = cmd_paste_buffer_exec 47 | }; 48 | 49 | enum cmd_retval 50 | cmd_paste_buffer_exec(struct cmd *self, struct cmd_q *cmdq) 51 | { 52 | struct args *args = self->args; 53 | struct window_pane *wp = cmdq->state.tflag.wp; 54 | struct paste_buffer *pb; 55 | const char *sepstr, *bufname, *bufdata, *bufend, *line; 56 | size_t seplen, bufsize; 57 | int bracket = args_has(args, 'p'); 58 | 59 | bufname = NULL; 60 | if (args_has(args, 'b')) 61 | bufname = args_get(args, 'b'); 62 | 63 | if (bufname == NULL) 64 | pb = paste_get_top(NULL); 65 | else { 66 | pb = paste_get_name(bufname); 67 | if (pb == NULL) { 68 | cmdq_error(cmdq, "no buffer %s", bufname); 69 | return (CMD_RETURN_ERROR); 70 | } 71 | } 72 | 73 | if (pb != NULL && ~wp->flags & PANE_INPUTOFF) { 74 | sepstr = args_get(args, 's'); 75 | if (sepstr == NULL) { 76 | if (args_has(args, 'r')) 77 | sepstr = "\n"; 78 | else 79 | sepstr = "\r"; 80 | } 81 | seplen = strlen(sepstr); 82 | 83 | if (bracket && (wp->screen->mode & MODE_BRACKETPASTE)) 84 | bufferevent_write(wp->event, "\033[200~", 6); 85 | 86 | bufdata = paste_buffer_data(pb, &bufsize); 87 | bufend = bufdata + bufsize; 88 | 89 | for (;;) { 90 | line = memchr(bufdata, '\n', bufend - bufdata); 91 | if (line == NULL) 92 | break; 93 | 94 | bufferevent_write(wp->event, bufdata, line - bufdata); 95 | bufferevent_write(wp->event, sepstr, seplen); 96 | 97 | bufdata = line + 1; 98 | } 99 | if (bufdata != bufend) 100 | bufferevent_write(wp->event, bufdata, bufend - bufdata); 101 | 102 | if (bracket && (wp->screen->mode & MODE_BRACKETPASTE)) 103 | bufferevent_write(wp->event, "\033[201~", 6); 104 | } 105 | 106 | if (pb != NULL && args_has(args, 'd')) 107 | paste_free(pb); 108 | 109 | return (CMD_RETURN_NORMAL); 110 | } 111 | -------------------------------------------------------------------------------- /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 | .name = "refresh-client", 31 | .alias = "refresh", 32 | 33 | .args = { "C:St:", 0, 0 }, 34 | .usage = "[-S] [-C size] " CMD_TARGET_CLIENT_USAGE, 35 | 36 | .tflag = CMD_CLIENT, 37 | 38 | .flags = 0, 39 | .exec = cmd_refresh_client_exec 40 | }; 41 | 42 | enum cmd_retval 43 | cmd_refresh_client_exec(struct cmd *self, struct cmd_q *cmdq) 44 | { 45 | struct args *args = self->args; 46 | struct client *c = cmdq->state.c; 47 | const char *size; 48 | u_int w, h; 49 | 50 | if (args_has(args, 'C')) { 51 | if ((size = args_get(args, 'C')) == NULL) { 52 | cmdq_error(cmdq, "missing size"); 53 | return (CMD_RETURN_ERROR); 54 | } 55 | if (sscanf(size, "%u,%u", &w, &h) != 2) { 56 | cmdq_error(cmdq, "bad size argument"); 57 | return (CMD_RETURN_ERROR); 58 | } 59 | if (w < PANE_MINIMUM || w > 5000 || 60 | h < PANE_MINIMUM || h > 5000) { 61 | cmdq_error(cmdq, "size too small or too big"); 62 | return (CMD_RETURN_ERROR); 63 | } 64 | if (!(c->flags & CLIENT_CONTROL)) { 65 | cmdq_error(cmdq, "not a control client"); 66 | return (CMD_RETURN_ERROR); 67 | } 68 | if (tty_set_size(&c->tty, w, h)) 69 | recalculate_sizes(); 70 | } else if (args_has(args, 'S')) { 71 | c->flags |= CLIENT_STATUSFORCE; 72 | server_status_client(c); 73 | } else { 74 | c->flags |= CLIENT_STATUSFORCE; 75 | server_redraw_client(c); 76 | } 77 | 78 | return (CMD_RETURN_NORMAL); 79 | } 80 | -------------------------------------------------------------------------------- /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 | .name = "rename-session", 33 | .alias = "rename", 34 | 35 | .args = { "t:", 1, 1 }, 36 | .usage = CMD_TARGET_SESSION_USAGE " new-name", 37 | 38 | .tflag = CMD_SESSION, 39 | 40 | .flags = 0, 41 | .exec = cmd_rename_session_exec 42 | }; 43 | 44 | enum cmd_retval 45 | cmd_rename_session_exec(struct cmd *self, struct cmd_q *cmdq) 46 | { 47 | struct args *args = self->args; 48 | struct session *s = cmdq->state.tflag.s; 49 | const char *newname; 50 | 51 | newname = args->argv[0]; 52 | if (!session_check_name(newname)) { 53 | cmdq_error(cmdq, "bad session name: %s", newname); 54 | return (CMD_RETURN_ERROR); 55 | } 56 | if (session_find(newname) != NULL) { 57 | cmdq_error(cmdq, "duplicate session: %s", newname); 58 | return (CMD_RETURN_ERROR); 59 | } 60 | 61 | RB_REMOVE(sessions, &sessions, s); 62 | free(s->name); 63 | s->name = xstrdup(newname); 64 | RB_INSERT(sessions, &sessions, s); 65 | 66 | server_status_session(s); 67 | notify_session_renamed(s); 68 | 69 | return (CMD_RETURN_NORMAL); 70 | } 71 | -------------------------------------------------------------------------------- /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 | .name = "rename-window", 33 | .alias = "renamew", 34 | 35 | .args = { "t:", 1, 1 }, 36 | .usage = CMD_TARGET_WINDOW_USAGE " new-name", 37 | 38 | .tflag = CMD_WINDOW, 39 | 40 | .flags = 0, 41 | .exec = cmd_rename_window_exec 42 | }; 43 | 44 | enum cmd_retval 45 | cmd_rename_window_exec(struct cmd *self, struct cmd_q *cmdq) 46 | { 47 | struct args *args = self->args; 48 | struct winlink *wl = cmdq->state.tflag.wl; 49 | 50 | window_set_name(wl->window, args->argv[0]); 51 | options_set_number(wl->window->options, "automatic-rename", 0); 52 | 53 | server_status_window(wl->window); 54 | 55 | return (CMD_RETURN_NORMAL); 56 | } 57 | -------------------------------------------------------------------------------- /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 | .name = "respawn-pane", 35 | .alias = "respawnp", 36 | 37 | .args = { "kt:", 0, -1 }, 38 | .usage = "[-k] " CMD_TARGET_PANE_USAGE " [command]", 39 | 40 | .tflag = CMD_PANE, 41 | 42 | .flags = 0, 43 | .exec = cmd_respawn_pane_exec 44 | }; 45 | 46 | enum cmd_retval 47 | cmd_respawn_pane_exec(struct cmd *self, struct cmd_q *cmdq) 48 | { 49 | struct args *args = self->args; 50 | struct winlink *wl = cmdq->state.tflag.wl; 51 | struct window *w = wl->window; 52 | struct window_pane *wp = cmdq->state.tflag.wp; 53 | struct session *s = cmdq->state.tflag.s; 54 | struct environ *env; 55 | const char *path; 56 | char *cause; 57 | u_int idx; 58 | struct environ_entry *envent; 59 | 60 | if (!args_has(self->args, 'k') && wp->fd != -1) { 61 | if (window_pane_index(wp, &idx) != 0) 62 | fatalx("index not found"); 63 | cmdq_error(cmdq, "pane still active: %s:%d.%u", 64 | s->name, wl->idx, idx); 65 | return (CMD_RETURN_ERROR); 66 | } 67 | 68 | env = environ_create(); 69 | environ_copy(global_environ, env); 70 | environ_copy(s->environ, env); 71 | server_fill_environ(s, env); 72 | 73 | window_pane_reset_mode(wp); 74 | screen_reinit(&wp->base); 75 | input_init(wp); 76 | 77 | path = NULL; 78 | if (cmdq->client != NULL && cmdq->client->session == NULL) 79 | envent = environ_find(cmdq->client->environ, "PATH"); 80 | else 81 | envent = environ_find(s->environ, "PATH"); 82 | if (envent != NULL) 83 | path = envent->value; 84 | 85 | if (window_pane_spawn(wp, args->argc, args->argv, path, NULL, NULL, env, 86 | s->tio, &cause) != 0) { 87 | cmdq_error(cmdq, "respawn pane failed: %s", cause); 88 | free(cause); 89 | environ_free(env); 90 | return (CMD_RETURN_ERROR); 91 | } 92 | wp->flags |= PANE_REDRAW; 93 | server_status_window(w); 94 | 95 | environ_free(env); 96 | return (CMD_RETURN_NORMAL); 97 | } 98 | -------------------------------------------------------------------------------- /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 | .name = "respawn-window", 34 | .alias = "respawnw", 35 | 36 | .args = { "kt:", 0, -1 }, 37 | .usage = "[-k] " CMD_TARGET_WINDOW_USAGE " [command]", 38 | 39 | .tflag = CMD_WINDOW, 40 | 41 | .flags = 0, 42 | .exec = cmd_respawn_window_exec 43 | }; 44 | 45 | enum cmd_retval 46 | cmd_respawn_window_exec(struct cmd *self, struct cmd_q *cmdq) 47 | { 48 | struct args *args = self->args; 49 | struct session *s = cmdq->state.tflag.s; 50 | struct winlink *wl = cmdq->state.tflag.wl; 51 | struct window *w = wl->window; 52 | struct window_pane *wp; 53 | struct environ *env; 54 | const char *path; 55 | char *cause; 56 | struct environ_entry *envent; 57 | 58 | if (!args_has(self->args, 'k')) { 59 | TAILQ_FOREACH(wp, &w->panes, entry) { 60 | if (wp->fd == -1) 61 | continue; 62 | cmdq_error(cmdq, "window still active: %s:%d", s->name, 63 | wl->idx); 64 | return (CMD_RETURN_ERROR); 65 | } 66 | } 67 | 68 | env = environ_create(); 69 | environ_copy(global_environ, env); 70 | environ_copy(s->environ, env); 71 | server_fill_environ(s, env); 72 | 73 | wp = TAILQ_FIRST(&w->panes); 74 | TAILQ_REMOVE(&w->panes, wp, entry); 75 | layout_free(w); 76 | window_destroy_panes(w); 77 | TAILQ_INSERT_HEAD(&w->panes, wp, entry); 78 | window_pane_resize(wp, w->sx, w->sy); 79 | 80 | path = NULL; 81 | if (cmdq->client != NULL && cmdq->client->session == NULL) 82 | envent = environ_find(cmdq->client->environ, "PATH"); 83 | else 84 | envent = environ_find(s->environ, "PATH"); 85 | if (envent != NULL) 86 | path = envent->value; 87 | 88 | if (window_pane_spawn(wp, args->argc, args->argv, path, NULL, NULL, env, 89 | s->tio, &cause) != 0) { 90 | cmdq_error(cmdq, "respawn window failed: %s", cause); 91 | free(cause); 92 | environ_free(env); 93 | server_destroy_pane(wp, 0); 94 | return (CMD_RETURN_ERROR); 95 | } 96 | layout_init(w, wp); 97 | window_pane_reset_mode(wp); 98 | screen_reinit(&wp->base); 99 | input_init(wp); 100 | window_set_active_pane(w, wp); 101 | 102 | recalculate_sizes(); 103 | server_redraw_window(w); 104 | 105 | environ_free(env); 106 | return (CMD_RETURN_NORMAL); 107 | } 108 | -------------------------------------------------------------------------------- /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 | .name = "rotate-window", 31 | .alias = "rotatew", 32 | 33 | .args = { "Dt:U", 0, 0 }, 34 | .usage = "[-DU] " CMD_TARGET_WINDOW_USAGE, 35 | 36 | .tflag = CMD_WINDOW, 37 | 38 | .flags = 0, 39 | .exec = cmd_rotate_window_exec 40 | }; 41 | 42 | enum cmd_retval 43 | cmd_rotate_window_exec(struct cmd *self, struct cmd_q *cmdq) 44 | { 45 | struct winlink *wl = cmdq->state.tflag.wl; 46 | struct window *w = wl->window; 47 | struct window_pane *wp, *wp2; 48 | struct layout_cell *lc; 49 | u_int sx, sy, xoff, yoff; 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 | -------------------------------------------------------------------------------- /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 | .name = "select-layout", 33 | .alias = "selectl", 34 | 35 | .args = { "nopt:", 0, 1 }, 36 | .usage = "[-nop] " CMD_TARGET_WINDOW_USAGE " [layout-name]", 37 | 38 | .tflag = CMD_WINDOW, 39 | 40 | .flags = 0, 41 | .exec = cmd_select_layout_exec 42 | }; 43 | 44 | const struct cmd_entry cmd_next_layout_entry = { 45 | .name = "next-layout", 46 | .alias = "nextl", 47 | 48 | .args = { "t:", 0, 0 }, 49 | .usage = CMD_TARGET_WINDOW_USAGE, 50 | 51 | .tflag = CMD_WINDOW, 52 | 53 | .flags = 0, 54 | .exec = cmd_select_layout_exec 55 | }; 56 | 57 | const struct cmd_entry cmd_previous_layout_entry = { 58 | .name = "previous-layout", 59 | .alias = "prevl", 60 | 61 | .args = { "t:", 0, 0 }, 62 | .usage = CMD_TARGET_WINDOW_USAGE, 63 | 64 | .tflag = CMD_WINDOW, 65 | 66 | .flags = 0, 67 | .exec = cmd_select_layout_exec 68 | }; 69 | 70 | enum cmd_retval 71 | cmd_select_layout_exec(struct cmd *self, struct cmd_q *cmdq) 72 | { 73 | struct args *args = self->args; 74 | struct winlink *wl = cmdq->state.tflag.wl; 75 | struct window *w; 76 | const char *layoutname; 77 | char *oldlayout; 78 | int next, previous, layout; 79 | 80 | w = wl->window; 81 | server_unzoom_window(w); 82 | 83 | next = self->entry == &cmd_next_layout_entry; 84 | if (args_has(args, 'n')) 85 | next = 1; 86 | previous = self->entry == &cmd_previous_layout_entry; 87 | if (args_has(args, 'p')) 88 | previous = 1; 89 | 90 | oldlayout = w->old_layout; 91 | w->old_layout = layout_dump(w->layout_root); 92 | 93 | if (next || previous) { 94 | if (next) 95 | layout_set_next(w); 96 | else 97 | layout_set_previous(w); 98 | goto changed; 99 | } 100 | 101 | if (!args_has(args, 'o')) { 102 | if (args->argc == 0) 103 | layout = w->lastlayout; 104 | else 105 | layout = layout_set_lookup(args->argv[0]); 106 | if (layout != -1) { 107 | layout_set_select(w, layout); 108 | goto changed; 109 | } 110 | } 111 | 112 | if (args->argc != 0) 113 | layoutname = args->argv[0]; 114 | else if (args_has(args, 'o')) 115 | layoutname = oldlayout; 116 | else 117 | layoutname = NULL; 118 | 119 | if (layoutname != NULL) { 120 | if (layout_parse(w, layoutname) == -1) { 121 | cmdq_error(cmdq, "can't set layout: %s", layoutname); 122 | goto error; 123 | } 124 | goto changed; 125 | } 126 | 127 | free(oldlayout); 128 | return (CMD_RETURN_NORMAL); 129 | 130 | changed: 131 | free(oldlayout); 132 | server_redraw_window(w); 133 | return (CMD_RETURN_NORMAL); 134 | 135 | error: 136 | free(w->old_layout); 137 | w->old_layout = oldlayout; 138 | return (CMD_RETURN_ERROR); 139 | } 140 | -------------------------------------------------------------------------------- /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 | .name = "send-keys", 34 | .alias = "send", 35 | 36 | .args = { "lRMt:", 0, -1 }, 37 | .usage = "[-lRM] " CMD_TARGET_PANE_USAGE " key ...", 38 | 39 | .tflag = CMD_PANE, 40 | 41 | .flags = 0, 42 | .exec = cmd_send_keys_exec 43 | }; 44 | 45 | const struct cmd_entry cmd_send_prefix_entry = { 46 | .name = "send-prefix", 47 | .alias = NULL, 48 | 49 | .args = { "2t:", 0, 0 }, 50 | .usage = "[-2] " CMD_TARGET_PANE_USAGE, 51 | 52 | .tflag = CMD_PANE, 53 | 54 | .flags = 0, 55 | .exec = cmd_send_keys_exec 56 | }; 57 | 58 | enum cmd_retval 59 | cmd_send_keys_exec(struct cmd *self, struct cmd_q *cmdq) 60 | { 61 | struct args *args = self->args; 62 | struct window_pane *wp = cmdq->state.tflag.wp; 63 | struct session *s = cmdq->state.tflag.s; 64 | struct mouse_event *m = &cmdq->item->mouse; 65 | const u_char *keystr; 66 | int i, literal; 67 | key_code key; 68 | 69 | if (args_has(args, 'M')) { 70 | wp = cmd_mouse_pane(m, &s, NULL); 71 | if (wp == NULL) { 72 | cmdq_error(cmdq, "no mouse target"); 73 | return (CMD_RETURN_ERROR); 74 | } 75 | window_pane_key(wp, NULL, s, m->key, m); 76 | return (CMD_RETURN_NORMAL); 77 | } 78 | 79 | if (self->entry == &cmd_send_prefix_entry) { 80 | if (args_has(args, '2')) 81 | key = options_get_number(s->options, "prefix2"); 82 | else 83 | key = options_get_number(s->options, "prefix"); 84 | window_pane_key(wp, NULL, s, key, NULL); 85 | return (CMD_RETURN_NORMAL); 86 | } 87 | 88 | if (args_has(args, 'R')) 89 | input_reset(wp, 1); 90 | 91 | for (i = 0; i < args->argc; i++) { 92 | literal = args_has(args, 'l'); 93 | if (!literal) { 94 | key = key_string_lookup_string(args->argv[i]); 95 | if (key != KEYC_NONE && key != KEYC_UNKNOWN) 96 | window_pane_key(wp, NULL, s, key, NULL); 97 | else 98 | literal = 1; 99 | } 100 | if (literal) { 101 | for (keystr = args->argv[i]; *keystr != '\0'; keystr++) 102 | window_pane_key(wp, NULL, s, *keystr, NULL); 103 | } 104 | } 105 | 106 | return (CMD_RETURN_NORMAL); 107 | } 108 | -------------------------------------------------------------------------------- /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, append to or delete 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 | .name = "set-buffer", 34 | .alias = "setb", 35 | 36 | .args = { "ab:n:", 0, 1 }, 37 | .usage = "[-a] " CMD_BUFFER_USAGE " [-n new-buffer-name] data", 38 | 39 | .flags = 0, 40 | .exec = cmd_set_buffer_exec 41 | }; 42 | 43 | const struct cmd_entry cmd_delete_buffer_entry = { 44 | .name = "delete-buffer", 45 | .alias = "deleteb", 46 | 47 | .args = { "b:", 0, 0 }, 48 | .usage = CMD_BUFFER_USAGE, 49 | 50 | .flags = 0, 51 | .exec = cmd_set_buffer_exec 52 | }; 53 | 54 | enum cmd_retval 55 | cmd_set_buffer_exec(struct cmd *self, struct cmd_q *cmdq) 56 | { 57 | struct args *args = self->args; 58 | struct paste_buffer *pb; 59 | char *bufdata, *cause; 60 | const char *bufname, *olddata; 61 | size_t bufsize, newsize; 62 | 63 | bufname = args_get(args, 'b'); 64 | if (bufname == NULL) 65 | pb = NULL; 66 | else 67 | pb = paste_get_name(bufname); 68 | 69 | if (self->entry == &cmd_delete_buffer_entry) { 70 | if (pb == NULL) 71 | pb = paste_get_top(&bufname); 72 | if (pb == NULL) { 73 | cmdq_error(cmdq, "no buffer"); 74 | return (CMD_RETURN_ERROR); 75 | } 76 | paste_free(pb); 77 | return (CMD_RETURN_NORMAL); 78 | } 79 | 80 | if (args_has(args, 'n')) { 81 | if (pb == NULL) 82 | pb = paste_get_top(&bufname); 83 | if (pb == NULL) { 84 | cmdq_error(cmdq, "no buffer"); 85 | return (CMD_RETURN_ERROR); 86 | } 87 | if (paste_rename(bufname, args_get(args, 'n'), &cause) != 0) { 88 | cmdq_error(cmdq, "%s", cause); 89 | free(cause); 90 | return (CMD_RETURN_ERROR); 91 | } 92 | return (CMD_RETURN_NORMAL); 93 | } 94 | 95 | if (args->argc != 1) { 96 | cmdq_error(cmdq, "no data specified"); 97 | return (CMD_RETURN_ERROR); 98 | } 99 | if ((newsize = strlen(args->argv[0])) == 0) 100 | return (CMD_RETURN_NORMAL); 101 | 102 | bufsize = 0; 103 | bufdata = NULL; 104 | 105 | if (args_has(args, 'a') && pb != NULL) { 106 | olddata = paste_buffer_data(pb, &bufsize); 107 | bufdata = xmalloc(bufsize); 108 | memcpy(bufdata, olddata, bufsize); 109 | } 110 | 111 | bufdata = xrealloc(bufdata, bufsize + newsize); 112 | memcpy(bufdata + bufsize, args->argv[0], newsize); 113 | bufsize += newsize; 114 | 115 | if (paste_set(bufdata, bufsize, bufname, &cause) != 0) { 116 | cmdq_error(cmdq, "%s", cause); 117 | free(bufdata); 118 | free(cause); 119 | return (CMD_RETURN_ERROR); 120 | } 121 | 122 | return (CMD_RETURN_NORMAL); 123 | } 124 | -------------------------------------------------------------------------------- /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 | .name = "set-environment", 34 | .alias = "setenv", 35 | 36 | .args = { "grt:u", 1, 2 }, 37 | .usage = "[-gru] " CMD_TARGET_SESSION_USAGE " name [value]", 38 | 39 | .tflag = CMD_SESSION_CANFAIL, 40 | 41 | .flags = 0, 42 | .exec = cmd_set_environment_exec 43 | }; 44 | 45 | enum cmd_retval 46 | cmd_set_environment_exec(struct cmd *self, struct cmd_q *cmdq) 47 | { 48 | struct args *args = self->args; 49 | struct environ *env; 50 | const char *name, *value, *target; 51 | 52 | name = args->argv[0]; 53 | if (*name == '\0') { 54 | cmdq_error(cmdq, "empty variable name"); 55 | return (CMD_RETURN_ERROR); 56 | } 57 | if (strchr(name, '=') != NULL) { 58 | cmdq_error(cmdq, "variable name contains ="); 59 | return (CMD_RETURN_ERROR); 60 | } 61 | 62 | if (args->argc < 2) 63 | value = NULL; 64 | else 65 | value = args->argv[1]; 66 | 67 | if (args_has(self->args, 'g')) 68 | env = global_environ; 69 | else { 70 | if (cmdq->state.tflag.s == NULL) { 71 | target = args_get(args, 't'); 72 | if (target != NULL) 73 | cmdq_error(cmdq, "no such session: %s", target); 74 | else 75 | cmdq_error(cmdq, "no current session"); 76 | return (CMD_RETURN_ERROR); 77 | } 78 | env = cmdq->state.tflag.s->environ; 79 | } 80 | 81 | if (args_has(self->args, 'u')) { 82 | if (value != NULL) { 83 | cmdq_error(cmdq, "can't specify a value with -u"); 84 | return (CMD_RETURN_ERROR); 85 | } 86 | environ_unset(env, name); 87 | } else if (args_has(self->args, 'r')) { 88 | if (value != NULL) { 89 | cmdq_error(cmdq, "can't specify a value with -r"); 90 | return (CMD_RETURN_ERROR); 91 | } 92 | environ_clear(env, name); 93 | } else { 94 | if (value == NULL) { 95 | cmdq_error(cmdq, "no value specified"); 96 | return (CMD_RETURN_ERROR); 97 | } 98 | environ_set(env, name, "%s", value); 99 | } 100 | 101 | return (CMD_RETURN_NORMAL); 102 | } 103 | -------------------------------------------------------------------------------- /cmd-set-hook.c: -------------------------------------------------------------------------------- 1 | /* $OpenBSD$ */ 2 | 3 | /* 4 | * Copyright (c) 2012 Thomas Adam 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 or show global or session hooks. 28 | */ 29 | 30 | enum cmd_retval cmd_set_hook_exec(struct cmd *, struct cmd_q *); 31 | 32 | const struct cmd_entry cmd_set_hook_entry = { 33 | .name = "set-hook", 34 | .alias = NULL, 35 | 36 | .args = { "gt:u", 1, 2 }, 37 | .usage = "[-gu] " CMD_TARGET_SESSION_USAGE " hook-name [command]", 38 | 39 | .tflag = CMD_SESSION, 40 | 41 | .flags = 0, 42 | .exec = cmd_set_hook_exec 43 | }; 44 | 45 | const struct cmd_entry cmd_show_hooks_entry = { 46 | .name = "show-hooks", 47 | .alias = NULL, 48 | 49 | .args = { "gt:", 0, 1 }, 50 | .usage = "[-g] " CMD_TARGET_SESSION_USAGE, 51 | 52 | .tflag = CMD_SESSION, 53 | 54 | .flags = 0, 55 | .exec = cmd_set_hook_exec 56 | }; 57 | 58 | enum cmd_retval 59 | cmd_set_hook_exec(struct cmd *self, struct cmd_q *cmdq) 60 | { 61 | struct args *args = self->args; 62 | struct cmd_list *cmdlist; 63 | struct hooks *hooks; 64 | struct hook *hook; 65 | char *cause, *tmp; 66 | const char *name, *cmd; 67 | 68 | if (args_has(args, 'g')) 69 | hooks = global_hooks; 70 | else 71 | hooks = cmdq->state.tflag.s->hooks; 72 | 73 | if (self->entry == &cmd_show_hooks_entry) { 74 | hook = hooks_first(hooks); 75 | while (hook != NULL) { 76 | tmp = cmd_list_print(hook->cmdlist); 77 | cmdq_print(cmdq, "%s -> %s", hook->name, tmp); 78 | free(tmp); 79 | 80 | hook = hooks_next(hook); 81 | } 82 | return (CMD_RETURN_NORMAL); 83 | } 84 | 85 | name = args->argv[0]; 86 | if (*name == '\0') { 87 | cmdq_error(cmdq, "invalid hook name"); 88 | return (CMD_RETURN_ERROR); 89 | } 90 | if (args->argc < 2) 91 | cmd = NULL; 92 | else 93 | cmd = args->argv[1]; 94 | 95 | if (args_has(args, 'u')) { 96 | if (cmd != NULL) { 97 | cmdq_error(cmdq, "command passed to unset hook: %s", 98 | name); 99 | return (CMD_RETURN_ERROR); 100 | } 101 | hooks_remove(hooks, name); 102 | return (CMD_RETURN_NORMAL); 103 | } 104 | 105 | if (cmd == NULL) { 106 | cmdq_error(cmdq, "no command to set hook: %s", name); 107 | return (CMD_RETURN_ERROR); 108 | } 109 | if (cmd_string_parse(cmd, &cmdlist, NULL, 0, &cause) != 0) { 110 | if (cause != NULL) { 111 | cmdq_error(cmdq, "%s", cause); 112 | free(cause); 113 | } 114 | return (CMD_RETURN_ERROR); 115 | } 116 | hooks_add(hooks, name, cmdlist); 117 | cmd_list_free(cmdlist); 118 | 119 | return (CMD_RETURN_NORMAL); 120 | } 121 | -------------------------------------------------------------------------------- /cmd-show-messages.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 | 25 | #include "tmux.h" 26 | 27 | /* 28 | * Show client message log. 29 | */ 30 | 31 | enum cmd_retval cmd_show_messages_exec(struct cmd *, struct cmd_q *); 32 | 33 | const struct cmd_entry cmd_show_messages_entry = { 34 | .name = "show-messages", 35 | .alias = "showmsgs", 36 | 37 | .args = { "JTt:", 0, 0 }, 38 | .usage = "[-JT] " CMD_TARGET_CLIENT_USAGE, 39 | 40 | .tflag = CMD_CLIENT, 41 | 42 | .flags = 0, 43 | .exec = cmd_show_messages_exec 44 | }; 45 | 46 | const struct cmd_entry cmd_server_info_entry = { 47 | .name = "server-info", 48 | .alias = "info", 49 | 50 | .args = { "", 0, 0 }, 51 | .usage = "", 52 | 53 | .flags = 0, 54 | .exec = cmd_show_messages_exec 55 | }; 56 | 57 | int cmd_show_messages_terminals(struct cmd_q *, int); 58 | int cmd_show_messages_jobs(struct cmd_q *, int); 59 | 60 | int 61 | cmd_show_messages_terminals(struct cmd_q *cmdq, int blank) 62 | { 63 | struct tty_term *term; 64 | u_int i, n; 65 | 66 | n = 0; 67 | LIST_FOREACH(term, &tty_terms, entry) { 68 | if (blank) { 69 | cmdq_print(cmdq, "%s", ""); 70 | blank = 0; 71 | } 72 | cmdq_print(cmdq, "Terminal %u: %s [references=%u, flags=0x%x]:", 73 | n, term->name, term->references, term->flags); 74 | n++; 75 | for (i = 0; i < tty_term_ncodes(); i++) 76 | cmdq_print(cmdq, "%s", tty_term_describe(term, i)); 77 | } 78 | return (n != 0); 79 | } 80 | 81 | int 82 | cmd_show_messages_jobs(struct cmd_q *cmdq, int blank) 83 | { 84 | struct job *job; 85 | u_int n; 86 | 87 | n = 0; 88 | LIST_FOREACH(job, &all_jobs, lentry) { 89 | if (blank) { 90 | cmdq_print(cmdq, "%s", ""); 91 | blank = 0; 92 | } 93 | cmdq_print(cmdq, "Job %u: %s [fd=%d, pid=%d, status=%d]", 94 | n, job->cmd, job->fd, job->pid, job->status); 95 | n++; 96 | } 97 | return (n != 0); 98 | } 99 | 100 | enum cmd_retval 101 | cmd_show_messages_exec(struct cmd *self, struct cmd_q *cmdq) 102 | { 103 | struct args *args = self->args; 104 | struct client *c = cmdq->state.c; 105 | struct message_entry *msg; 106 | char *tim; 107 | int done, blank; 108 | 109 | done = blank = 0; 110 | if (args_has(args, 'T') || self->entry == &cmd_server_info_entry) { 111 | blank = cmd_show_messages_terminals(cmdq, blank); 112 | done = 1; 113 | } 114 | if (args_has(args, 'J') || self->entry == &cmd_server_info_entry) { 115 | cmd_show_messages_jobs(cmdq, blank); 116 | done = 1; 117 | } 118 | if (done) 119 | return (CMD_RETURN_NORMAL); 120 | 121 | TAILQ_FOREACH(msg, &c->message_log, entry) { 122 | tim = ctime(&msg->msg_time); 123 | *strchr(tim, '\n') = '\0'; 124 | 125 | cmdq_print(cmdq, "%s %s", tim, msg->msg); 126 | } 127 | 128 | return (CMD_RETURN_NORMAL); 129 | } 130 | -------------------------------------------------------------------------------- /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 | .name = "source-file", 35 | .alias = "source", 36 | 37 | .args = { "", 1, 1 }, 38 | .usage = "path", 39 | 40 | .flags = 0, 41 | .exec = cmd_source_file_exec 42 | }; 43 | 44 | enum cmd_retval 45 | cmd_source_file_exec(struct cmd *self, struct cmd_q *cmdq) 46 | { 47 | struct args *args = self->args; 48 | struct cmd_q *cmdq1; 49 | char *cause; 50 | 51 | cmdq1 = cmdq_new(cmdq->client); 52 | cmdq1->emptyfn = cmd_source_file_done; 53 | cmdq1->data = cmdq; 54 | 55 | switch (load_cfg(args->argv[0], cmdq1, &cause)) { 56 | case -1: 57 | if (cfg_references == 0) { 58 | cmdq_free(cmdq1); 59 | cmdq_error(cmdq, "%s", cause); 60 | free(cause); 61 | return (CMD_RETURN_ERROR); 62 | } 63 | cfg_add_cause("%s", cause); 64 | free(cause); 65 | /* FALLTHROUGH */ 66 | case 0: 67 | if (cfg_references == 0) 68 | cfg_print_causes(cmdq); 69 | cmdq_free(cmdq1); 70 | return (CMD_RETURN_NORMAL); 71 | } 72 | 73 | cmdq->references++; 74 | cfg_references++; 75 | 76 | cmdq_continue(cmdq1); 77 | return (CMD_RETURN_WAIT); 78 | } 79 | 80 | void 81 | cmd_source_file_done(struct cmd_q *cmdq1) 82 | { 83 | struct cmd_q *cmdq = cmdq1->data; 84 | 85 | if (cmdq1->client_exit >= 0) 86 | cmdq->client_exit = cmdq1->client_exit; 87 | 88 | cmdq_free(cmdq1); 89 | 90 | cfg_references--; 91 | 92 | if (cmdq_free(cmdq)) 93 | return; 94 | 95 | if (cfg_references == 0) 96 | cfg_print_causes(cmdq); 97 | cmdq_continue(cmdq); 98 | } 99 | -------------------------------------------------------------------------------- /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 | .name = "swap-window", 33 | .alias = "swapw", 34 | 35 | .args = { "ds:t:", 0, 0 }, 36 | .usage = "[-d] " CMD_SRCDST_WINDOW_USAGE, 37 | 38 | .sflag = CMD_WINDOW_MARKED, 39 | .tflag = CMD_WINDOW, 40 | 41 | .flags = 0, 42 | .exec = cmd_swap_window_exec 43 | }; 44 | 45 | enum cmd_retval 46 | cmd_swap_window_exec(struct cmd *self, struct cmd_q *cmdq) 47 | { 48 | #ifdef TMATE 49 | cmdq_error(cmdq, "swap window is not supported with tmate"); 50 | return (CMD_RETURN_ERROR); 51 | #else 52 | struct session *src, *dst; 53 | struct session_group *sg_src, *sg_dst; 54 | struct winlink *wl_src, *wl_dst; 55 | struct window *w; 56 | 57 | wl_src = cmdq->state.sflag.wl; 58 | src = cmdq->state.sflag.s; 59 | sg_src = session_group_find(src); 60 | 61 | wl_dst = cmdq->state.tflag.wl; 62 | dst = cmdq->state.tflag.s; 63 | sg_dst = session_group_find(dst); 64 | 65 | if (src != dst && sg_src != NULL && sg_dst != NULL && 66 | sg_src == sg_dst) { 67 | cmdq_error(cmdq, "can't move window, sessions are grouped"); 68 | return (CMD_RETURN_ERROR); 69 | } 70 | 71 | if (wl_dst->window == wl_src->window) 72 | return (CMD_RETURN_NORMAL); 73 | 74 | w = wl_dst->window; 75 | wl_dst->window = wl_src->window; 76 | wl_src->window = w; 77 | 78 | if (!args_has(self->args, 'd')) { 79 | session_select(dst, wl_dst->idx); 80 | if (src != dst) 81 | session_select(src, wl_src->idx); 82 | } 83 | session_group_synchronize_from(src); 84 | server_redraw_session_group(src); 85 | if (src != dst) { 86 | session_group_synchronize_from(dst); 87 | server_redraw_session_group(dst); 88 | } 89 | recalculate_sizes(); 90 | 91 | return (CMD_RETURN_NORMAL); 92 | #endif 93 | } 94 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | #ifndef HAVE_CLOSEFROM 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | #ifdef HAVE_FCNTL_H 24 | # include 25 | #endif 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #ifdef HAVE_DIRENT_H 32 | # include 33 | # define NAMLEN(dirent) strlen((dirent)->d_name) 34 | #else 35 | # define dirent direct 36 | # define NAMLEN(dirent) (dirent)->d_namlen 37 | # ifdef HAVE_SYS_NDIR_H 38 | # include 39 | # endif 40 | # ifdef HAVE_SYS_DIR_H 41 | # include 42 | # endif 43 | # ifdef HAVE_NDIR_H 44 | # include 45 | # endif 46 | #endif 47 | 48 | #include "tmux.h" 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/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 | -------------------------------------------------------------------------------- /compat/fgetln.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015 Joerg Jung 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 | /* 18 | * portable fgetln() version, NOT reentrant 19 | */ 20 | 21 | #include 22 | #include 23 | #include 24 | 25 | #include "tmux.h" 26 | 27 | char * 28 | fgetln(FILE *fp, size_t *len) 29 | { 30 | static char *buf = NULL; 31 | static size_t bufsz = 0; 32 | size_t r = 0; 33 | char *p; 34 | int c, e; 35 | 36 | if (!fp || !len) { 37 | errno = EINVAL; 38 | return NULL; 39 | } 40 | if (!buf) { 41 | if (!(buf = calloc(1, BUFSIZ))) 42 | return NULL; 43 | bufsz = BUFSIZ; 44 | } 45 | while ((c = getc(fp)) != EOF) { 46 | buf[r++] = c; 47 | if (r == bufsz) { 48 | if (!(p = reallocarray(buf, 2, bufsz))) { 49 | e = errno; 50 | free(buf); 51 | errno = e; 52 | buf = NULL, bufsz = 0; 53 | return NULL; 54 | } 55 | buf = p, bufsz = 2 * bufsz; 56 | } 57 | if (c == '\n') 58 | break; 59 | } 60 | return (*len = r) ? buf : NULL; 61 | } 62 | -------------------------------------------------------------------------------- /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 | 44 | if (name != NULL) 45 | strlcpy(name, path, TTY_NAME_MAX); 46 | 47 | if ((slave = open(path, O_RDWR|O_NOCTTY)) == -1) 48 | goto out; 49 | 50 | switch (pid = fork()) { 51 | case -1: 52 | goto out; 53 | case 0: 54 | close(*master); 55 | 56 | close(pipe_fd[1]); 57 | while (read(pipe_fd[0], &dummy, 1) == -1) { 58 | if (errno != EINTR) 59 | break; 60 | } 61 | close(pipe_fd[0]); 62 | 63 | fd = open(_PATH_TTY, O_RDWR|O_NOCTTY); 64 | if (fd >= 0) { 65 | ioctl(fd, TIOCNOTTY, NULL); 66 | close(fd); 67 | } 68 | 69 | if (setsid() < 0) 70 | fatal("setsid"); 71 | 72 | fd = open(_PATH_TTY, O_RDWR|O_NOCTTY); 73 | if (fd >= 0) 74 | fatalx("open succeeded (failed to disconnect)"); 75 | 76 | fd = open(path, O_RDWR); 77 | if (fd < 0) 78 | fatal("open failed"); 79 | close(fd); 80 | 81 | fd = open("/dev/tty", O_WRONLY); 82 | if (fd < 0) 83 | fatal("open failed"); 84 | close(fd); 85 | 86 | if (tio != NULL && tcsetattr(slave, TCSAFLUSH, tio) == -1) 87 | fatal("tcsetattr failed"); 88 | if (ioctl(slave, TIOCSWINSZ, ws) == -1) 89 | fatal("ioctl failed"); 90 | 91 | dup2(slave, 0); 92 | dup2(slave, 1); 93 | dup2(slave, 2); 94 | if (slave > 2) 95 | close(slave); 96 | 97 | return (0); 98 | } 99 | 100 | close(slave); 101 | 102 | close(pipe_fd[0]); 103 | close(pipe_fd[1]); 104 | return (pid); 105 | 106 | out: 107 | if (*master != -1) 108 | close(*master); 109 | if (slave != -1) 110 | close(slave); 111 | 112 | close(pipe_fd[0]); 113 | close(pipe_fd[1]); 114 | return (-1); 115 | } 116 | -------------------------------------------------------------------------------- /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/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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /compat/reallocarray.c: -------------------------------------------------------------------------------- 1 | /* $OpenBSD: reallocarray.c,v 1.3 2015/09/13 08:31:47 guenther Exp $ */ 2 | /* 3 | * Copyright (c) 2008 Otto Moerbeek 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 USE, DATA OR PROFITS, WHETHER IN AN 14 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 | */ 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | #include "tmux.h" 24 | 25 | /* 26 | * This is sqrt(SIZE_MAX+1), as s1*s2 <= SIZE_MAX 27 | * if both s1 < MUL_NO_OVERFLOW and s2 < MUL_NO_OVERFLOW 28 | */ 29 | #define MUL_NO_OVERFLOW ((size_t)1 << (sizeof(size_t) * 4)) 30 | 31 | void * 32 | reallocarray(void *optr, size_t nmemb, size_t size) 33 | { 34 | if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) && 35 | nmemb > 0 && SIZE_MAX / nmemb < size) { 36 | errno = ENOMEM; 37 | return NULL; 38 | } 39 | return realloc(optr, size * nmemb); 40 | } 41 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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/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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /compat/vis.h: -------------------------------------------------------------------------------- 1 | /* $OpenBSD: vis.h,v 1.15 2015/07/20 01:52:27 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 | #define VIS_DQ 0x200 /* backslash-escape double quotes */ 54 | #define VIS_ALL 0x400 /* encode all characters */ 55 | 56 | /* 57 | * other 58 | */ 59 | #define VIS_NOSLASH 0x40 /* inhibit printing '\' */ 60 | #define VIS_GLOB 0x100 /* encode glob(3) magics and '#' */ 61 | 62 | /* 63 | * unvis return codes 64 | */ 65 | #define UNVIS_VALID 1 /* character valid */ 66 | #define UNVIS_VALIDPUSH 2 /* character valid, push back passed char */ 67 | #define UNVIS_NOCHAR 3 /* valid sequence, no character produced */ 68 | #define UNVIS_SYNBAD -1 /* unrecognized escape sequence */ 69 | #define UNVIS_ERROR -2 /* decoder in unknown state (unrecoverable) */ 70 | 71 | /* 72 | * unvis flags 73 | */ 74 | #define UNVIS_END 1 /* no more characters */ 75 | 76 | char *vis(char *, int, int, int); 77 | int strvis(char *, const char *, int); 78 | int stravis(char **, const char *, int); 79 | int strnvis(char *, const char *, size_t, int); 80 | int strvisx(char *, const char *, size_t, int); 81 | int strunvis(char *, const char *); 82 | int unvis(char *, char, int *, int); 83 | ssize_t strnunvis(char *, const char *, size_t); 84 | 85 | #endif /* !_VIS_H_ */ 86 | -------------------------------------------------------------------------------- /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_client_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_client_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 | -------------------------------------------------------------------------------- /example_tmux.conf: -------------------------------------------------------------------------------- 1 | # 2 | # Example .tmux.conf 3 | # 4 | # By Nicholas Marriott. Public domain. 5 | # 6 | 7 | # Some tweaks to the status line 8 | set -g status-bg green 9 | set -g status-right "%H:%M" 10 | set -g window-status-current-attr "underscore" 11 | 12 | # No bells at all 13 | set -g bell-action none 14 | 15 | # Lock after 15 minutes 16 | set -g lock-after-time 1800 17 | 18 | # Keep windows around after they exit 19 | set -g remain-on-exit on 20 | 21 | # Turn on xterm-keys so that additional function keys get escape sequences 22 | set -g xterm-keys on 23 | 24 | # Change the prefix key to C-a 25 | set -g prefix C-a 26 | unbind C-b 27 | bind C-a send-prefix 28 | 29 | # Turn the mouse on, but without copy mode dragging 30 | set -g mouse on 31 | unbind -n MouseDrag1Pane 32 | unbind -temacs-copy MouseDrag1Pane 33 | 34 | # Some extra key bindings to select higher numbered windows 35 | bind F1 selectw -t:10 36 | bind F2 selectw -t:11 37 | bind F3 selectw -t:12 38 | bind F4 selectw -t:13 39 | bind F5 selectw -t:14 40 | bind F6 selectw -t:15 41 | bind F7 selectw -t:16 42 | bind F8 selectw -t:17 43 | bind F9 selectw -t:18 44 | bind F10 selectw -t:19 45 | bind F11 selectw -t:20 46 | bind F12 selectw -t:21 47 | 48 | # Keys to toggle monitoring activity in a window, and synchronize-panes 49 | bind m set monitor-activity 50 | bind y set synchronize-panes\; display 'synchronize-panes #{?synchronize-panes,on,off}' 51 | 52 | # Keys to hide and show a window name from the status line 53 | bind '-' set window-status-format '#I'\; set window-status-current-format '#I' 54 | bind '+' set window-status-format '#I:#W#F'\; set window-status-current-format '#I:#W#F' 55 | 56 | # Create a single default session 57 | new -d -s0 -nirssi 'exec irssi' 58 | set -t0:0 monitor-activity on 59 | set -t0:0 aggressive-resize on 60 | neww -d -ntodo 'exec emacs ~/TODO' 61 | setw -t0:1 aggressive-resize on 62 | neww -d -nmutt 'exec mutt' 63 | setw -t0:2 aggressive-resize on 64 | neww -d 65 | neww -d 66 | neww -d 67 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /logo/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tmate-io/tmate/ac919516f4f1b10ec928e20b3a5034d18f609d68/logo/favicon.ico -------------------------------------------------------------------------------- /logo/tmux-logo-huge.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tmate-io/tmate/ac919516f4f1b10ec928e20b3a5034d18f609d68/logo/tmux-logo-huge.png -------------------------------------------------------------------------------- /logo/tmux-logo-large.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tmate-io/tmate/ac919516f4f1b10ec928e20b3a5034d18f609d68/logo/tmux-logo-large.png -------------------------------------------------------------------------------- /logo/tmux-logo-medium.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tmate-io/tmate/ac919516f4f1b10ec928e20b3a5034d18f609d68/logo/tmux-logo-medium.png -------------------------------------------------------------------------------- /logo/tmux-logo-small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tmate-io/tmate/ac919516f4f1b10ec928e20b3a5034d18f609d68/logo/tmux-logo-small.png -------------------------------------------------------------------------------- /logo/tmux-logomark.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | logomark copy 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /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 | #include 21 | 22 | #include 23 | #include 24 | #include 25 | 26 | #include "tmux.h" 27 | 28 | char * 29 | osdep_get_name(__unused int fd, char *tty) 30 | { 31 | struct psinfo p; 32 | char *path; 33 | ssize_t bytes; 34 | int f, ttyfd, retval; 35 | pid_t pgrp; 36 | 37 | if ((ttyfd = open(tty, O_RDONLY|O_NOCTTY)) == -1) 38 | return (NULL); 39 | 40 | retval = ioctl(ttyfd, TIOCGPGRP, &pgrp); 41 | close(ttyfd); 42 | if (retval == -1) 43 | return (NULL); 44 | 45 | xasprintf(&path, "/proc/%u/psinfo", (u_int) pgrp); 46 | f = open(path, O_RDONLY); 47 | free(path); 48 | if (f < 0) 49 | return (NULL); 50 | 51 | bytes = read(f, &p, sizeof(p)); 52 | close(f); 53 | if (bytes != sizeof(p)) 54 | return (NULL); 55 | 56 | return (xstrdup(p.pr_fname)); 57 | } 58 | 59 | char * 60 | osdep_get_cwd(int fd) 61 | { 62 | static char target[MAXPATHLEN + 1]; 63 | char *path; 64 | const char *ttypath; 65 | ssize_t n; 66 | pid_t pgrp; 67 | int len, retval, ttyfd; 68 | 69 | if ((ttypath = ptsname(fd)) == NULL) 70 | return (NULL); 71 | if ((ttyfd = open(ttypath, O_RDONLY|O_NOCTTY)) == -1) 72 | return (NULL); 73 | 74 | retval = ioctl(ttyfd, TIOCGPGRP, &pgrp); 75 | close(ttyfd); 76 | if (retval == -1) 77 | return (NULL); 78 | 79 | xasprintf(&path, "/proc/%u/cwd", (u_int) pgrp); 80 | n = readlink(path, target, MAXPATHLEN); 81 | free(path); 82 | if (n > 0) { 83 | target[n] = '\0'; 84 | if ((len = strlen(target)) > 1 && target[len - 1] == '/') 85 | target[len - 1] = '\0'; 86 | return (target); 87 | } 88 | return (NULL); 89 | } 90 | 91 | struct event_base * 92 | osdep_event_init(void) 93 | { 94 | return (event_init()); 95 | } 96 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | #ifndef __unused 32 | #define __unused __attribute__ ((__unused__)) 33 | #endif 34 | 35 | char * 36 | osdep_get_name(int fd, __unused char *tty) 37 | { 38 | struct proc_bsdinfo bsdinfo; 39 | pid_t pgrp; 40 | int ret; 41 | 42 | if ((pgrp = tcgetpgrp(fd)) == -1) 43 | return (NULL); 44 | 45 | ret = proc_pidinfo(pgrp, PROC_PIDTBSDINFO, 0, 46 | &bsdinfo, sizeof bsdinfo); 47 | if (ret == sizeof bsdinfo && *bsdinfo.pbi_comm != '\0') 48 | return (strdup(bsdinfo.pbi_comm)); 49 | return (NULL); 50 | } 51 | 52 | char * 53 | osdep_get_cwd(int fd) 54 | { 55 | static char wd[PATH_MAX]; 56 | struct proc_vnodepathinfo pathinfo; 57 | pid_t pgrp; 58 | int ret; 59 | 60 | if ((pgrp = tcgetpgrp(fd)) == -1) 61 | return (NULL); 62 | 63 | ret = proc_pidinfo(pgrp, PROC_PIDVNODEPATHINFO, 0, 64 | &pathinfo, sizeof pathinfo); 65 | if (ret == sizeof pathinfo) { 66 | strlcpy(wd, pathinfo.pvi_cdir.vip_path, sizeof wd); 67 | return (wd); 68 | } 69 | return (NULL); 70 | } 71 | 72 | struct event_base * 73 | osdep_event_init(void) 74 | { 75 | /* 76 | * On OS X, kqueue and poll are both completely broken and don't 77 | * work on anything except socket file descriptors (yes, really). 78 | */ 79 | setenv("EVENT_NOKQUEUE", "1", 1); 80 | setenv("EVENT_NOPOLL", "1", 1); 81 | return (event_init()); 82 | } 83 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /presentations/tmux_asiabsdcon11.odt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tmate-io/tmate/ac919516f4f1b10ec928e20b3a5034d18f609d68/presentations/tmux_asiabsdcon11.odt -------------------------------------------------------------------------------- /presentations/tmux_asiabsdcon11.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tmate-io/tmate/ac919516f4f1b10ec928e20b3a5034d18f609d68/presentations/tmux_asiabsdcon11.pdf -------------------------------------------------------------------------------- /presentations/tmux_linuxtag_2011.odp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tmate-io/tmate/ac919516f4f1b10ec928e20b3a5034d18f609d68/presentations/tmux_linuxtag_2011.odp -------------------------------------------------------------------------------- /tmate-debug.c: -------------------------------------------------------------------------------- 1 | #ifdef HAVE_EXECINFO_H 2 | #include 3 | #endif 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include "tmate.h" 9 | 10 | #ifndef HAVE_BACKTRACE 11 | 12 | void tmate_print_stack_trace(void) {} 13 | void tmate_catch_sigsegv(void) {} 14 | void tmate_preload_trace_lib(void) {} 15 | 16 | #else 17 | 18 | #if DEBUG 19 | 20 | static int print_resolved_stack_frame(const char *frame) 21 | { 22 | char file[100]; 23 | char cmd[200]; 24 | char output[300]; 25 | char address[20]; 26 | char *line; 27 | FILE *ps; 28 | 29 | static regex_t _regex; 30 | static regex_t *regex; 31 | regmatch_t matches[3]; 32 | 33 | if (!regex) { 34 | if (regcomp(&_regex, "(.+)\\(\\) \\[([^]]+)\\]", REG_EXTENDED)) 35 | return -1; 36 | regex = &_regex; 37 | } 38 | 39 | if (regexec(regex, frame, 3, matches, 0)) 40 | return -1; 41 | 42 | memcpy(file, &frame[matches[1].rm_so], matches[1].rm_eo - matches[1].rm_so); 43 | file[matches[1].rm_eo - matches[1].rm_so] = 0; 44 | 45 | memcpy(address, &frame[matches[2].rm_so], matches[2].rm_eo - matches[2].rm_so); 46 | address[matches[2].rm_eo - matches[2].rm_so] = 0; 47 | 48 | sprintf(cmd, "addr2line -e %s %s -f -p -s", file, address); 49 | 50 | ps = popen(cmd, "r"); 51 | if (!ps) 52 | return -1; 53 | 54 | line = fgets(output, sizeof(output), ps); 55 | pclose(ps); 56 | 57 | if (!line) 58 | return -1; 59 | 60 | line[strlen(line)-1] = 0; /* remove \n */ 61 | tmate_debug("%s(%s) [%s]", file, line, address); 62 | return 0; 63 | } 64 | #endif 65 | 66 | void tmate_print_stack_trace(void) 67 | { 68 | void *array[20]; 69 | size_t size; 70 | char **strings; 71 | size_t i; 72 | 73 | size = backtrace (array, 20); 74 | strings = backtrace_symbols (array, size); 75 | 76 | tmate_info ("============ %zd stack frames ============", size); 77 | 78 | for (i = 1; i < size; i++) { 79 | #if DEBUG 80 | if (print_resolved_stack_frame(strings[i]) < 0) 81 | #endif 82 | tmate_info("%s", strings[i]); 83 | } 84 | 85 | free (strings); 86 | } 87 | 88 | static void handle_crash(int sig) 89 | { 90 | /* TODO send stack trace to server */ 91 | const char *what = sig == SIGSEGV ? "SIGSEGV" : "SIGABRT"; 92 | tmate_info("%s printing stack trace", what); 93 | tmate_print_stack_trace(); 94 | 95 | /* Reraise */ 96 | signal(sig, NULL); 97 | kill(getpid(), sig); 98 | } 99 | 100 | void tmate_catch_sigsegv(void) 101 | { 102 | signal(SIGSEGV, handle_crash); 103 | signal(SIGABRT, handle_crash); 104 | } 105 | 106 | void tmate_preload_trace_lib(void) 107 | { 108 | void *array[1]; 109 | backtrace(array, 1); 110 | } 111 | 112 | #endif 113 | -------------------------------------------------------------------------------- /tmate-env.c: -------------------------------------------------------------------------------- 1 | #include "tmate.h" 2 | 3 | struct tmate_env { 4 | TAILQ_ENTRY(tmate_env) entry; 5 | char *name; 6 | char *value; 7 | }; 8 | 9 | TAILQ_HEAD(, tmate_env) tmate_env_list; 10 | 11 | void tmate_set_env(const char *name, const char *value) 12 | { 13 | struct tmate_env *tmate_env; 14 | 15 | TAILQ_FOREACH(tmate_env, &tmate_env_list, entry) { 16 | if (!strcmp(tmate_env->name, name)) { 17 | free(tmate_env->value); 18 | tmate_env->value = xstrdup(value); 19 | return; 20 | } 21 | } 22 | 23 | tmate_env = xmalloc(sizeof(*tmate_env)); 24 | tmate_env->name = xstrdup(name); 25 | tmate_env->value = xstrdup(value); 26 | TAILQ_INSERT_HEAD(&tmate_env_list, tmate_env, entry); 27 | } 28 | 29 | void tmate_format(struct format_tree *ft) 30 | { 31 | struct tmate_env *tmate_env; 32 | 33 | TAILQ_FOREACH(tmate_env, &tmate_env_list, entry) { 34 | format_add(ft, tmate_env->name, "%s", tmate_env->value); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /tmate-msg.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "tmate.h" 3 | 4 | void status_message_callback(int, short, void *); 5 | 6 | /* Very similar to status.c:status_message_set */ 7 | 8 | static void tmate_status_message_client(struct client *c, const char *message) 9 | { 10 | struct timeval tv; 11 | struct message_entry *msg, *msg1; 12 | int delay; 13 | u_int limit; 14 | 15 | limit = options_get_number(global_options, "message-limit"); 16 | delay = options_get_number(c->session ? c->session->options : global_s_options, 17 | "tmate-display-time"); 18 | 19 | status_prompt_clear(c); 20 | status_message_clear(c); 21 | 22 | xasprintf(&c->message_string, "[tmate] %s", message); 23 | 24 | msg = xcalloc(1, sizeof *msg); 25 | msg->msg_time = time(NULL); 26 | msg->msg_num = c->message_next++; 27 | msg->msg = xstrdup(c->message_string); 28 | TAILQ_INSERT_TAIL(&c->message_log, msg, entry); 29 | 30 | TAILQ_FOREACH_SAFE(msg, &c->message_log, entry, msg1) { 31 | if (msg->msg_num + limit >= c->message_next) 32 | break; 33 | free(msg->msg); 34 | TAILQ_REMOVE(&c->message_log, msg, entry); 35 | free(msg); 36 | } 37 | 38 | if (delay > 0) { 39 | tv.tv_sec = delay / 1000; 40 | tv.tv_usec = (delay % 1000) * 1000L; 41 | 42 | if (event_initialized(&c->message_timer)) 43 | evtimer_del(&c->message_timer); 44 | evtimer_set(&c->message_timer, status_message_callback, c); 45 | evtimer_add(&c->message_timer, &tv); 46 | } 47 | 48 | c->flags |= CLIENT_STATUS | CLIENT_FORCE_STATUS; 49 | 50 | recalculate_sizes(); 51 | } 52 | 53 | static void tmate_status_message_session(const char *message) 54 | { 55 | if (tmate_foreground) 56 | return; 57 | 58 | struct session *s; 59 | s = RB_MIN(sessions, &sessions); 60 | if (!s) { 61 | cfg_add_cause("%s", message); 62 | return; 63 | } 64 | 65 | struct window_pane *wp; 66 | wp = s->curw->window->active; 67 | if (wp->mode == &window_copy_mode) 68 | window_copy_add(wp, "%s", message); 69 | } 70 | 71 | void __tmate_status_message(const char *fmt, va_list ap) 72 | { 73 | struct client *c; 74 | char *message; 75 | 76 | xvasprintf(&message, fmt, ap); 77 | tmate_info("%s", message); 78 | 79 | TAILQ_FOREACH(c, &clients, entry) { 80 | if (c && !(c->flags & CLIENT_READONLY)) 81 | tmate_status_message_client(c, message); 82 | } 83 | 84 | tmate_status_message_session(message); 85 | 86 | free(message); 87 | } 88 | 89 | void tmate_status_message(const char *fmt, ...) 90 | { 91 | va_list ap; 92 | 93 | va_start(ap, fmt); 94 | __tmate_status_message(fmt, ap); 95 | va_end(ap); 96 | } 97 | -------------------------------------------------------------------------------- /tmate-protocol.h: -------------------------------------------------------------------------------- 1 | #ifndef TMATE_PROTOCOL_H 2 | #define TMATE_PROTOCOL_H 3 | 4 | enum tmate_control_out_msg_types { 5 | TMATE_CTL_HEADER, 6 | TMATE_CTL_DEAMON_OUT_MSG, 7 | TMATE_CTL_SNAPSHOT, 8 | TMATE_CTL_CLIENT_JOIN, 9 | TMATE_CTL_CLIENT_LEFT, 10 | TMATE_CTL_EXEC, 11 | TMATE_CTL_LATENCY, 12 | }; 13 | 14 | /* 15 | [TMATE_CTL_HEADER, int: ctl_proto_version, string: ip_address, string: pubkey, 16 | string: session_token, string: session_token_ro, string: ssh_cmd_fmt] 17 | string: client_version, int: client_protocol_version] 18 | [TMATE_CTL_DEAMON_OUT_MSG, object: msg] 19 | [TMATE_CTL_SNAPSHOT, [[int: pane_id, [int: cur_x, int: cur_y], int: mode, 20 | [[string: line_utf8, [int: char_attr, ...]], ...], ...], ...]] 21 | [TMATE_CTL_CLIENT_JOIN, int: client_id, string: ip_address, string: pubkey, boolean: readonly] 22 | [TMATE_CTL_CLIENT_LEFT, int: client_id] 23 | [TMATE_CTL_EXEC, string: username, string: ip_address, string: pubkey, string: command] 24 | [TMATE_CTL_LATENCY, int: client_id, int: latency_ms] // client_id == -1: tmate host 25 | */ 26 | 27 | enum tmate_control_in_msg_types { 28 | TMATE_CTL_DEAMON_FWD_MSG, 29 | TMATE_CTL_REQUEST_SNAPSHOT, 30 | TMATE_CTL_PANE_KEYS, 31 | TMATE_CTL_RESIZE, 32 | TMATE_CTL_EXEC_RESPONSE, 33 | TMATE_CTL_RENAME_SESSION, 34 | }; 35 | 36 | /* 37 | [TMATE_CTL_DEAMON_FWD_MSG, object: msg] 38 | [TMATE_CTL_REQUEST_SNAPSHOT, int: max_history_lines] 39 | [TMATE_CTL_PANE_KEYS, int: pane_id, string: keys] 40 | [TMATE_CTL_RESIZE, int: sx, int: sy] // sx == -1: no clients 41 | [TMATE_CTL_EXEC_RESPONSE, int: exit_code, string: message] 42 | [TMATE_CTL_RENAME_SESSION, string: stoken, string: stoken_ro] 43 | */ 44 | 45 | enum tmate_daemon_out_msg_types { 46 | TMATE_OUT_HEADER, 47 | TMATE_OUT_SYNC_LAYOUT, 48 | TMATE_OUT_PTY_DATA, 49 | TMATE_OUT_EXEC_CMD_STR, 50 | TMATE_OUT_FAILED_CMD, 51 | TMATE_OUT_STATUS, 52 | TMATE_OUT_SYNC_COPY_MODE, 53 | TMATE_OUT_WRITE_COPY_MODE, 54 | TMATE_OUT_FIN, 55 | TMATE_OUT_READY, 56 | TMATE_OUT_RECONNECT, 57 | TMATE_OUT_SNAPSHOT, 58 | TMATE_OUT_EXEC_CMD, 59 | TMATE_OUT_UNAME, 60 | }; 61 | 62 | /* 63 | [TMATE_OUT_HEADER, int: proto_version, string: version] 64 | [TMATE_OUT_SYNC_LAYOUT, [int: sx, int: sy, [[int: win_id, string: win_name, 65 | [[int: pane_id, int: sx, int: sy, int: xoff, int: yoff], ...], 66 | int: active_pane_id], ...], int: active_win_id] 67 | [TMATE_OUT_PTY_DATA, int: pane_id, binary: buffer] 68 | [TMATE_OUT_EXEC_CMD_STR, string: cmd] 69 | [TMATE_OUT_FAILED_CMD, int: client_id, string: cause] 70 | [TMATE_OUT_STATUS, string: left, string: right] 71 | [TMATE_OUT_SYNC_COPY_MODE, int: pane_id, [int: backing, int: oy, int: cx, int: cy, 72 | [int: selx, int: sely, int: flags], 73 | [int: type, string: input_prompt, string: input_str]]) 74 | // Any of the array can be [] 75 | [TMATE_OUT_WRITE_COPY_MODE, int: pane_id, string: str] 76 | [TMATE_OUT_FIN] 77 | [TMATE_OUT_READY] 78 | [TMATE_OUT_RECONNECT, string: reconnection_data] 79 | [TMATE_OUT_SNAPSHOT, ...] 80 | [TMATE_OUT_EXEC_CMD, string: cmd_name, ...string: args] 81 | [TMATE_OUT_UNAME, string: name.sysname, string: name.nodename, 82 | string: name.release, string: name.version, string: name.machine] 83 | */ 84 | 85 | enum tmate_daemon_in_msg_types { 86 | TMATE_IN_NOTIFY, 87 | TMATE_IN_LEGACY_PANE_KEY, 88 | TMATE_IN_RESIZE, 89 | TMATE_IN_EXEC_CMD_STR, 90 | TMATE_IN_SET_ENV, 91 | TMATE_IN_READY, 92 | TMATE_IN_PANE_KEY, 93 | TMATE_IN_EXEC_CMD, 94 | }; 95 | 96 | /* 97 | [TMATE_IN_NOTIFY, string: msg] 98 | [TMATE_IN_PANE_KEY, int: key] 99 | [TMATE_IN_RESIZE, int: sx, int: sy] // sx == -1: no clients 100 | [TMATE_IN_EXEC_CMD_STR, int: client_id, string: cmd] 101 | [TMATE_IN_SET_ENV, string: name, string: value] 102 | [TMATE_IN_READY] 103 | [TMATE_IN_PANE_KEY, int: pane_id, uint64 keycode] // pane_id == -1: active pane 104 | [TMATE_IN_EXEC_CMD, int: client_id, ...string: args] 105 | */ 106 | 107 | #endif 108 | -------------------------------------------------------------------------------- /tmate.1: -------------------------------------------------------------------------------- 1 | tmux.1 -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /tools/cmp-cvs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/ksh 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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /window-copy.h: -------------------------------------------------------------------------------- 1 | #ifndef WINDOW_COPY_H 2 | #define WINDOW_COPY_H 3 | 4 | #include "tmux.h" 5 | 6 | enum window_copy_input_type { 7 | WINDOW_COPY_OFF, 8 | WINDOW_COPY_NAMEDBUFFER, 9 | WINDOW_COPY_NUMERICPREFIX, 10 | WINDOW_COPY_SEARCHUP, 11 | WINDOW_COPY_SEARCHDOWN, 12 | WINDOW_COPY_JUMPFORWARD, 13 | WINDOW_COPY_JUMPBACK, 14 | WINDOW_COPY_JUMPTOFORWARD, 15 | WINDOW_COPY_JUMPTOBACK, 16 | WINDOW_COPY_GOTOLINE, 17 | #ifdef TMATE 18 | WINDOW_COPY_PASSWORD, 19 | #endif 20 | }; 21 | 22 | /* 23 | * Copy-mode's visible screen (the "screen" field) is filled from one of 24 | * two sources: the original contents of the pane (used when we 25 | * actually enter via the "copy-mode" command, to copy the contents of 26 | * the current pane), or else a series of lines containing the output 27 | * from an output-writing tmux command (such as any of the "show-*" or 28 | * "list-*" commands). 29 | * 30 | * In either case, the full content of the copy-mode grid is pointed at 31 | * by the "backing" field, and is copied into "screen" as needed (that 32 | * is, when scrolling occurs). When copy-mode is backed by a pane, 33 | * backing points directly at that pane's screen structure (&wp->base); 34 | * when backed by a list of output-lines from a command, it points at 35 | * a newly-allocated screen structure (which is deallocated when the 36 | * mode ends). 37 | */ 38 | 39 | #ifdef TMATE 40 | typedef void (*copy_password_callback)(const char *password, void *private); 41 | #endif 42 | 43 | struct window_copy_mode_data { 44 | struct screen screen; 45 | 46 | struct screen *backing; 47 | int backing_written; /* backing display started */ 48 | 49 | struct mode_key_data mdata; 50 | 51 | u_int oy; 52 | 53 | u_int selx; 54 | u_int sely; 55 | 56 | int rectflag; /* in rectangle copy mode? */ 57 | int scroll_exit; /* exit on scroll to end? */ 58 | 59 | u_int cx; 60 | u_int cy; 61 | 62 | u_int lastcx; /* position in last line w/ content */ 63 | u_int lastsx; /* size of last line w/ content */ 64 | 65 | enum window_copy_input_type inputtype; 66 | const char *inputprompt; 67 | char *inputstr; 68 | int inputexit; 69 | 70 | int numprefix; 71 | 72 | enum window_copy_input_type searchtype; 73 | char *searchstr; 74 | 75 | enum window_copy_input_type jumptype; 76 | char jumpchar; 77 | 78 | #ifdef TMATE 79 | copy_password_callback password_cb; 80 | void *password_cb_private; 81 | #endif 82 | }; 83 | 84 | extern int window_copy_update_selection(struct window_pane *, int); 85 | extern void window_copy_redraw_screen(struct window_pane *); 86 | 87 | #endif 88 | -------------------------------------------------------------------------------- /xmalloc.c: -------------------------------------------------------------------------------- 1 | /* $OpenBSD$ */ 2 | 3 | /* 4 | * Author: Tatu Ylonen 5 | * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland 6 | * All rights reserved 7 | * Versions of malloc and friends that check their results, and never return 8 | * failure (they call fatal if they encounter an error). 9 | * 10 | * As far as I am concerned, the code I have written for this software 11 | * can be used freely for any purpose. Any derived versions of this 12 | * software must be clearly marked as such, and if the derived work is 13 | * incompatible with the protocol description in the RFC file, it must be 14 | * called by a name other than "ssh" or "Secure Shell". 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | #include "tmux.h" 25 | 26 | void * 27 | xmalloc(size_t size) 28 | { 29 | void *ptr; 30 | 31 | if (size == 0) 32 | fatal("xmalloc: zero size"); 33 | ptr = malloc(size); 34 | if (ptr == NULL) 35 | fatal("xmalloc: allocating %zu bytes: %s", 36 | size, strerror(errno)); 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 | fatal("xcalloc: zero size"); 47 | ptr = calloc(nmemb, size); 48 | if (ptr == NULL) 49 | fatal("xcalloc: allocating %zu * %zu bytes: %s", 50 | nmemb, size, strerror(errno)); 51 | return ptr; 52 | } 53 | 54 | void * 55 | xrealloc(void *ptr, size_t size) 56 | { 57 | return xreallocarray(ptr, 1, size); 58 | } 59 | 60 | void * 61 | xreallocarray(void *ptr, size_t nmemb, size_t size) 62 | { 63 | void *new_ptr; 64 | 65 | if (nmemb == 0 || size == 0) 66 | fatal("xreallocarray: zero size"); 67 | new_ptr = reallocarray(ptr, nmemb, size); 68 | if (new_ptr == NULL) 69 | fatal("xreallocarray: allocating %zu * %zu bytes: %s", 70 | nmemb, size, strerror(errno)); 71 | return new_ptr; 72 | } 73 | 74 | char * 75 | xstrdup(const char *str) 76 | { 77 | char *cp; 78 | 79 | if ((cp = strdup(str)) == NULL) 80 | fatal("xstrdup: %s", strerror(errno)); 81 | return cp; 82 | } 83 | 84 | int 85 | xasprintf(char **ret, const char *fmt, ...) 86 | { 87 | va_list ap; 88 | int i; 89 | 90 | va_start(ap, fmt); 91 | i = xvasprintf(ret, fmt, ap); 92 | va_end(ap); 93 | 94 | return i; 95 | } 96 | 97 | __attribute__((__format__(__printf__, 2, 0))) 98 | int 99 | xvasprintf(char **ret, const char *fmt, va_list ap) 100 | { 101 | int i; 102 | 103 | i = vasprintf(ret, fmt, ap); 104 | 105 | if (i < 0 || *ret == NULL) 106 | fatal("xasprintf: %s", strerror(errno)); 107 | 108 | return i; 109 | } 110 | 111 | int 112 | xsnprintf(char *str, size_t len, const char *fmt, ...) 113 | { 114 | va_list ap; 115 | int i; 116 | 117 | va_start(ap, fmt); 118 | i = xvsnprintf(str, len, fmt, ap); 119 | va_end(ap); 120 | 121 | return i; 122 | } 123 | 124 | __attribute__((__format__(__printf__, 3, 0))) 125 | int 126 | xvsnprintf(char *str, size_t len, const char *fmt, va_list ap) 127 | { 128 | int i; 129 | 130 | if (len > INT_MAX) 131 | fatal("xsnprintf: len > INT_MAX"); 132 | 133 | i = vsnprintf(str, len, fmt, ap); 134 | 135 | if (i < 0 || i >= (int)len) 136 | fatal("xsnprintf: overflow"); 137 | 138 | return i; 139 | } 140 | -------------------------------------------------------------------------------- /xmalloc.h: -------------------------------------------------------------------------------- 1 | /* $OpenBSD$ */ 2 | 3 | /* 4 | * Author: Tatu Ylonen 5 | * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland 6 | * All rights reserved 7 | * Created: Mon Mar 20 22:09:17 1995 ylo 8 | * 9 | * Versions of malloc and friends that check their results, and never return 10 | * failure (they call fatal if they encounter an error). 11 | * 12 | * As far as I am concerned, the code I have written for this software 13 | * can be used freely for any purpose. Any derived versions of this 14 | * software must be clearly marked as such, and if the derived work is 15 | * incompatible with the protocol description in the RFC file, it must be 16 | * called by a name other than "ssh" or "Secure Shell". 17 | */ 18 | 19 | #ifndef XMALLOC_H 20 | #define XMALLOC_H 21 | 22 | #if !defined(__bounded__) 23 | # define __bounded__(x, y, z) 24 | #endif 25 | 26 | void *xmalloc(size_t); 27 | void *xcalloc(size_t, size_t); 28 | void *xrealloc(void *, size_t); 29 | void *xreallocarray(void *, size_t, size_t); 30 | char *xstrdup(const char *); 31 | int xasprintf(char **, const char *, ...) 32 | __attribute__((__format__ (printf, 2, 3))) 33 | __attribute__((__nonnull__ (2))); 34 | int xvasprintf(char **, const char *, va_list) 35 | __attribute__((__nonnull__ (2))); 36 | int xsnprintf(char *, size_t, const char *, ...) 37 | __attribute__((__format__ (printf, 3, 4))) 38 | __attribute__((__nonnull__ (3))) 39 | __attribute__((__bounded__ (__string__, 1, 2))); 40 | int xvsnprintf(char *, size_t, const char *, va_list) 41 | __attribute__((__nonnull__ (3))) 42 | __attribute__((__bounded__ (__string__, 1, 2))); 43 | 44 | #endif /* XMALLOC_H */ 45 | --------------------------------------------------------------------------------