How can I portably determine the maximum value of the pid_t
type? There's no PID_MAX constant on my system.
(Note, I mean the maximum value permitted by the data type, not the de facto maximum value the system will assign to processes.)
Use case: I'm converting a user-supplied string specification of a pid to a pid_t
, and want to make sure the user's input doesn't exceed the type's capacity.
On 32-bit platforms, 32768 is the maximum value for pid_max. On 64-bit systems, pid_max can be set to any value up to 2^22 ( PID_MAX_LIMIT , approximately 4 million).
In other words, uid_t and gid_t are unsigned 32-bit integers and pid_t is a signed 32-bit integer. This applies for both 32- and 64-bits.
What is a Parcel Identifier (PID)? A PID is a nine-digit number that uniquely identifies a parcel in the land title register of British Columbia. The Registrar assigns PID numbers to parcels for which a title is being registered. The Land Title Act refers to the PID as the permanent parcel identifier.
What I've done sometimes in the past is used a larger data type, and then when I convert to my smaller type, immediately convert back to the larger type and check that the value didn't change.
For example, say you used an int64_t instead, then you might have something like:
int64_t my_pid64;
/* ... parse string value into my_pid64 ... */
pid_t my_pid = (pid_t) my_pid64;
if ((int64_t) my_pid != my_pid64) /* check that value was not out of range of pid_t */
{
/* ... handle error ... */
}
There's no great option for the larger data type to use. "long" used to be the largest primitive integer data type but that's not true on some common compilers/architectures anymore--even for Linux (see comments below). Meanwhile, the intmax_t type has poor library support. The result is that int64_t is sometimes more useful in practice.
But, basically your options for a larger data type are probably long, int64_t and intmax_t.
POSIX (2008) says:
blksize_t, pid_t, and ssize_t shall be signed integer types.
And:
The implementation shall support one or more programming environments in which the widths of blksize_t, pid_t, size_t, ssize_t, and suseconds_t are no greater than the width of type long.
So you could convert user strings to long
and then check for overflow for the pid_t type using long pid; .. pid == (pid_t)pid
.
Steven's answer is a good approach.
But if you really want to determine the max pid_t
value without relying on undefined behavior, I think your best bet is:
#include <sys/types.h>
#include <limits.h>
#include <stdlib.h>
static inline pid_t get_max_pid_t()
{
if (sizeof(pid_t) == sizeof(short)) return SHRT_MAX;
if (sizeof(pid_t) == sizeof(int)) return INT_MAX;
if (sizeof(pid_t) == sizeof(long)) return LONG_MAX;
#if defined(LLONG_MAX) // C99
if (sizeof(pid_t) == sizeof(long long)) return LLONG_MAX;
#endif
abort();
}
POSIX guarantees that pid_t
is a signed integral type. This code assumes that the size of a signed integral type uniquely determines that type. I think this is an excellent assumption, but I am not sure whether the standard guarantees it.
Any decent compiler will inline and constant-propagate all of this into non-existence, so performance is not a concern.
(Aside: In C++ you would write std::numeric_limits<pid_t>::max()
and be done with it.)
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