lineedit: reduce stack usage
netstat: reduce stack usage; fix handling of NULs in unix socket filenames static.has_inode 1 - -1 do_info 119 116 -3 deinit_S 60 51 -9 unix_do_one 578 451 -127 parse_and_put_prompt 966 825 -141 ------------------------------------------------------------------------------ (add/remove: 0/1 grow/shrink: 0/4 up/down: 0/-281) Total: -281 bytes
This commit is contained in:
parent
2bec513996
commit
7221c8c22d
@ -91,7 +91,6 @@ struct statics {
|
|||||||
|
|
||||||
const char *cmdedit_prompt;
|
const char *cmdedit_prompt;
|
||||||
#if ENABLE_FEATURE_EDITING_FANCY_PROMPT
|
#if ENABLE_FEATURE_EDITING_FANCY_PROMPT
|
||||||
char *hostname_buf;
|
|
||||||
int num_ok_lines; /* = 1; */
|
int num_ok_lines; /* = 1; */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -136,7 +135,6 @@ static struct statics *const ptr_to_statics __attribute__ ((section (".data")));
|
|||||||
#define command_len (S.command_len )
|
#define command_len (S.command_len )
|
||||||
#define command_ps (S.command_ps )
|
#define command_ps (S.command_ps )
|
||||||
#define cmdedit_prompt (S.cmdedit_prompt )
|
#define cmdedit_prompt (S.cmdedit_prompt )
|
||||||
#define hostname_buf (S.hostname_buf )
|
|
||||||
#define num_ok_lines (S.num_ok_lines )
|
#define num_ok_lines (S.num_ok_lines )
|
||||||
#define user_buf (S.user_buf )
|
#define user_buf (S.user_buf )
|
||||||
#define home_pwd_buf (S.home_pwd_buf )
|
#define home_pwd_buf (S.home_pwd_buf )
|
||||||
@ -155,7 +153,6 @@ static struct statics *const ptr_to_statics __attribute__ ((section (".data")));
|
|||||||
static void deinit_S(void)
|
static void deinit_S(void)
|
||||||
{
|
{
|
||||||
#if ENABLE_FEATURE_EDITING_FANCY_PROMPT
|
#if ENABLE_FEATURE_EDITING_FANCY_PROMPT
|
||||||
free(hostname_buf);
|
|
||||||
/* This one is allocated only if FANCY_PROMPT is on
|
/* This one is allocated only if FANCY_PROMPT is on
|
||||||
* (otherwise it points to verbatim prompt (NOT malloced) */
|
* (otherwise it points to verbatim prompt (NOT malloced) */
|
||||||
free((char*)cmdedit_prompt);
|
free((char*)cmdedit_prompt);
|
||||||
@ -381,14 +378,14 @@ static void username_tab_completion(char *ud, char *with_shash_flg)
|
|||||||
if (with_shash_flg) { /* "~/..." or "~user/..." */
|
if (with_shash_flg) { /* "~/..." or "~user/..." */
|
||||||
char *sav_ud = ud - 1;
|
char *sav_ud = ud - 1;
|
||||||
char *home = NULL;
|
char *home = NULL;
|
||||||
char *temp;
|
|
||||||
|
|
||||||
if (*ud == '/') { /* "~/..." */
|
if (*ud == '/') { /* "~/..." */
|
||||||
home = home_pwd_buf;
|
home = home_pwd_buf;
|
||||||
} else {
|
} else {
|
||||||
/* "~user/..." */
|
/* "~user/..." */
|
||||||
|
char *temp;
|
||||||
temp = strchr(ud, '/');
|
temp = strchr(ud, '/');
|
||||||
*temp = 0; /* ~user\0 */
|
*temp = '\0'; /* ~user\0 */
|
||||||
entry = getpwnam(ud);
|
entry = getpwnam(ud);
|
||||||
*temp = '/'; /* restore ~user/... */
|
*temp = '/'; /* restore ~user/... */
|
||||||
ud = temp;
|
ud = temp;
|
||||||
@ -1163,21 +1160,23 @@ static void parse_and_put_prompt(const char *prmt_ptr)
|
|||||||
size_t cur_prmt_len = 0;
|
size_t cur_prmt_len = 0;
|
||||||
char flg_not_length = '[';
|
char flg_not_length = '[';
|
||||||
char *prmt_mem_ptr = xzalloc(1);
|
char *prmt_mem_ptr = xzalloc(1);
|
||||||
char *pwd_buf = xrealloc_getcwd_or_warn(NULL);
|
char *cwd_buf = xrealloc_getcwd_or_warn(NULL);
|
||||||
char buf2[PATH_MAX + 1];
|
char cbuf[2];
|
||||||
char buf[2];
|
|
||||||
char c;
|
char c;
|
||||||
char *pbuf;
|
char *pbuf;
|
||||||
|
|
||||||
cmdedit_prmt_len = 0;
|
cmdedit_prmt_len = 0;
|
||||||
|
|
||||||
if (!pwd_buf) {
|
if (!cwd_buf) {
|
||||||
pwd_buf = (char *)bb_msg_unknown;
|
cwd_buf = (char *)bb_msg_unknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cbuf[1] = '\0'; /* never changes */
|
||||||
|
|
||||||
while (*prmt_ptr) {
|
while (*prmt_ptr) {
|
||||||
pbuf = buf;
|
char *free_me = NULL;
|
||||||
pbuf[1] = 0;
|
|
||||||
|
pbuf = cbuf;
|
||||||
c = *prmt_ptr++;
|
c = *prmt_ptr++;
|
||||||
if (c == '\\') {
|
if (c == '\\') {
|
||||||
const char *cp = prmt_ptr;
|
const char *cp = prmt_ptr;
|
||||||
@ -1188,6 +1187,7 @@ static void parse_and_put_prompt(const char *prmt_ptr)
|
|||||||
if (*cp == '\0')
|
if (*cp == '\0')
|
||||||
break;
|
break;
|
||||||
c = *prmt_ptr++;
|
c = *prmt_ptr++;
|
||||||
|
|
||||||
switch (c) {
|
switch (c) {
|
||||||
#if ENABLE_FEATURE_GETUSERNAME_AND_HOMEDIR
|
#if ENABLE_FEATURE_GETUSERNAME_AND_HOMEDIR
|
||||||
case 'u':
|
case 'u':
|
||||||
@ -1195,87 +1195,81 @@ static void parse_and_put_prompt(const char *prmt_ptr)
|
|||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
case 'h':
|
case 'h':
|
||||||
pbuf = hostname_buf;
|
pbuf = free_me = xzalloc(256);
|
||||||
if (!pbuf) {
|
if (gethostname(pbuf, 255) < 0) {
|
||||||
pbuf = xzalloc(256);
|
pbuf[0] = '?';
|
||||||
if (gethostname(pbuf, 255) < 0) {
|
pbuf[1] = '\0';
|
||||||
strcpy(pbuf, "?");
|
|
||||||
} else {
|
|
||||||
char *s = strchr(pbuf, '.');
|
|
||||||
if (s)
|
|
||||||
*s = '\0';
|
|
||||||
}
|
|
||||||
hostname_buf = pbuf;
|
|
||||||
}
|
}
|
||||||
|
*strchrnul(pbuf, '.') = '\0';
|
||||||
break;
|
break;
|
||||||
case '$':
|
case '$':
|
||||||
c = (geteuid() == 0 ? '#' : '$');
|
c = (geteuid() == 0 ? '#' : '$');
|
||||||
break;
|
break;
|
||||||
#if ENABLE_FEATURE_GETUSERNAME_AND_HOMEDIR
|
#if ENABLE_FEATURE_GETUSERNAME_AND_HOMEDIR
|
||||||
case 'w':
|
case 'w':
|
||||||
pbuf = pwd_buf;
|
/* /home/user[/something] -> ~[/something] */
|
||||||
|
pbuf = cwd_buf;
|
||||||
l = strlen(home_pwd_buf);
|
l = strlen(home_pwd_buf);
|
||||||
if (l != 0
|
if (l != 0
|
||||||
&& strncmp(home_pwd_buf, pbuf, l) == 0
|
&& strncmp(home_pwd_buf, cwd_buf, l) == 0
|
||||||
&& (pbuf[l]=='/' || pbuf[l]=='\0')
|
&& (cwd_buf[l]=='/' || cwd_buf[l]=='\0')
|
||||||
&& strlen(pwd_buf+l) < PATH_MAX
|
&& strlen(cwd_buf + l) < PATH_MAX
|
||||||
) {
|
) {
|
||||||
pbuf = buf2;
|
pbuf = free_me = xasprintf("~%s", cwd_buf + l);
|
||||||
*pbuf = '~';
|
|
||||||
strcpy(pbuf+1, pwd_buf+l);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
case 'W':
|
case 'W':
|
||||||
pbuf = pwd_buf;
|
pbuf = cwd_buf;
|
||||||
cp = strrchr(pbuf, '/');
|
cp = strrchr(pbuf, '/');
|
||||||
if (cp != NULL && cp != pbuf)
|
if (cp != NULL && cp != pbuf)
|
||||||
pbuf += (cp-pbuf) + 1;
|
pbuf += (cp-pbuf) + 1;
|
||||||
break;
|
break;
|
||||||
case '!':
|
case '!':
|
||||||
pbuf = buf2;
|
pbuf = free_me = xasprintf("%d", num_ok_lines);
|
||||||
snprintf(buf2, sizeof(buf2), "%d", num_ok_lines);
|
|
||||||
break;
|
break;
|
||||||
case 'e': case 'E': /* \e \E = \033 */
|
case 'e': case 'E': /* \e \E = \033 */
|
||||||
c = '\033';
|
c = '\033';
|
||||||
break;
|
break;
|
||||||
case 'x': case 'X':
|
case 'x': case 'X': {
|
||||||
|
char buf2[4];
|
||||||
for (l = 0; l < 3;) {
|
for (l = 0; l < 3;) {
|
||||||
int h;
|
unsigned h;
|
||||||
buf2[l++] = *prmt_ptr;
|
buf2[l++] = *prmt_ptr;
|
||||||
buf2[l] = 0;
|
buf2[l] = '\0';
|
||||||
h = strtol(buf2, &pbuf, 16);
|
h = strtoul(buf2, &pbuf, 16);
|
||||||
if (h > UCHAR_MAX || (pbuf - buf2) < l) {
|
if (h > UCHAR_MAX || (pbuf - buf2) < l) {
|
||||||
l--;
|
buf2[--l] = '\0';
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
prmt_ptr++;
|
prmt_ptr++;
|
||||||
}
|
}
|
||||||
buf2[l] = 0;
|
c = (char)strtoul(buf2, NULL, 16);
|
||||||
c = (char)strtol(buf2, NULL, 16);
|
|
||||||
if (c == 0)
|
if (c == 0)
|
||||||
c = '?';
|
c = '?';
|
||||||
pbuf = buf;
|
pbuf = cbuf;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case '[': case ']':
|
case '[': case ']':
|
||||||
if (c == flg_not_length) {
|
if (c == flg_not_length) {
|
||||||
flg_not_length = (flg_not_length == '[' ? ']' : '[');
|
flg_not_length = (flg_not_length == '[' ? ']' : '[');
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
} /* switch */
|
||||||
}
|
} /* if */
|
||||||
}
|
} /* if */
|
||||||
if (pbuf == buf)
|
cbuf[0] = c;
|
||||||
*pbuf = c;
|
|
||||||
cur_prmt_len = strlen(pbuf);
|
cur_prmt_len = strlen(pbuf);
|
||||||
prmt_len += cur_prmt_len;
|
prmt_len += cur_prmt_len;
|
||||||
if (flg_not_length != ']')
|
if (flg_not_length != ']')
|
||||||
cmdedit_prmt_len += cur_prmt_len;
|
cmdedit_prmt_len += cur_prmt_len;
|
||||||
prmt_mem_ptr = strcat(xrealloc(prmt_mem_ptr, prmt_len+1), pbuf);
|
prmt_mem_ptr = strcat(xrealloc(prmt_mem_ptr, prmt_len+1), pbuf);
|
||||||
}
|
free(free_me);
|
||||||
if (pwd_buf != (char *)bb_msg_unknown)
|
} /* while */
|
||||||
free(pwd_buf);
|
|
||||||
|
if (cwd_buf != (char *)bb_msg_unknown)
|
||||||
|
free(cwd_buf);
|
||||||
cmdedit_prompt = prmt_mem_ptr;
|
cmdedit_prompt = prmt_mem_ptr;
|
||||||
put_prompt();
|
put_prompt();
|
||||||
}
|
}
|
||||||
@ -1397,7 +1391,6 @@ int read_line_input(const char *prompt, char *command, int maxsize, line_input_t
|
|||||||
if (entry) {
|
if (entry) {
|
||||||
user_buf = xstrdup(entry->pw_name);
|
user_buf = xstrdup(entry->pw_name);
|
||||||
home_pwd_buf = xstrdup(entry->pw_dir);
|
home_pwd_buf = xstrdup(entry->pw_dir);
|
||||||
/* They are not freed on exit (too small to bother) */
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -148,7 +148,7 @@ static char *ip_port_str(struct sockaddr *addr, int port, const char *proto, int
|
|||||||
return host_port;
|
return host_port;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tcp_do_one(int lnr, const char *line)
|
static void tcp_do_one(int lnr, char *line)
|
||||||
{
|
{
|
||||||
char local_addr[64], rem_addr[64];
|
char local_addr[64], rem_addr[64];
|
||||||
char more[512];
|
char more[512];
|
||||||
@ -201,7 +201,7 @@ static void tcp_do_one(int lnr, const char *line)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void udp_do_one(int lnr, const char *line)
|
static void udp_do_one(int lnr, char *line)
|
||||||
{
|
{
|
||||||
char local_addr[64], rem_addr[64];
|
char local_addr[64], rem_addr[64];
|
||||||
const char *state_str;
|
const char *state_str;
|
||||||
@ -283,7 +283,7 @@ static void udp_do_one(int lnr, const char *line)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void raw_do_one(int lnr, const char *line)
|
static void raw_do_one(int lnr, char *line)
|
||||||
{
|
{
|
||||||
char local_addr[64], rem_addr[64];
|
char local_addr[64], rem_addr[64];
|
||||||
char more[512];
|
char more[512];
|
||||||
@ -339,31 +339,37 @@ static void raw_do_one(int lnr, const char *line)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void unix_do_one(int nr, const char *line)
|
static void unix_do_one(int nr, char *line)
|
||||||
{
|
{
|
||||||
static smallint has_inode = 0;
|
|
||||||
|
|
||||||
char path[PATH_MAX], ss_flags[32];
|
|
||||||
const char *ss_proto, *ss_state, *ss_type;
|
|
||||||
int num, state, type, inode;
|
|
||||||
void *d;
|
|
||||||
unsigned long refcnt, proto, unix_flags;
|
unsigned long refcnt, proto, unix_flags;
|
||||||
|
unsigned long inode;
|
||||||
|
int type, state;
|
||||||
|
int num, path_ofs;
|
||||||
|
void *d;
|
||||||
|
const char *ss_proto, *ss_state, *ss_type;
|
||||||
|
char ss_flags[32];
|
||||||
|
|
||||||
if (nr == 0) {
|
if (nr == 0)
|
||||||
if (strstr(line, "Inode"))
|
return; /* skip header */
|
||||||
has_inode = 1;
|
|
||||||
|
{
|
||||||
|
char *last = last_char_is(line, '\n');
|
||||||
|
if (last)
|
||||||
|
*last = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 2.6.15 may report lines like "... @/tmp/fam-user-^@^@^@^@^@^@^@..."
|
||||||
|
* (those ^@ are NUL bytes). fgets sees them as tons of empty lines. */
|
||||||
|
if (!line[0])
|
||||||
|
return;
|
||||||
|
|
||||||
|
path_ofs = 0; /* paranoia */
|
||||||
|
num = sscanf(line, "%p: %lX %lX %lX %X %X %lu %n",
|
||||||
|
&d, &refcnt, &proto, &unix_flags, &type, &state, &inode, &path_ofs);
|
||||||
|
if (num < 7) {
|
||||||
|
bb_error_msg("got bogus unix line '%s'", line);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
path[0] = '\0';
|
|
||||||
num = sscanf(line, "%p: %lX %lX %lX %X %X %d %s",
|
|
||||||
&d, &refcnt, &proto, &unix_flags, &type, &state, &inode, path);
|
|
||||||
if (num < 6) {
|
|
||||||
bb_error_msg("warning, got bogus unix line");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!has_inode)
|
|
||||||
sprintf(path, "%d", inode);
|
|
||||||
|
|
||||||
if ((flags & (NETSTAT_LISTENING|NETSTAT_CONNECTED)) != (NETSTAT_LISTENING|NETSTAT_CONNECTED)) {
|
if ((flags & (NETSTAT_LISTENING|NETSTAT_CONNECTED)) != (NETSTAT_LISTENING|NETSTAT_CONNECTED)) {
|
||||||
if ((state == SS_UNCONNECTED) && (unix_flags & SO_ACCEPTCON)) {
|
if ((state == SS_UNCONNECTED) && (unix_flags & SO_ACCEPTCON)) {
|
||||||
if (!(flags & NETSTAT_LISTENING))
|
if (!(flags & NETSTAT_LISTENING))
|
||||||
@ -439,13 +445,9 @@ static void unix_do_one(int nr, const char *line)
|
|||||||
strcat(ss_flags, "N ");
|
strcat(ss_flags, "N ");
|
||||||
strcat(ss_flags, "]");
|
strcat(ss_flags, "]");
|
||||||
|
|
||||||
printf("%-5s %-6ld %-11s %-10s %-13s ",
|
printf("%-5s %-6ld %-11s %-10s %-13s %6lu %s\n",
|
||||||
ss_proto, refcnt, ss_flags, ss_type, ss_state);
|
ss_proto, refcnt, ss_flags, ss_type, ss_state, inode,
|
||||||
if (has_inode)
|
line + path_ofs);
|
||||||
printf("%-6d ", inode);
|
|
||||||
else
|
|
||||||
printf("- ");
|
|
||||||
puts(path);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define _PATH_PROCNET_UDP "/proc/net/udp"
|
#define _PATH_PROCNET_UDP "/proc/net/udp"
|
||||||
@ -456,10 +458,11 @@ static void unix_do_one(int nr, const char *line)
|
|||||||
#define _PATH_PROCNET_RAW6 "/proc/net/raw6"
|
#define _PATH_PROCNET_RAW6 "/proc/net/raw6"
|
||||||
#define _PATH_PROCNET_UNIX "/proc/net/unix"
|
#define _PATH_PROCNET_UNIX "/proc/net/unix"
|
||||||
|
|
||||||
static void do_info(const char *file, const char *name, void (*proc)(int, const char *))
|
static void do_info(const char *file, const char *name, void (*proc)(int, char *))
|
||||||
{
|
{
|
||||||
int lnr = 0;
|
int lnr;
|
||||||
FILE *procinfo;
|
FILE *procinfo;
|
||||||
|
char *buffer;
|
||||||
|
|
||||||
procinfo = fopen(file, "r");
|
procinfo = fopen(file, "r");
|
||||||
if (procinfo == NULL) {
|
if (procinfo == NULL) {
|
||||||
@ -470,13 +473,14 @@ static void do_info(const char *file, const char *name, void (*proc)(int, const
|
|||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
lnr = 0;
|
||||||
do {
|
do {
|
||||||
char *buffer = xmalloc_fgets(procinfo);
|
buffer = xmalloc_fgets(procinfo);
|
||||||
if (buffer) {
|
if (buffer) {
|
||||||
(proc)(lnr++, buffer);
|
(proc)(lnr++, buffer);
|
||||||
free(buffer);
|
free(buffer);
|
||||||
}
|
}
|
||||||
} while (!feof(procinfo));
|
} while (buffer);
|
||||||
fclose(procinfo);
|
fclose(procinfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user