2012-10-11 99 views
6

¿Cómo puedo determinar portablemente el valor máximo del tipo pid_t? No hay constante PID_MAX en mi sistema.¿Cómo puedo determinar el valor máximo de un pid_t?

(Nota, es decir el valor máximo permitido por el tipo de datos, no el de facto valor máximo, el sistema asignará a los procesos.)

Caso de uso: estoy convirtiendo una por el usuario Especificación de cadena suministrada de un pid a pid_t, y quiere asegurarse de que la entrada del usuario no exceda la capacidad del tipo.

+3

no es 'sizeof' suficiente para su propósito? (No estoy seguro de por qué necesitarías eso, ¿te importaría elaborar?) – Mat

+1

'/ proc/sys/kernel/pid_max' define el pid máximo, que puedes editar. –

+0

@KingsIndian, gracias. Me refiero al máximo del tipo, no al valor máximo del sistema en la práctica. – pilcrow

Respuesta

2

POSIX (2008) says:

tipos enteros

blksize_t, pid_t y ssize_t deberá ser firmado.

Y:

La aplicación deberá soportar uno o más entornos de programación en la que las anchuras de blksize_t, pid_t, size_t, ssize_t y suseconds_t no son mayores que el ancho de tipo long.

Por lo que podría convertir las cadenas de usuario para long y luego comprobar si hay desbordamiento para el tipo pid_t usando long pid; .. pid == (pid_t)pid.

0

En una de sus cabeceras:

#ifndef PID_MAX 
#define PID_MAX INT_MAX // or whatever value you see fit 
#endif 

también pueden hacerlo sobre la base de la definición depende del servidor/OS basado en las variables de entorno.

Look: Similar post : Maximum PID in Linux

+0

Gracias, @SparKot. No estoy seguro de cómo su respuesta sabe * a priori * que 'pid_t' es un' int' en lugar de, por ejemplo, un 'long'. Por separado, no creo que la publicación vinculada sea relevante: quiero el tipo de datos máximo, no el valor máximo que asignará el sistema (que podría ser menor). – pilcrow

6

Lo que he hecho a veces en el pasado se utiliza un tipo de datos más grande, y luego cuando convierto a mi tipo más pequeño, de inmediato convertir de nuevo al tipo más grande y comprobar que el valor no cambió

Por ejemplo, digamos que usted usa un int64_t lugar, entonces usted podría tener algo como:

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 ... */ 
} 

No hay gran opción para el tipo de datos más grande de usar. "largo" solía ser el tipo de datos entero primitivo más grande, pero eso ya no es cierto en algunos compiladores/arquitecturas comunes, incluso para Linux (ver comentarios a continuación). Mientras tanto, el tipo intmax_t tiene poca compatibilidad con la biblioteca. El resultado es que int64_t a veces es más útil en la práctica.

Pero, básicamente, sus opciones para un tipo de datos más grande son probablemente largas, int64_t e intmax_t.

+0

"todavía está en Linux" - está en Linux para x64 (el mismo tamaño que 'long long' aunque con menor rango), pero no en Linux para x86 (el mismo tamaño que' int', más pequeño que 'long long') . –

+0

Gracias por la aclaración – Steven

1

La respuesta de Steven es un buen enfoque.

Pero si realmente desea determinar el valor máximo pid_t sin depender de un comportamiento indefinido, creo que lo mejor es:

#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(); 
} 

garantías POSIX que pid_t es un tipo entero con signo. Este código supone que el tamaño de un tipo integral firmado determina de manera única ese tipo.Creo que esta es una suposición excelente, pero no estoy seguro de si el estándar lo garantiza.

Cualquier compilador decente se alineará y propagará constantemente todo esto a la inexistencia, por lo que el rendimiento no es una preocupación.

(Aparte: En C++ usted escribiría std::numeric_limits<pid_t>::max() y hacerse con él.)

Cuestiones relacionadas