30 votes

Pourquoi getenv a-t-il été standardisé mais pas setenv?

À partir des réponses et des commentaires sur cette question, je comprends que getenv est défini par la norme C++, mais setenv ne l'est pas. Et en effet, le programme suivant

#include <cstdlib>
#include <iostream>

int main ( int argc, char **argv )
{
    std::cout << std::getenv("PATH") << std::endl;  // no errors

    std::setenv("PATH", "/home/phydeaux/.local/bin:...", true);  // error
}

ne compile pas pour moi (clang 3.9).

Pourquoi était l'un de ces apparemment fonctions complémentaires standardisée, mais pas dans l'autre?

30voto

Jonathan Leffler Points 299946

Le C90 standard inclut getenv(); par conséquent, le C++98 standard fait trop.

Lorsque la norme a été créé à l'origine, le précédent pour l'environnement a été putenv(); l' setenv() fonction n'a pas été conçue jusqu'à ce que plus tard. Le comité des normes pour éviter la création de nouvelles fonctions quand il le pouvait, mais aussi d'éviter la standardisation problématique fonctions lorsque cela est possible (oui, localeconv() et gets() sont des contre-exemples). Le comportement de l' putenv() est problématique. Vous devez passer de la mémoire qui n'est pas automatique durée, mais vous ne pouvez pas savoir si vous pouvez vous permettre de l'utiliser à nouveau. C'est comme forcé de fuite de mémoire. C'était Une Bonne Chose™, putenv() n'était pas standardisée.

La justification de la norme C explicitement dit (§7.20.4.5, p163):

Une correspondante putenv fonction a été omis de la Norme, depuis son utilité à l'extérieur d'un multi-processus environnement est discutable, et depuis sa définition est bien le domaine d'un système d'exploitation standard.

La plate-forme des Api spécifiques à intervenir et à apporter les fonctionnalités manquantes dans un moyen adapté.


Les premières éditions de la norme POSIX (1988 essai; 1990) n'incluent pas setenv() ou putenv(). L'X/Open Guide Portabilité (XPG) Question 1 ne comprennent putenv() basé sur son apparition dans le SVID (System V Interface Definition) - qui ne comprennent pas l' setenv(). Le XPG Question 6 a été ajouté setenv() et unsetenv() (voir l'histoire des sections pour les fonctions à l'Url liée à l'). Curieusement, sur un Mac exécutant mac os Sierra 10.12.6, man 3 setenv a une section historique qui identifie:

Les fonctions setenv() et unsetenv() est apparue dans la Version 7 d'AT&T UNIX. Le putenv() la fonction est apparu en 4.3 BSD-Reno.

Ce qui est inattendu et probablement erronée depuis le UNIX Manuel du Programmeur Vol 1 (1979) ne comprend pas tout de putenv(), setenv() ou unsetenv(). L' putenv() fonction a été ajoutée à l'AT&T variantes de Unix à un certain stade dans les années 80; il a été dans le SVID et documentés par le temps SVR4 a été libéré en 1990 et fait partie du Système III. Je pense que ils ont presque les plates-formes inversées. 4.3 BSD-Reno a été publié en juin 1990, après que les deux premiers C et POSIX normes ont été libérés.

Il y a des discussions dans les commentaires avec Random832 , maintenant supprimé, en mentionnant TUHS – Unix Patrimoine de la Société en tant que source d'information sur les anciennes versions d'Unix. La chaîne inclus mon observation: Si rien d'autre, cette discussion met l'accent sur pourquoi les comités de normalisation a bien d'orienter clairement de la "configuration de l'environnement"! Il semble que l' putenv() n'a pas été à la 7ème Édition UNIX, contrairement à ma mémoire. Je suis assez sûr que c'est un système que j'ai utilisé à partir de 1983, qui a été beaucoup de la 7e Édition avec du matériel de Système III, dont certains à partir du PTB. C'est une partie de SVR4 (j'ai un manuel pour ça), et a été défini dans une certaine version de l'SVID (probablement avant SVR4).

Le C justification mentionne également des préoccupations au sujet de gets() mais inclus en dépit de ces préoccupations; il a été (très raisonnablement) retiré de C11, bien sûr (mais POSIX fait toujours référence à C99, pas C11).

4voto

mksteve Points 3337

setenv n'est pas possible dans certains des environnements originaux C "a été définie.

la fonction getenv vous permet de voir votre environnement. la création d'un nouveau processus avec exec[lv][p][e] vous permet de créer un enfant avec une maladie héréditaire ou nouvel environnement.

Cependant, setenv, serait de modifier l'état du processus appelant, qui n'était pas toujours possible.

Je suppose que c'est parce qu'elle augmente l'écriture de l'interface pour l'appelant, et qui n'était pas nécessaire à l'origine, et est un risque pour la sécurité de ces jours.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X