Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Add support for connecting via UNIX socket #63

Merged
merged 2 commits into from
Jan 10, 2018
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 51 additions & 21 deletions rmate
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ hostname=$($(hostname_command))
# default configuration
host=localhost
port=52698
unix=
eval home=$(builtin printf "~%q" "${SUDO_USER:-$LOGNAME}")

function load_config {
Expand All @@ -65,13 +66,16 @@ function load_config {

local host_pattern="^host(:[[:space:]]+|=)([^ ]+)"
local port_pattern="^port(:[[:space:]]+|=)([0-9]+)"
local unix_pattern="^unix(:[[:space:]]+|=)(.+)"

if [ -f "$rc_file" ]; then
while read -r row; do
if [[ "$row" =~ $host_pattern ]]; then
host=${BASH_REMATCH[2]}
elif [[ "$row" =~ $port_pattern ]]; then
port=${BASH_REMATCH[2]}
elif [[ "$row" =~ $unix_pattern ]]; then
unix=${BASH_REMATCH[2]}
fi
done < "$rc_file"
fi
Expand All @@ -83,7 +87,7 @@ done

host="${RMATE_HOST:-$host}"
port="${RMATE_PORT:-$port}"

unix="${RMATE_UNIX:-$unix}"

# misc initialization
filepaths=()
Expand All @@ -103,6 +107,7 @@ function showusage {
-H, --host HOST Connect to HOST. Use 'auto' to detect the host from
SSH. Defaults to $host.
-p, --port PORT Port number to use for connection. Defaults to $port.
-u, --unix PATH UNIX socket for connection. Overrides host/port.
-w, --[no-]wait Wait for file to be closed by TextMate.
-l, --line LINE Place caret on line number after loading file.
+N Alias for --line, if N is a number (eg.: +5).
Expand Down Expand Up @@ -165,6 +170,10 @@ while [[ "${1:0:1}" = "-" || "$1" =~ ^\+([0-9]+)$ ]]; do
port=$2
shift
;;
-u|--unix)
unix=$2
shift
;;
-w|--wait)
nowait=false
;;
Expand Down Expand Up @@ -272,29 +281,29 @@ function open_file {
displayname="$hostname:untitled"
fi

echo "open" 1>&3
echo "display-name: $displayname" 1>&3
echo "real-path: $realpath" 1>&3
echo "data-on-save: yes" 1>&3
echo "re-activate: yes" 1>&3
echo "token: $filepath" 1>&3
echo "open" 1>&4
echo "display-name: $displayname" 1>&4
echo "real-path: $realpath" 1>&4
echo "data-on-save: yes" 1>&4
echo "re-activate: yes" 1>&4
echo "token: $filepath" 1>&4

if [[ $new = true ]]; then
echo "new: yes" 1>&3
echo "new: yes" 1>&4
fi

if [ "$selection" != "" ]; then
echo "selection: $selection" 1>&3
echo "selection: $selection" 1>&4
fi

if [ "$filetype" != "" ]; then
echo "file-type: $filetype" 1>&3
echo "file-type: $filetype" 1>&4
fi

if [ "$filepath" != "-" ] && [ -f "$filepath" ]; then
filesize=$(($(wc -c <"$realpath")))
echo "data: $filesize" 1>&3
cat "$realpath" 1>&3
echo "data: $filesize" 1>&4
cat "$realpath" 1>&4
elif [ "$filepath" = "-" ]; then
if [ -t 0 ]; then
echo "Reading from stdin, press ^D to stop"
Expand All @@ -306,13 +315,13 @@ function open_file {
data=`cat; echo x`
data=${data%x}
filesize=$(($(echo -ne "$data" | wc -c)))
echo "data: $filesize" 1>&3
echo -n "$data" 1>&3
echo "data: $filesize" 1>&4
echo -n "$data" 1>&4
else
echo "data: 0" 1>&3
echo "data: 0" 1>&4
fi

echo 1>&3
echo 1>&4
}

function handle_connection {
Expand Down Expand Up @@ -381,11 +390,32 @@ function handle_connection {

# connect to textmate and send command
#
exec 3<> "/dev/tcp/$host/$port"
if [ -n "$unix" ] ; then
if [ ! -S "$unix" ] ; then
echo "$unix is not a socket!"
exit 1
fi

fifodir=$(mktemp -d) && \
mkfifo "$fifodir/in" "$fifodir/out" && \
( (nc -U "$unix" < "$fifodir/in" > "$fifodir/out" &) &) && \
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if I should be doing something smarter than nothing with the stderr of nc; maybe direct it to a file in the fifodir and cat it out if there's a connection error?

exec 4> "$fifodir/in" && \
exec 3< "$fifodir/out"

if [ $? -gt 0 ]; then
echo "Unable to connect to TextMate on $host:$port"
exit 1
connect_status=$?

[ -d "$fifodir" ] && rm -rf "$fifodir"
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After everything is connected we can just trash the fifodir immediately, as everything has its file descriptors open and nothing else will need to refer to anything there by name again.


if [ $connect_status -gt 0 ] ; then
echo "Unable to connect to TextMate on $unix"
exit 1
fi
else
exec 3<> "/dev/tcp/$host/$port" && exec 4>&3
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately I wasn't able to figure out how to get read and write to the socket happening on the same file descriptor, so I had to split them, and that meant splitting them even in the TCP case :(

if [ $? -gt 0 ]; then
echo "Unable to connect to TextMate on $host:$port"
exit 1
fi
fi

read -r server_info 0<&3
Expand All @@ -396,7 +426,7 @@ for i in "${!filepaths[@]}"; do
open_file "$i"
done

echo "." 1>&3
echo "." 1>&4

if [[ $nowait = true ]]; then
exec </dev/null >/dev/null 2>/dev/null
Expand Down