1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-01-09 01:18:00 +00:00

Make the backend_init error message dynamic. (NFC)

Now, instead of a 'const char *' in the static data segment, error
messages returned from backend setup are dynamically allocated and
freed by the caller.

This will allow me to make the messages much more specific (including
errno values and the like). However, this commit is pure refactoring:
I've _just_ changed the allocation policy, and left all the messages
alone.
This commit is contained in:
Simon Tatham 2020-04-18 13:28:33 +01:00
parent d9c4ce9fd8
commit df2994a05a
14 changed files with 88 additions and 87 deletions

10
putty.h
View File

@ -495,10 +495,10 @@ struct Backend {
const BackendVtable *vt; const BackendVtable *vt;
}; };
struct BackendVtable { struct BackendVtable {
const char *(*init) (const BackendVtable *vt, Seat *seat, char *(*init) (const BackendVtable *vt, Seat *seat,
Backend **backend_out, LogContext *logctx, Conf *conf, Backend **backend_out, LogContext *logctx, Conf *conf,
const char *host, int port, const char *host, int port, char **realhost,
char **realhost, bool nodelay, bool keepalive); bool nodelay, bool keepalive);
void (*free) (Backend *be); void (*free) (Backend *be);
/* Pass in a replacement configuration. */ /* Pass in a replacement configuration. */
@ -540,7 +540,7 @@ struct BackendVtable {
unsigned serial_parity_mask, serial_flow_mask; unsigned serial_parity_mask, serial_flow_mask;
}; };
static inline const char *backend_init( static inline char *backend_init(
const BackendVtable *vt, Seat *seat, Backend **out, LogContext *logctx, const BackendVtable *vt, Seat *seat, Backend **out, LogContext *logctx,
Conf *conf, const char *host, int port, char **rhost, bool nd, bool ka) Conf *conf, const char *host, int port, char **rhost, bool nd, bool ka)
{ return vt->init(vt, seat, out, logctx, conf, host, port, rhost, nd, ka); } { return vt->init(vt, seat, out, logctx, conf, host, port, rhost, nd, ka); }

12
raw.c
View File

@ -119,10 +119,10 @@ static const PlugVtable Raw_plugvt = {
* Also places the canonical host name into `realhost'. It must be * Also places the canonical host name into `realhost'. It must be
* freed by the caller. * freed by the caller.
*/ */
static const char *raw_init(const BackendVtable *vt, Seat *seat, static char *raw_init(const BackendVtable *vt, Seat *seat,
Backend **backend_handle, LogContext *logctx, Backend **backend_handle, LogContext *logctx,
Conf *conf, const char *host, int port, Conf *conf, const char *host, int port,
char **realhost, bool nodelay, bool keepalive) char **realhost, bool nodelay, bool keepalive)
{ {
SockAddr *addr; SockAddr *addr;
const char *err; const char *err;
@ -155,7 +155,7 @@ static const char *raw_init(const BackendVtable *vt, Seat *seat,
raw->logctx, "main connection"); raw->logctx, "main connection");
if ((err = sk_addr_error(addr)) != NULL) { if ((err = sk_addr_error(addr)) != NULL) {
sk_addr_free(addr); sk_addr_free(addr);
return err; return dupstr(err);
} }
if (port < 0) if (port < 0)
@ -167,7 +167,7 @@ static const char *raw_init(const BackendVtable *vt, Seat *seat,
raw->s = new_connection(addr, *realhost, port, false, true, nodelay, raw->s = new_connection(addr, *realhost, port, false, true, nodelay,
keepalive, &raw->plug, conf); keepalive, &raw->plug, conf);
if ((err = sk_socket_error(raw->s)) != NULL) if ((err = sk_socket_error(raw->s)) != NULL)
return err; return dupstr(err);
loghost = conf_get_str(conf, CONF_loghost); loghost = conf_get_str(conf, CONF_loghost);
if (*loghost) { if (*loghost) {

View File

@ -153,10 +153,10 @@ static const PlugVtable Rlogin_plugvt = {
* Also places the canonical host name into `realhost'. It must be * Also places the canonical host name into `realhost'. It must be
* freed by the caller. * freed by the caller.
*/ */
static const char *rlogin_init(const BackendVtable *vt, Seat *seat, static char *rlogin_init(const BackendVtable *vt, Seat *seat,
Backend **backend_handle, LogContext *logctx, Backend **backend_handle, LogContext *logctx,
Conf *conf, const char *host, int port, Conf *conf, const char *host, int port,
char **realhost, bool nodelay, bool keepalive) char **realhost, bool nodelay, bool keepalive)
{ {
SockAddr *addr; SockAddr *addr;
const char *err; const char *err;
@ -188,7 +188,7 @@ static const char *rlogin_init(const BackendVtable *vt, Seat *seat,
rlogin->logctx, "rlogin connection"); rlogin->logctx, "rlogin connection");
if ((err = sk_addr_error(addr)) != NULL) { if ((err = sk_addr_error(addr)) != NULL) {
sk_addr_free(addr); sk_addr_free(addr);
return err; return dupstr(err);
} }
if (port < 0) if (port < 0)
@ -200,7 +200,7 @@ static const char *rlogin_init(const BackendVtable *vt, Seat *seat,
rlogin->s = new_connection(addr, *realhost, port, true, false, rlogin->s = new_connection(addr, *realhost, port, true, false,
nodelay, keepalive, &rlogin->plug, conf); nodelay, keepalive, &rlogin->plug, conf);
if ((err = sk_socket_error(rlogin->s)) != NULL) if ((err = sk_socket_error(rlogin->s)) != NULL)
return err; return dupstr(err);
loghost = conf_get_str(conf, CONF_loghost); loghost = conf_get_str(conf, CONF_loghost);
if (*loghost) { if (*loghost) {

22
ssh.c
View File

@ -704,7 +704,7 @@ static const PlugVtable Ssh_plugvt = {
* Also places the canonical host name into `realhost'. It must be * Also places the canonical host name into `realhost'. It must be
* freed by the caller. * freed by the caller.
*/ */
static const char *connect_to_host( static char *connect_to_host(
Ssh *ssh, const char *host, int port, char **realhost, Ssh *ssh, const char *host, int port, char **realhost,
bool nodelay, bool keepalive) bool nodelay, bool keepalive)
{ {
@ -765,7 +765,7 @@ static const char *connect_to_host(
ssh->logctx, "SSH connection"); ssh->logctx, "SSH connection");
if ((err = sk_addr_error(addr)) != NULL) { if ((err = sk_addr_error(addr)) != NULL) {
sk_addr_free(addr); sk_addr_free(addr);
return err; return dupstr(err);
} }
ssh->fullhostname = dupstr(*realhost); /* save in case of GSSAPI */ ssh->fullhostname = dupstr(*realhost); /* save in case of GSSAPI */
@ -775,7 +775,7 @@ static const char *connect_to_host(
if ((err = sk_socket_error(ssh->s)) != NULL) { if ((err = sk_socket_error(ssh->s)) != NULL) {
ssh->s = NULL; ssh->s = NULL;
seat_notify_remote_exit(ssh->seat); seat_notify_remote_exit(ssh->seat);
return err; return dupstr(err);
} }
} }
@ -870,12 +870,11 @@ bool ssh_is_bare(Ssh *ssh)
* *
* Returns an error message, or NULL on success. * Returns an error message, or NULL on success.
*/ */
static const char *ssh_init(const BackendVtable *vt, Seat *seat, static char *ssh_init(const BackendVtable *vt, Seat *seat,
Backend **backend_handle, LogContext *logctx, Backend **backend_handle, LogContext *logctx,
Conf *conf, const char *host, int port, Conf *conf, const char *host, int port,
char **realhost, bool nodelay, bool keepalive) char **realhost, bool nodelay, bool keepalive)
{ {
const char *p;
Ssh *ssh; Ssh *ssh;
ssh = snew(Ssh); ssh = snew(Ssh);
@ -906,15 +905,16 @@ static const char *ssh_init(const BackendVtable *vt, Seat *seat,
random_ref(); /* do this now - may be needed by sharing setup code */ random_ref(); /* do this now - may be needed by sharing setup code */
ssh->need_random_unref = true; ssh->need_random_unref = true;
p = connect_to_host(ssh, host, port, realhost, nodelay, keepalive); char *conn_err = connect_to_host(
if (p != NULL) { ssh, host, port, realhost, nodelay, keepalive);
if (conn_err) {
/* Call random_unref now instead of waiting until the caller /* Call random_unref now instead of waiting until the caller
* frees this useless Ssh object, in case the caller is * frees this useless Ssh object, in case the caller is
* impatient and just exits without bothering, in which case * impatient and just exits without bothering, in which case
* the random seed won't be re-saved. */ * the random seed won't be re-saved. */
ssh->need_random_unref = false; ssh->need_random_unref = false;
random_unref(); random_unref();
return p; return conn_err;
} }
return NULL; return NULL;

View File

@ -635,11 +635,11 @@ static void supdup_send_config(Supdup *supdup)
* Also places the canonical host name into `realhost'. It must be * Also places the canonical host name into `realhost'. It must be
* freed by the caller. * freed by the caller.
*/ */
static const char *supdup_init(const BackendVtable *x, Seat *seat, static char *supdup_init(const BackendVtable *x, Seat *seat,
Backend **backend_handle, Backend **backend_handle,
LogContext *logctx, Conf *conf, LogContext *logctx, Conf *conf,
const char *host, int port, char **realhost, const char *host, int port, char **realhost,
bool nodelay, bool keepalive) bool nodelay, bool keepalive)
{ {
static const PlugVtable fn_table = { static const PlugVtable fn_table = {
.log = supdup_log, .log = supdup_log,
@ -696,7 +696,7 @@ static const char *supdup_init(const BackendVtable *x, Seat *seat,
addr = name_lookup(host, port, realhost, supdup->conf, addressfamily, NULL, ""); addr = name_lookup(host, port, realhost, supdup->conf, addressfamily, NULL, "");
if ((err = sk_addr_error(addr)) != NULL) { if ((err = sk_addr_error(addr)) != NULL) {
sk_addr_free(addr); sk_addr_free(addr);
return err; return dupstr(err);
} }
if (port < 0) if (port < 0)
@ -708,7 +708,7 @@ static const char *supdup_init(const BackendVtable *x, Seat *seat,
supdup->s = new_connection(addr, *realhost, port, false, true, supdup->s = new_connection(addr, *realhost, port, false, true,
nodelay, keepalive, &supdup->plug, supdup->conf); nodelay, keepalive, &supdup->plug, supdup->conf);
if ((err = sk_socket_error(supdup->s)) != NULL) if ((err = sk_socket_error(supdup->s)) != NULL)
return err; return dupstr(err);
supdup->pinger = pinger_new(supdup->conf, &supdup->backend); supdup->pinger = pinger_new(supdup->conf, &supdup->backend);

View File

@ -678,10 +678,10 @@ static const PlugVtable Telnet_plugvt = {
* Also places the canonical host name into `realhost'. It must be * Also places the canonical host name into `realhost'. It must be
* freed by the caller. * freed by the caller.
*/ */
static const char *telnet_init(const BackendVtable *vt, Seat *seat, static char *telnet_init(const BackendVtable *vt, Seat *seat,
Backend **backend_handle, LogContext *logctx, Backend **backend_handle, LogContext *logctx,
Conf *conf, const char *host, int port, Conf *conf, const char *host, int port,
char **realhost, bool nodelay, bool keepalive) char **realhost, bool nodelay, bool keepalive)
{ {
SockAddr *addr; SockAddr *addr;
const char *err; const char *err;
@ -720,7 +720,7 @@ static const char *telnet_init(const BackendVtable *vt, Seat *seat,
telnet->logctx, "Telnet connection"); telnet->logctx, "Telnet connection");
if ((err = sk_addr_error(addr)) != NULL) { if ((err = sk_addr_error(addr)) != NULL) {
sk_addr_free(addr); sk_addr_free(addr);
return err; return dupstr(err);
} }
if (port < 0) if (port < 0)
@ -732,7 +732,7 @@ static const char *telnet_init(const BackendVtable *vt, Seat *seat,
telnet->s = new_connection(addr, *realhost, port, false, true, nodelay, telnet->s = new_connection(addr, *realhost, port, false, true, nodelay,
keepalive, &telnet->plug, telnet->conf); keepalive, &telnet->plug, telnet->conf);
if ((err = sk_socket_error(telnet->s)) != NULL) if ((err = sk_socket_error(telnet->s)) != NULL)
return err; return dupstr(err);
telnet->pinger = pinger_new(telnet->conf, &telnet->backend); telnet->pinger = pinger_new(telnet->conf, &telnet->backend);

View File

@ -32,12 +32,10 @@
#include "putty.h" #include "putty.h"
static const char *null_init(const BackendVtable *, Seat *, Backend **, static char *null_init(const BackendVtable *, Seat *, Backend **, LogContext *,
LogContext *, Conf *, const char *, int, char **, Conf *, const char *, int, char **, bool, bool);
bool, bool); static char *loop_init(const BackendVtable *, Seat *, Backend **, LogContext *,
static const char *loop_init(const BackendVtable *, Seat *, Backend **, Conf *, const char *, int, char **, bool, bool);
LogContext *, Conf *, const char *, int, char **,
bool, bool);
static void null_free(Backend *); static void null_free(Backend *);
static void loop_free(Backend *); static void loop_free(Backend *);
static void null_reconfig(Backend *, Conf *); static void null_reconfig(Backend *, Conf *);
@ -104,10 +102,10 @@ struct loop_state {
Backend backend; Backend backend;
}; };
static const char *null_init(const BackendVtable *vt, Seat *seat, static char *null_init(const BackendVtable *vt, Seat *seat,
Backend **backend_handle, LogContext *logctx, Backend **backend_handle, LogContext *logctx,
Conf *conf, const char *host, int port, Conf *conf, const char *host, int port,
char **realhost, bool nodelay, bool keepalive) { char **realhost, bool nodelay, bool keepalive) {
/* No local authentication phase in this protocol */ /* No local authentication phase in this protocol */
seat_set_trust_status(seat, false); seat_set_trust_status(seat, false);
@ -115,10 +113,10 @@ static const char *null_init(const BackendVtable *vt, Seat *seat,
return NULL; return NULL;
} }
static const char *loop_init(const BackendVtable *vt, Seat *seat, static char *loop_init(const BackendVtable *vt, Seat *seat,
Backend **backend_handle, LogContext *logctx, Backend **backend_handle, LogContext *logctx,
Conf *conf, const char *host, int port, Conf *conf, const char *host, int port,
char **realhost, bool nodelay, bool keepalive) { char **realhost, bool nodelay, bool keepalive) {
struct loop_state *st = snew(struct loop_state); struct loop_state *st = snew(struct loop_state);
/* No local authentication phase in this protocol */ /* No local authentication phase in this protocol */

View File

@ -5088,8 +5088,7 @@ static void gtk_seat_update_specials_menu(Seat *seat)
static void start_backend(GtkFrontend *inst) static void start_backend(GtkFrontend *inst)
{ {
const struct BackendVtable *vt; const struct BackendVtable *vt;
char *realhost; char *error, *realhost;
const char *error;
char *s; char *s;
vt = select_backend(inst->conf); vt = select_backend(inst->conf);
@ -5107,6 +5106,7 @@ static void start_backend(GtkFrontend *inst)
seat_connection_fatal(&inst->seat, seat_connection_fatal(&inst->seat,
"Unable to open connection to %s:\n%s", "Unable to open connection to %s:\n%s",
conf_dest(inst->conf), error); conf_dest(inst->conf), error);
sfree(error);
inst->exited = true; inst->exited = true;
return; return;
} }

View File

@ -914,8 +914,7 @@ int main(int argc, char **argv)
*/ */
logctx = log_init(console_cli_logpolicy, conf); logctx = log_init(console_cli_logpolicy, conf);
{ {
const char *error; char *error, *realhost;
char *realhost;
/* nodelay is only useful if stdin is a terminal device */ /* nodelay is only useful if stdin is a terminal device */
bool nodelay = conf_get_bool(conf, CONF_tcp_nodelay) && isatty(0); bool nodelay = conf_get_bool(conf, CONF_tcp_nodelay) && isatty(0);
@ -931,6 +930,7 @@ int main(int argc, char **argv)
conf_get_bool(conf, CONF_tcp_keepalives)); conf_get_bool(conf, CONF_tcp_keepalives));
if (error) { if (error) {
fprintf(stderr, "Unable to open connection:\n%s\n", error); fprintf(stderr, "Unable to open connection:\n%s\n", error);
sfree(error);
return 1; return 1;
} }
ldisc_create(conf, NULL, backend, plink_seat); ldisc_create(conf, NULL, backend, plink_seat);

View File

@ -1270,10 +1270,10 @@ Backend *pty_backend_create(
* it gets the argv array from the global variable pty_argv, expecting * it gets the argv array from the global variable pty_argv, expecting
* that it will have been invoked by pterm. * that it will have been invoked by pterm.
*/ */
static const char *pty_init(const BackendVtable *vt, Seat *seat, static char *pty_init(const BackendVtable *vt, Seat *seat,
Backend **backend_handle, LogContext *logctx, Backend **backend_handle, LogContext *logctx,
Conf *conf, const char *host, int port, Conf *conf, const char *host, int port,
char **realhost, bool nodelay, bool keepalive) char **realhost, bool nodelay, bool keepalive)
{ {
const char *cmd = NULL; const char *cmd = NULL;
struct ssh_ttymodes modes; struct ssh_ttymodes modes;

View File

@ -63,14 +63,15 @@ static void serial_select_result(int fd, int event);
static void serial_uxsel_setup(Serial *serial); static void serial_uxsel_setup(Serial *serial);
static void serial_try_write(Serial *serial); static void serial_try_write(Serial *serial);
static const char *serial_configure(Serial *serial, Conf *conf) static char *serial_configure(Serial *serial, Conf *conf)
{ {
struct termios options; struct termios options;
int bflag, bval, speed, flow, parity; int bflag, bval, speed, flow, parity;
const char *str; const char *str;
if (serial->fd < 0) if (serial->fd < 0)
return "Unable to reconfigure already-closed serial connection"; return dupstr("Unable to reconfigure already-closed "
"serial connection");
tcgetattr(serial->fd, &options); tcgetattr(serial->fd, &options);
@ -189,7 +190,8 @@ static const char *serial_configure(Serial *serial, Conf *conf)
case 6: options.c_cflag |= CS6; break; case 6: options.c_cflag |= CS6; break;
case 7: options.c_cflag |= CS7; break; case 7: options.c_cflag |= CS7; break;
case 8: options.c_cflag |= CS8; break; case 8: options.c_cflag |= CS8; break;
default: return "Invalid number of data bits (need 5, 6, 7 or 8)"; default: return dupstr("Invalid number of data bits "
"(need 5, 6, 7 or 8)");
} }
logeventf(serial->logctx, "Configuring %d data bits", logeventf(serial->logctx, "Configuring %d data bits",
conf_get_int(conf, CONF_serdatabits)); conf_get_int(conf, CONF_serdatabits));
@ -266,7 +268,7 @@ static const char *serial_configure(Serial *serial, Conf *conf)
options.c_cc[VTIME] = 0; options.c_cc[VTIME] = 0;
if (tcsetattr(serial->fd, TCSANOW, &options) < 0) if (tcsetattr(serial->fd, TCSANOW, &options) < 0)
return "Unable to configure serial port"; return dupstr("Unable to configure serial port");
return NULL; return NULL;
} }
@ -279,13 +281,13 @@ static const char *serial_configure(Serial *serial, Conf *conf)
* Also places the canonical host name into `realhost'. It must be * Also places the canonical host name into `realhost'. It must be
* freed by the caller. * freed by the caller.
*/ */
static const char *serial_init(const BackendVtable *vt, Seat *seat, static char *serial_init(const BackendVtable *vt, Seat *seat,
Backend **backend_handle, LogContext *logctx, Backend **backend_handle, LogContext *logctx,
Conf *conf, const char *host, int port, Conf *conf, const char *host, int port,
char **realhost, bool nodelay, bool keepalive) char **realhost, bool nodelay, bool keepalive)
{ {
Serial *serial; Serial *serial;
const char *err; char *err;
char *line; char *line;
/* No local authentication phase in this protocol */ /* No local authentication phase in this protocol */
@ -306,7 +308,7 @@ static const char *serial_init(const BackendVtable *vt, Seat *seat,
serial->fd = open(line, O_RDWR | O_NOCTTY | O_NDELAY | O_NONBLOCK); serial->fd = open(line, O_RDWR | O_NOCTTY | O_NDELAY | O_NONBLOCK);
if (serial->fd < 0) if (serial->fd < 0)
return "Unable to open serial port"; return dupstr("Unable to open serial port");
cloexec(serial->fd); cloexec(serial->fd);

View File

@ -368,9 +368,8 @@ static WinGuiSeat wgs = { .seat.vt = &win_seat_vt,
static void start_backend(void) static void start_backend(void)
{ {
const struct BackendVtable *vt; const struct BackendVtable *vt;
const char *error;
const char *title; const char *title;
char *realhost; char *error, *realhost;
int i; int i;
/* /*
@ -397,6 +396,7 @@ static void start_backend(void)
char *str = dupprintf("%s Error", appname); char *str = dupprintf("%s Error", appname);
char *msg = dupprintf("Unable to open connection to\n%s\n%s", char *msg = dupprintf("Unable to open connection to\n%s\n%s",
conf_dest(conf), error); conf_dest(conf), error);
sfree(error);
MessageBox(NULL, msg, str, MB_ICONERROR | MB_OK); MessageBox(NULL, msg, str, MB_ICONERROR | MB_OK);
sfree(str); sfree(str);
sfree(msg); sfree(msg);

View File

@ -492,8 +492,7 @@ int main(int argc, char **argv)
*/ */
winselcli_setup(); /* ensure event object exists */ winselcli_setup(); /* ensure event object exists */
{ {
const char *error; char *error, *realhost;
char *realhost;
/* nodelay is only useful if stdin is a character device (console) */ /* nodelay is only useful if stdin is a character device (console) */
bool nodelay = conf_get_bool(conf, CONF_tcp_nodelay) && bool nodelay = conf_get_bool(conf, CONF_tcp_nodelay) &&
(GetFileType(GetStdHandle(STD_INPUT_HANDLE)) == FILE_TYPE_CHAR); (GetFileType(GetStdHandle(STD_INPUT_HANDLE)) == FILE_TYPE_CHAR);
@ -505,6 +504,7 @@ int main(int argc, char **argv)
conf_get_bool(conf, CONF_tcp_keepalives)); conf_get_bool(conf, CONF_tcp_keepalives));
if (error) { if (error) {
fprintf(stderr, "Unable to open connection:\n%s", error); fprintf(stderr, "Unable to open connection:\n%s", error);
sfree(error);
return 1; return 1;
} }
sfree(realhost); sfree(realhost);

View File

@ -91,7 +91,7 @@ static void serial_sentdata(struct handle *h, size_t new_backlog, int err)
} }
} }
static const char *serial_configure(Serial *serial, HANDLE serport, Conf *conf) static char *serial_configure(Serial *serial, HANDLE serport, Conf *conf)
{ {
DCB dcb; DCB dcb;
COMMTIMEOUTS timeouts; COMMTIMEOUTS timeouts;
@ -134,7 +134,8 @@ static const char *serial_configure(Serial *serial, HANDLE serport, Conf *conf)
case 2: dcb.StopBits = ONESTOPBIT; str = "1 stop bit"; break; case 2: dcb.StopBits = ONESTOPBIT; str = "1 stop bit"; break;
case 3: dcb.StopBits = ONE5STOPBITS; str = "1.5 stop bits"; break; case 3: dcb.StopBits = ONE5STOPBITS; str = "1.5 stop bits"; break;
case 4: dcb.StopBits = TWOSTOPBITS; str = "2 stop bits"; break; case 4: dcb.StopBits = TWOSTOPBITS; str = "2 stop bits"; break;
default: return "Invalid number of stop bits (need 1, 1.5 or 2)"; default: return dupstr("Invalid number of stop bits "
"(need 1, 1.5 or 2)");
} }
logeventf(serial->logctx, "Configuring %s", str); logeventf(serial->logctx, "Configuring %s", str);
@ -169,7 +170,7 @@ static const char *serial_configure(Serial *serial, HANDLE serport, Conf *conf)
logeventf(serial->logctx, "Configuring %s flow control", str); logeventf(serial->logctx, "Configuring %s flow control", str);
if (!SetCommState(serport, &dcb)) if (!SetCommState(serport, &dcb))
return "Unable to configure serial port"; return dupstr("Unable to configure serial port");
timeouts.ReadIntervalTimeout = 1; timeouts.ReadIntervalTimeout = 1;
timeouts.ReadTotalTimeoutMultiplier = 0; timeouts.ReadTotalTimeoutMultiplier = 0;
@ -177,7 +178,7 @@ static const char *serial_configure(Serial *serial, HANDLE serport, Conf *conf)
timeouts.WriteTotalTimeoutMultiplier = 0; timeouts.WriteTotalTimeoutMultiplier = 0;
timeouts.WriteTotalTimeoutConstant = 0; timeouts.WriteTotalTimeoutConstant = 0;
if (!SetCommTimeouts(serport, &timeouts)) if (!SetCommTimeouts(serport, &timeouts))
return "Unable to configure serial timeouts"; return dupstr("Unable to configure serial timeouts");
} }
return NULL; return NULL;
@ -191,14 +192,14 @@ static const char *serial_configure(Serial *serial, HANDLE serport, Conf *conf)
* Also places the canonical host name into `realhost'. It must be * Also places the canonical host name into `realhost'. It must be
* freed by the caller. * freed by the caller.
*/ */
static const char *serial_init(const BackendVtable *vt, Seat *seat, static char *serial_init(const BackendVtable *vt, Seat *seat,
Backend **backend_handle, LogContext *logctx, Backend **backend_handle, LogContext *logctx,
Conf *conf, const char *host, int port, Conf *conf, const char *host, int port,
char **realhost, bool nodelay, bool keepalive) char **realhost, bool nodelay, bool keepalive)
{ {
Serial *serial; Serial *serial;
HANDLE serport; HANDLE serport;
const char *err; char *err;
char *serline; char *serline;
/* No local authentication phase in this protocol */ /* No local authentication phase in this protocol */
@ -250,7 +251,7 @@ static const char *serial_init(const BackendVtable *vt, Seat *seat,
} }
if (serport == INVALID_HANDLE_VALUE) if (serport == INVALID_HANDLE_VALUE)
return "Unable to open serial port"; return dupstr("Unable to open serial port");
err = serial_configure(serial, serport, conf); err = serial_configure(serial, serport, conf);
if (err) if (err)