|  | 
| 16 | 16 | package daemon | 
| 17 | 17 | 
 | 
| 18 | 18 | import ( | 
|  | 19 | +	"errors" | 
| 19 | 20 | 	"fmt" | 
| 20 | 21 | 	"io" | 
| 21 | 22 | 	"io/ioutil" | 
| 22 | 23 | 	"net" | 
| 23 | 24 | 	"net/http" | 
| 24 | 25 | 	"os" | 
| 25 | 26 | 	"runtime" | 
|  | 27 | +	"syscall" | 
| 26 | 28 | 
 | 
|  | 29 | +	"github.com/arduino/arduino-cli/cli/errorcodes" | 
|  | 30 | +	"github.com/arduino/arduino-cli/cli/feedback" | 
| 27 | 31 | 	"github.com/arduino/arduino-cli/cli/globals" | 
| 28 | 32 | 	"github.com/arduino/arduino-cli/commands/daemon" | 
| 29 | 33 | 	srv_commands "github.com/arduino/arduino-cli/rpc/commands" | 
| @@ -87,8 +91,29 @@ func runDaemonCommand(cmd *cobra.Command, args []string) { | 
| 87 | 91 | 	logrus.Infof("Starting daemon on TCP port %s", port) | 
| 88 | 92 | 	lis, err := net.Listen("tcp", fmt.Sprintf(":%s", port)) | 
| 89 | 93 | 	if err != nil { | 
| 90 |  | -		logrus.Fatalf("failed to listen: %v", err) | 
|  | 94 | +		// Invalid port, such as "Foo" | 
|  | 95 | +		var dnsError *net.DNSError | 
|  | 96 | +		if errors.As(err, &dnsError) { | 
|  | 97 | +			feedback.Errorf("Failed to listen on TCP port: %s. %s is unknown name.", port, dnsError.Name) | 
|  | 98 | +			os.Exit(errorcodes.ErrCoreConfig) | 
|  | 99 | +		} | 
|  | 100 | +		// Invalid port number, such as -1 | 
|  | 101 | +		var addrError *net.AddrError | 
|  | 102 | +		if errors.As(err, &addrError) { | 
|  | 103 | +			feedback.Errorf("Failed to listen on TCP port: %s. %s is an invalid port.", port, addrError.Addr) | 
|  | 104 | +			os.Exit(errorcodes.ErrCoreConfig) | 
|  | 105 | +		} | 
|  | 106 | +		// Port is already in use | 
|  | 107 | +		var syscallErr *os.SyscallError | 
|  | 108 | +		if errors.As(err, &syscallErr) && errors.Is(syscallErr.Err, syscall.EADDRINUSE) { | 
|  | 109 | +			feedback.Errorf("Failed to listen on TCP port: %s. Address already in use.", port) | 
|  | 110 | +			os.Exit(errorcodes.ErrNetwork) | 
|  | 111 | +		} | 
|  | 112 | +		feedback.Errorf("Failed to listen on TCP port: %s. Unexpected error: %v", port, err) | 
|  | 113 | +		os.Exit(errorcodes.ErrGeneric) | 
| 91 | 114 | 	} | 
|  | 115 | +	// This message will show up on the stdout of the daemon process so that gRPC clients know it is time to connect. | 
|  | 116 | +	logrus.Infof("Daemon is listening on TCP port %s...", port) | 
| 92 | 117 | 	if err := s.Serve(lis); err != nil { | 
| 93 | 118 | 		logrus.Fatalf("failed to serve: %v", err) | 
| 94 | 119 | 	} | 
|  | 
0 commit comments