Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

system() et open() (pipes) sûrs et portables

12 réponses
Avatar
Manuel Pégourié-Gonnard
Bonjour,

system() existe, si je comprends bien, sous deux formes essentiellement
différentes du point de vue de la sécurité : celle qui fait
potentiellement appel à un shell (l'argument est un scalaire ou une liste
à un élément), et celle qui ne fait jamais appel à un shell (l'argument
est une liste à plus d'un élément, ou il y a un premier argument suivi
sans virgule par un deuxième qui est alors interpété comme une liste).

Lorsqu'on lance une commande externe, et qu'une partie de la ligne de
commande est d'origine mal contrôlée (entrée utilisateur), si l'on veut
être sûr de savoir ce qui se passe, il faut mieux, il me semble,
utiliser la deuxième forme.

Ma question est : y a-t-il la moindre raison de ne pas préférer cette
deuxième forme, dès lors qu'on n'a pas réellement besoin d'appeler un
shell ? Par exemple en matière de portabilité (il s'agit d'un script qui
doit tourner au moins sous Unix, Windows, et Cygwin).

Même question quand il s'agit d'ouvrir une commande avec un pipe vers son
entrée standard ou depuis sa sortie standard : peut-on toujours utiliser
la forme à plus de trois arguments sur les plateformes citées ? Dans
perldoc -f open, je lis :

The last example in each block shows the pipe as "list form",
which is not yet supported on all platforms. A good rule of
thumb is that if your platform has true "fork()" (in other
words, if your platform is UNIX) you can use the list form.

qui m'inquiète un peu, parce qu'il me semble que celà exclut windows.

Visiblement il y a des trucs à lire à ce sujet dans perlipc, mais je
n'ai pas trouvé à quel endroit, je m'y attaquerai demain (ça a l'air
d'un gros morceau).

Merci d'avance pour vos conseils !

--
Manuel Pégourié-Gonnard Institut de mathématiques de Jussieu
http://weblog.elzevir.fr/ http://people.math.jussieu.fr/~mpg/

2 réponses

1 2
Avatar
Manuel Pégourié-Gonnard
Manuel Pégourié-Gonnard scripsit :

Paul Gaborit scripsit :

En fait, sous Windows, le fork() est émulé en utilisant du
multi-threading. Pour en savoir plus sur les limitations de cette
émulation, il faut commencer par lire 'perlfork'. Il y a une solution
pour émuler les tubes (pipes).



Mais ça a l'air très bien ça ! (Je viens de le lire, mais ne l'ai pas
encore testé.)



Ça marche à merveille avec le Perl 5.10.0 de Strawberry Perl (en tout
cas sur le Windows XP sur lequel j'ai testé). Par contre ça ne
fonctionne pas avec le Perl 5.8.8 que le script en question devra
utiliser. Retour à la case fichier temporaire (ou usage de Win32).

--
Manuel Pégourié-Gonnard Institut de mathématiques de Jussieu
http://weblog.elzevir.fr/ http://people.math.jussieu.fr/~mpg/
Avatar
Manuel Pégourié-Gonnard
Marc Espie scripsit :

Concernant les fichiers temporaires, il y a File::Temp, qui contient
entres autres un equivalent de mkstemp, qui est la bonne solution sur
les Unix (creation de temporaire sans race condition) et plein
d'autres cochonneries.



J'ai essayé, et je dois dire que pour l'instant ça me semble
satisfaisant. J'utilise

use File::Temp 'filetemp';
# ...
my ($tmp_fh, $tmp_name) = filetemp()

et tout semble très bien se passer. Je n'ai effectivement pas testé les
race condition, j'avoue que je ne saurais pas trop comment faire
d'ailleurs, mais la doc semble affirmer que tout est pris en charge, je
n'ai a priori pas de raison de croire que c'est faux (sauf si tu me dis
le contraire).

Au final, pour le script qui m'intéressait, j'ai commencé par le faire
proprement (enfin, aussi proprement que je peux) sous Unix, avec la
forme liste d'un open() pour ouvrir un pipe. Puis j'ai ajouté à un
endroit un test sur $^O pour faire autrement (fichier temporaire) sous
Windows, et j'ai testé sous windows.

--
Manuel Pégourié-Gonnard Institut de mathématiques de Jussieu
http://weblog.elzevir.fr/ http://people.math.jussieu.fr/~mpg/
1 2