diff options
Diffstat (limited to 'tools/perf/util/print-events.c')
| -rw-r--r-- | tools/perf/util/print-events.c | 50 | 
1 files changed, 39 insertions, 11 deletions
diff --git a/tools/perf/util/print-events.c b/tools/perf/util/print-events.c index 62e9ea7dcf40..ee145cec42c0 100644 --- a/tools/perf/util/print-events.c +++ b/tools/perf/util/print-events.c @@ -4,7 +4,9 @@  #include <stdio.h>  #include <stdlib.h>  #include <string.h> +#include <fcntl.h>  #include <sys/param.h> +#include <unistd.h>  #include <api/fs/tracing_path.h>  #include <linux/stddef.h> @@ -56,7 +58,18 @@ static const struct event_symbol event_symbols_tool[PERF_TOOL_MAX] = {  /*   * Print the events from <debugfs_mount_point>/tracing/events   */ -void print_tracepoint_events(const struct print_callbacks *print_cb, void *print_state) +void print_tracepoint_events(const struct print_callbacks *print_cb __maybe_unused, void *print_state __maybe_unused) +{ +	char *events_path = get_tracing_file("events"); +	int events_fd = open(events_path, O_PATH); + +	put_tracing_file(events_path); +	if (events_fd < 0) { +		printf("Error: failed to open tracing events directory\n"); +		return; +	} + +#ifdef HAVE_SCANDIRAT_SUPPORT  {  	struct dirent **sys_namelist = NULL;  	int sys_items = tracing_events__scandir_alphasort(&sys_namelist); @@ -64,30 +77,34 @@ void print_tracepoint_events(const struct print_callbacks *print_cb, void *print  	for (int i = 0; i < sys_items; i++) {  		struct dirent *sys_dirent = sys_namelist[i];  		struct dirent **evt_namelist = NULL; -		char *dir_path; +		int dir_fd;  		int evt_items;  		if (sys_dirent->d_type != DT_DIR ||  		    !strcmp(sys_dirent->d_name, ".") ||  		    !strcmp(sys_dirent->d_name, "..")) -			continue; +			goto next_sys; -		dir_path = get_events_file(sys_dirent->d_name); -		if (!dir_path) -			continue; +		dir_fd = openat(events_fd, sys_dirent->d_name, O_PATH); +		if (dir_fd < 0) +			goto next_sys; -		evt_items = scandir(dir_path, &evt_namelist, NULL, alphasort); +		evt_items = scandirat(events_fd, sys_dirent->d_name, &evt_namelist, NULL, alphasort);  		for (int j = 0; j < evt_items; j++) {  			struct dirent *evt_dirent = evt_namelist[j];  			char evt_path[MAXPATHLEN]; +			int evt_fd;  			if (evt_dirent->d_type != DT_DIR ||  			    !strcmp(evt_dirent->d_name, ".") ||  			    !strcmp(evt_dirent->d_name, "..")) -				continue; +				goto next_evt; -			if (tp_event_has_id(dir_path, evt_dirent) != 0) -				continue; +			snprintf(evt_path, sizeof(evt_path), "%s/id", evt_dirent->d_name); +			evt_fd = openat(dir_fd, evt_path, O_RDONLY); +			if (evt_fd < 0) +				goto next_evt; +			close(evt_fd);  			snprintf(evt_path, MAXPATHLEN, "%s:%s",  				 sys_dirent->d_name, evt_dirent->d_name); @@ -102,12 +119,23 @@ void print_tracepoint_events(const struct print_callbacks *print_cb, void *print  					/*desc=*/NULL,  					/*long_desc=*/NULL,  					/*encoding_desc=*/NULL); +next_evt: +			free(evt_namelist[j]);  		} -		free(dir_path); +		close(dir_fd);  		free(evt_namelist); +next_sys: +		free(sys_namelist[i]);  	} +  	free(sys_namelist);  } +#else +	printf("\nWARNING: Your libc doesn't have the scandirat function, please ask its maintainers to implement it.\n" +	       "         As a rough fallback, please do 'ls %s' to see the available tracepoint events.\n", events_path); +#endif +	close(events_fd); +}  void print_sdt_events(const struct print_callbacks *print_cb, void *print_state)  {  |