mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-01-09 17:38:00 +00:00
Allocate the SSH specials list dynamically.
The last list we returned is now stored in the main Ssh structure rather than being a static array in ssh_get_specials. The main point of this is that I want to start adding more dynamic things to it, for which I can't predict the array's max length in advance. But also this fixes a conceptual wrongness, in that if a process had more than one Ssh instance in it then their specials arrays would have taken turns occupying the old static array, and although the current single-threaded client code in the GUI front ends wouldn't have minded (it would have read out the contents just once immediately after get_specials returned), it still feels as if it was a bug waiting to happen.
This commit is contained in:
parent
6ef6cb1573
commit
10a48c3591
44
ssh.c
44
ssh.c
@ -954,6 +954,11 @@ struct ssh_tag {
|
||||
*/
|
||||
struct ssh_gss_liblist *gsslibs;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The last list returned from get_specials.
|
||||
*/
|
||||
struct telnet_special *specials;
|
||||
};
|
||||
|
||||
#define logevent(s) logevent(ssh->frontend, s)
|
||||
@ -11004,6 +11009,7 @@ static const char *ssh_init(void *frontend_handle, void **backend_handle,
|
||||
ssh->connshare = NULL;
|
||||
ssh->attempting_connshare = FALSE;
|
||||
ssh->session_started = FALSE;
|
||||
ssh->specials = NULL;
|
||||
|
||||
*backend_handle = ssh;
|
||||
|
||||
@ -11151,6 +11157,7 @@ static void ssh_free(void *handle)
|
||||
sfree(ssh->v_s);
|
||||
sfree(ssh->fullhostname);
|
||||
sfree(ssh->hostkey_str);
|
||||
sfree(ssh->specials);
|
||||
if (ssh->crcda_ctx) {
|
||||
crcda_free_context(ssh->crcda_ctx);
|
||||
ssh->crcda_ctx = NULL;
|
||||
@ -11364,19 +11371,24 @@ static const struct telnet_special *ssh_get_specials(void *handle)
|
||||
static const struct telnet_special specials_end[] = {
|
||||
{NULL, TS_EXITMENU}
|
||||
};
|
||||
/* XXX review this length for any changes: */
|
||||
static struct telnet_special ssh_specials[lenof(ssh2_ignore_special) +
|
||||
lenof(ssh2_rekey_special) +
|
||||
lenof(ssh2_session_specials) +
|
||||
lenof(specials_end)];
|
||||
|
||||
struct telnet_special *specials = NULL;
|
||||
int nspecials = 0, specialsize = 0;
|
||||
|
||||
Ssh ssh = (Ssh) handle;
|
||||
int i = 0;
|
||||
#define ADD_SPECIALS(name) \
|
||||
do { \
|
||||
assert((i + lenof(name)) <= lenof(ssh_specials)); \
|
||||
memcpy(&ssh_specials[i], name, sizeof name); \
|
||||
i += lenof(name); \
|
||||
} while(0)
|
||||
|
||||
sfree(ssh->specials);
|
||||
|
||||
#define ADD_SPECIALS(name) do \
|
||||
{ \
|
||||
int len = lenof(name); \
|
||||
if (nspecials + len > specialsize) { \
|
||||
specialsize = (nspecials + len) * 5 / 4 + 32; \
|
||||
specials = sresize(specials, specialsize, struct telnet_special); \
|
||||
} \
|
||||
memcpy(specials+nspecials, name, len*sizeof(struct telnet_special)); \
|
||||
nspecials += len; \
|
||||
} while (0)
|
||||
|
||||
if (ssh->version == 1) {
|
||||
/* Don't bother offering IGNORE if we've decided the remote
|
||||
@ -11393,9 +11405,13 @@ static const struct telnet_special *ssh_get_specials(void *handle)
|
||||
ADD_SPECIALS(ssh2_session_specials);
|
||||
} /* else we're not ready yet */
|
||||
|
||||
if (i) {
|
||||
if (nspecials)
|
||||
ADD_SPECIALS(specials_end);
|
||||
return ssh_specials;
|
||||
|
||||
ssh->specials = specials;
|
||||
|
||||
if (nspecials) {
|
||||
return specials;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user