12
votes

Open () ne définit pas le drapeau O_Cloexec

J'essaie de définir le drapeau O_Cloexec à l'aide d'Ouvrir () et n'ayez pas de réussir.

Considérez la microtest suivante: xxx

Lorsque vous allumez sous Linux avec la version 2.6 du noyau Le test réussit et imprime "OK!", mais échoue avec 3,8 ou 3,9 noyaux.

Qu'est-ce qui ne va pas? Merci!


1 commentaires

Notez que le drapeau peut être vrai avant même avant le support O_Cloexec en 2.6.38


3 Réponses :


2
votes

Le paramètre d'appel FCNTL f_getfd , le drapeau est fd_cloexec et le support o_cloexec est apparu en 2.6. 23 . Lire les manuels: xxx


7 commentaires

OP a dit qu'il réussit au noyau 2.6 mais échoue sur 3,8 / 3.9


Le test échoue lors de la course sur le noyau 3.8 qui prend évidemment en charge O_Cloexec. Veuillez lire la question.


Cette réponse est correcte dans la mesure où la droite moyen d'obtenir le statut cloexec est d'utiliser f_getfd et testez pour fd_cloexec , parce que cloexec est un drapeau qui s'applique à chaque descripteur de fichier plutôt que le fichier ouvert sous-jacent. Cela n'explique pas pourquoi l'ABI pour f_getfl apparemment changé, cependant.


Pourriez-vous s'il vous plaît citer la spécification décrivant la méthode droite ? Des manuels, je vois que le test est parfaitement droit .


Non, ce n'est jamais documenté comme ça. F_GETFL est juste les drapeaux ouverts du fichier; quelqu'un a décidé que le bit doit être pris comme il ne touche pas le fichier ouvert, mais le descripteur de fichier uniquement. Voilà pourquoi il est pas documenté.


De plus, f_getfl semble retourner tout ce qui a été donné aux drapeaux ouverts et moins filtrés, même ignorés.


Ainsi, ce n'était jamais un moyen fiable de voir si un drapeau était soutenu.



12
votes

Il a été décidé que l'exposition o_cloexec drapeau sur fcntl (fd, f_getfl) est une fuite de sécurité. Modification a été apportée par ce commettre dans le noyau 3.6-RC7: xxx

En d'autres termes, vous ne devriez pas avoir invoqué sur o_cloexec être visible en premier lieu.


0 commentaires

2
votes

Vous le faites mal. Vous devriez faire de cette façon:

int ret = fcntl(fd, F_GETFD);
if (ret & FD_CLOEXEC) {
...
}


0 commentaires