Portál AbcLinuxu, 13. května 2024 09:21


Dotaz: kqueue ve FreeBSD cloexec

26.12.2015 12:08 Jiří
kqueue ve FreeBSD cloexec
Přečteno: 491×
Odpovědět | Admin
Nevíte, jestli kqueue() vrací deskriptor, co je automaticky označen close-on-exec? Nikde o tom nemůžu najít žádnou zmíňku a přijde mi divné, kdyby nebylo, znemožňovalo by to použití tohoto volání ve vícevláknovém programu. Děkuji.
Nástroje: Začni sledovat (0) ?Zašle upozornění na váš email při vložení nového komentáře.

Odpovědi

27.12.2015 12:47 BS
Rozbalit Rozbalit vše Re: kqueue ve FreeBSD cloexec
Odpovědět | | Sbalit | Link | Blokovat | Admin
Zrovna sedím u FreeBSD mašiny, takže není nic snazšího než se zeptat.
#include <sys/types.h>
#include <sys/event.h>
#include <sys/time.h>
#include <stdio.h>
#include <fcntl.h>


int main(void)
{
  int kq, flags;
  
  if ((kq = kqueue()) == -1) 
    return -1; 
  if ((flags = fcntl(kq, F_GETFL, NULL)) == -1)
    return -1; 
  printf("FD_CLOEXEC: %s\n", (flags & FD_CLOEXEC) ? "yes" : "no");
  return 0;
}
Odpověď zní:

FD_CLOEXEC: no
27.12.2015 12:57 BS
Rozbalit Rozbalit vše Re: kqueue ve FreeBSD cloexec
Pardon,

musím dementovat sám sebe, takto to nejde. Jsem zblblý z Linuxu, FreeBSD neumí přes fcntl číst CLOEXEC bit.
27.12.2015 13:07 Jiří
Rozbalit Rozbalit vše Re: kqueue ve FreeBSD cloexec
Já jsem si to před chvílí zkusil, fd číslo předám jako argument child procesu a tam to bylo normálně dostupné, takže zůstal otevřený. Našel jsem toto a zdá se, že NetBSD má proto kqueue1() s flagem, ale FreeBSD nic. To je smutné, protože kvůli tomu musím použít obyčejný poll(), nemohu si dovolit v knihovně vytvořit kqueue deskriptor, když nevím, jestli uživatel nemá nějaká vlákna, kde forkuje.
27.12.2015 13:13 Jiří
Rozbalit Rozbalit vše Re: kqueue ve FreeBSD cloexec
Fungovalo by, kdybych vytvořil condition variable s mutexem, zaregistroval pthread_atfork(), a před kqueue() zamknul mutex a v pthread_atfork ho taky zkoušel zamknout? Není to tuším async signal safe, ale vždycky to bude voláno z vlákna, co volá fork a to nebude to moje, o kterém vím, že fork nevolá?
27.12.2015 13:14 BS
Rozbalit Rozbalit vše Re: kqueue ve FreeBSD cloexec
Nicméně s mírnou modifikací, když nechci číst flagy, ale přímo CLOEXEC bit tak to lze, viz z man fcntl. Takže snad finálně.
#include <sys/types.h>
#include <sys/event.h>
#include <sys/time.h>
#include <stdio.h>
#include <fcntl.h>


int main(void)
{
  int kq, flags;
  
  if ((kq = kqueue()) == -1) 
    return -1; 
  if ((flags = fcntl(kq, F_GETFD, NULL)) == -1) /* Nikoli GETFL, ale GETFD*/
    return -1; 
  printf("FD_CLOEXEC: %s\n", (flags & FD_CLOEXEC) ? "yes" : "no");
  return 0;
}
Závěr je ale stejný, COLOEXEC by default není, což je standardní, neznám žádný FD, který by tento bit měl ve výchozím stavu.

Bit lze pak nastavit pomocí
fcntl(kq, F_SETFD, FD_CLOEXEC);
Omlouvám se za počáteční zmatenost. FreeBSD mám na desktopu, ale programuji hlavně pro Linux.
27.12.2015 16:12 Jiří
Rozbalit Rozbalit vše Re: kqueue ve FreeBSD cloexec
COLOEXEC by default není, což je standardní, neznám žádný FD, který by tento bit měl ve výchozím stavu.
Já taky ne, ale spoustě systémových volání jde nastavit flag, aby to tak bylo.
Omlouvám se za počáteční zmatenost. FreeBSD mám na desktopu, ale programuji hlavně pro Linux.
Nic se neděje, alespoň se někdo snaží pomoci. Nastavit potom jde, ale protože se jedná o knihovnu, nemůžu zaručit, jak jsem zmínil výše, že uživatel nemá další vlákno, kde forkuje, a mezi kqueue() a fcntl() pak vzniká race-condition, kdy mi může deskriptor uniknout do uživatelova podprocesu.
10.2.2016 16:20 Jardík
Rozbalit Rozbalit vše Re: kqueue ve FreeBSD cloexec
Odpovědět | | Sbalit | Link | Blokovat | Admin
Z manuálové stránky:
The kqueue() system call creates a new kernel event queue and returns a descriptor. The queue is not inherited by a child created with fork(2).
Proces před exec() většinou sebe fork()ne, takže v tomto případě nastavení CLOEXEC není třeba. Problém bude, když nějaké vlákno přímo zavolá exec() bez forknutí.

Založit nové vláknoNahoru

Tiskni Sdílej: Linkuj Jaggni to Vybrali.sme.sk Google Del.icio.us Facebook

ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.