diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2007-12-03 10:45:14 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2007-12-03 10:45:14 +0000 |
commit | 7221c8c22dd527700204eb5cc4d0651af4273f4f (patch) | |
tree | 9f45c168efd2a83c7a700dfc2161e9fa2823a222 | |
parent | 2bec5139964ebf814ffddbedd526651361be69f8 (diff) | |
download | busybox-w32-7221c8c22dd527700204eb5cc4d0651af4273f4f.tar.gz busybox-w32-7221c8c22dd527700204eb5cc4d0651af4273f4f.tar.bz2 busybox-w32-7221c8c22dd527700204eb5cc4d0651af4273f4f.zip |
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
-rw-r--r-- | libbb/lineedit.c | 93 | ||||
-rw-r--r-- | networking/netstat.c | 70 |
2 files changed, 80 insertions, 83 deletions
diff --git a/libbb/lineedit.c b/libbb/lineedit.c index 07db6358d..1397409cc 100644 --- a/libbb/lineedit.c +++ b/libbb/lineedit.c | |||
@@ -91,7 +91,6 @@ struct statics { | |||
91 | 91 | ||
92 | const char *cmdedit_prompt; | 92 | const char *cmdedit_prompt; |
93 | #if ENABLE_FEATURE_EDITING_FANCY_PROMPT | 93 | #if ENABLE_FEATURE_EDITING_FANCY_PROMPT |
94 | char *hostname_buf; | ||
95 | int num_ok_lines; /* = 1; */ | 94 | int num_ok_lines; /* = 1; */ |
96 | #endif | 95 | #endif |
97 | 96 | ||
@@ -136,7 +135,6 @@ static struct statics *const ptr_to_statics __attribute__ ((section (".data"))); | |||
136 | #define command_len (S.command_len ) | 135 | #define command_len (S.command_len ) |
137 | #define command_ps (S.command_ps ) | 136 | #define command_ps (S.command_ps ) |
138 | #define cmdedit_prompt (S.cmdedit_prompt ) | 137 | #define cmdedit_prompt (S.cmdedit_prompt ) |
139 | #define hostname_buf (S.hostname_buf ) | ||
140 | #define num_ok_lines (S.num_ok_lines ) | 138 | #define num_ok_lines (S.num_ok_lines ) |
141 | #define user_buf (S.user_buf ) | 139 | #define user_buf (S.user_buf ) |
142 | #define home_pwd_buf (S.home_pwd_buf ) | 140 | #define home_pwd_buf (S.home_pwd_buf ) |
@@ -155,7 +153,6 @@ static struct statics *const ptr_to_statics __attribute__ ((section (".data"))); | |||
155 | static void deinit_S(void) | 153 | static void deinit_S(void) |
156 | { | 154 | { |
157 | #if ENABLE_FEATURE_EDITING_FANCY_PROMPT | 155 | #if ENABLE_FEATURE_EDITING_FANCY_PROMPT |
158 | free(hostname_buf); | ||
159 | /* This one is allocated only if FANCY_PROMPT is on | 156 | /* This one is allocated only if FANCY_PROMPT is on |
160 | * (otherwise it points to verbatim prompt (NOT malloced) */ | 157 | * (otherwise it points to verbatim prompt (NOT malloced) */ |
161 | free((char*)cmdedit_prompt); | 158 | free((char*)cmdedit_prompt); |
@@ -381,14 +378,14 @@ static void username_tab_completion(char *ud, char *with_shash_flg) | |||
381 | if (with_shash_flg) { /* "~/..." or "~user/..." */ | 378 | if (with_shash_flg) { /* "~/..." or "~user/..." */ |
382 | char *sav_ud = ud - 1; | 379 | char *sav_ud = ud - 1; |
383 | char *home = NULL; | 380 | char *home = NULL; |
384 | char *temp; | ||
385 | 381 | ||
386 | if (*ud == '/') { /* "~/..." */ | 382 | if (*ud == '/') { /* "~/..." */ |
387 | home = home_pwd_buf; | 383 | home = home_pwd_buf; |
388 | } else { | 384 | } else { |
389 | /* "~user/..." */ | 385 | /* "~user/..." */ |
386 | char *temp; | ||
390 | temp = strchr(ud, '/'); | 387 | temp = strchr(ud, '/'); |
391 | *temp = 0; /* ~user\0 */ | 388 | *temp = '\0'; /* ~user\0 */ |
392 | entry = getpwnam(ud); | 389 | entry = getpwnam(ud); |
393 | *temp = '/'; /* restore ~user/... */ | 390 | *temp = '/'; /* restore ~user/... */ |
394 | ud = temp; | 391 | ud = temp; |
@@ -1163,21 +1160,23 @@ static void parse_and_put_prompt(const char *prmt_ptr) | |||
1163 | size_t cur_prmt_len = 0; | 1160 | size_t cur_prmt_len = 0; |
1164 | char flg_not_length = '['; | 1161 | char flg_not_length = '['; |
1165 | char *prmt_mem_ptr = xzalloc(1); | 1162 | char *prmt_mem_ptr = xzalloc(1); |
1166 | char *pwd_buf = xrealloc_getcwd_or_warn(NULL); | 1163 | char *cwd_buf = xrealloc_getcwd_or_warn(NULL); |
1167 | char buf2[PATH_MAX + 1]; | 1164 | char cbuf[2]; |
1168 | char buf[2]; | ||
1169 | char c; | 1165 | char c; |
1170 | char *pbuf; | 1166 | char *pbuf; |
1171 | 1167 | ||
1172 | cmdedit_prmt_len = 0; | 1168 | cmdedit_prmt_len = 0; |
1173 | 1169 | ||
1174 | if (!pwd_buf) { | 1170 | if (!cwd_buf) { |
1175 | pwd_buf = (char *)bb_msg_unknown; | 1171 | cwd_buf = (char *)bb_msg_unknown; |
1176 | } | 1172 | } |
1177 | 1173 | ||
1174 | cbuf[1] = '\0'; /* never changes */ | ||
1175 | |||
1178 | while (*prmt_ptr) { | 1176 | while (*prmt_ptr) { |
1179 | pbuf = buf; | 1177 | char *free_me = NULL; |
1180 | pbuf[1] = 0; | 1178 | |
1179 | pbuf = cbuf; | ||
1181 | c = *prmt_ptr++; | 1180 | c = *prmt_ptr++; |
1182 | if (c == '\\') { | 1181 | if (c == '\\') { |
1183 | const char *cp = prmt_ptr; | 1182 | const char *cp = prmt_ptr; |
@@ -1188,6 +1187,7 @@ static void parse_and_put_prompt(const char *prmt_ptr) | |||
1188 | if (*cp == '\0') | 1187 | if (*cp == '\0') |
1189 | break; | 1188 | break; |
1190 | c = *prmt_ptr++; | 1189 | c = *prmt_ptr++; |
1190 | |||
1191 | switch (c) { | 1191 | switch (c) { |
1192 | #if ENABLE_FEATURE_GETUSERNAME_AND_HOMEDIR | 1192 | #if ENABLE_FEATURE_GETUSERNAME_AND_HOMEDIR |
1193 | case 'u': | 1193 | case 'u': |
@@ -1195,87 +1195,81 @@ static void parse_and_put_prompt(const char *prmt_ptr) | |||
1195 | break; | 1195 | break; |
1196 | #endif | 1196 | #endif |
1197 | case 'h': | 1197 | case 'h': |
1198 | pbuf = hostname_buf; | 1198 | pbuf = free_me = xzalloc(256); |
1199 | if (!pbuf) { | 1199 | if (gethostname(pbuf, 255) < 0) { |
1200 | pbuf = xzalloc(256); | 1200 | pbuf[0] = '?'; |
1201 | if (gethostname(pbuf, 255) < 0) { | 1201 | pbuf[1] = '\0'; |
1202 | strcpy(pbuf, "?"); | ||
1203 | } else { | ||
1204 | char *s = strchr(pbuf, '.'); | ||
1205 | if (s) | ||
1206 | *s = '\0'; | ||
1207 | } | ||
1208 | hostname_buf = pbuf; | ||
1209 | } | 1202 | } |
1203 | *strchrnul(pbuf, '.') = '\0'; | ||
1210 | break; | 1204 | break; |
1211 | case '$': | 1205 | case '$': |
1212 | c = (geteuid() == 0 ? '#' : '$'); | 1206 | c = (geteuid() == 0 ? '#' : '$'); |
1213 | break; | 1207 | break; |
1214 | #if ENABLE_FEATURE_GETUSERNAME_AND_HOMEDIR | 1208 | #if ENABLE_FEATURE_GETUSERNAME_AND_HOMEDIR |
1215 | case 'w': | 1209 | case 'w': |
1216 | pbuf = pwd_buf; | 1210 | /* /home/user[/something] -> ~[/something] */ |
1211 | pbuf = cwd_buf; | ||
1217 | l = strlen(home_pwd_buf); | 1212 | l = strlen(home_pwd_buf); |
1218 | if (l != 0 | 1213 | if (l != 0 |
1219 | && strncmp(home_pwd_buf, pbuf, l) == 0 | 1214 | && strncmp(home_pwd_buf, cwd_buf, l) == 0 |
1220 | && (pbuf[l]=='/' || pbuf[l]=='\0') | 1215 | && (cwd_buf[l]=='/' || cwd_buf[l]=='\0') |
1221 | && strlen(pwd_buf+l) < PATH_MAX | 1216 | && strlen(cwd_buf + l) < PATH_MAX |
1222 | ) { | 1217 | ) { |
1223 | pbuf = buf2; | 1218 | pbuf = free_me = xasprintf("~%s", cwd_buf + l); |
1224 | *pbuf = '~'; | ||
1225 | strcpy(pbuf+1, pwd_buf+l); | ||
1226 | } | 1219 | } |
1227 | break; | 1220 | break; |
1228 | #endif | 1221 | #endif |
1229 | case 'W': | 1222 | case 'W': |
1230 | pbuf = pwd_buf; | 1223 | pbuf = cwd_buf; |
1231 | cp = strrchr(pbuf, '/'); | 1224 | cp = strrchr(pbuf, '/'); |
1232 | if (cp != NULL && cp != pbuf) | 1225 | if (cp != NULL && cp != pbuf) |
1233 | pbuf += (cp-pbuf) + 1; | 1226 | pbuf += (cp-pbuf) + 1; |
1234 | break; | 1227 | break; |
1235 | case '!': | 1228 | case '!': |
1236 | pbuf = buf2; | 1229 | pbuf = free_me = xasprintf("%d", num_ok_lines); |
1237 | snprintf(buf2, sizeof(buf2), "%d", num_ok_lines); | ||
1238 | break; | 1230 | break; |
1239 | case 'e': case 'E': /* \e \E = \033 */ | 1231 | case 'e': case 'E': /* \e \E = \033 */ |
1240 | c = '\033'; | 1232 | c = '\033'; |
1241 | break; | 1233 | break; |
1242 | case 'x': case 'X': | 1234 | case 'x': case 'X': { |
1235 | char buf2[4]; | ||
1243 | for (l = 0; l < 3;) { | 1236 | for (l = 0; l < 3;) { |
1244 | int h; | 1237 | unsigned h; |
1245 | buf2[l++] = *prmt_ptr; | 1238 | buf2[l++] = *prmt_ptr; |
1246 | buf2[l] = 0; | 1239 | buf2[l] = '\0'; |
1247 | h = strtol(buf2, &pbuf, 16); | 1240 | h = strtoul(buf2, &pbuf, 16); |
1248 | if (h > UCHAR_MAX || (pbuf - buf2) < l) { | 1241 | if (h > UCHAR_MAX || (pbuf - buf2) < l) { |
1249 | l--; | 1242 | buf2[--l] = '\0'; |
1250 | break; | 1243 | break; |
1251 | } | 1244 | } |
1252 | prmt_ptr++; | 1245 | prmt_ptr++; |
1253 | } | 1246 | } |
1254 | buf2[l] = 0; | 1247 | c = (char)strtoul(buf2, NULL, 16); |
1255 | c = (char)strtol(buf2, NULL, 16); | ||
1256 | if (c == 0) | 1248 | if (c == 0) |
1257 | c = '?'; | 1249 | c = '?'; |
1258 | pbuf = buf; | 1250 | pbuf = cbuf; |
1259 | break; | 1251 | break; |
1252 | } | ||
1260 | case '[': case ']': | 1253 | case '[': case ']': |
1261 | if (c == flg_not_length) { | 1254 | if (c == flg_not_length) { |
1262 | flg_not_length = (flg_not_length == '[' ? ']' : '['); | 1255 | flg_not_length = (flg_not_length == '[' ? ']' : '['); |
1263 | continue; | 1256 | continue; |
1264 | } | 1257 | } |
1265 | break; | 1258 | break; |
1266 | } | 1259 | } /* switch */ |
1267 | } | 1260 | } /* if */ |
1268 | } | 1261 | } /* if */ |
1269 | if (pbuf == buf) | 1262 | cbuf[0] = c; |
1270 | *pbuf = c; | ||
1271 | cur_prmt_len = strlen(pbuf); | 1263 | cur_prmt_len = strlen(pbuf); |
1272 | prmt_len += cur_prmt_len; | 1264 | prmt_len += cur_prmt_len; |
1273 | if (flg_not_length != ']') | 1265 | if (flg_not_length != ']') |
1274 | cmdedit_prmt_len += cur_prmt_len; | 1266 | cmdedit_prmt_len += cur_prmt_len; |
1275 | prmt_mem_ptr = strcat(xrealloc(prmt_mem_ptr, prmt_len+1), pbuf); | 1267 | prmt_mem_ptr = strcat(xrealloc(prmt_mem_ptr, prmt_len+1), pbuf); |
1276 | } | 1268 | free(free_me); |
1277 | if (pwd_buf != (char *)bb_msg_unknown) | 1269 | } /* while */ |
1278 | free(pwd_buf); | 1270 | |
1271 | if (cwd_buf != (char *)bb_msg_unknown) | ||
1272 | free(cwd_buf); | ||
1279 | cmdedit_prompt = prmt_mem_ptr; | 1273 | cmdedit_prompt = prmt_mem_ptr; |
1280 | put_prompt(); | 1274 | put_prompt(); |
1281 | } | 1275 | } |
@@ -1397,7 +1391,6 @@ int read_line_input(const char *prompt, char *command, int maxsize, line_input_t | |||
1397 | if (entry) { | 1391 | if (entry) { |
1398 | user_buf = xstrdup(entry->pw_name); | 1392 | user_buf = xstrdup(entry->pw_name); |
1399 | home_pwd_buf = xstrdup(entry->pw_dir); | 1393 | home_pwd_buf = xstrdup(entry->pw_dir); |
1400 | /* They are not freed on exit (too small to bother) */ | ||
1401 | } | 1394 | } |
1402 | } | 1395 | } |
1403 | #endif | 1396 | #endif |
diff --git a/networking/netstat.c b/networking/netstat.c index 11f141947..d86c2ff5e 100644 --- a/networking/netstat.c +++ b/networking/netstat.c | |||
@@ -148,7 +148,7 @@ static char *ip_port_str(struct sockaddr *addr, int port, const char *proto, int | |||
148 | return host_port; | 148 | return host_port; |
149 | } | 149 | } |
150 | 150 | ||
151 | static void tcp_do_one(int lnr, const char *line) | 151 | static void tcp_do_one(int lnr, char *line) |
152 | { | 152 | { |
153 | char local_addr[64], rem_addr[64]; | 153 | char local_addr[64], rem_addr[64]; |
154 | char more[512]; | 154 | char more[512]; |
@@ -201,7 +201,7 @@ static void tcp_do_one(int lnr, const char *line) | |||
201 | } | 201 | } |
202 | } | 202 | } |
203 | 203 | ||
204 | static void udp_do_one(int lnr, const char *line) | 204 | static void udp_do_one(int lnr, char *line) |
205 | { | 205 | { |
206 | char local_addr[64], rem_addr[64]; | 206 | char local_addr[64], rem_addr[64]; |
207 | const char *state_str; | 207 | const char *state_str; |
@@ -283,7 +283,7 @@ static void udp_do_one(int lnr, const char *line) | |||
283 | } | 283 | } |
284 | } | 284 | } |
285 | 285 | ||
286 | static void raw_do_one(int lnr, const char *line) | 286 | static void raw_do_one(int lnr, char *line) |
287 | { | 287 | { |
288 | char local_addr[64], rem_addr[64]; | 288 | char local_addr[64], rem_addr[64]; |
289 | char more[512]; | 289 | char more[512]; |
@@ -339,31 +339,37 @@ static void raw_do_one(int lnr, const char *line) | |||
339 | } | 339 | } |
340 | } | 340 | } |
341 | 341 | ||
342 | static void unix_do_one(int nr, const char *line) | 342 | static void unix_do_one(int nr, char *line) |
343 | { | 343 | { |
344 | static smallint has_inode = 0; | ||
345 | |||
346 | char path[PATH_MAX], ss_flags[32]; | ||
347 | const char *ss_proto, *ss_state, *ss_type; | ||
348 | int num, state, type, inode; | ||
349 | void *d; | ||
350 | unsigned long refcnt, proto, unix_flags; | 344 | unsigned long refcnt, proto, unix_flags; |
345 | unsigned long inode; | ||
346 | int type, state; | ||
347 | int num, path_ofs; | ||
348 | void *d; | ||
349 | const char *ss_proto, *ss_state, *ss_type; | ||
350 | char ss_flags[32]; | ||
351 | 351 | ||
352 | if (nr == 0) { | 352 | if (nr == 0) |
353 | if (strstr(line, "Inode")) | 353 | return; /* skip header */ |
354 | has_inode = 1; | 354 | |
355 | return; | 355 | { |
356 | char *last = last_char_is(line, '\n'); | ||
357 | if (last) | ||
358 | *last = '\0'; | ||
356 | } | 359 | } |
357 | path[0] = '\0'; | 360 | |
358 | num = sscanf(line, "%p: %lX %lX %lX %X %X %d %s", | 361 | /* 2.6.15 may report lines like "... @/tmp/fam-user-^@^@^@^@^@^@^@..." |
359 | &d, &refcnt, &proto, &unix_flags, &type, &state, &inode, path); | 362 | * (those ^@ are NUL bytes). fgets sees them as tons of empty lines. */ |
360 | if (num < 6) { | 363 | if (!line[0]) |
361 | bb_error_msg("warning, got bogus unix line"); | ||
362 | return; | 364 | return; |
363 | } | ||
364 | if (!has_inode) | ||
365 | sprintf(path, "%d", inode); | ||
366 | 365 | ||
366 | path_ofs = 0; /* paranoia */ | ||
367 | num = sscanf(line, "%p: %lX %lX %lX %X %X %lu %n", | ||
368 | &d, &refcnt, &proto, &unix_flags, &type, &state, &inode, &path_ofs); | ||
369 | if (num < 7) { | ||
370 | bb_error_msg("got bogus unix line '%s'", line); | ||
371 | return; | ||
372 | } | ||
367 | if ((flags & (NETSTAT_LISTENING|NETSTAT_CONNECTED)) != (NETSTAT_LISTENING|NETSTAT_CONNECTED)) { | 373 | if ((flags & (NETSTAT_LISTENING|NETSTAT_CONNECTED)) != (NETSTAT_LISTENING|NETSTAT_CONNECTED)) { |
368 | if ((state == SS_UNCONNECTED) && (unix_flags & SO_ACCEPTCON)) { | 374 | if ((state == SS_UNCONNECTED) && (unix_flags & SO_ACCEPTCON)) { |
369 | if (!(flags & NETSTAT_LISTENING)) | 375 | if (!(flags & NETSTAT_LISTENING)) |
@@ -439,13 +445,9 @@ static void unix_do_one(int nr, const char *line) | |||
439 | strcat(ss_flags, "N "); | 445 | strcat(ss_flags, "N "); |
440 | strcat(ss_flags, "]"); | 446 | strcat(ss_flags, "]"); |
441 | 447 | ||
442 | printf("%-5s %-6ld %-11s %-10s %-13s ", | 448 | printf("%-5s %-6ld %-11s %-10s %-13s %6lu %s\n", |
443 | ss_proto, refcnt, ss_flags, ss_type, ss_state); | 449 | ss_proto, refcnt, ss_flags, ss_type, ss_state, inode, |
444 | if (has_inode) | 450 | line + path_ofs); |
445 | printf("%-6d ", inode); | ||
446 | else | ||
447 | printf("- "); | ||
448 | puts(path); | ||
449 | } | 451 | } |
450 | 452 | ||
451 | #define _PATH_PROCNET_UDP "/proc/net/udp" | 453 | #define _PATH_PROCNET_UDP "/proc/net/udp" |
@@ -456,10 +458,11 @@ static void unix_do_one(int nr, const char *line) | |||
456 | #define _PATH_PROCNET_RAW6 "/proc/net/raw6" | 458 | #define _PATH_PROCNET_RAW6 "/proc/net/raw6" |
457 | #define _PATH_PROCNET_UNIX "/proc/net/unix" | 459 | #define _PATH_PROCNET_UNIX "/proc/net/unix" |
458 | 460 | ||
459 | static void do_info(const char *file, const char *name, void (*proc)(int, const char *)) | 461 | static void do_info(const char *file, const char *name, void (*proc)(int, char *)) |
460 | { | 462 | { |
461 | int lnr = 0; | 463 | int lnr; |
462 | FILE *procinfo; | 464 | FILE *procinfo; |
465 | char *buffer; | ||
463 | 466 | ||
464 | procinfo = fopen(file, "r"); | 467 | procinfo = fopen(file, "r"); |
465 | if (procinfo == NULL) { | 468 | if (procinfo == NULL) { |
@@ -470,13 +473,14 @@ static void do_info(const char *file, const char *name, void (*proc)(int, const | |||
470 | } | 473 | } |
471 | return; | 474 | return; |
472 | } | 475 | } |
476 | lnr = 0; | ||
473 | do { | 477 | do { |
474 | char *buffer = xmalloc_fgets(procinfo); | 478 | buffer = xmalloc_fgets(procinfo); |
475 | if (buffer) { | 479 | if (buffer) { |
476 | (proc)(lnr++, buffer); | 480 | (proc)(lnr++, buffer); |
477 | free(buffer); | 481 | free(buffer); |
478 | } | 482 | } |
479 | } while (!feof(procinfo)); | 483 | } while (buffer); |
480 | fclose(procinfo); | 484 | fclose(procinfo); |
481 | } | 485 | } |
482 | 486 | ||