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:
		| @@ -491,10 +491,11 @@ static int exclude_file(const llist_t *excluded_files, const char *file) | ||||
| #  define exclude_file(excluded_files, file) 0 | ||||
| # endif | ||||
|  | ||||
| static int FAST_FUNC writeFileToTarball(const char *fileName, struct stat *statbuf, | ||||
| 			void *userData, int depth UNUSED_PARAM) | ||||
| static int FAST_FUNC writeFileToTarball(struct recursive_state *state, | ||||
| 		const char *fileName, | ||||
| 		struct stat *statbuf) | ||||
| { | ||||
| 	struct TarBallInfo *tbInfo = (struct TarBallInfo *) userData; | ||||
| 	struct TarBallInfo *tbInfo = (struct TarBallInfo *) state->userData; | ||||
| 	const char *header_name; | ||||
| 	int inputFileFd = -1; | ||||
|  | ||||
| @@ -700,7 +701,7 @@ static NOINLINE int writeTarFile( | ||||
| 	/* Read the directory/files and iterate over them one at a time */ | ||||
| 	while (filelist) { | ||||
| 		if (!recursive_action(filelist->data, recurseFlags, | ||||
| 				writeFileToTarball, writeFileToTarball, tbInfo, 0) | ||||
| 				writeFileToTarball, writeFileToTarball, tbInfo) | ||||
| 		) { | ||||
| 			errorFlag = TRUE; | ||||
| 		} | ||||
|   | ||||
| @@ -65,12 +65,14 @@ | ||||
|  * 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; | ||||
|  | ||||
| 	/* match coreutils behavior */ | ||||
| 	if (depth == 0) { | ||||
| 	if (state->depth == 0) { | ||||
| 		/* statbuf holds lstat result, but we need stat (follow link) */ | ||||
| 		if (stat(fileName, statbuf)) | ||||
| 			goto err; | ||||
| @@ -79,9 +81,9 @@ static int FAST_FUNC fileAction(const char *fileName, struct stat *statbuf, void | ||||
| 			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) | ||||
| 		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 (OPT_VERBOSE | ||||
| @@ -136,8 +138,7 @@ int chmod_main(int argc UNUSED_PARAM, char **argv) | ||||
| 			OPT_RECURSE,    // recurse | ||||
| 			fileAction,     // file action | ||||
| 			fileAction,     // dir action | ||||
| 			smode,          // user data | ||||
| 			0)              // depth | ||||
| 			smode)          // user data | ||||
| 		) { | ||||
| 			retval = EXIT_FAILURE; | ||||
| 		} | ||||
|   | ||||
| @@ -97,10 +97,10 @@ struct param_t { | ||||
| 	chown_fptr chown_func; | ||||
| }; | ||||
|  | ||||
| static int FAST_FUNC fileAction(const char *fileName, struct stat *statbuf, | ||||
| 		void *vparam, int depth UNUSED_PARAM) | ||||
| static int FAST_FUNC fileAction(struct recursive_state *state 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 | ||||
| 	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; | ||||
| @@ -159,8 +159,7 @@ int chown_main(int argc UNUSED_PARAM, char **argv) | ||||
| 				flags,          /* flags */ | ||||
| 				fileAction,     /* file action */ | ||||
| 				fileAction,     /* dir action */ | ||||
| 				¶m,         /* user data */ | ||||
| 				0)              /* depth */ | ||||
| 				¶m)         /* user data */ | ||||
| 		) { | ||||
| 			retval = EXIT_FAILURE; | ||||
| 		} | ||||
|   | ||||
| @@ -131,12 +131,13 @@ static int bb_alphasort(const void *p1, const void *p2) | ||||
| 	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; | ||||
|  | ||||
| 	if (depth == 1 | ||||
| 	if (state->depth == 1 | ||||
| 	 && (  !(statbuf->st_mode & (S_IFREG | S_IFLNK)) | ||||
| 	    || invalid_name(file) | ||||
| 	    || (!(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, | ||||
| 			act,            /* file action */ | ||||
| 			act,            /* dir action */ | ||||
| 			NULL,           /* user data */ | ||||
| 			0               /* depth */ | ||||
| 			NULL            /* user data */ | ||||
| 	); | ||||
|  | ||||
| 	if (!names) | ||||
|   | ||||
| @@ -803,11 +803,11 @@ struct dlist { | ||||
| }; | ||||
|  | ||||
| /* This function adds a filename to dl, the directory listing. */ | ||||
| static int FAST_FUNC add_to_dirlist(const char *filename, | ||||
| 		struct stat *sb UNUSED_PARAM, | ||||
| 		void *userdata, int depth UNUSED_PARAM) | ||||
| static int FAST_FUNC add_to_dirlist(struct recursive_state *state, | ||||
| 		const char *filename, | ||||
| 		struct stat *sb UNUSED_PARAM) | ||||
| { | ||||
| 	struct dlist *const l = userdata; | ||||
| 	struct dlist *const l = state->userData; | ||||
| 	const char *file = filename + l->len; | ||||
| 	while (*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 | ||||
|  * to the list and prevents recursive_action from recursing into it. | ||||
|  */ | ||||
| static int FAST_FUNC skip_dir(const char *filename, | ||||
| 		struct stat *sb, void *userdata, | ||||
| 		int depth) | ||||
| static int FAST_FUNC skip_dir(struct recursive_state *state, | ||||
| 		const char *filename, | ||||
| 		struct stat *sb) | ||||
| { | ||||
| 	if (!(option_mask32 & FLAG(r)) && depth) { | ||||
| 		add_to_dirlist(filename, sb, userdata, depth); | ||||
| 	if (!(option_mask32 & FLAG(r)) && state->depth) { | ||||
| 		add_to_dirlist(state, filename, sb); | ||||
| 		return SKIP; | ||||
| 	} | ||||
| 	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". | ||||
| 		 * Testcase: diff -r /tmp / | ||||
| 		 * (it would recurse deep into /proc without this code) */ | ||||
| 		struct dlist *const l = userdata; | ||||
| 		struct dlist *const l = state->userData; | ||||
| 		filename += l->len; | ||||
| 		if (filename[0]) { | ||||
| 			struct stat osb; | ||||
| @@ -868,7 +868,7 @@ static void diffdir(char *p[2], const char *s_start) | ||||
| 		 * add_to_dirlist will remove it. */ | ||||
| 		list[i].len = strlen(p[i]); | ||||
| 		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. | ||||
| 		 * GNU diff does this ignoring any number of trailing dots. | ||||
| 		 * We don't, so for us dotted files almost always are | ||||
|   | ||||
| @@ -889,10 +889,10 @@ ACTF(links) | ||||
| } | ||||
| #endif | ||||
|  | ||||
| static int FAST_FUNC fileAction(const char *fileName, | ||||
| 		struct stat *statbuf, | ||||
| 		void *userData UNUSED_PARAM, | ||||
| 		int depth IF_NOT_FEATURE_FIND_MAXDEPTH(UNUSED_PARAM)) | ||||
| static int FAST_FUNC fileAction( | ||||
| 		struct recursive_state *state IF_NOT_FEATURE_FIND_MAXDEPTH(UNUSED_PARAM), | ||||
| 		const char *fileName, | ||||
| 		struct stat *statbuf) | ||||
| { | ||||
| 	int r; | ||||
| 	int same_fs = 1; | ||||
| @@ -911,12 +911,12 @@ static int FAST_FUNC fileAction(const char *fileName, | ||||
| #endif | ||||
|  | ||||
| #if ENABLE_FEATURE_FIND_MAXDEPTH | ||||
| 	if (depth < G.minmaxdepth[0]) { | ||||
| 	if (state->depth < G.minmaxdepth[0]) { | ||||
| 		if (same_fs) | ||||
| 			return TRUE; /* skip this, continue recursing */ | ||||
| 		return SKIP; /* stop recursing */ | ||||
| 	} | ||||
| 	if (depth > G.minmaxdepth[1]) | ||||
| 	if (state->depth > G.minmaxdepth[1]) | ||||
| 		return SKIP; /* stop recursing */ | ||||
| #endif | ||||
|  | ||||
| @@ -927,7 +927,7 @@ static int FAST_FUNC fileAction(const char *fileName, | ||||
|  | ||||
| #if ENABLE_FEATURE_FIND_MAXDEPTH | ||||
| 	if (S_ISDIR(statbuf->st_mode)) { | ||||
| 		if (depth == G.minmaxdepth[1]) | ||||
| 		if (state->depth == G.minmaxdepth[1]) | ||||
| 			return SKIP; | ||||
| 	} | ||||
| #endif | ||||
| @@ -1570,8 +1570,7 @@ int find_main(int argc UNUSED_PARAM, char **argv) | ||||
| 				G.recurse_flags,/* flags */ | ||||
| 				fileAction,     /* file action */ | ||||
| 				fileAction,     /* dir action */ | ||||
| 				NULL,           /* user data */ | ||||
| 				0)              /* depth */ | ||||
| 				NULL)           /* user data */ | ||||
| 		) { | ||||
| 			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)); | ||||
| } | ||||
|  | ||||
| static int FAST_FUNC file_action_grep(const char *filename, | ||||
| 			struct stat *statbuf, | ||||
| 			void* matched, | ||||
| 			int depth UNUSED_PARAM) | ||||
| static int FAST_FUNC file_action_grep(struct recursive_state *state UNUSED_PARAM, | ||||
| 		const char *filename, | ||||
| 		struct stat *statbuf) | ||||
| { | ||||
| 	FILE *file; | ||||
|  | ||||
| @@ -686,7 +685,7 @@ static int FAST_FUNC file_action_grep(const char *filename, | ||||
| 		return 0; | ||||
| 	} | ||||
| 	cur_file = filename; | ||||
| 	*(int*)matched |= grep_file(file); | ||||
| 	*(int*)state->userData |= grep_file(file); | ||||
| 	fclose(file); | ||||
| 	return 1; | ||||
| } | ||||
| @@ -702,8 +701,8 @@ static int grep_dir(const char *dir) | ||||
| 		| 0, | ||||
| 		/* fileAction= */ file_action_grep, | ||||
| 		/* dirAction= */ NULL, | ||||
| 		/* userData= */ &matched, | ||||
| 		0); | ||||
| 		/* userData= */ &matched | ||||
| 	); | ||||
| 	return matched; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -441,10 +441,18 @@ enum { | ||||
| 	ACTION_DANGLING_OK    = (1 << 5), | ||||
| }; | ||||
| typedef uint8_t recurse_flags_t; | ||||
| extern int recursive_action(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) FAST_FUNC; | ||||
| typedef struct recursive_state { | ||||
| 	unsigned flags; | ||||
| 	unsigned depth; | ||||
| 	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; | ||||
| enum { GETPTY_BUFSIZE = 16 }; /* more than enough for "/dev/ttyXXX" */ | ||||
|   | ||||
| @@ -21,10 +21,9 @@ | ||||
|  * is so stinking huge. | ||||
|  */ | ||||
|  | ||||
| static int FAST_FUNC true_action(const char *fileName UNUSED_PARAM, | ||||
| 		struct stat *statbuf UNUSED_PARAM, | ||||
| 		void* userData UNUSED_PARAM, | ||||
| 		int depth UNUSED_PARAM) | ||||
| static int FAST_FUNC true_action(struct recursive_state *state UNUSED_PARAM, | ||||
| 		const char *fileName UNUSED_PARAM, | ||||
| 		struct stat *statbuf UNUSED_PARAM) | ||||
| { | ||||
| 	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. | ||||
|  */ | ||||
|  | ||||
| int FAST_FUNC recursive_action(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) | ||||
| static int recursive_action1(recursive_state_t *state, const char *fileName) | ||||
| { | ||||
| 	struct stat statbuf; | ||||
| 	unsigned follow; | ||||
| @@ -78,24 +72,21 @@ int FAST_FUNC recursive_action(const char *fileName, | ||||
| 	DIR *dir; | ||||
| 	struct dirent *next; | ||||
|  | ||||
| 	if (!fileAction) fileAction = true_action; | ||||
| 	if (!dirAction) dirAction = true_action; | ||||
|  | ||||
| 	follow = ACTION_FOLLOWLINKS; | ||||
| 	if (depth == 0) | ||||
| 	if (state->depth == 0) | ||||
| 		follow = ACTION_FOLLOWLINKS | ACTION_FOLLOWLINKS_L0; | ||||
| 	follow &= flags; | ||||
| 	follow &= state->flags; | ||||
| 	status = (follow ? stat : lstat)(fileName, &statbuf); | ||||
| 	if (status < 0) { | ||||
| #ifdef DEBUG_RECURS_ACTION | ||||
| 		bb_error_msg("status=%d flags=%x", status, flags); | ||||
| 		bb_error_msg("status=%d flags=%x", status, state->flags); | ||||
| #endif | ||||
| 		if ((flags & ACTION_DANGLING_OK) | ||||
| 		if ((state->flags & ACTION_DANGLING_OK) | ||||
| 		 && errno == ENOENT | ||||
| 		 && lstat(fileName, &statbuf) == 0 | ||||
| 		) { | ||||
| 			/* Dangling link */ | ||||
| 			return fileAction(fileName, &statbuf, userData, depth); | ||||
| 			return state->fileAction(state, fileName, &statbuf); | ||||
| 		} | ||||
| 		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). | ||||
| 	 * Then we can skip checking first part: if it is true, then | ||||
| 	 * (!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) | ||||
| 	) { | ||||
| 		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) */ | ||||
|  | ||||
| 	if (!(flags & ACTION_RECURSE)) { | ||||
| 		return dirAction(fileName, &statbuf, userData, depth); | ||||
| 	if (!(state->flags & ACTION_RECURSE)) { | ||||
| 		return state->dirAction(state, fileName, &statbuf); | ||||
| 	} | ||||
|  | ||||
| 	if (!(flags & ACTION_DEPTHFIRST)) { | ||||
| 		status = dirAction(fileName, &statbuf, userData, depth); | ||||
| 	if (!(state->flags & ACTION_DEPTHFIRST)) { | ||||
| 		status = state->dirAction(state, fileName, &statbuf); | ||||
| 		if (status == FALSE) | ||||
| 			goto done_nak_warn; | ||||
| 		if (status == SKIP) | ||||
| @@ -140,11 +131,13 @@ int FAST_FUNC recursive_action(const char *fileName, | ||||
| 			continue; | ||||
|  | ||||
| 		/* process every file (NB: ACTION_RECURSE is set in flags) */ | ||||
| 		s = recursive_action(nextFile, flags, fileAction, dirAction, | ||||
| 						userData, depth + 1); | ||||
| 		state->depth++; | ||||
| 		s = recursive_action1(state, nextFile); | ||||
| 		if (s == FALSE) | ||||
| 			status = FALSE; | ||||
| 		free(nextFile); | ||||
| 		state->depth--; | ||||
|  | ||||
| //#define RECURSE_RESULT_ABORT -1 | ||||
| //		if (s == RECURSE_RESULT_ABORT) { | ||||
| //			closedir(dir); | ||||
| @@ -153,15 +146,36 @@ int FAST_FUNC recursive_action(const char *fileName, | ||||
| 	} | ||||
| 	closedir(dir); | ||||
|  | ||||
| 	if (flags & ACTION_DEPTHFIRST) { | ||||
| 		if (!dirAction(fileName, &statbuf, userData, depth)) | ||||
| 	if (state->flags & ACTION_DEPTHFIRST) { | ||||
| 		if (!state->dirAction(state, fileName, &statbuf)) | ||||
| 			goto done_nak_warn; | ||||
| 	} | ||||
|  | ||||
| 	return status; | ||||
|  | ||||
|  done_nak_warn: | ||||
| 	if (!(flags & ACTION_QUIET)) | ||||
| 	if (!(state->flags & ACTION_QUIET)) | ||||
| 		bb_simple_perror_msg(fileName); | ||||
| 	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 | ||||
|  */ | ||||
|  | ||||
| static int FAST_FUNC parse_module(const char *fname, struct stat *sb UNUSED_PARAM, | ||||
| 				void *data, int depth UNUSED_PARAM) | ||||
| static int FAST_FUNC parse_module(struct recursive_state *state, | ||||
| 		const char *fname, | ||||
| 		struct stat *sb UNUSED_PARAM) | ||||
| { | ||||
| 	module_db *modules = data; | ||||
| 	module_db *modules = state->userData; | ||||
| 	char *image, *ptr; | ||||
| 	module_entry *e; | ||||
|  | ||||
| @@ -201,11 +202,12 @@ int depmod_main(int argc UNUSED_PARAM, char **argv) | ||||
| 	memset(&modules, 0, sizeof(modules)); | ||||
| 	if (*argv) { | ||||
| 		do { | ||||
| 			parse_module(*argv, /*sb (unused):*/ NULL, &modules, 0); | ||||
| 			recursive_action(*argv, 0 /* no ACTION_RECURSE! */, | ||||
| 				parse_module, NULL, &modules); | ||||
| 		} while (*++argv); | ||||
| 	} else { | ||||
| 		recursive_action(".", ACTION_RECURSE, | ||||
| 				parse_module, NULL, &modules, 0); | ||||
| 				parse_module, NULL, &modules); | ||||
| 	} | ||||
|  | ||||
| 	/* Generate dependency and alias files */ | ||||
|   | ||||
| @@ -751,8 +751,7 @@ static int process_module(char *name, const char *cmdline_options) | ||||
| 			ACTION_RECURSE, /* flags */ | ||||
| 			fileAction, /* file action */ | ||||
| 			NULL, /* dir action */ | ||||
| 			name, /* user data */ | ||||
| 			0 /* depth */ | ||||
| 			name /* user data */ | ||||
| 		); | ||||
| 		dbg1_error_msg("dirscan complete"); | ||||
| 		/* 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, | ||||
| 					struct stat *statbuf UNUSED_PARAM, | ||||
| 					void *userdata UNUSED_PARAM, | ||||
| 					int depth) | ||||
| static int FAST_FUNC config_file_action(struct recursive_state *state, | ||||
| 		const char *filename, | ||||
| 		struct stat *statbuf UNUSED_PARAM) | ||||
| { | ||||
| 	char *tokens[3]; | ||||
| 	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/ | ||||
| 	 * _subdirectories_: | ||||
| 	 */ | ||||
| 	if (depth > 1) | ||||
| 	if (state->depth > 1) | ||||
| 		return SKIP; /* stop recursing */ | ||||
| //TODO: instead, can use dirAction in recursive_action() to SKIP dirs | ||||
| //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, | ||||
| 	 * "include FILE_NOT_ENDING_IN_CONF" must work too. | ||||
| 	 */ | ||||
| 	if (depth != 0) { | ||||
| 	if (state->depth != 0) { | ||||
| 		if (!is_suffixed_with(base, ".conf")) | ||||
| 			goto error; | ||||
| 	} | ||||
| @@ -329,8 +328,7 @@ static int FAST_FUNC config_file_action(const char *filename, | ||||
| static int read_config(const char *path) | ||||
| { | ||||
| 	return recursive_action(path, ACTION_RECURSE | ACTION_QUIET, | ||||
| 				config_file_action, NULL, NULL, | ||||
| 				/*depth:*/ 0); | ||||
| 				config_file_action, NULL, NULL); | ||||
| } | ||||
|  | ||||
| static const char *humanly_readable_name(struct module_entry *m) | ||||
|   | ||||
| @@ -272,10 +272,9 @@ static long extract_socket_inode(const char *lname) | ||||
| 	return inode; | ||||
| } | ||||
|  | ||||
| static int FAST_FUNC add_to_prg_cache_if_socket(const char *fileName, | ||||
| 		struct stat *statbuf UNUSED_PARAM, | ||||
| 		void *pid_slash_progname, | ||||
| 		int depth UNUSED_PARAM) | ||||
| static int FAST_FUNC add_to_prg_cache_if_socket(struct recursive_state *state, | ||||
| 		const char *fileName, | ||||
| 		struct stat *statbuf UNUSED_PARAM) | ||||
| { | ||||
| 	char *linkname; | ||||
| 	long inode; | ||||
| @@ -284,16 +283,17 @@ static int FAST_FUNC add_to_prg_cache_if_socket(const char *fileName, | ||||
| 	if (linkname != NULL) { | ||||
| 		inode = extract_socket_inode(linkname); | ||||
| 		free(linkname); | ||||
| 		if (inode >= 0) | ||||
| 			prg_cache_add(inode, (char *)pid_slash_progname); | ||||
| 		if (inode >= 0) { | ||||
| 			char *pid_slash_progname = state->userData; | ||||
| 			prg_cache_add(inode, pid_slash_progname); | ||||
| 		} | ||||
| 	} | ||||
| 	return TRUE; | ||||
| } | ||||
|  | ||||
| static int FAST_FUNC dir_act(const char *fileName, | ||||
| 		struct stat *statbuf UNUSED_PARAM, | ||||
| 		void *userData UNUSED_PARAM, | ||||
| 		int depth) | ||||
| static int FAST_FUNC dir_act(struct recursive_state *state, | ||||
| 		const char *fileName, | ||||
| 		struct stat *statbuf UNUSED_PARAM) | ||||
| { | ||||
| 	const char *pid; | ||||
| 	char *pid_slash_progname; | ||||
| @@ -301,7 +301,7 @@ static int FAST_FUNC dir_act(const char *fileName, | ||||
| 	char cmdline_buf[512]; | ||||
| 	int n, len; | ||||
|  | ||||
| 	if (depth == 0) /* "/proc" itself */ | ||||
| 	if (state->depth == 0) /* "/proc" itself */ | ||||
| 		return TRUE; /* continue looking one level below /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, | ||||
| 			add_to_prg_cache_if_socket, | ||||
| 			NULL, | ||||
| 			(void *)pid_slash_progname, | ||||
| 			0); | ||||
| 			(void *)pid_slash_progname | ||||
| 	); | ||||
| 	free(pid_slash_progname); | ||||
|  | ||||
| 	if (!n) | ||||
| @@ -337,7 +337,7 @@ static void prg_cache_load(void) | ||||
|  | ||||
| 	prg_cache_loaded = 1; | ||||
| 	load_ok = recursive_action("/proc", ACTION_RECURSE | ACTION_QUIET, | ||||
| 				NULL, dir_act, NULL, 0); | ||||
| 				NULL, dir_act, NULL); | ||||
| 	if (load_ok) | ||||
| 		return; | ||||
|  | ||||
|   | ||||
| @@ -62,11 +62,9 @@ static char *type = NULL; | ||||
| static char *range = 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, | ||||
| 		struct stat *stbuf UNUSED_PARAM, | ||||
| 		void *userData UNUSED_PARAM, | ||||
| 		int depth UNUSED_PARAM) | ||||
| 		struct stat *stbuf UNUSED_PARAM) | ||||
| { | ||||
| 	context_t 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), | ||||
| 					change_filedir_context, | ||||
| 					change_filedir_context, | ||||
| 					NULL, 0) != TRUE) | ||||
| 					NULL) != TRUE) | ||||
| 			errors = 1; | ||||
| 	} | ||||
| 	return errors; | ||||
|   | ||||
| @@ -463,11 +463,9 @@ static int restore(const char *file) | ||||
|  * This function is called by recursive_action on each file during | ||||
|  * the directory traversal. | ||||
|  */ | ||||
| static int FAST_FUNC apply_spec( | ||||
| static int FAST_FUNC apply_spec(struct recursive_state *state UNUSED_PARAM, | ||||
| 		const char *file, | ||||
| 		struct stat *sb, | ||||
| 		void *userData UNUSED_PARAM, | ||||
| 		int depth UNUSED_PARAM) | ||||
| 		struct stat *sb) | ||||
| { | ||||
| 	if (!follow_mounts) { | ||||
| 		/* setfiles does not process across different mount points */ | ||||
| @@ -535,7 +533,7 @@ static int process_one(char *name) | ||||
| 				ACTION_RECURSE, | ||||
| 				apply_spec, | ||||
| 				apply_spec, | ||||
| 				NULL, 0) != TRUE | ||||
| 				NULL) != TRUE | ||||
| 		) { | ||||
| 			bb_error_msg("error while labeling %s", name); | ||||
| 			goto err; | ||||
|   | ||||
| @@ -37,11 +37,9 @@ enum { | ||||
| /* | ||||
|  * 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, | ||||
| 		struct stat *statbuf UNUSED_PARAM, | ||||
| 		void *userData UNUSED_PARAM, | ||||
| 		int depth UNUSED_PARAM) | ||||
| 		struct stat *statbuf UNUSED_PARAM) | ||||
| { | ||||
| 	parser_t *parser; | ||||
| 	char *tokens[3]; | ||||
| @@ -117,8 +115,7 @@ int lspci_main(int argc UNUSED_PARAM, char **argv) | ||||
| 			ACTION_RECURSE, | ||||
| 			fileAction, | ||||
| 			NULL, /* dirAction */ | ||||
| 			NULL, /* userData */ | ||||
| 			0 /* depth */); | ||||
|  | ||||
| 			NULL /* userData */ | ||||
| 	); | ||||
| 	return EXIT_SUCCESS; | ||||
| } | ||||
|   | ||||
| @@ -24,11 +24,9 @@ | ||||
|  | ||||
| #include "libbb.h" | ||||
|  | ||||
| static int FAST_FUNC fileAction( | ||||
| static int FAST_FUNC fileAction(struct recursive_state *state UNUSED_PARAM, | ||||
| 		const char *fileName, | ||||
| 		struct stat *statbuf UNUSED_PARAM, | ||||
| 		void *userData UNUSED_PARAM, | ||||
| 		int depth UNUSED_PARAM) | ||||
| 		struct stat *statbuf UNUSED_PARAM) | ||||
| { | ||||
| 	parser_t *parser; | ||||
| 	char *tokens[4]; | ||||
| @@ -80,8 +78,8 @@ int lsusb_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) | ||||
| 			ACTION_RECURSE, | ||||
| 			fileAction, | ||||
| 			NULL, /* dirAction */ | ||||
| 			NULL, /* userData */ | ||||
| 			0 /* depth */); | ||||
| 			NULL /* userData */ | ||||
| 	); | ||||
|  | ||||
| 	return EXIT_SUCCESS; | ||||
| } | ||||
|   | ||||
| @@ -845,13 +845,12 @@ static ssize_t readlink2(char *buf, size_t bufsize) | ||||
| /* File callback for /sys/ traversal. | ||||
|  * We act only on "/sys/.../dev" (pseudo)file | ||||
|  */ | ||||
| static int FAST_FUNC fileAction(const char *fileName, | ||||
| 		struct stat *statbuf UNUSED_PARAM, | ||||
| 		void *userData, | ||||
| 		int depth UNUSED_PARAM) | ||||
| static int FAST_FUNC fileAction(struct recursive_state *state, | ||||
| 		const char *fileName, | ||||
| 		struct stat *statbuf UNUSED_PARAM) | ||||
| { | ||||
| 	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]; | ||||
| 	int res; | ||||
|  | ||||
| @@ -888,12 +887,11 @@ static int FAST_FUNC fileAction(const char *fileName, | ||||
| } | ||||
|  | ||||
| /* Directory callback for /sys/ traversal */ | ||||
| static int FAST_FUNC dirAction(const char *fileName UNUSED_PARAM, | ||||
| 		struct stat *statbuf UNUSED_PARAM, | ||||
| 		void *userData UNUSED_PARAM, | ||||
| 		int depth) | ||||
| static int FAST_FUNC dirAction(struct recursive_state *state, | ||||
| 		const char *fileName UNUSED_PARAM, | ||||
| 		struct stat *statbuf UNUSED_PARAM) | ||||
| { | ||||
| 	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 | ||||
| @@ -1149,7 +1147,7 @@ static void initial_scan(char *temp) | ||||
| 	/* Create all devices from /sys/dev hierarchy */ | ||||
| 	recursive_action("/sys/dev", | ||||
| 			 ACTION_RECURSE | ACTION_FOLLOWLINKS, | ||||
| 			 fileAction, dirAction, temp, 0); | ||||
| 			 fileAction, dirAction, temp); | ||||
| } | ||||
|  | ||||
| #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. | ||||
|  * If device node does not exist, it will be temporarily created. */ | ||||
| static int FAST_FUNC | ||||
| uuidcache_check_device(const char *device, | ||||
| 		struct stat *statbuf, | ||||
| 		void *userData UNUSED_PARAM, | ||||
| 		int depth UNUSED_PARAM) | ||||
| uuidcache_check_device(struct recursive_state *state UNUSED_PARAM, | ||||
| 		const char *device, | ||||
| 		struct stat *statbuf) | ||||
| { | ||||
| 	/* note: this check rejects links to devices, among other nodes */ | ||||
| 	if (!S_ISBLK(statbuf->st_mode) | ||||
| @@ -145,12 +144,13 @@ uuidcache_init(int scan_devices) | ||||
| 	 * This is unacceptably complex. Let's just scan /dev. | ||||
| 	 * (Maybe add scanning of /sys/block/XXX/dev for devices | ||||
| 	 * somehow not having their /dev/XXX entries created?) */ | ||||
| 	if (scan_devices) | ||||
| 	if (scan_devices) { | ||||
| 		recursive_action("/dev", ACTION_RECURSE, | ||||
| 			uuidcache_check_device, /* file_action */ | ||||
| 			NULL, /* dir_action */ | ||||
| 			NULL, /* userData */ | ||||
| 			0 /* depth */); | ||||
| 			NULL /* userData */ | ||||
| 		); | ||||
| 	} | ||||
|  | ||||
| 	return uuidCache; | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user