libbb: shrink recursive_action() by reducing memory pressure

function                                             old     new   delta
recursive_action1                                      -     316    +316
file_action_grep                                     161     164      +3
add_to_prg_cache_if_socket                           202     205      +3
depmod_main                                          509     511      +2
writeFileToTarball                                   488     489      +1
parse_module                                         281     282      +1
fileAction                                           207     208      +1
act                                                  189     190      +1
add_to_dirlist                                        65      64      -1
writeTarFile                                         196     194      -2
uuidcache_init                                        47      45      -2
uuidcache_check_device                               109     107      -2
true_action                                            8       6      -2
run_parts_main                                       310     308      -2
netstat_main                                         534     532      -2
lsusb_main                                            29      27      -2
lspci_main                                            45      43      -2
initial_scan                                         138     136      -2
grep_main                                            845     843      -2
find_main                                            482     480      -2
config_file_action                                   437     435      -2
chmod_main                                           142     140      -2
dirAction                                             14      10      -4
diff_main                                           1544    1540      -4
chown_main                                           154     148      -6
skip_dir                                             136     129      -7
dir_act                                              191     184      -7
recursive_action                                     453      69    -384
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 7/20 up/down: 328/-439)        Total: -111 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
Denys Vlasenko 2020-10-01 21:52:16 +02:00
parent 3c3928fc65
commit 689d0650ab
19 changed files with 159 additions and 150 deletions

View File

@ -491,10 +491,11 @@ static int exclude_file(const llist_t *excluded_files, const char *file)
# define exclude_file(excluded_files, file) 0 # define exclude_file(excluded_files, file) 0
# endif # endif
static int FAST_FUNC writeFileToTarball(const char *fileName, struct stat *statbuf, static int FAST_FUNC writeFileToTarball(struct recursive_state *state,
void *userData, int depth UNUSED_PARAM) const char *fileName,
struct stat *statbuf)
{ {
struct TarBallInfo *tbInfo = (struct TarBallInfo *) userData; struct TarBallInfo *tbInfo = (struct TarBallInfo *) state->userData;
const char *header_name; const char *header_name;
int inputFileFd = -1; int inputFileFd = -1;
@ -700,7 +701,7 @@ static NOINLINE int writeTarFile(
/* Read the directory/files and iterate over them one at a time */ /* Read the directory/files and iterate over them one at a time */
while (filelist) { while (filelist) {
if (!recursive_action(filelist->data, recurseFlags, if (!recursive_action(filelist->data, recurseFlags,
writeFileToTarball, writeFileToTarball, tbInfo, 0) writeFileToTarball, writeFileToTarball, tbInfo)
) { ) {
errorFlag = TRUE; errorFlag = TRUE;
} }

View File

@ -65,12 +65,14 @@
* symbolic links encountered during recursive directory traversals. * symbolic links encountered during recursive directory traversals.
*/ */
static int FAST_FUNC fileAction(const char *fileName, struct stat *statbuf, void* param, int depth) static int FAST_FUNC fileAction(struct recursive_state *state,
const char *fileName,
struct stat *statbuf)
{ {
mode_t newmode; mode_t newmode;
/* match coreutils behavior */ /* match coreutils behavior */
if (depth == 0) { if (state->depth == 0) {
/* statbuf holds lstat result, but we need stat (follow link) */ /* statbuf holds lstat result, but we need stat (follow link) */
if (stat(fileName, statbuf)) if (stat(fileName, statbuf))
goto err; goto err;
@ -79,9 +81,9 @@ static int FAST_FUNC fileAction(const char *fileName, struct stat *statbuf, void
return TRUE; return TRUE;
} }
newmode = bb_parse_mode((char *)param, statbuf->st_mode); newmode = bb_parse_mode((char *)state->userData, statbuf->st_mode);
if (newmode == (mode_t)-1) if (newmode == (mode_t)-1)
bb_error_msg_and_die("invalid mode '%s'", (char *)param); bb_error_msg_and_die("invalid mode '%s'", (char *)state->userData);
if (chmod(fileName, newmode) == 0) { if (chmod(fileName, newmode) == 0) {
if (OPT_VERBOSE if (OPT_VERBOSE
@ -136,8 +138,7 @@ int chmod_main(int argc UNUSED_PARAM, char **argv)
OPT_RECURSE, // recurse OPT_RECURSE, // recurse
fileAction, // file action fileAction, // file action
fileAction, // dir action fileAction, // dir action
smode, // user data smode) // user data
0) // depth
) { ) {
retval = EXIT_FAILURE; retval = EXIT_FAILURE;
} }

View File

@ -97,10 +97,10 @@ struct param_t {
chown_fptr chown_func; chown_fptr chown_func;
}; };
static int FAST_FUNC fileAction(const char *fileName, struct stat *statbuf, static int FAST_FUNC fileAction(struct recursive_state *state UNUSED_PARAM,
void *vparam, int depth UNUSED_PARAM) const char *fileName, struct stat *statbuf)
{ {
#define param (*(struct param_t*)vparam) #define param (*(struct param_t*)state->userData)
#define opt option_mask32 #define opt option_mask32
uid_t u = (param.ugid.uid == (uid_t)-1L) ? statbuf->st_uid : param.ugid.uid; uid_t u = (param.ugid.uid == (uid_t)-1L) ? statbuf->st_uid : param.ugid.uid;
gid_t g = (param.ugid.gid == (gid_t)-1L) ? statbuf->st_gid : param.ugid.gid; gid_t g = (param.ugid.gid == (gid_t)-1L) ? statbuf->st_gid : param.ugid.gid;
@ -159,8 +159,7 @@ int chown_main(int argc UNUSED_PARAM, char **argv)
flags, /* flags */ flags, /* flags */
fileAction, /* file action */ fileAction, /* file action */
fileAction, /* dir action */ fileAction, /* dir action */
&param, /* user data */ &param) /* user data */
0) /* depth */
) { ) {
retval = EXIT_FAILURE; retval = EXIT_FAILURE;
} }

View File

@ -131,12 +131,13 @@ static int bb_alphasort(const void *p1, const void *p2)
return (option_mask32 & OPT_r) ? -r : r; return (option_mask32 & OPT_r) ? -r : r;
} }
static int FAST_FUNC act(const char *file, struct stat *statbuf, void *args UNUSED_PARAM, int depth) static int FAST_FUNC act(struct recursive_state *state,
const char *file, struct stat *statbuf)
{ {
if (depth == 0) if (state->depth == 0)
return TRUE; return TRUE;
if (depth == 1 if (state->depth == 1
&& ( !(statbuf->st_mode & (S_IFREG | S_IFLNK)) && ( !(statbuf->st_mode & (S_IFREG | S_IFLNK))
|| invalid_name(file) || invalid_name(file)
|| (!(option_mask32 & OPT_l) && access(file, X_OK) != 0)) || (!(option_mask32 & OPT_l) && access(file, X_OK) != 0))
@ -199,8 +200,7 @@ int run_parts_main(int argc UNUSED_PARAM, char **argv)
ACTION_RECURSE|ACTION_FOLLOWLINKS, ACTION_RECURSE|ACTION_FOLLOWLINKS,
act, /* file action */ act, /* file action */
act, /* dir action */ act, /* dir action */
NULL, /* user data */ NULL /* user data */
0 /* depth */
); );
if (!names) if (!names)

View File

@ -803,11 +803,11 @@ struct dlist {
}; };
/* This function adds a filename to dl, the directory listing. */ /* This function adds a filename to dl, the directory listing. */
static int FAST_FUNC add_to_dirlist(const char *filename, static int FAST_FUNC add_to_dirlist(struct recursive_state *state,
struct stat *sb UNUSED_PARAM, const char *filename,
void *userdata, int depth UNUSED_PARAM) struct stat *sb UNUSED_PARAM)
{ {
struct dlist *const l = userdata; struct dlist *const l = state->userData;
const char *file = filename + l->len; const char *file = filename + l->len;
while (*file == '/') while (*file == '/')
file++; file++;
@ -820,12 +820,12 @@ static int FAST_FUNC add_to_dirlist(const char *filename,
/* If recursion is not set, this function adds the directory /* If recursion is not set, this function adds the directory
* to the list and prevents recursive_action from recursing into it. * to the list and prevents recursive_action from recursing into it.
*/ */
static int FAST_FUNC skip_dir(const char *filename, static int FAST_FUNC skip_dir(struct recursive_state *state,
struct stat *sb, void *userdata, const char *filename,
int depth) struct stat *sb)
{ {
if (!(option_mask32 & FLAG(r)) && depth) { if (!(option_mask32 & FLAG(r)) && state->depth) {
add_to_dirlist(filename, sb, userdata, depth); add_to_dirlist(state, filename, sb);
return SKIP; return SKIP;
} }
if (!(option_mask32 & FLAG(N))) { if (!(option_mask32 & FLAG(N))) {
@ -833,7 +833,7 @@ static int FAST_FUNC skip_dir(const char *filename,
* which do not exist on the "other side". * which do not exist on the "other side".
* Testcase: diff -r /tmp / * Testcase: diff -r /tmp /
* (it would recurse deep into /proc without this code) */ * (it would recurse deep into /proc without this code) */
struct dlist *const l = userdata; struct dlist *const l = state->userData;
filename += l->len; filename += l->len;
if (filename[0]) { if (filename[0]) {
struct stat osb; struct stat osb;
@ -868,7 +868,7 @@ static void diffdir(char *p[2], const char *s_start)
* add_to_dirlist will remove it. */ * add_to_dirlist will remove it. */
list[i].len = strlen(p[i]); list[i].len = strlen(p[i]);
recursive_action(p[i], ACTION_RECURSE | ACTION_FOLLOWLINKS, recursive_action(p[i], ACTION_RECURSE | ACTION_FOLLOWLINKS,
add_to_dirlist, skip_dir, &list[i], 0); add_to_dirlist, skip_dir, &list[i]);
/* Sort dl alphabetically. /* Sort dl alphabetically.
* GNU diff does this ignoring any number of trailing dots. * GNU diff does this ignoring any number of trailing dots.
* We don't, so for us dotted files almost always are * We don't, so for us dotted files almost always are

View File

@ -889,10 +889,10 @@ ACTF(links)
} }
#endif #endif
static int FAST_FUNC fileAction(const char *fileName, static int FAST_FUNC fileAction(
struct stat *statbuf, struct recursive_state *state IF_NOT_FEATURE_FIND_MAXDEPTH(UNUSED_PARAM),
void *userData UNUSED_PARAM, const char *fileName,
int depth IF_NOT_FEATURE_FIND_MAXDEPTH(UNUSED_PARAM)) struct stat *statbuf)
{ {
int r; int r;
int same_fs = 1; int same_fs = 1;
@ -911,12 +911,12 @@ static int FAST_FUNC fileAction(const char *fileName,
#endif #endif
#if ENABLE_FEATURE_FIND_MAXDEPTH #if ENABLE_FEATURE_FIND_MAXDEPTH
if (depth < G.minmaxdepth[0]) { if (state->depth < G.minmaxdepth[0]) {
if (same_fs) if (same_fs)
return TRUE; /* skip this, continue recursing */ return TRUE; /* skip this, continue recursing */
return SKIP; /* stop recursing */ return SKIP; /* stop recursing */
} }
if (depth > G.minmaxdepth[1]) if (state->depth > G.minmaxdepth[1])
return SKIP; /* stop recursing */ return SKIP; /* stop recursing */
#endif #endif
@ -927,7 +927,7 @@ static int FAST_FUNC fileAction(const char *fileName,
#if ENABLE_FEATURE_FIND_MAXDEPTH #if ENABLE_FEATURE_FIND_MAXDEPTH
if (S_ISDIR(statbuf->st_mode)) { if (S_ISDIR(statbuf->st_mode)) {
if (depth == G.minmaxdepth[1]) if (state->depth == G.minmaxdepth[1])
return SKIP; return SKIP;
} }
#endif #endif
@ -1570,8 +1570,7 @@ int find_main(int argc UNUSED_PARAM, char **argv)
G.recurse_flags,/* flags */ G.recurse_flags,/* flags */
fileAction, /* file action */ fileAction, /* file action */
fileAction, /* dir action */ fileAction, /* dir action */
NULL, /* user data */ NULL) /* user data */
0) /* depth */
) { ) {
G.exitstatus |= EXIT_FAILURE; G.exitstatus |= EXIT_FAILURE;
} }

View File

@ -656,10 +656,9 @@ static void load_pattern_list(llist_t **lst, char *pattern)
llist_add_to(lst, new_grep_list_data(p, 0)); llist_add_to(lst, new_grep_list_data(p, 0));
} }
static int FAST_FUNC file_action_grep(const char *filename, static int FAST_FUNC file_action_grep(struct recursive_state *state UNUSED_PARAM,
struct stat *statbuf, const char *filename,
void* matched, struct stat *statbuf)
int depth UNUSED_PARAM)
{ {
FILE *file; FILE *file;
@ -686,7 +685,7 @@ static int FAST_FUNC file_action_grep(const char *filename,
return 0; return 0;
} }
cur_file = filename; cur_file = filename;
*(int*)matched |= grep_file(file); *(int*)state->userData |= grep_file(file);
fclose(file); fclose(file);
return 1; return 1;
} }
@ -702,8 +701,8 @@ static int grep_dir(const char *dir)
| 0, | 0,
/* fileAction= */ file_action_grep, /* fileAction= */ file_action_grep,
/* dirAction= */ NULL, /* dirAction= */ NULL,
/* userData= */ &matched, /* userData= */ &matched
0); );
return matched; return matched;
} }

View File

@ -441,10 +441,18 @@ enum {
ACTION_DANGLING_OK = (1 << 5), ACTION_DANGLING_OK = (1 << 5),
}; };
typedef uint8_t recurse_flags_t; typedef uint8_t recurse_flags_t;
extern int recursive_action(const char *fileName, unsigned flags, typedef struct recursive_state {
int FAST_FUNC (*fileAction)(const char *fileName, struct stat* statbuf, void* userData, int depth), unsigned flags;
int FAST_FUNC (*dirAction)(const char *fileName, struct stat* statbuf, void* userData, int depth), unsigned depth;
void* userData, unsigned depth) FAST_FUNC; void *userData;
int FAST_FUNC (*fileAction)(struct recursive_state *state, const char *fileName, struct stat* statbuf);
int FAST_FUNC (*dirAction)(struct recursive_state *state, const char *fileName, struct stat* statbuf);
} recursive_state_t;
int recursive_action(const char *fileName, unsigned flags,
int FAST_FUNC (*fileAction)(struct recursive_state *state, const char *fileName, struct stat* statbuf),
int FAST_FUNC (*dirAction)(struct recursive_state *state, const char *fileName, struct stat* statbuf),
void *userData
) FAST_FUNC;
extern int device_open(const char *device, int mode) FAST_FUNC; extern int device_open(const char *device, int mode) FAST_FUNC;
enum { GETPTY_BUFSIZE = 16 }; /* more than enough for "/dev/ttyXXX" */ enum { GETPTY_BUFSIZE = 16 }; /* more than enough for "/dev/ttyXXX" */

View File

@ -21,10 +21,9 @@
* is so stinking huge. * is so stinking huge.
*/ */
static int FAST_FUNC true_action(const char *fileName UNUSED_PARAM, static int FAST_FUNC true_action(struct recursive_state *state UNUSED_PARAM,
struct stat *statbuf UNUSED_PARAM, const char *fileName UNUSED_PARAM,
void* userData UNUSED_PARAM, struct stat *statbuf UNUSED_PARAM)
int depth UNUSED_PARAM)
{ {
return TRUE; return TRUE;
} }
@ -65,12 +64,7 @@ static int FAST_FUNC true_action(const char *fileName UNUSED_PARAM,
* 1: stat(statbuf). Calls dirAction and optionally recurse on link to dir. * 1: stat(statbuf). Calls dirAction and optionally recurse on link to dir.
*/ */
int FAST_FUNC recursive_action(const char *fileName, static int recursive_action1(recursive_state_t *state, const char *fileName)
unsigned flags,
int FAST_FUNC (*fileAction)(const char *fileName, struct stat *statbuf, void* userData, int depth),
int FAST_FUNC (*dirAction)(const char *fileName, struct stat *statbuf, void* userData, int depth),
void* userData,
unsigned depth)
{ {
struct stat statbuf; struct stat statbuf;
unsigned follow; unsigned follow;
@ -78,24 +72,21 @@ int FAST_FUNC recursive_action(const char *fileName,
DIR *dir; DIR *dir;
struct dirent *next; struct dirent *next;
if (!fileAction) fileAction = true_action;
if (!dirAction) dirAction = true_action;
follow = ACTION_FOLLOWLINKS; follow = ACTION_FOLLOWLINKS;
if (depth == 0) if (state->depth == 0)
follow = ACTION_FOLLOWLINKS | ACTION_FOLLOWLINKS_L0; follow = ACTION_FOLLOWLINKS | ACTION_FOLLOWLINKS_L0;
follow &= flags; follow &= state->flags;
status = (follow ? stat : lstat)(fileName, &statbuf); status = (follow ? stat : lstat)(fileName, &statbuf);
if (status < 0) { if (status < 0) {
#ifdef DEBUG_RECURS_ACTION #ifdef DEBUG_RECURS_ACTION
bb_error_msg("status=%d flags=%x", status, flags); bb_error_msg("status=%d flags=%x", status, state->flags);
#endif #endif
if ((flags & ACTION_DANGLING_OK) if ((state->flags & ACTION_DANGLING_OK)
&& errno == ENOENT && errno == ENOENT
&& lstat(fileName, &statbuf) == 0 && lstat(fileName, &statbuf) == 0
) { ) {
/* Dangling link */ /* Dangling link */
return fileAction(fileName, &statbuf, userData, depth); return state->fileAction(state, fileName, &statbuf);
} }
goto done_nak_warn; goto done_nak_warn;
} }
@ -103,20 +94,20 @@ int FAST_FUNC recursive_action(const char *fileName,
/* If S_ISLNK(m), then we know that !S_ISDIR(m). /* If S_ISLNK(m), then we know that !S_ISDIR(m).
* Then we can skip checking first part: if it is true, then * Then we can skip checking first part: if it is true, then
* (!dir) is also true! */ * (!dir) is also true! */
if ( /* (!(flags & ACTION_FOLLOWLINKS) && S_ISLNK(statbuf.st_mode)) || */ if ( /* (!(state->flags & ACTION_FOLLOWLINKS) && S_ISLNK(statbuf.st_mode)) || */
!S_ISDIR(statbuf.st_mode) !S_ISDIR(statbuf.st_mode)
) { ) {
return fileAction(fileName, &statbuf, userData, depth); return state->fileAction(state, fileName, &statbuf);
} }
/* It's a directory (or a link to one, and followLinks is set) */ /* It's a directory (or a link to one, and followLinks is set) */
if (!(flags & ACTION_RECURSE)) { if (!(state->flags & ACTION_RECURSE)) {
return dirAction(fileName, &statbuf, userData, depth); return state->dirAction(state, fileName, &statbuf);
} }
if (!(flags & ACTION_DEPTHFIRST)) { if (!(state->flags & ACTION_DEPTHFIRST)) {
status = dirAction(fileName, &statbuf, userData, depth); status = state->dirAction(state, fileName, &statbuf);
if (status == FALSE) if (status == FALSE)
goto done_nak_warn; goto done_nak_warn;
if (status == SKIP) if (status == SKIP)
@ -140,11 +131,13 @@ int FAST_FUNC recursive_action(const char *fileName,
continue; continue;
/* process every file (NB: ACTION_RECURSE is set in flags) */ /* process every file (NB: ACTION_RECURSE is set in flags) */
s = recursive_action(nextFile, flags, fileAction, dirAction, state->depth++;
userData, depth + 1); s = recursive_action1(state, nextFile);
if (s == FALSE) if (s == FALSE)
status = FALSE; status = FALSE;
free(nextFile); free(nextFile);
state->depth--;
//#define RECURSE_RESULT_ABORT -1 //#define RECURSE_RESULT_ABORT -1
// if (s == RECURSE_RESULT_ABORT) { // if (s == RECURSE_RESULT_ABORT) {
// closedir(dir); // closedir(dir);
@ -153,15 +146,36 @@ int FAST_FUNC recursive_action(const char *fileName,
} }
closedir(dir); closedir(dir);
if (flags & ACTION_DEPTHFIRST) { if (state->flags & ACTION_DEPTHFIRST) {
if (!dirAction(fileName, &statbuf, userData, depth)) if (!state->dirAction(state, fileName, &statbuf))
goto done_nak_warn; goto done_nak_warn;
} }
return status; return status;
done_nak_warn: done_nak_warn:
if (!(flags & ACTION_QUIET)) if (!(state->flags & ACTION_QUIET))
bb_simple_perror_msg(fileName); bb_simple_perror_msg(fileName);
return FALSE; return FALSE;
} }
int FAST_FUNC recursive_action(const char *fileName,
unsigned flags,
int FAST_FUNC (*fileAction)(struct recursive_state *state, const char *fileName, struct stat* statbuf),
int FAST_FUNC (*dirAction)(struct recursive_state *state, const char *fileName, struct stat* statbuf),
void *userData)
{
/* Keeping a part of variables of recusive descent in a "state structure"
* instead of passing ALL of them down as parameters of recursive_action1()
* relieves register pressure, both in recursive_action1()
* and in every file/dirAction().
*/
recursive_state_t state;
state.flags = flags;
state.depth = 0;
state.userData = userData;
state.fileAction = fileAction ? fileAction : true_action;
state.dirAction = dirAction ? dirAction : true_action;
return recursive_action1(&state, fileName);
}

View File

@ -32,10 +32,11 @@
* for each depends, look through our list of full paths and emit if found * for each depends, look through our list of full paths and emit if found
*/ */
static int FAST_FUNC parse_module(const char *fname, struct stat *sb UNUSED_PARAM, static int FAST_FUNC parse_module(struct recursive_state *state,
void *data, int depth UNUSED_PARAM) const char *fname,
struct stat *sb UNUSED_PARAM)
{ {
module_db *modules = data; module_db *modules = state->userData;
char *image, *ptr; char *image, *ptr;
module_entry *e; module_entry *e;
@ -201,11 +202,12 @@ int depmod_main(int argc UNUSED_PARAM, char **argv)
memset(&modules, 0, sizeof(modules)); memset(&modules, 0, sizeof(modules));
if (*argv) { if (*argv) {
do { do {
parse_module(*argv, /*sb (unused):*/ NULL, &modules, 0); recursive_action(*argv, 0 /* no ACTION_RECURSE! */,
parse_module, NULL, &modules);
} while (*++argv); } while (*++argv);
} else { } else {
recursive_action(".", ACTION_RECURSE, recursive_action(".", ACTION_RECURSE,
parse_module, NULL, &modules, 0); parse_module, NULL, &modules);
} }
/* Generate dependency and alias files */ /* Generate dependency and alias files */

View File

@ -751,8 +751,7 @@ static int process_module(char *name, const char *cmdline_options)
ACTION_RECURSE, /* flags */ ACTION_RECURSE, /* flags */
fileAction, /* file action */ fileAction, /* file action */
NULL, /* dir action */ NULL, /* dir action */
name, /* user data */ name /* user data */
0 /* depth */
); );
dbg1_error_msg("dirscan complete"); dbg1_error_msg("dirscan complete");
/* Module was not found, or load failed, or is_remove */ /* Module was not found, or load failed, or is_remove */

View File

@ -235,10 +235,9 @@ static void add_probe(const char *name)
} }
} }
static int FAST_FUNC config_file_action(const char *filename, static int FAST_FUNC config_file_action(struct recursive_state *state,
struct stat *statbuf UNUSED_PARAM, const char *filename,
void *userdata UNUSED_PARAM, struct stat *statbuf UNUSED_PARAM)
int depth)
{ {
char *tokens[3]; char *tokens[3];
parser_t *p; parser_t *p;
@ -255,7 +254,7 @@ static int FAST_FUNC config_file_action(const char *filename,
* that we shouldn't recurse into /etc/modprobe.d/dir/ * that we shouldn't recurse into /etc/modprobe.d/dir/
* _subdirectories_: * _subdirectories_:
*/ */
if (depth > 1) if (state->depth > 1)
return SKIP; /* stop recursing */ return SKIP; /* stop recursing */
//TODO: instead, can use dirAction in recursive_action() to SKIP dirs //TODO: instead, can use dirAction in recursive_action() to SKIP dirs
//on depth == 1 level. But that's more code... //on depth == 1 level. But that's more code...
@ -264,7 +263,7 @@ static int FAST_FUNC config_file_action(const char *filename,
* depth==0: read_config("modules.{symbols,alias}") must work, * depth==0: read_config("modules.{symbols,alias}") must work,
* "include FILE_NOT_ENDING_IN_CONF" must work too. * "include FILE_NOT_ENDING_IN_CONF" must work too.
*/ */
if (depth != 0) { if (state->depth != 0) {
if (!is_suffixed_with(base, ".conf")) if (!is_suffixed_with(base, ".conf"))
goto error; goto error;
} }
@ -329,8 +328,7 @@ static int FAST_FUNC config_file_action(const char *filename,
static int read_config(const char *path) static int read_config(const char *path)
{ {
return recursive_action(path, ACTION_RECURSE | ACTION_QUIET, return recursive_action(path, ACTION_RECURSE | ACTION_QUIET,
config_file_action, NULL, NULL, config_file_action, NULL, NULL);
/*depth:*/ 0);
} }
static const char *humanly_readable_name(struct module_entry *m) static const char *humanly_readable_name(struct module_entry *m)

View File

@ -272,10 +272,9 @@ static long extract_socket_inode(const char *lname)
return inode; return inode;
} }
static int FAST_FUNC add_to_prg_cache_if_socket(const char *fileName, static int FAST_FUNC add_to_prg_cache_if_socket(struct recursive_state *state,
struct stat *statbuf UNUSED_PARAM, const char *fileName,
void *pid_slash_progname, struct stat *statbuf UNUSED_PARAM)
int depth UNUSED_PARAM)
{ {
char *linkname; char *linkname;
long inode; long inode;
@ -284,16 +283,17 @@ static int FAST_FUNC add_to_prg_cache_if_socket(const char *fileName,
if (linkname != NULL) { if (linkname != NULL) {
inode = extract_socket_inode(linkname); inode = extract_socket_inode(linkname);
free(linkname); free(linkname);
if (inode >= 0) if (inode >= 0) {
prg_cache_add(inode, (char *)pid_slash_progname); char *pid_slash_progname = state->userData;
prg_cache_add(inode, pid_slash_progname);
}
} }
return TRUE; return TRUE;
} }
static int FAST_FUNC dir_act(const char *fileName, static int FAST_FUNC dir_act(struct recursive_state *state,
struct stat *statbuf UNUSED_PARAM, const char *fileName,
void *userData UNUSED_PARAM, struct stat *statbuf UNUSED_PARAM)
int depth)
{ {
const char *pid; const char *pid;
char *pid_slash_progname; char *pid_slash_progname;
@ -301,7 +301,7 @@ static int FAST_FUNC dir_act(const char *fileName,
char cmdline_buf[512]; char cmdline_buf[512];
int n, len; int n, len;
if (depth == 0) /* "/proc" itself */ if (state->depth == 0) /* "/proc" itself */
return TRUE; /* continue looking one level below /proc */ return TRUE; /* continue looking one level below /proc */
pid = fileName + sizeof("/proc/")-1; /* point after "/proc/" */ pid = fileName + sizeof("/proc/")-1; /* point after "/proc/" */
@ -321,8 +321,8 @@ static int FAST_FUNC dir_act(const char *fileName,
ACTION_RECURSE | ACTION_QUIET, ACTION_RECURSE | ACTION_QUIET,
add_to_prg_cache_if_socket, add_to_prg_cache_if_socket,
NULL, NULL,
(void *)pid_slash_progname, (void *)pid_slash_progname
0); );
free(pid_slash_progname); free(pid_slash_progname);
if (!n) if (!n)
@ -337,7 +337,7 @@ static void prg_cache_load(void)
prg_cache_loaded = 1; prg_cache_loaded = 1;
load_ok = recursive_action("/proc", ACTION_RECURSE | ACTION_QUIET, load_ok = recursive_action("/proc", ACTION_RECURSE | ACTION_QUIET,
NULL, dir_act, NULL, 0); NULL, dir_act, NULL);
if (load_ok) if (load_ok)
return; return;

View File

@ -62,11 +62,9 @@ static char *type = NULL;
static char *range = NULL; static char *range = NULL;
static char *specified_context = NULL; static char *specified_context = NULL;
static int FAST_FUNC change_filedir_context( static int FAST_FUNC change_filedir_context(struct recursive_state *state UNUSED_PARAM,
const char *fname, const char *fname,
struct stat *stbuf UNUSED_PARAM, struct stat *stbuf UNUSED_PARAM)
void *userData UNUSED_PARAM,
int depth UNUSED_PARAM)
{ {
context_t context = NULL; context_t context = NULL;
security_context_t file_context = NULL; security_context_t file_context = NULL;
@ -207,7 +205,7 @@ int chcon_main(int argc UNUSED_PARAM, char **argv)
((option_mask32 & OPT_RECURSIVE) ? ACTION_RECURSE : 0), ((option_mask32 & OPT_RECURSIVE) ? ACTION_RECURSE : 0),
change_filedir_context, change_filedir_context,
change_filedir_context, change_filedir_context,
NULL, 0) != TRUE) NULL) != TRUE)
errors = 1; errors = 1;
} }
return errors; return errors;

View File

@ -463,11 +463,9 @@ static int restore(const char *file)
* This function is called by recursive_action on each file during * This function is called by recursive_action on each file during
* the directory traversal. * the directory traversal.
*/ */
static int FAST_FUNC apply_spec( static int FAST_FUNC apply_spec(struct recursive_state *state UNUSED_PARAM,
const char *file, const char *file,
struct stat *sb, struct stat *sb)
void *userData UNUSED_PARAM,
int depth UNUSED_PARAM)
{ {
if (!follow_mounts) { if (!follow_mounts) {
/* setfiles does not process across different mount points */ /* setfiles does not process across different mount points */
@ -535,7 +533,7 @@ static int process_one(char *name)
ACTION_RECURSE, ACTION_RECURSE,
apply_spec, apply_spec,
apply_spec, apply_spec,
NULL, 0) != TRUE NULL) != TRUE
) { ) {
bb_error_msg("error while labeling %s", name); bb_error_msg("error while labeling %s", name);
goto err; goto err;

View File

@ -37,11 +37,9 @@ enum {
/* /*
* PCI_SLOT_NAME PCI_CLASS: PCI_VID:PCI_DID [PCI_SUBSYS_VID:PCI_SUBSYS_DID] [DRIVER] * PCI_SLOT_NAME PCI_CLASS: PCI_VID:PCI_DID [PCI_SUBSYS_VID:PCI_SUBSYS_DID] [DRIVER]
*/ */
static int FAST_FUNC fileAction( static int FAST_FUNC fileAction(struct recursive_state *state UNUSED_PARAM,
const char *fileName, const char *fileName,
struct stat *statbuf UNUSED_PARAM, struct stat *statbuf UNUSED_PARAM)
void *userData UNUSED_PARAM,
int depth UNUSED_PARAM)
{ {
parser_t *parser; parser_t *parser;
char *tokens[3]; char *tokens[3];
@ -117,8 +115,7 @@ int lspci_main(int argc UNUSED_PARAM, char **argv)
ACTION_RECURSE, ACTION_RECURSE,
fileAction, fileAction,
NULL, /* dirAction */ NULL, /* dirAction */
NULL, /* userData */ NULL /* userData */
0 /* depth */); );
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }

View File

@ -24,11 +24,9 @@
#include "libbb.h" #include "libbb.h"
static int FAST_FUNC fileAction( static int FAST_FUNC fileAction(struct recursive_state *state UNUSED_PARAM,
const char *fileName, const char *fileName,
struct stat *statbuf UNUSED_PARAM, struct stat *statbuf UNUSED_PARAM)
void *userData UNUSED_PARAM,
int depth UNUSED_PARAM)
{ {
parser_t *parser; parser_t *parser;
char *tokens[4]; char *tokens[4];
@ -80,8 +78,8 @@ int lsusb_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
ACTION_RECURSE, ACTION_RECURSE,
fileAction, fileAction,
NULL, /* dirAction */ NULL, /* dirAction */
NULL, /* userData */ NULL /* userData */
0 /* depth */); );
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }

View File

@ -845,13 +845,12 @@ static ssize_t readlink2(char *buf, size_t bufsize)
/* File callback for /sys/ traversal. /* File callback for /sys/ traversal.
* We act only on "/sys/.../dev" (pseudo)file * We act only on "/sys/.../dev" (pseudo)file
*/ */
static int FAST_FUNC fileAction(const char *fileName, static int FAST_FUNC fileAction(struct recursive_state *state,
struct stat *statbuf UNUSED_PARAM, const char *fileName,
void *userData, struct stat *statbuf UNUSED_PARAM)
int depth UNUSED_PARAM)
{ {
size_t len = strlen(fileName) - 4; /* can't underflow */ size_t len = strlen(fileName) - 4; /* can't underflow */
char *path = userData; /* char array[PATH_MAX + SCRATCH_SIZE] */ char *path = state->userData; /* char array[PATH_MAX + SCRATCH_SIZE] */
char subsys[PATH_MAX]; char subsys[PATH_MAX];
int res; int res;
@ -888,12 +887,11 @@ static int FAST_FUNC fileAction(const char *fileName,
} }
/* Directory callback for /sys/ traversal */ /* Directory callback for /sys/ traversal */
static int FAST_FUNC dirAction(const char *fileName UNUSED_PARAM, static int FAST_FUNC dirAction(struct recursive_state *state,
struct stat *statbuf UNUSED_PARAM, const char *fileName UNUSED_PARAM,
void *userData UNUSED_PARAM, struct stat *statbuf UNUSED_PARAM)
int depth)
{ {
return (depth >= MAX_SYSFS_DEPTH ? SKIP : TRUE); return (state->depth >= MAX_SYSFS_DEPTH ? SKIP : TRUE);
} }
/* For the full gory details, see linux/Documentation/firmware_class/README /* For the full gory details, see linux/Documentation/firmware_class/README
@ -1149,7 +1147,7 @@ static void initial_scan(char *temp)
/* Create all devices from /sys/dev hierarchy */ /* Create all devices from /sys/dev hierarchy */
recursive_action("/sys/dev", recursive_action("/sys/dev",
ACTION_RECURSE | ACTION_FOLLOWLINKS, ACTION_RECURSE | ACTION_FOLLOWLINKS,
fileAction, dirAction, temp, 0); fileAction, dirAction, temp);
} }
#if ENABLE_FEATURE_MDEV_DAEMON #if ENABLE_FEATURE_MDEV_DAEMON

View File

@ -102,10 +102,9 @@ uuidcache_addentry(char *device, /*int major, int minor,*/ char *label, char *uu
* add a cache entry for this device. * add a cache entry for this device.
* If device node does not exist, it will be temporarily created. */ * If device node does not exist, it will be temporarily created. */
static int FAST_FUNC static int FAST_FUNC
uuidcache_check_device(const char *device, uuidcache_check_device(struct recursive_state *state UNUSED_PARAM,
struct stat *statbuf, const char *device,
void *userData UNUSED_PARAM, struct stat *statbuf)
int depth UNUSED_PARAM)
{ {
/* note: this check rejects links to devices, among other nodes */ /* note: this check rejects links to devices, among other nodes */
if (!S_ISBLK(statbuf->st_mode) if (!S_ISBLK(statbuf->st_mode)
@ -145,12 +144,13 @@ uuidcache_init(int scan_devices)
* This is unacceptably complex. Let's just scan /dev. * This is unacceptably complex. Let's just scan /dev.
* (Maybe add scanning of /sys/block/XXX/dev for devices * (Maybe add scanning of /sys/block/XXX/dev for devices
* somehow not having their /dev/XXX entries created?) */ * somehow not having their /dev/XXX entries created?) */
if (scan_devices) if (scan_devices) {
recursive_action("/dev", ACTION_RECURSE, recursive_action("/dev", ACTION_RECURSE,
uuidcache_check_device, /* file_action */ uuidcache_check_device, /* file_action */
NULL, /* dir_action */ NULL, /* dir_action */
NULL, /* userData */ NULL /* userData */
0 /* depth */); );
}
return uuidCache; return uuidCache;
} }