2012-10-11 26 views
6

Jak mogę przenośnie określić maksymalną wartość typu pid_t? W moim systemie nie ma stałej PID_MAX.Jak mogę ustalić maksymalną wartość pid_t?

(Uwaga, to znaczy maksymalnej wartości dopuszczalnej przez typ danych, a nie de facto maksymalna wartość system przypisze do procesów.)

przypadków użycia: mam konwertowania grupę użytkowników dostarczono specyfikację ciągu pid do pid_t i chcemy upewnić się, że dane wejściowe użytkownika nie przekraczają pojemności tego typu.

+3

nie jest 'sizeof' wystarczające do celu? (Nie jestem pewien, dlaczego potrzebujesz tego, ale czy chcesz opracować?) – Mat

+1

'/ proc/sys/kernel/pid_max' definiuje maksymalny pid, który możesz edytować. –

+0

@KingsIndian, dzięki. Mam na myśli maksymalny typ, a nie maksymalną wartość systemu w praktyce. – pilcrow

Odpowiedz

2

POSIX (2008) says:

blksize_t, pid_t i ssize_t zostaną podpisane rodzaje całkowitymi.

I:

Realizacja wspiera jeden lub więcej środowisk programistycznych w którym szerokości blksize_t, pid_t, size_t, ssize_t i suseconds_t nie większa niż szerokość typu long.

Więc można konwertować ciągi użytkownika do long a następnie sprawdzić przelewu dla danego typu pid_t wykorzystaniem long pid; .. pid == (pid_t)pid.

0

W jednym z nagłówkami:

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

można też zrobić to na podstawie definicji zależnej serwer/OS oparty na zmiennych środowiskowych.

Look: Similar post : Maximum PID in Linux

+0

Dzięki, @SparKot. Nie jestem pewien, jak twoja odpowiedź wie * a priori *, że 'pid_t' to' int' zamiast, powiedzmy, 'long'. Oddzielnie, nie sądzę, że linkowany post jest istotny: chcę mieć typ danych max, a nie maksymalną wartość, którą system przydzieli (może być niższy). – pilcrow

6

Co robiłem w przeszłości czasami stosowany jest większy typ danych, a następnie, gdy przekonwertować do mojego mniejszego typu, natychmiast przekształcić z powrotem do większego typu i sprawdzić, czy wartości nie uległo zmianie.

Na przykład, można powiedzieć, użył int64_t zamiast, to może masz coś takiego:

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

Nie ma świetnym rozwiązaniem dla większych typu danych do wykorzystania. "long" był kiedyś największym prymitywnym typem danych liczbowych, ale nie jest to prawdą w niektórych typowych kompilatorach/architekturach - nawet w Linuksie (patrz komentarze poniżej). Tymczasem typ intmax_t ma słabą obsługę biblioteki. W rezultacie int64_t jest czasami bardziej przydatny w praktyce.

Ale zasadniczo opcje większych typów danych są prawdopodobnie długie, int64_t i intmax_t.

+0

"wciąż jest na Linuksie" - jest na Linuksie dla x64 (taki sam rozmiar jak "long long", ale z niższą pozycją), ale nie na Linuksie dla x86 (ten sam rozmiar co 'int', mniejszy niż' long long') . –

+0

Dzięki za wyjaśnienie – Steven

1

Odpowiedź Steven jest dobrym podejściem.

Ale jeśli naprawdę chcesz, aby określić maksymalną wartość pid_t bez polegania na zachowanie niezdefiniowane, myślę, że najlepiej jest:

#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 gwarantuje, że pid_t jest podpisana integralną typu. Kod ten zakłada, że ​​rozmiar podpisanego typu integralnego jednoznacznie określa ten typ.Myślę, że to doskonałe założenie, ale nie jestem pewien, czy standard to gwarantuje.

Każdy przyzwoity kompilator będzie wbudowywał i stale propagował to wszystko w nieistnienie, więc wydajność nie jest problemem.

(Na marginesie: W C++ byłoby piszesz std::numeric_limits<pid_t>::max() i być z nim zrobić.)

Powiązane problemy