2017-02-08 1 views
1

Im essayant d'ouvrir un fichier de périphérique (mais la question est principalement un fichier général) et il travaille avec la ligne suivanteappel système ouvert avec le paramètre 0 comme un drapeau

fd = open(path,0); 

mais a échoué avec la ligne suivante

fd = open(path,O_RDONLY,0777) 

(même sans le mode 0777) Je ne comprends pas tout ce qui est le sens de puting 0 au lieu d'un drapeau et pourquoi son travail.

Répondre

0

The POSIX specifications for open() exigent exactement l'une des constantes définies O_EXEC, O_RDONLY, O_WRONLY, O_RDWR ou O_SEARCH être inclus dans les drapeaux, mais ils ne précisent pas les valeurs de ces constantes. En effet, ils notent dans la logique que "dans les implémentations historiques, la valeur de O_RDONLY est nulle." Dans une telle implémentation, spécifier des indicateurs à 0 équivaut à spécifier (seulement) O_RDONLY.

L'utilisation du terme «historique» par POSIX ne doit pas être interprétée comme suggérant qu'il est rare que O_RDONLY ait la valeur 0; au contraire, il est assez commun dans les implémentations actuelles. Néanmoins, vous ne devez pas spécifier les indicateurs comme 0 lorsque vous voulez dire O_RDONLY, car cela laisse votre code ouvert à la rupture sur les systèmes avec des définitions différentes des constantes de l'indicateur.

Si vous pouvez effectivement ouvrir avec des drapeaux donnés comme 0 mais pas avec des drapeaux donnés comme O_RDONLY (ce qui semble douteux), alors il doit être vrai que O_RDONLY a une valeur différente de 0 dans votre implémentation. Il se peut alors que l'un des autres membres du groupe de constantes obligatoires ait la valeur 0 et que vous puissiez ouvrir le fichier cible dans le mode correspondant. Par exemple, le chemin désigne peut-être un répertoire et O_SEARCH a une valeur 0. Sinon, vous obtenez un comportement indéfini de open(). UB n'a pas à se manifester comme renvoyant un indicateur d'erreur, et si cela n'arrive pas, cela ne vous dit rien.


Additif: étant donné que open(path, O_RDONLY) échoue pour vous (comme indiqué par le retour -1), il serait intéressant de sonder la cause de l'erreur en examinant errno, ou, mieux, en imprimant un diagnostic via perror().