NAZWA¶
msgrcv, msgsnd - przekazywanie komunikatów kolejki Systemu V
SKŁADNIA¶
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,
int msgflg);
OPIS¶
Wywołań systemowych
msgsnd() i
msgrcv() używa
się do - odpowiednio - wysyłania komunikatów do kolejki
komunikatów i odbierania komunikatów z kolejki Systemu V.
Aby wysłać komunikat, proces wywołujący musi
mieć uprawnienie do zapisu na kolejce komunikatów, a aby
odebrać komunikat - uprawnienie do odczytu kolejki.
Parametr
msgp jest wskaźnikiem do zdefiniowanej przez proces
wywołujący struktury, której ogólna postać
wygląda tak:
struct msgbuf {
long mtype; /* typ wiadomości, musi być > 0 */
char mtext[1]; /* dane wiadomości */
};
Pole
mtext jest tablicą (lub inna strukturą) o rozmiarze
określonym przez
msgsz, będącym nieujemną
liczbą całkowitą. Dozwolone są komunikaty o
zerowej długości (tzn. niezawierające pola
mtext).
Wartość pola
mtype musi być liczbą
ściśle dodatnią, która może
służyć procesowi odbierającemu komunikaty do
filtrowania kolejki (zobacz opis
msgrcv() poniżej).
msgsnd()¶
Wywołanie systemowe
msgsnd() dołącza kopię
komunikatu wskazywanego przez
msgp do kolejki o identyfikatorze
określonym przez
msqid.
Gdy w kolejce jest wystarczająco dużo miejsca, to
msgsnd()
natychmiast kończy się pomyślnie.
(Pojemność kolejki określona jest w polu
msg_qbytes struktury danych stowarzyszonej z kolejką. Podczas
tworzenia kolejki polu temu jest przypisywana wartość
początkowa wynosząca
MSGMNB bajtów, lecz
ograniczenie to może zostać zmienione za pomocą
msgctl(2)). Kolejka komunikatów jest uważana za
pełną w jednym z następujących przypadków:
- *
- Dodanie nowego komunikatu do kolejki spowoduje, że suma
bajtów w kolejki przekroczy maksymalny rozmiar kolejki (pole
msg_qbytes).
- *
- Dodanie kolejnego komunikatu do kolejki spowoduje, że
całkowita liczba komunikatów w kolejce przekroczy maksymalny
rozmiar kolejki (pole msg_qbytes). To sprawdzenie jest konieczne
aby zapobiec umieszczaniu w kolejce nieograniczonej liczby
komunikatów o zerowej długości. Choć takie
komunikaty nie zawierają danych, to wciąż
zajmują (zablokowaną) pamięć
jądra.
Jeśli w kolejce obecna jest niewystarczająca ilość
wolnego miejsca, to domyślne zachowaniem
msgsnd() jest blokada
do momentu uzyskania wolnej przestrzeni. Jeśli w
msgflg
określono
IPC_NOWAIT, to zamiast tego wywołanie
zwróci błąd
EAGAIN.
Wstrzymane wywołanie
msgsnd() może się także
nie powieść, jeżeli:
- *
- kolejka zostanie usunięta z systemu - w tym przypadku
wywołanie systemowe zgłosi błąd,
przypisując zmiennej errno wartość
EIDRM;
- *
- zostanie przechwycony sygnał - wtedy wywołanie to powoduje
przypisanie zmiennej errno wartości EINTR; patrz
signal(7) ( msgsnd() po przerwaniu przez
obsługę sygnału nie jest nigdy automatycznie
restartowane, niezależnie od ustawienia znacznika SA_RESTART
podanego podczas ustanawiania funkcji obsługi sygnału).
Jeśli operacja zakończy się pomyślnie, to struktura
danych opisująca kolejkę zostanie zmodyfikowana w
następujący sposób:
- msg_lspid przypisany zostanie identyfikator procesu
wykonującego tę operację.
- msg_qnum zostanie zwiększone o 1.
- msg_stime zostanie przypisany bieżący czas.
msgrcv()¶
Wywołanie systemowe
msgrcv usuwa komunikat z kolejki
określonej przez
msqid i umieszcza go w buforze wskazywanym
przez parametr
msgp.
Parametr
msgsz określa maksymalny rozmiar w bajtach pola
mtext struktury wskazywanej przez parametr
msgp. Jeśli
dane komunikatu zajmują więcej bajtów niż
msgsz, to wynik zależy od tego, czy w
msgflg przekazano
znacznik
MSG_NOERROR. Jeżeli podano
MSG_NOERROR, to tekst
komunikatu zostanie obcięty (obcięta część
zostanie utracona); jeżeli
MSG_NOERROR nie występuje, to
komunikat nie jest usuwany z kolejki, a wywołanie systemowe
kończy się błędem, zwracając
wartość -1 i ustawiając
errno na
E2BIG.
Jeżeli podano
MSG_COPY w
msgflg (zob. poniżej),
parametr
msgtyp określa rodzaj komunikatu w
następujący sposób:
- *
- Jeśli msgtyp jest równy 0, to czytany jest pierwszy
komunikat z kolejki.
- *
- Jeśli msgtyp ma wartość większą
niż 0, to z kolejki odczytywany jest pierwszy komunikat o typie
msgtyp, chyba że w parametrze msgflg zostanie
ustawiony znacznik MSG_EXCEPT, co spowoduje, że z kolejki
zostanie odczytany pierwszy komunikat o typie różnym od
msgtyp.
- *
- Jeśli msgtyp ma wartość mniejszą
niż 0, to z kolejki zostanie odczytany pierwszy komunikat o
najniższym numerze typu, mniejszym lub równym
wartości bezwzględnej msgtyp.
Parametr
msgflg jest maską bitową, utworzoną jako
alternatywa (OR) zera lub więcej następujących
znaczników:
- IPC_NOWAIT
- Nie wstrzymuje pracy procesu, jeśli w kolejce nie ma
komunikatów odpowiedniego typu. Wywołanie systemowe
zwróci wówczas błąd, przypisując
zmiennej errno wartość ENOMSG.
- MSG_COPY (od Linuksa 3.8)
- Nieniszcząco pobiega kopię komunikatu w pozycję
porządkową w kolejce określoną przez
msgtyp (komunikaty są pomyślane do numerowania od 0).
Tę flagę należy podać w połączeniu
z IPC_NOWAIT, co skutkuje tym, że jeśli w danej
pozycji nie ma dostępnego komunikatu, to wywołanie
natychmiast zwraca błąd ENOMSG. Ponieważ
zmienia to znaczenie msgtyp w różny sposób,
MSG_COPY i MSG_EXCEPT nie
mogą być podane równocześnie w
msgflg.
Flaga MSG_COPY została dodana dla zaimplementowania w
jądrze funkcji przywracania do punktu kontrolnego
(checkpoint-restore) i jest dostępna wyłącznie wtedy,
jeśli jądro zbudowano z opcją
CONFIG_CHECKPOINT_RESTORE.
- MSG_EXCEPT
- Użyte z parametrem msgtyp większym od 0, spowoduje
odczytanie z kolejki pierwszego komunikatu o typie różnym od
msgtyp.
- MSG_NOERROR
- Spowoduje obcięcie komunikatu, jeśli jego dane są
dłuższe niż msgsz bajtów.
Jeśli w kolejce nie ma komunikatu spełniającego te warunki,
a znacznik
IPC_NOWAIT nie został ustawiony w
msgflg, to
proces zostanie wstrzymany, dopóki nie nastąpi jedno z
poniższych zdarzeń:
- *
- Komunikat odpowiedniego typu zostanie umieszczony w kolejce.
- *
- Kolejka zostanie usunięta z systemu. W tym przypadku
wywołanie systemowe zgłosi błąd,
przypisując zmiennej errno wartość
EIDRM.
- *
- Proces wywołujący przechwytuje sygnał. W takim
przypadku wywołanie systemowe kończy się
niepowodzeniem, ustawiając errno na EINTR.
(msgrcv() po przerwaniu przez obsługę sygnału
nie jest nigdy automatycznie restartowane, niezależnie od
ustawienia znacznika SA_RESTART podczas ustanawiania funkcji
obsługi sygnału).
Jeśli operacja zakończy się pomyślnie, to struktura
danych opisująca kolejkę zostanie zmodyfikowana w
następujący sposób:
- msg_lrpid przyjmie wartość równą
identyfikatorowi wołającego procesu
- msg_qnum zostanie zmniejszone o 1.
- msg_rtime zostanie przypisany bieżący czas.
WARTOŚĆ ZWRACANA¶
W przypadku niepowodzenia obydwa wywołania zwrócą -1 i
przypiszą zmiennej
errno wartość
określającą rodzaj błędu. W przeciwnym
przypadku,
msgsnd() zwróci 0, a
msgrvc() zwróci
liczbę bajtów skopiowanych z kolejki do tablicy
mtext.
BŁĘDY¶
Jeśli wywołanie
msgsnd() się nie powiedzie, to
zmienna
errno przyjmie jedną z poniższych
wartości:
- EACCES
- Proces wywołujący nie ma prawa do zapisu danej kolejki
komunikatów, ani nie ma ustawionego atrybutu
CAP_IPC_OWNER.
- EAGAIN
- Komunikat nie może zostać wysłany z powodu
ograniczenia msg_qbytes dotyczącego kolejki, a nie
przekazano znacznika IPC_NOWAIT w parametrze mgsflg.
- EFAULT
- Adres wskazywany przez msgp jest niedostępny.
- EIDRM
- Kolejka komunikatów została usunięta.
- EINTR
- Podczas oczekiwania na zwolnienie miejsca w kolejce, proces
przechwycił sygnał.
- EINVAL
- Niewłaściwa wartość msqid, mtype
(powinna być dodatnia) lub msgsz (powinna być
większa lub równa 0 i mniejsza lub równa
MSGMAX).
- ENOMEM
- Brak w systemie pamięci na skopiowanie komunikatu wskazywanego
przez msgp.
Jeśli wywołanie
msgrcv() się nie powiedzie, to
zmiennej
errno zostanie przypisana jedna z poniższych
wartości:
- E2BIG
- Tekst komunikatu jest dłuższy niż msgsz i nie
ustawiono znacznika MSG_NOERROR w parametrze msgflg.
- EACCES
- Proces wywołujący nie ma prawa do odczytu danej kolejki
komunikatów, ani nie ma ustawionego atrybutu
CAP_IPC_OWNER.
- EAGAIN
- Brak dostępnych komunikatów w kolejce, a podano
IPC_NOWAIT w msgflg.
- EFAULT
- Adres wskazywany przez msgp jest niedostępny.
- EIDRM
- Proces oczekiwał na komunikat, ale w międzyczasie kolejka
została usunięta.
- EINTR
- Proces przechwycił sygnał podczas oczekiwania na odebranie
komunikatu; patrz signal(7).
- EINVAL
- msgqid był niepoprawny lub msgsz był mniejszy
od 0.
- EINVAL (od Linuksa 3.14)
- msgflg określono jako MSG_COPY, ale nie
IPC_NOWAIT.
- EINVAL (od Linuksa 3.14)
- msgflg określono jako MSG_COPY i
MSG_EXCEPT.
- ENOMSG
- Znacznik IPC_NOWAIT został przekazany w msgflg, ale w
kolejce nie ma komunikatu żądanego typu.
- ENOMSG
- IPC_NOWAIT i MSG_COPY zostały określone w
msgflg, a kolejka zawiera mniej niż msgtyp
komunikatów.
- ENOSYS (od Linuksa 3.8)
- MSG_COPY zostało określone w msgflg, a
jądro zostało skonfigurowane bez opcji
CONFIG_CHECKPOINT_RESTORE.
ZGODNE Z¶
SVr4, POSIX.1-2001.
Znaczniki
MSG_EXCEPT i
MSG_COPY są charakterystyczne dla
Linuksa, ich definicje można pobrać przez zdefiniowane makra
testującego funkcje
_GNU_SOURCE.
UWAGI¶
Dołączenie
<sys/types.h> i
<sys/ipc.h>
nie jest wymagane na Linuksie ani przez żadną z wersji POSIX.
Jednak niektóre stare implementacje wymagają
dołączenia tych plików nagłówkowych, SVID
również dokumentuje ich dołączenie. Aplikacje
które mają być przenośne na tego typu stare
systemy mogą wymagać dołączenia omawianych
plików nagłówkowych.
Parametr
msgp jest deklarowany jako
struct msgbuf * w glibc
2.0 i glibc 2.1. W glibc 2.2 i późniejszych jest deklarowany
jako
void *, zgodnie z wymaganiami SUSv2 i SUSv3.
Wywołania
msgsnd() dotyczą następujące
ograniczenia systemowe:
- MSGMAX
- Maksymalny rozmiar tekstu komunikatu: 8192 bajty (pod Linuksem ten limit
można odczytać i modyfikować, używając
pliku /proc/sys/kernel/msgmax).
- MSGMNB
- Domyślny maksymalny łączny rozmiar wszystkich
komunikatów w kolejce: 16384 bajty (pod Linuksem można ten
limit odczytać i zmienić, używając pliku
/proc/sys/kernel/msgmnb). Proces uprzywilejowany (w Linuksie:
proces ze możliwością CAP_SYS_RESOURCE)
może za pomocą wywołania msgctl()
ustawić rozmiar kolejki komunikatów na wartość
większą niż MSGMNB.
W tej implementacji nie ma jawnego systemowego ograniczenia liczby
komunikatów przechowywanych w kolejce (
MSGTQL) i na rozmiar
obszaru (w bajtach) przeznaczonego na komunikaty (
MSGPOOL).
BŁĘDY¶
W Linuksie 3.13 i wcześniejszych, jeśli
msgrcv()
było wywołane ze znacznikiem
MSG_COPY, lecz bez
IPC_NOWAIT, a kolejka komunikatów zawierała mniej
niż
msgtyp komunikatów, to wywołanie było
zablokowane aż do zapisania kolejnego komunikatu do kolejki. W tym
momencie wywołanie zwracało kopię komunikatu
bez
względu na to czy komunikat był w pozycji
msgtyp.
Błąd ten został naprawiony w jądrze Linux 3.14.
Podanie zarówno w
msgflg zarówno
MSG_COPY jak i
MSC_EXCEPT jest błędem logicznym (ponieważ oba te
znaczniki wymagają innej interpretacji
msgtyp). W Linuksie 3.13
błąd ten nie był diagnozowany przez
msgsrv().
Zostało to naprawione w jądrze Linux 3.14.
ZOBACZ TAKŻE¶
msgctl(2),
msgget(2),
capabilities(7),
mq_overview(7),
svipc(7)
O STRONIE¶
Angielska wersja tej strony pochodzi z wydania 3.71 projektu Linux
man-pages. Opis projektu, informacje dotyczące zgłaszania
błędów, oraz najnowszą wersję
oryginału można znaleźć pod adresem
http://www.kernel.org/doc/man-pages/.
TŁUMACZENIE¶
Autorami polskiego tłumaczenia niniejszej strony podręcznika man
są: Rafał Lewczuk (PTM) <R.Lewczuk@elka.pw.edu.p>, Andrzej
Krzysztofowicz (PTM) <ankry@mif.pg.gda.pl>, Robert Luberda
<robert@debian.org> i Michał Kułach
<michal.kulach@gmail.com>.
Polskie tłumaczenie jest częścią projektu
manpages-pl; uwagi, pomoc, zgłaszanie błędów na
stronie
http://sourceforge.net/projects/manpages-pl/. Jest zgodne z
wersją
3.71 oryginału.