Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I determine the maximum value of a pid_t?

Tags:

c

linux

size

pid

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.

like image 269
pilcrow Avatar asked Oct 11 '12 14:10

pilcrow


People also ask

How do you find the maximum limit of PID?

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).

How many bytes is a Pid_t?

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.

How many numbers is a PID?

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.


3 Answers

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.

like image 175
Steven Avatar answered Sep 19 '22 01:09

Steven


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.

like image 32
jfs Avatar answered Sep 22 '22 01:09

jfs


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.)

like image 31
Nemo Avatar answered Sep 21 '22 01:09

Nemo