Skip to content

Commit

Permalink
send: use send instead of nc or echo to communicate with the unix socket
Browse files Browse the repository at this point in the history
Using echo to write data to a unix socket as if it is a regular file
"works", but it doesn't respect the usual protocol that `netcat` uses.

However, `netcat` comes in two main flavors. GNU and BSD.

BSD netcat has the -w and -U flag, both of which are missing form GNU.

The reliability of savvy record now has a hard dependency on the version
of netcat installed on the user's machine.

`socat` is a third alternative but that is not guaranteed to be
installed by default in most cases.

This commit introduces `savvy send` to address all the issue above.

`send` is a simple go program that creates a conn to the unix socket and
uses the go standard library to write data to the socket and close the
conn.

send will support all the platforms that Go supports by default and we
no longer rely on the user having a particular binary.
  • Loading branch information
joshi4 committed Feb 19, 2024
1 parent 2873032 commit 1935876
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 2 deletions.
48 changes: 48 additions & 0 deletions cmd/send.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package cmd

import (
"fmt"
"net"
"os"

"github.com/getsavvyinc/savvy-cli/display"
"github.com/spf13/cobra"
)

// sendCmd represents the send command
var sendCmd = &cobra.Command{
Use: "send",
// Send is meant for internal use only.
Hidden: true,
Short: "Send data to the unix socket listening at SAVVY_SOCKET_PATH",
Long: `Send data to the unix socket listening at SAVVY_SOCKET_PATH`,
Run: func(cmd *cobra.Command, args []string) {
socketPath := os.Getenv("SAVVY_SOCKET_PATH")
if socketPath == "" {
err := fmt.Errorf("cannot record commands: SAVVY_SOCKET_PATH is not set")
display.ErrorWithSupportCTA(err)
return
}
conn, err := net.Dial("unix", socketPath)
if err != nil {
err = fmt.Errorf("failed to record command: %v", err)
display.ErrorWithSupportCTA(err)
return
}
defer conn.Close()
message := args[:]
if len(message) == 0 {
// nothing to do.
return
}
if _, err = conn.Write([]byte(fmt.Sprintf("%s\n", message))); err != nil {
err = fmt.Errorf("failed to record command locally: %v", err)
display.ErrorWithSupportCTA(err)
return
}
},
}

func init() {
rootCmd.AddCommand(sendCmd)
}
2 changes: 1 addition & 1 deletion cmd/setup/bash-preexec.sh
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ savvy_cmd_pre_exec() {
#TODO: expand aliases
local cmd=$BASH_COMMAND
if [[ "${SAVVY_CONTEXT}" == "1" ]] ; then
nc -w0 -U $SAVVY_INPUT_FILE <<< "$cmd"
SAVVY_SOCKET_PATH=${SAVVY_INPUT_FILE} savvy send "$cmd"
fi
}

Expand Down
2 changes: 1 addition & 1 deletion cmd/setup/savvy.zsh
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ function __savvy_cmd_pre_exec__() {
# $2 is the command with all the aliases expanded
local cmd=$3
if [[ "${SAVVY_CONTEXT}" == "1" ]] ; then
nc -w0 -U $SAVVY_INPUT_FILE <<< "$cmd"
SAVVY_SOCKET_PATH=${SAVVY_INPUT_FILE} savvy send "$cmd"
fi
}
add-zsh-hook preexec __savvy_cmd_pre_exec__
Expand Down

0 comments on commit 1935876

Please sign in to comment.