How much size do I need to allocate for /proc/%u/fd/%u
?
In strace code they allocated char path[sizeof("/proc/%u/fd/%u") + 2 * sizeof(int)*3];
I didn't understand the calc , how did they calc this size?
That may seem a rather bizarre way to do it, but it works (see below). They're assuming that you'll need no more than 2 + 3n
characters for both the process ID and file descriptor, where n
is the number of bytes in an integer (2
because the %u
will be replaced, 3n
because of the sizeof
component).
It does actually work, as per the following chars/int
values (for 8-bit char
), formula results, and the maximum unsigned int
that will come from it:
chars/int sizeof(int) * 3 + 2 max value
--------- ------------------- --------------------
1 5 255 (3/5 needed)
2 8 65535 (5/8 needed)
4 14 4294967296 (10/14)
8 26 18446744073709551616 (20/26)
16 50 3.3 * 10^38 (39/50)
You can see that the storage allocated keeps up with the storage required, to the point where you could just as easily use:
char path[sizeof("/proc/%u/fd/%u") + 2 * sizeof(int) * 3 - 2];
// add this ^^^
And it will also work for char
sizes beyond eight bits as well since doubling the bits in a value at most doubles the number of decimal digits (the table shows this with the needed size: 3, 5, 10, 20, 39, ...
). That, combined with the fact that the int
doubles in size as well, means there will always be enough space.
You may think that, for safety and portability, you could actually get the maximum PID and process file descriptor respectively from /proc/sys/kernel/pid_max
and /proc/<pid>/limits
(programatically) and use that to dynamically allocate enough space to hold the information:
pax:~> cat /proc/sys/kernel/pid_max
32768
pax:~> cat /proc/self/limits | awk '$1$2$3=="Maxopenfiles"{print $5}'
4096
Hence the first %u
would need 5 characters and the second four characters.
Or, you could just allocate 20 characters for each on the likely case that you won't see 66-bit PIDs or FDs anytime in the near future :-) You could still check against the procfs
files, if only to exit gracefully if they were too large.
But, to be honest, both of those are overkill, since you may already have a thing that's meant to provide the limit on file paths, PATH_MAX
(see limits.h
), for Linux. It's probably okay to use that and wear the minimal wastage. And, if you don't have that, you could either get the value from maximum length with a call to pathconf()
. Or choose a sensible default (say, 60 characters), then just use snprintf
to detect if the actual path was longer than your buffer, and exit gracefully.
If you really wanted to use the optimal method for minimal storage (i.e., you think a PATH_MAX
of 4K is too much wastage) then, by all means, use the strace
method, but with two subtracted as per my earlier comment(a).
(a) If you're going to worry about 4K here and there, you may as well do it fully :-)
The best answer is, replace this calculation for MAX_PATH
(include <limits.h>
) that makes your code to more cleaner and portable.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With