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:
parent
3c3928fc65
commit
689d0650ab
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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 */
|
||||||
¶m, /* user data */
|
¶m) /* user data */
|
||||||
0) /* depth */
|
|
||||||
) {
|
) {
|
||||||
retval = EXIT_FAILURE;
|
retval = EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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" */
|
||||||
|
@ -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);
|
||||||
|
}
|
||||||
|
@ -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 */
|
||||||
|
@ -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 */
|
||||||
|
@ -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)
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user