[PATCH 1/2] util.c: add universal search_fdinfo() function

Masatake YAMATO yamato at redhat.com
Sun Mar 26 19:26:28 UTC 2023


> search_fdinfo() takes pid, fd and line prefix, reads corresponding
> procfs entry and returns a string of the value. The result is allocated
> with strdup(), so caller should free it.
> 
> Signed-off-by: leedagee <leedageea at gmail.com>

Useful change. The change looks good for me but I have a comment about the interface.

I wrote similar code for lsfd, a part of util-linux.
https://github.com/util-linux/util-linux/blob/master/misc-utils/lsfd.c#L685 (GPLv2 or later)
https://github.com/util-linux/util-linux/blob/master/misc-utils/lsfd-file.c#L325 (GPLv2 or later)
https://github.com/util-linux/util-linux/blob/master/misc-utils/lsfd-file.c#L280 (GPLv2 or later)

If you use a callback function in the interface, you can reduce the strdup invcation.
Reducing strdup invcation helps reducing forgetting to call free().

    typedef bool (*scan_fdinfo_fn) (const char *search_prefix, const char *value, void *data);
    bool scan_fdinfo(pid_t pid_of_fd, int fd, const char *search_pfx, size_t search_pfx_len,
		     scan_fdinfo_fn handler, void *data);
		 
The "bool" for scan_fdinfo_fn is for controling the loop in scan_fdinfo; returning true
from the handler means the handler handled the value. scan_fdinfo() can stop the iteration.
scan_fdinfo() returns true if the handler returns true.

Masatake YAMATO

> ---
>  src/util.c | 34 +++++++++++++++++++++++++---------
>  1 file changed, 25 insertions(+), 9 deletions(-)
> 
> diff --git a/src/util.c b/src/util.c
> index 4fe45bf13..c27457467 100644
> --- a/src/util.c
> +++ b/src/util.c
> @@ -709,37 +709,53 @@ printdev(struct tcb *tcp, int fd, const char *path, const struct finfo *finfo)
>  	return false;
>  }
>  
> -pid_t
> -pidfd_get_pid(pid_t pid_of_fd, int fd)
> +static char *
> +search_fdinfo(pid_t pid_of_fd, int fd, const char *search_pfx,
> +	      size_t search_pfx_len)
>  {
>  	int proc_pid = 0;
>  	translate_pid(NULL, pid_of_fd, PT_TID, &proc_pid);
>  	if (!proc_pid)
> -		return -1;
> +		return NULL;
>  
>  	char fdi_path[sizeof("/proc/%u/fdinfo/%u") + 2 * sizeof(int) * 3];
>  	xsprintf(fdi_path, "/proc/%u/fdinfo/%u", proc_pid, fd);
>  
>  	FILE *f = fopen_stream(fdi_path, "r");
>  	if (!f)
> -		return -1;
> +		return NULL;
>  
> -	static const char pid_pfx[] = "Pid:\t";
> -	char *line = NULL;
> +	char *line = NULL, *result = NULL;
>  	size_t sz = 0;
> -	pid_t pid = -1;
>  	while (getline(&line, &sz, f) > 0) {
> -		const char *pos = STR_STRIP_PREFIX(line, pid_pfx);
> +		const char *pos =
> +		  str_strip_prefix_len(line, search_pfx, search_pfx_len - 1);
>  		if (pos == line)
>  			continue;
>  
> -		pid = string_to_uint_ex(pos, NULL, INT_MAX, "\n");
> +		result = xstrdup(pos);
>  		break;
>  	}
>  
>  	free(line);
>  	fclose(f);
>  
> +	return result;
> +}
> +
> +pid_t
> +pidfd_get_pid(pid_t pid_of_fd, int fd)
> +{
> +	static const char pid_pfx[] = "Pid:\t";
> +
> +	char *result = search_fdinfo(pid_of_fd, fd, pid_pfx, sizeof(pid_pfx));
> +
> +	if (result == NULL)
> +		return -1;
> +
> +	pid_t pid = string_to_uint_ex(result, NULL, INT_MAX, "\n");
> +
> +	free(result);
>  	return pid;
>  }
>  
> -- 
> 2.35.3
> 
> -- 
> Strace-devel mailing list
> Strace-devel at lists.strace.io
> https://lists.strace.io/mailman/listinfo/strace-devel
> 



More information about the Strace-devel mailing list