table of contents
- bookworm 1:4.18.1-1
 - bookworm-backports 1:4.27.0-1~bpo12+1
 - testing 1:4.27.0-1
 - unstable 1:4.27.0-1
 
| semctl(2) | System Calls Manual | semctl(2) | 
NAZWA¶
semctl - steruje semaforami Systemu V
BIBLIOTEKA¶
Standardowa biblioteka C (libc, -lc)
SKŁADNIA¶
#include <sys/sem.h>
int semctl(int semid, int semnum, int cmd, ...);
OPIS¶
semctl() wykonuje operację sterującą określoną przez cmd na zestawie semaforów Systemu V określonym przez semid lub na semaforze o numerze semnum z tego zestawu. (Numeracja semaforów w zestawie semaforów zaczyna się od 0).
W zależności od cmd funkcja przyjmuje trzy lub cztery argumenty. Jeśli są cztery, to czwarty jest typu union semun. Program wywołujący musi zdefiniować tę unię jako:
  
union semun {
    int              val;    /* Wartość dla SETVAL */
    struct semid_ds *buf;    /* Bufor dla IPC_STAT, IPC_SET */
    unsigned short  *array;  /* Tablica dla GETALL, SETALL */
    struct seminfo  *__buf;  /* Bufor dla IPC_INFO
                                (specyficzne dla Linuksa) */
};
Struktura danych semid_ds jest zdefiniowana w <sys/sem.h> następująco:
  
struct semid_ds {
    struct ipc_perm sem_perm;  /* Prawa dostępu */
    time_t          sem_otime; /* Czas ostatniej operacji semop */
    time_t          sem_ctime; /* Czas utworzenia/ostatniej zmiany
                                  za pomocą semctl() */
    unsigned long   sem_nsems; /* Liczba semaforów w zestawie */
};
Pola struktury semid_ds są następujące:
- sem_perm
 - Jest to struktura ipc_perm (zob. niżej), która określa prawa dostępu do zestawu semaforów.
 - sem_otime
 - Czas ostatniego wywołania funkcji systemowej semop(2).
 - sem_ctime
 - Czas utworzenia zestawu semaforów albo czas ostatniej operacji IPCSET, SETVAL lub SETALL z SETVAL().
 - sem_nsems
 - Liczba semaforów w zestawie. Każdy semafor zestawu jest identyfikowany przez nieujemną liczbę całkowitą z zakresu od 0 do sem_nsems-1.
 
Struktura ipc_perm jest zdefiniowana następująco (wyróżnione pola można ustawić za pomocą IPC_SET):
  
struct ipc_perm {
    key_t          __key; /* Klucz podany w semget(2) */
    uid_t          uid;   /* Efektywny UID właściciela */
    gid_t          gid;   /* Efektywny GID właściciela */
    uid_t          cuid;  /* Efektywny UID twórcy */
    gid_t          cgid;  /* Efektywny GID twórcy */
    unsigned short mode;  /* Uprawnienia */
    unsigned short __seq; /* Numer sekwencji */
};
Najmniej znaczące 9 bitów pola mode struktury ipc_perm definiuje uprawnienia dostępu do segmentu pamięci dzielonej. Istnieją następujące bity uprawnień:
| 0400 | Odczyt przez użytkownika | 
| 0200 | Zapis przez użytkownika | 
| 0040 | Odczyt przez grupę | 
| 0020 | Zapis przez grupę | 
| 0004 | Odczyt przez pozostałych | 
| 0002 | Zapis przez pozostałych | 
Dla zestawu semaforów „zapis” znaczy w praktyce „modyfikację”. Bity 0100, 0010 i 0001 (bity praw do uruchamiania) nie są przez system wykorzystywane.
Poprawne wartości parametru cmd to:
- IPC_STAT
 - Kopiuje informacje ze struktury kontrolnej jądra skojarzonej z semid do struktury semid_ds wskazywanej przez arg.__buf. Argument semnum jest ignorowany. Wywołujący musi mieć uprawnienie odczytu zestawu semaforów.
 - IPC_SET
 - Zapis wartości niektórych pól struktury semid_ds wskazywanej przez parametr arg.buf do struktury kontrolnej zestawu semaforów. Pole sem_ctime zostanie automatycznie uaktualnione.
 
- Zaktualizowane mogą również zostać następujące pola tej struktury: sem_perm.uid, sem_perm.gid i (9 najmniej znaczących bitów z) sem_perm.mode.
 - Efektywny identyfikator użytkownika procesu wywołującego musi odpowiadać właścicielowi (sem_perm.uid) lub twórcy (sem_perm.cuid) zestawu semaforów albo wywołujący musi być uprzywilejowany. Argument semnum jest pomijany.
 
- IPC_RMID
 - Usuwa natychmiast zestaw semaforów. Wznawia wszystkie procesy zablokowane w wywołaniu semop(2) (wywołanie to zasygnalizuje błąd i ustawi zmienną errno na EIDRM). Efektywny identyfikator użytkownika procesu wywołującego musi odpowiadać twórcy lub właścicielowi zestawu semaforów albo proces wywołujący musi być uprzywilejowany. Argument semnum jest pomijany.
 - IPC_INFO (specyficzne dla Linuksa)
 - Zwraca w strukturze, na którą wskazuje arg.__buf, informacje o systemowych ograniczeniach i parametrach semaforów. Struktura jest typu seminfo i jest zdefiniowana w <sys/shm.h>, pod warunkiem, że zdefiniowano również makro _GNU_SOURCE:
 
- 
    
struct seminfo {
int semmap; /* Liczba wpisów w mapie semaforów
nieużywane przez jądro */
int semmni; /* Maksymalna liczba zestawów semaforów */
int semmns; /* Maksymalna liczba semaforów we wszystkich
zestawach semaforów */
int semmnu; /* Maksymalna liczba struktur wycofania (undo)
w systemie; nieużywane przez jądro*/
int semmsl; /* Maksymalna liczba semaforów
w zestawie */
int semopm; /* Maksymalna liczba operacji dla
semop(2) */
int semume; /* Maksymalna liczba wpisów wycofania (undo)
procesu; nieużywane przez jądro */
int semusz; /* Rozmiar struktury sem_undo */
int semvmx; /* Maksymalna wartość semafora */
int semaem; /* Maksymalna wartość możliwa do zapamiętania
dla regulacji semafora (SEM_UNDO) */ };
 - Ustawienia semmsl, semmns, semopm oraz semmni można zmienić za pomocą plików w /proc/sys/kernel/sem; szczegóły można znaleźć w podręczniku proc(5).
 
- SEM_INFO (specyficzne dla Linuksa)
 - Zwraca strukturę seminfo zawierającą te same informacje co w przypadku IPC_INFO, z tym wyjątkiem, że w następujących polach zwracane są informacje o zasobach systemowych wykorzystywanych przez semafory: pole semusz zwraca liczbę zestawów semaforów istniejących obecnie w systemie; pole semaem zwraca całkowitą liczbę semaforów we wszystkich zestawach semaforów w systemie.
 - SEM_STAT (specyficzne dla Linuksa)
 - Zwraca strukturę semid_ds, taką jak dla IPC_STAT. Jednakże parametr semid nie jest identyfikatorem segmentu, ale indeksem wewnętrznej tablicy jądra przechowującej informacje o wszystkich segmentach zestawach semaforów w systemie.
 - SEM_STAT_ANY (specyficzne dla Linuksa, od Linuksa 4.17)
 - Zwraca strukturę semid_ds, jak dla SEM_STAT. Jednak sem_perm.mode nie jest sprawdzany pod kątem uprawnień odczytu do semid co oznacza, że każdy użytkownik może wykonać tę operację (podobnie jak każdy użytkownik może odczytać /proc/sysvipc/sem, pozyskując te same informacje).
 - GETALL
 - Zwraca (bieżącą) wartość semval dla wszystkich semaforów z zestawu, umieszczając je w tablicy arg.array. Argument semnum jest pomijany. Proces wywołujący musi mieć prawa do odczytu zestawu semaforów.
 - GETNCNT
 - Zwraca wartość semncnt skojarzoną z semaforem o numerze semnum w zestawie (tzn. liczbę procesów oczekujących na zwiększenie wartości przez semafor). Proces wywołujący musi mieć prawa do odczytu zestawu semaforów.
 - GETPID
 - Zwraca wartość sempid skojarzoną z semaforem o numerze semnum w zestawie. Jest to identyfikator procesu, który wykonał ostatnią operację na tym semaforze (ale zob. UWAGI). Proces wywołujący musi mieć prawa do odczytu zestawu semaforów.
 - GETVAL
 - Zwraca semval (tj. wartość semafora) semafora o numerze semnum w zestawie semaforów. Proces wywołujący musi mieć prawa do odczytu zestawu semaforów.
 - GETZCNT
 - Zwraca wartość semzcnt skojarzoną z semaforem o numerze semnum w zestawie (tzn. liczbę procesów oczekujących na osiągnięcie przez semafor wartości 0). Proces wywołujący musi mieć prawa do odczytu zestawu semaforów.
 - SETALL
 - Przypisuje wartości semval wszystkim semaforom zestawu, korzystając z tablicy arg.array, jednocześnie aktualizuje pole sem_ctime struktury semid_ds skojarzonej z zestawem. Wpisy wycofania (undo; patrz semop(2)) są czyszczone dla wszystkich zmienianych semaforów we wszystkich procesach. Jeżeli zmiany wartości semaforów pozwoliłyby na odblokowanie procesów oczekujących w wywołaniach semop(2), to te procesy są wznawiane. Argument semnum jest pomijany. Proces wywołujący musi mieć prawa do modyfikacji (zapisu) zestawu semaforów.
 - SETVAL
 - Przypisuje wartość semval do arg.val semafora o numerze semnum w zestawie, aktualizując jednocześnie pole sem_ctime struktury semid_ds skojarzonej z zestawem semaforów. Wpisy wycofania (undo) są czyszczone dla zmienianych semaforów we wszystkich procesach. Jeżeli zmiany wartości semaforów pozwoliłyby na odblokowanie procesów oczekujących w wywołaniach semop(2), to te procesy są wznawiane. Proces wywołujący funkcję musi mieć prawa do modyfikacji zestawu semaforów.
 
WARTOŚĆ ZWRACANA¶
Po pomyślnym zakończeniu, semctl() zwraca nieujemną wartość zależną od parametru op:
- GETNCNT
 - wartość semncnt.
 - GETPID
 - wartość sempid.
 - GETVAL
 - wartość semval.
 - GETZCNT
 - wartość semzcnt.
 - IPC_INFO
 - indeks najwyższego używanego wpisu w wewnętrznej tablicy jądra przechowującej informacje o wszystkich zestawach semaforów (informacji tej można użyć w operacjach SEM_STAT lub SEM_STAT_ANY, aby otrzymać informacje o wszystkich zestawach semaforów w systemie).
 - SEM_INFO
 - tak jak IPC_INFO.
 - SEM_STAT
 - identyfikator zestawu semaforów, którego indeks został podany w semid.
 - SEM_STAT_ANY
 - tak jak SEM_STAT.
 
Dla wszystkich pozostałych wartości cmd w razie pomyślnego zakończenia zwracane jest 0.
W razie błędu semctl() zwraca -1, a zmiennej errno zostanie nadana wartość określająca rodzaj błędu.
BŁĘDY¶
- EACCES
 - Argument cmd ma jedną z wartości: GETALL, GETPID, GETVAL, GETNCNT, GETZCNT, IPC_STAT, SEM_STAT, SEM_STAT_ANY, SETALL lub SETVAL, a proces wywołujący nie ma wystarczających uprawnień do działania na zbiorze semaforów oraz nie ma ustawionego przywileju CAP_IPC_OWNER (ang. capability), w przestrzeni nazw użytkownika, która zarządza jego przestrzenią IPC.
 - EFAULT
 - Adres wskazywany przez arg.buf lub arg.array jest niedostępny.
 - EIDRM
 - Zestaw semaforów został usunięty.
 - EINVAL
 - Niepoprawna wartość parametru cmd lub semid. Albo: w przypadku operacji SEM_STAT wartość indeksu podana w parametrze semid odwoływała się do obecnie nieużywanego elementu tablicy.
 - EPERM
 - Parametr cmd jest równy IPC_SET lub IPC_RMID, ale identyfikator efektywnego użytkownika procesu wywołującego nie jest twórcą (określonym w sem_perm.cuid) ani właścicielem (określonym w sem_perm.uid) zestawu semaforów, a proces nie ma przywileju CAP_SYS_ADMIN (ang. capability).
 - ERANGE
 - Argument cmd ma wartość SETALL lub SETVAL, ale przekazywana wartość semafora semval (dla któregoś z semaforów zestawu) jest mniejsza od 0 lub większa od wartości ograniczenia systemowego SEMVMX.
 
STANDARDY¶
POSIX.1-2001, POSIX.1-2008, SVr4.
POSIX.1 określa pole sem_nsems struktury semid_ds jako będące typu unsigned short i tak też jest ono zdefiniowane w większości systemów. Tak było również w Linuksie 2.2 i wcześniejszych, lecz od Linuksa 2.4 pole to jest typu unsigned long.
UWAGI¶
Operacje IPC_INFO, SEM_STAT oraz SEM_INFO są używane przez program ipcs(1) w celu dostarczenia informacji o zajmowanych zasobach. W przyszłości operacje te mogą zostać zmodyfikowane lub przeniesione do interfejsu systemu plików /proc.
Niektóre pola struktury struct semid_ds były w Linuksie 2.2 typu short, ale stały się typu long w Linuksie 2.4. Aby to wykorzystać, powinna wystarczyć rekompilacja pod glibc-2.1.91 lub nowszą. (Jądro rozróżnia stare wywołania od nowych za pomocą znacznika IPC_64 w cmd).
We wcześniejszych wersjach biblioteki glibc unia semun była zdefiniowana w <sys/sem.h>, jednakże POSIX.1 wymaga, żeby to program wywołujący definiował tę unię. Wersje glibc, które nie definiują tej unii, definiują makro _SEM_SEMUN_UNDEFINED w <sys/sem.h>.
Na wywołanie semctl() wpływa następujące ograniczenie systemowe dotyczące zbioru semaforów:
- SEMVMX
 - Maksymalna wartość semval: zależna od implementacji (32767).
 
W celu uzyskania lepszej przenośności, najlepiej zawsze wywoływać semctl() z czterema argumentami.
Wartość sempid¶
POSIX.1 definiuje sempid jako "identyfikator procesu ostatniej operacji" na semaforze i wprost zauważa, że wartość tak jest ustawiana przez pomyślne wywołanie semop(2), z implikacją, że żaden inny interfejs nie wpływa na wartość sempid.
Choć niektóre implementacje są zgodne z zachowaniem opisanym w POSIX.1, to inne nie są (błąd prawdopodobnie leży tu w specyfikacji POSIX.1, jako że nie zauważyła ona tylu przykładów istniejących implementacji). Różne inne implementacje aktualizują sempid również przy innych operacjach aktualizujących wartość semafora: operacjach SETVAL i SETALL, jak również dostosowaniach semafora wykonywanych przy zakończeniu procesu jako konsekwencji użycia flagi SEM_UNDO (zob. semop(2)).
Linux aktualizuje sempid również przy operacjach SETVAL i dostosowaniach semafora. Jednak, nieco niekonsekwentnie, do wersji Linuksa 4.5 włącznie, jądro nie aktualizowało sempid przy operacjach SETALL. Skorygowano to w Linuksie 4.6.
PRZYKŁADY¶
Zobacz shmop(2).
ZOBACZ TAKŻE¶
ipc(2), semget(2), semop(2), capabilities(7), sem_overview(7), sysvipc(7)
TŁUMACZENIE¶
Tłumaczenie niniejszej strony podręcznika: Rafał Lewczuk <R.Lewczuk@elka.pw.edu.p>, Andrzej Krzysztofowicz <ankry@green.mf.pg.gda.pl>, Robert Luberda <robert@debian.org> i Michał Kułach <michal.kulach@gmail.com>
Niniejsze tłumaczenie jest wolną dokumentacją. Bliższe informacje o warunkach licencji można uzyskać zapoznając się z GNU General Public License w wersji 3 lub nowszej. Nie przyjmuje się ŻADNEJ ODPOWIEDZIALNOŚCI.
Błędy w tłumaczeniu strony podręcznika prosimy zgłaszać na adres listy dyskusyjnej manpages-pl-list@lists.sourceforge.net.
| 15 grudnia 2022 r. | Linux man-pages 6.03 |