1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-06-30 19:12:48 -05:00

Merge out from trunk, to keep this branch viable. We are now up to

date as of r7913.

[originally from svn r7914]
[r7913 == d7eda6d99c]
This commit is contained in:
Simon Tatham
2008-03-10 18:48:36 +00:00
81 changed files with 2085 additions and 933 deletions

View File

@ -49,6 +49,7 @@ struct uctrl {
GtkAdjustment *adj; /* for the scrollbar in a list box */
guint entrysig;
guint textsig;
int nclicks;
};
struct dlgparam {
@ -98,8 +99,10 @@ static gboolean listitem_single_key(GtkWidget *item, GdkEventKey *event,
gpointer data);
static gboolean listitem_multi_key(GtkWidget *item, GdkEventKey *event,
gpointer data);
static gboolean listitem_button(GtkWidget *item, GdkEventButton *event,
gpointer data);
static gboolean listitem_button_press(GtkWidget *item, GdkEventButton *event,
gpointer data);
static gboolean listitem_button_release(GtkWidget *item, GdkEventButton *event,
gpointer data);
static void menuitem_activate(GtkMenuItem *item, gpointer data);
static void coloursel_ok(GtkButton *button, gpointer data);
static void coloursel_cancel(GtkButton *button, gpointer data);
@ -467,7 +470,9 @@ void dlg_listbox_addwithid(union control *ctrl, void *dlg,
gtk_signal_connect(GTK_OBJECT(listitem), "focus_in_event",
GTK_SIGNAL_FUNC(widget_focus), dp);
gtk_signal_connect(GTK_OBJECT(listitem), "button_press_event",
GTK_SIGNAL_FUNC(listitem_button), dp);
GTK_SIGNAL_FUNC(listitem_button_press), dp);
gtk_signal_connect(GTK_OBJECT(listitem), "button_release_event",
GTK_SIGNAL_FUNC(listitem_button_release), dp);
gtk_object_set_data(GTK_OBJECT(listitem), "user-data",
GINT_TO_POINTER(id));
} else {
@ -1121,13 +1126,26 @@ static gboolean listitem_multi_key(GtkWidget *item, GdkEventKey *event,
return listitem_key(item, event, data, TRUE);
}
static gboolean listitem_button(GtkWidget *item, GdkEventButton *event,
gpointer data)
static gboolean listitem_button_press(GtkWidget *item, GdkEventButton *event,
gpointer data)
{
struct dlgparam *dp = (struct dlgparam *)data;
if (event->type == GDK_2BUTTON_PRESS ||
event->type == GDK_3BUTTON_PRESS) {
struct uctrl *uc = dlg_find_bywidget(dp, GTK_WIDGET(item));
struct uctrl *uc = dlg_find_bywidget(dp, GTK_WIDGET(item));
switch (event->type) {
default:
case GDK_BUTTON_PRESS: uc->nclicks = 1; break;
case GDK_2BUTTON_PRESS: uc->nclicks = 2; break;
case GDK_3BUTTON_PRESS: uc->nclicks = 3; break;
}
return FALSE;
}
static gboolean listitem_button_release(GtkWidget *item, GdkEventButton *event,
gpointer data)
{
struct dlgparam *dp = (struct dlgparam *)data;
struct uctrl *uc = dlg_find_bywidget(dp, GTK_WIDGET(item));
if (uc->nclicks>1) {
uc->ctrl->generic.handler(uc->ctrl, dp, dp->data, EVENT_ACTION);
return TRUE;
}
@ -1412,6 +1430,7 @@ GtkWidget *layout_ctrls(struct dlgparam *dp, struct Shortcuts *scs,
uc->entry = uc->list = uc->menu = NULL;
uc->button = uc->optmenu = uc->text = NULL;
uc->label = NULL;
uc->nclicks = 0;
switch (ctrl->generic.type) {
case CTRL_BUTTON:
@ -2749,7 +2768,7 @@ static void licence_clicked(GtkButton *button, gpointer data)
char *title;
char *licence =
"Copyright 1997-2007 Simon Tatham.\n\n"
"Copyright 1997-2008 Simon Tatham.\n\n"
"Portions copyright Robert de Bath, Joris van Rantwijk, Delian "
"Delchev, Andreas Schultz, Jeroen Massar, Wez Furlong, Nicolas "
@ -2830,7 +2849,7 @@ void about_box(void *window)
w, FALSE, FALSE, 5);
gtk_widget_show(w);
w = gtk_label_new("Copyright 1997-2007 Simon Tatham. All rights reserved");
w = gtk_label_new("Copyright 1997-2008 Simon Tatham. All rights reserved");
gtk_box_pack_start(GTK_BOX(GTK_DIALOG(aboutbox)->vbox),
w, FALSE, FALSE, 5);
gtk_widget_show(w);

View File

@ -663,13 +663,12 @@ gint key_event(GtkWidget *widget, GdkEventKey *event, gpointer data)
end = 2;
}
/* Control-Break is the same as Control-C */
/* Control-Break sends a Break special to the backend */
if (event->keyval == GDK_Break &&
(event->state & GDK_CONTROL_MASK)) {
output[1] = '\003';
use_ucsoutput = FALSE;
end = 2;
special = TRUE;
if (inst->back)
inst->back->special(inst->backhandle, TS_BRK);
return TRUE;
}
/* We handle Return ourselves, because it needs to be flagged as
@ -724,6 +723,13 @@ gint key_event(GtkWidget *widget, GdkEventKey *event, gpointer data)
end = 1 + sprintf(output+1, "\033[Z");
use_ucsoutput = FALSE;
}
/* And normal Tab is Tab, if the keymap hasn't already told us.
* (Curiously, at least one version of the MacOS 10.5 X server
* doesn't translate Tab for us. */
if (event->keyval == GDK_Tab && end <= 1) {
output[1] = '\t';
end = 2;
}
/*
* NetHack keypad mode.
@ -1431,7 +1437,7 @@ void palette_reset(void *frontend)
int r = i / 36, g = (i / 6) % 6, b = i % 6;
inst->cols[i+16].red = r ? r * 0x2828 + 0x3737 : 0;
inst->cols[i+16].green = g ? g * 0x2828 + 0x3737 : 0;
inst->cols[i+16].blue = b ? b + 0x2828 + 0x3737 : 0;
inst->cols[i+16].blue = b ? b * 0x2828 + 0x3737 : 0;
} else {
int shade = i - 216;
shade = shade * 0x0a0a + 0x0808;
@ -1864,7 +1870,7 @@ void sys_cursor(void *frontend, int x, int y)
*/
void do_beep(void *frontend, int mode)
{
if (mode != BELL_VISUAL)
if (mode == BELL_DEFAULT)
gdk_beep();
}
@ -2408,7 +2414,7 @@ static void help(FILE *fp) {
}
}
int do_cmdline(int argc, char **argv, int do_everything,
int do_cmdline(int argc, char **argv, int do_everything, int *allow_launch,
struct gui_data *inst, Config *cfg)
{
int err = 0;
@ -2614,7 +2620,8 @@ int do_cmdline(int argc, char **argv, int do_everything,
exit(1);
} else if(p[0] != '-' && (!do_everything ||
process_nonoption_arg(p, cfg))) {
process_nonoption_arg(p, cfg,
allow_launch))) {
/* do nothing */
} else {
@ -3321,6 +3328,7 @@ void set_window_icon(GtkWidget *window, const char *const *const *icon,
int n_icon)
{
GdkPixmap *iconpm;
GdkBitmap *iconmask;
#if GTK_CHECK_VERSION(2,0,0)
GList *iconlist;
int n;
@ -3330,9 +3338,9 @@ void set_window_icon(GtkWidget *window, const char *const *const *icon,
return;
gtk_widget_realize(window);
iconpm = gdk_pixmap_create_from_xpm_d(window->window, NULL,
iconpm = gdk_pixmap_create_from_xpm_d(window->window, &iconmask,
NULL, (gchar **)icon[0]);
gdk_window_set_icon(window->window, NULL, iconpm, NULL);
gdk_window_set_icon(window->window, NULL, iconpm, iconmask);
#if GTK_CHECK_VERSION(2,0,0)
iconlist = NULL;
@ -3492,15 +3500,23 @@ int pt_main(int argc, char **argv)
/* Splatter this argument so it doesn't clutter a ps listing */
memset(argv[1], 0, strlen(argv[1]));
} else {
if (do_cmdline(argc, argv, 0, inst, &inst->cfg))
/* By default, we bring up the config dialog, rather than launching
* a session. This gets set to TRUE if something happens to change
* that (e.g., a hostname is specified on the command-line). */
int allow_launch = FALSE;
if (do_cmdline(argc, argv, 0, &allow_launch, inst, &inst->cfg))
exit(1); /* pre-defaults pass to get -class */
do_defaults(NULL, &inst->cfg);
if (do_cmdline(argc, argv, 1, inst, &inst->cfg))
if (do_cmdline(argc, argv, 1, &allow_launch, inst, &inst->cfg))
exit(1); /* post-defaults, do everything */
cmdline_run_saved(&inst->cfg);
if (!cfg_launchable(&inst->cfg) && !cfgbox(&inst->cfg))
if (loaded_session)
allow_launch = TRUE;
if ((!allow_launch || !cfg_launchable(&inst->cfg)) &&
!cfgbox(&inst->cfg))
exit(0); /* config box hit Cancel */
}

View File

@ -60,6 +60,18 @@ extern long tickcount_offset;
#define WCHAR wchar_t
#define BYTE unsigned char
/*
* Unix-specific global flag
*
* FLAG_STDERR_TTY indicates that standard error might be a terminal and
* might get its configuration munged, so anything trying to output plain
* text (i.e. with newlines in it) will need to put it back into cooked
* mode first. Applications setting this flag should also call
* stderr_tty_init() before messing with any terminal modes, and can call
* premsg() before outputting text to stderr and postmsg() afterwards.
*/
#define FLAG_STDERR_TTY 0x1000
/* Things pty.c needs from pterm.c */
char *get_x_display(void *frontend);
int font_dimension(void *frontend, int which);/* 0 for width, 1 for height */
@ -80,7 +92,7 @@ int reallyclose(void *frontend);
/* Things pterm.c needs from {ptermm,uxputty}.c */
char *make_default_wintitle(char *hostname);
int process_nonoption_arg(char *arg, Config *cfg);
int process_nonoption_arg(char *arg, Config *cfg, int *allow_launch);
/* pterm.c needs this special function in xkeysym.c */
int keysym_to_unicode(int keysym);
@ -91,6 +103,12 @@ char *x_get_default(const char *key);
/* Things uxstore.c provides to pterm.c */
void provide_xrm_string(char *string);
/* Things provided by uxcons.c */
struct termios;
void stderr_tty_init(void);
void premsg(struct termios *);
void postmsg(struct termios *);
/* The interface used by uxsel.c */
void uxsel_init(void);
typedef int (*uxsel_callback_fn)(int fd, int event);

View File

@ -18,6 +18,31 @@ int console_batch_mode = FALSE;
static void *console_logctx = NULL;
static struct termios orig_termios_stderr;
static int stderr_is_a_tty;
void stderr_tty_init()
{
/* Ensure that if stderr is a tty, we can get it back to a sane state. */
if ((flags & FLAG_STDERR_TTY) && isatty(STDERR_FILENO)) {
stderr_is_a_tty = TRUE;
tcgetattr(STDERR_FILENO, &orig_termios_stderr);
}
}
void premsg(struct termios *cf)
{
if (stderr_is_a_tty) {
tcgetattr(STDERR_FILENO, cf);
tcsetattr(STDERR_FILENO, TCSADRAIN, &orig_termios_stderr);
}
}
void postmsg(struct termios *cf)
{
if (stderr_is_a_tty)
tcsetattr(STDERR_FILENO, TCSADRAIN, cf);
}
/*
* Clean up and exit.
*/
@ -101,6 +126,7 @@ int verify_ssh_host_key(void *frontend, char *host, int port, char *keytype,
static const char abandoned[] = "Connection abandoned.\n";
char line[32];
struct termios cf;
/*
* Verify the key.
@ -110,6 +136,7 @@ int verify_ssh_host_key(void *frontend, char *host, int port, char *keytype,
if (ret == 0) /* success - key matched OK */
return 1;
premsg(&cf);
if (ret == 2) { /* key was different */
if (console_batch_mode) {
fprintf(stderr, wrongmsg_batch, keytype, fingerprint);
@ -141,9 +168,11 @@ int verify_ssh_host_key(void *frontend, char *host, int port, char *keytype,
if (line[0] != '\0' && line[0] != '\r' && line[0] != '\n') {
if (line[0] == 'y' || line[0] == 'Y')
store_host_key(host, port, keytype, keystr);
postmsg(&cf);
return 1;
} else {
fprintf(stderr, abandoned);
postmsg(&cf);
return 0;
}
}
@ -166,7 +195,9 @@ int askalg(void *frontend, const char *algtype, const char *algname,
static const char abandoned[] = "Connection abandoned.\n";
char line[32];
struct termios cf;
premsg(&cf);
if (console_batch_mode) {
fprintf(stderr, msg_batch, algtype, algname);
return 0;
@ -187,9 +218,11 @@ int askalg(void *frontend, const char *algtype, const char *algname,
}
if (line[0] == 'y' || line[0] == 'Y') {
postmsg(&cf);
return 1;
} else {
fprintf(stderr, abandoned);
postmsg(&cf);
return 0;
}
}
@ -215,7 +248,9 @@ int askappend(void *frontend, Filename filename,
"Logging will not be enabled.\n";
char line[32];
struct termios cf;
premsg(&cf);
if (console_batch_mode) {
fprintf(stderr, msgtemplate_batch, FILENAME_MAX, filename.path);
fflush(stderr);
@ -235,6 +270,7 @@ int askappend(void *frontend, Filename filename,
tcsetattr(0, TCSANOW, &oldmode);
}
postmsg(&cf);
if (line[0] == 'y' || line[0] == 'Y')
return 2;
else if (line[0] == 'n' || line[0] == 'N')
@ -266,7 +302,10 @@ void old_keyfile_warning(void)
"Once the key is loaded into PuTTYgen, you can perform\n"
"this conversion simply by saving it again.\n";
struct termios cf;
premsg(&cf);
fputs(message, stderr);
postmsg(&cf);
}
void console_provide_logctx(void *logctx)
@ -276,8 +315,11 @@ void console_provide_logctx(void *logctx)
void logevent(void *frontend, const char *string)
{
struct termios cf;
premsg(&cf);
if (console_logctx)
log_eventlog(console_logctx, string);
postmsg(&cf);
}
static void console_data_untrusted(const char *data, int len)

View File

@ -97,6 +97,10 @@ static int cmpfortree(void *av, void *bv)
return -1;
if (as > bs)
return +1;
if (a < b)
return -1;
if (a > b)
return +1;
return 0;
}
@ -453,6 +457,14 @@ static int try_connect(Actual_Socket sock)
short localport;
int fl, salen;
/*
* Remove the socket from the tree before we overwrite its
* internal socket id, because that forms part of the tree's
* sorting criterion. We'll add it back before exiting this
* function, whether we changed anything or not.
*/
del234(sktree, sock);
if (sock->s >= 0)
close(sock->s);
@ -605,9 +617,14 @@ static int try_connect(Actual_Socket sock)
}
uxsel_tell(sock);
add234(sktree, sock);
ret:
/*
* No matter what happened, put the socket back in the tree.
*/
add234(sktree, sock);
if (err)
plug_log(sock->plug, 1, sock->addr, sock->port, strerror(err), err);
return err;
@ -1060,6 +1077,7 @@ static int net_select_result(int fd, int event)
#endif
socklen_t addrlen = sizeof(ss);
int t; /* socket of connection */
int fl;
memset(&ss, 0, addrlen);
t = accept(s->s, (struct sockaddr *)&ss, &addrlen);
@ -1067,6 +1085,10 @@ static int net_select_result(int fd, int event)
break;
}
fl = fcntl(t, F_GETFL);
if (fl != -1)
fcntl(t, F_SETFL, fl | O_NONBLOCK);
if (s->localhost_only &&
!sockaddr_is_loopback((struct sockaddr *)&ss)) {
close(t); /* someone let nonlocal through?! */

View File

@ -27,14 +27,19 @@
void *logctx;
static struct termios orig_termios;
void fatalbox(char *p, ...)
{
struct termios cf;
va_list ap;
premsg(&cf);
fprintf(stderr, "FATAL ERROR: ");
va_start(ap, p);
vfprintf(stderr, p, ap);
va_end(ap);
fputc('\n', stderr);
postmsg(&cf);
if (logctx) {
log_free(logctx);
logctx = NULL;
@ -43,12 +48,15 @@ void fatalbox(char *p, ...)
}
void modalfatalbox(char *p, ...)
{
struct termios cf;
va_list ap;
premsg(&cf);
fprintf(stderr, "FATAL ERROR: ");
va_start(ap, p);
vfprintf(stderr, p, ap);
va_end(ap);
fputc('\n', stderr);
postmsg(&cf);
if (logctx) {
log_free(logctx);
logctx = NULL;
@ -57,12 +65,15 @@ void modalfatalbox(char *p, ...)
}
void connection_fatal(void *frontend, char *p, ...)
{
struct termios cf;
va_list ap;
premsg(&cf);
fprintf(stderr, "FATAL ERROR: ");
va_start(ap, p);
vfprintf(stderr, p, ap);
va_end(ap);
fputc('\n', stderr);
postmsg(&cf);
if (logctx) {
log_free(logctx);
logctx = NULL;
@ -71,17 +82,19 @@ void connection_fatal(void *frontend, char *p, ...)
}
void cmdline_error(char *p, ...)
{
struct termios cf;
va_list ap;
premsg(&cf);
fprintf(stderr, "plink: ");
va_start(ap, p);
vfprintf(stderr, p, ap);
va_end(ap);
fputc('\n', stderr);
postmsg(&cf);
exit(1);
}
static int local_tty = 0; /* do we have a local tty? */
static struct termios orig_termios;
static int local_tty = FALSE; /* do we have a local tty? */
static Backend *back;
static void *backhandle;
@ -106,7 +119,7 @@ int platform_default_i(const char *name, int def)
if (!strcmp(name, "TermWidth") ||
!strcmp(name, "TermHeight")) {
struct winsize size;
if (ioctl(0, TIOCGWINSZ, (void *)&size) >= 0)
if (ioctl(STDIN_FILENO, TIOCGWINSZ, (void *)&size) >= 0)
return (!strcmp(name, "TermWidth") ? size.ws_col : size.ws_row);
}
return def;
@ -180,7 +193,7 @@ void ldisc_update(void *frontend, int echo, int edit)
*/
mode.c_iflag = (mode.c_iflag | INPCK | PARMRK) & ~IGNPAR;
tcsetattr(0, TCSANOW, &mode);
tcsetattr(STDIN_FILENO, TCSANOW, &mode);
}
/* Helper function to extract a special character from a termios. */
@ -366,48 +379,49 @@ char *get_ttymode(void *frontend, const char *mode)
void cleanup_termios(void)
{
if (local_tty)
tcsetattr(0, TCSANOW, &orig_termios);
tcsetattr(STDIN_FILENO, TCSANOW, &orig_termios);
}
bufchain stdout_data, stderr_data;
void try_output(int is_stderr)
int try_output(int is_stderr)
{
bufchain *chain = (is_stderr ? &stderr_data : &stdout_data);
int fd = (is_stderr ? 2 : 1);
int fd = (is_stderr ? STDERR_FILENO : STDOUT_FILENO);
void *senddata;
int sendlen, ret;
int sendlen, ret, fl;
if (bufchain_size(chain) == 0)
return;
return bufchain_size(&stdout_data) + bufchain_size(&stderr_data);
bufchain_prefix(chain, &senddata, &sendlen);
ret = write(fd, senddata, sendlen);
if (ret > 0)
bufchain_consume(chain, ret);
else if (ret < 0) {
fl = fcntl(fd, F_GETFL);
if (fl != -1 && !(fl & O_NONBLOCK))
fcntl(fd, F_SETFL, fl | O_NONBLOCK);
do {
bufchain_prefix(chain, &senddata, &sendlen);
ret = write(fd, senddata, sendlen);
if (ret > 0)
bufchain_consume(chain, ret);
} while (ret == sendlen && bufchain_size(chain) != 0);
if (fl != -1 && !(fl & O_NONBLOCK))
fcntl(fd, F_SETFL, fl);
if (ret < 0 && errno != EAGAIN) {
perror(is_stderr ? "stderr: write" : "stdout: write");
exit(1);
}
return bufchain_size(&stdout_data) + bufchain_size(&stderr_data);
}
int from_backend(void *frontend_handle, int is_stderr,
const char *data, int len)
{
int osize, esize;
if (is_stderr) {
bufchain_add(&stderr_data, data, len);
try_output(1);
return try_output(TRUE);
} else {
bufchain_add(&stdout_data, data, len);
try_output(0);
return try_output(FALSE);
}
osize = bufchain_size(&stdout_data);
esize = bufchain_size(&stderr_data);
return osize + esize;
}
int from_backend_untrusted(void *frontend_handle, const char *data, int len)
@ -582,7 +596,9 @@ int main(int argc, char **argv)
default_protocol = PROT_SSH;
default_port = 22;
flags = FLAG_STDERR;
flags = FLAG_STDERR | FLAG_STDERR_TTY;
stderr_tty_init();
/*
* Process the command line.
*/
@ -596,15 +612,11 @@ int main(int argc, char **argv)
* Override the default protocol if PLINK_PROTOCOL is set.
*/
char *p = getenv("PLINK_PROTOCOL");
int i;
if (p) {
for (i = 0; backends[i].backend != NULL; i++) {
if (!strcmp(backends[i].name, p)) {
default_protocol = cfg.protocol = backends[i].protocol;
default_port = cfg.port =
backends[i].backend->default_port;
break;
}
const Backend *b = backend_from_name(p);
if (b) {
default_protocol = cfg.protocol = b->protocol;
default_port = cfg.port = b->default_port;
}
}
}
@ -681,19 +693,14 @@ int main(int argc, char **argv)
*/
r = strchr(p, ',');
if (r) {
int i, j;
for (i = 0; backends[i].backend != NULL; i++) {
j = strlen(backends[i].name);
if (j == r - p &&
!memcmp(backends[i].name, p, j)) {
default_protocol = cfg.protocol =
backends[i].protocol;
portnumber =
backends[i].backend->default_port;
p = r + 1;
break;
}
const Backend *b;
*r = '\0';
b = backend_from_name(p);
if (b) {
default_protocol = cfg.protocol = b->protocol;
portnumber = b->default_port;
}
p = r + 1;
}
/*
@ -836,19 +843,11 @@ int main(int argc, char **argv)
* Select protocol. This is farmed out into a table in a
* separate file to enable an ssh-free variant.
*/
{
int i;
back = NULL;
for (i = 0; backends[i].backend != NULL; i++)
if (backends[i].protocol == cfg.protocol) {
back = backends[i].backend;
break;
}
if (back == NULL) {
fprintf(stderr,
"Internal fault: Unsupported protocol found\n");
return 1;
}
back = backend_from_proto(cfg.protocol);
if (back == NULL) {
fprintf(stderr,
"Internal fault: Unsupported protocol found\n");
return 1;
}
/*
@ -869,6 +868,14 @@ int main(int argc, char **argv)
sk_init();
uxsel_init();
/*
* Unix Plink doesn't provide any way to add forwardings after the
* connection is set up, so if there are none now, we can safely set
* the "simple" flag.
*/
if (cfg.protocol == PROT_SSH && !cfg.x11_forward && !cfg.agentfwd &&
cfg.portfwd[0] == '\0' && cfg.portfwd[1] == '\0')
cfg.ssh_simple = TRUE;
/*
* Start up the connection.
*/
@ -897,7 +904,7 @@ int main(int argc, char **argv)
* fails, because we know we aren't necessarily running in a
* console.
*/
local_tty = (tcgetattr(0, &orig_termios) == 0);
local_tty = (tcgetattr(STDIN_FILENO, &orig_termios) == 0);
atexit(cleanup_termios);
ldisc_update(NULL, 1, 1);
sending = FALSE;
@ -921,17 +928,17 @@ int main(int argc, char **argv)
back->sendok(backhandle) &&
back->sendbuffer(backhandle) < MAX_STDIN_BACKLOG) {
/* If we're OK to send, then try to read from stdin. */
FD_SET_MAX(0, maxfd, rset);
FD_SET_MAX(STDIN_FILENO, maxfd, rset);
}
if (bufchain_size(&stdout_data) > 0) {
/* If we have data for stdout, try to write to stdout. */
FD_SET_MAX(1, maxfd, wset);
FD_SET_MAX(STDOUT_FILENO, maxfd, wset);
}
if (bufchain_size(&stderr_data) > 0) {
/* If we have data for stderr, try to write to stderr. */
FD_SET_MAX(2, maxfd, wset);
FD_SET_MAX(STDERR_FILENO, maxfd, wset);
}
/* Count the currently active fds. */
@ -1028,12 +1035,12 @@ int main(int argc, char **argv)
back->size(backhandle, size.ws_col, size.ws_row);
}
if (FD_ISSET(0, &rset)) {
if (FD_ISSET(STDIN_FILENO, &rset)) {
char buf[4096];
int ret;
if (connopen && back->connected(backhandle)) {
ret = read(0, buf, sizeof(buf));
ret = read(STDIN_FILENO, buf, sizeof(buf));
if (ret < 0) {
perror("stdin: read");
exit(1);
@ -1049,12 +1056,12 @@ int main(int argc, char **argv)
}
}
if (FD_ISSET(1, &wset)) {
try_output(0);
if (FD_ISSET(STDOUT_FILENO, &wset)) {
back->unthrottle(backhandle, try_output(FALSE));
}
if (FD_ISSET(2, &wset)) {
try_output(1);
if (FD_ISSET(STDERR_FILENO, &wset)) {
back->unthrottle(backhandle, try_output(TRUE));
}
if ((!connopen || !back->connected(backhandle)) &&

View File

@ -33,7 +33,7 @@ void cleanup_exit(int code)
exit(code);
}
int process_nonoption_arg(char *arg, Config *cfg)
int process_nonoption_arg(char *arg, Config *cfg, int *allow_launch)
{
return 0; /* pterm doesn't have any. */
}

View File

@ -360,8 +360,10 @@ static void pty_open_master(Pty pty)
/*
* Set the pty master into non-blocking mode.
*/
int i = 1;
ioctl(pty->master_fd, FIONBIO, &i);
int fl;
fl = fcntl(pty->master_fd, F_GETFL);
if (fl != -1 && !(fl & O_NONBLOCK))
fcntl(pty->master_fd, F_SETFL, fl | O_NONBLOCK);
}
if (!ptys_by_fd)
@ -775,10 +777,10 @@ static const char *pty_init(void *frontend, void **backend_handle, Config *cfg,
close(slavefd);
setsid();
#ifdef TIOCSCTTY
ioctl(slavefd, TIOCSCTTY, 1);
ioctl(0, TIOCSCTTY, 1);
#endif
pgrp = getpid();
tcsetpgrp(slavefd, pgrp);
tcsetpgrp(0, pgrp);
setpgid(pgrp, pgrp);
close(open(pty->name, O_WRONLY, 0));
setpgid(pgrp, pgrp);
@ -1085,5 +1087,7 @@ Backend pty_backend = {
pty_provide_logctx,
pty_unthrottle,
pty_cfg_info,
1
"pty",
-1,
0
};

View File

@ -33,13 +33,7 @@ void cleanup_exit(int code)
Backend *select_backend(Config *cfg)
{
int i;
Backend *back = NULL;
for (i = 0; backends[i].backend != NULL; i++)
if (backends[i].protocol == cfg->protocol) {
back = backends[i].backend;
break;
}
Backend *back = backend_from_proto(cfg->protocol);
assert(back != NULL);
return back;
}
@ -53,7 +47,7 @@ static int got_host = 0;
const int use_event_log = 1, new_session = 1, saved_sessions = 1;
int process_nonoption_arg(char *arg, Config *cfg)
int process_nonoption_arg(char *arg, Config *cfg, int *allow_launch)
{
char *p, *q = arg;
@ -104,6 +98,8 @@ int process_nonoption_arg(char *arg, Config *cfg)
cfg->host[sizeof(cfg->host) - 1] = '\0';
got_host = 1;
}
if (got_host)
*allow_launch = TRUE;
return 1;
}
@ -135,13 +131,10 @@ int main(int argc, char **argv)
default_protocol = be_default_protocol;
/* Find the appropriate default port. */
{
int i;
Backend *b = backend_from_proto(default_protocol);
default_port = 0; /* illegal */
for (i = 0; backends[i].backend != NULL; i++)
if (backends[i].protocol == default_protocol) {
default_port = backends[i].backend->default_port;
break;
}
if (b)
default_port = b->default_port;
}
return pt_main(argc, argv);
}

View File

@ -536,5 +536,7 @@ Backend serial_backend = {
serial_provide_logctx,
serial_unthrottle,
serial_cfg_info,
1
"serial",
PROT_SERIAL,
0
};