Gentoo Forums
Gentoo Forums
Gentoo Forums
Quick Search: in
[perl] Problème en invoquant sys/ioctl.ph (résolu)
View unanswered posts
View posts from last 24 hours

 
Reply to topic    Gentoo Forums Forum Index French
View previous topic :: View next topic  
Author Message
razer
l33t
l33t


Joined: 08 Oct 2004
Posts: 893
Location: Paris - France

PostPosted: Mon Aug 20, 2007 7:33 am    Post subject: [perl] Problème en invoquant sys/ioctl.ph (résolu) Reply with quote

Hello,
J'ai un problème, à priori nouveau, avec perl.
Je travaille sur un projet perl qui utilise sys/ioctl.ph pour manipuler un handler
Lors de l'exécution, le message suivant apparaît uniquement lorsque la ligne require "sys/ioctl.ph"; est présente dans mon programme :
Code:
Constant subroutine __USE_POSIX undefined at /usr/lib/perl5/site_perl/5.8.8/i686-linux/features.ph line 8.
Constant subroutine __USE_POSIX2 undefined at /usr/lib/perl5/site_perl/5.8.8/i686-linux/features.ph line 9.
Constant subroutine __USE_POSIX199309 undefined at /usr/lib/perl5/site_perl/5.8.8/i686-linux/features.ph line 10.
Constant subroutine __USE_POSIX199506 undefined at /usr/lib/perl5/site_perl/5.8.8/i686-linux/features.ph line 11.
Constant subroutine __USE_LARGEFILE undefined at /usr/lib/perl5/site_perl/5.8.8/i686-linux/features.ph line 16.
Constant subroutine __USE_FILE_OFFSET64 undefined at /usr/lib/perl5/site_perl/5.8.8/i686-linux/features.ph line 18.
Constant subroutine __USE_BSD undefined at /usr/lib/perl5/site_perl/5.8.8/i686-linux/features.ph line 19.
Constant subroutine __USE_SVID undefined at /usr/lib/perl5/site_perl/5.8.8/i686-linux/features.ph line 20.
Constant subroutine __USE_MISC undefined at /usr/lib/perl5/site_perl/5.8.8/i686-linux/features.ph line 21.
Constant subroutine __GNU_LIBRARY__ undefined at /usr/lib/perl5/site_perl/5.8.8/i686-linux/features.ph line 156.
Operator or semicolon missing before &__inline at (eval 77) line 1.
Ambiguous use of & resolved as operator & at (eval 77) line 1.
Can't locate asm-generic/ioctl.ph in @INC (did you run h2ph?) (@INC contains: /home/razer/.gnome2/mailpictures/ /etc/perl /usr/lib/perl5/vendor_perl/5.8.8/i686-linux /usr/lib/perl5/vendor_perl/5.8.8 /usr/lib/perl5/vendor_perl /usr/lib/perl5/site_perl/5.8.8/i686-linux /usr/lib/perl5/site_perl/5.8.8 /usr/lib/perl5/site_perl/5.8.7 /usr/lib/perl5/site_perl/5.8.7/i686-linux /usr/lib/perl5/site_perl /usr/lib/perl5/5.8.8/i686-linux /usr/lib/perl5/5.8.8 /usr/local/lib/site_perl .) at /usr/lib/perl5/site_perl/5.8.8/i686-linux/asm/ioctl.ph line 5.
Compilation failed in require at /usr/lib/perl5/site_perl/5.8.8/i686-linux/asm/ioctls.ph line 7.
Compilation failed in require at /usr/lib/perl5/site_perl/5.8.8/i686-linux/bits/ioctls.ph line 8.
Compilation failed in require at /usr/lib/perl5/site_perl/5.8.8/i686-linux/sys/ioctl.ph line 8.
Compilation failed in require at ./mailpictures.pl line 10.


Je peux rendre l'erreur non fatale en faisant un lien symbolique de /usr/lib/perl5/site_perl/5.8.8/i686-linux/asm vers /usr/lib/perl5/site_perl/5.8.8/i686-linux/asm-generic, mais les premiers warnings sont toujours là, et je n'aime pas trop garder ce genre de bricolage...

Je précise quand même que :
Je suis en ~arch
Mon système vient d'être totalement émergé pour/avec gcc-4.2/glibc2.6
En utilisant gnu hashstyle et binutils-2.17.50.0.16

Oui je sais j'attire sans doute les problèmes avec tout çà, mais je ne suis pas sur gentoo pour rien ;)

Si quelqu'un a une idée sur l'origine du problème, ou tout du moins sur l'ebuild responsable de cette erreur...


Last edited by razer on Thu Aug 30, 2007 8:06 pm; edited 1 time in total
Back to top
View user's profile Send private message
Bob_Le_Mou
Tux's lil' helper
Tux's lil' helper


Joined: 17 Jun 2004
Posts: 114
Location: Pantin, France

PostPosted: Tue Aug 21, 2007 2:55 pm    Post subject: Reply with quote

Salut,

Mes connaissance en perl sont peu rouillées, et je pense que tu dois travailler vraiment "bas niveau" avec perl, parce que je n'ai jamais utilisé "require" de cette façon, d'ailleurs je lui préfère "use".

Ensuite, lorsque j'inclus un module ([...]/toto/titi.pm) c'est toujours du genre use/require toto::titi ...

Enfin, corrige moi, si je me trompe, un handler c'est un handle ?
Et si oui, pourquoi tu n'utilises pas IO::handle ?

Sinon, je ne vois pas...
_________________
Rimouski, c'est loin-in d'ici...
Back to top
View user's profile Send private message
razer
l33t
l33t


Joined: 08 Oct 2004
Posts: 893
Location: Paris - France

PostPosted: Tue Aug 21, 2007 6:20 pm    Post subject: Reply with quote

->@Bob_Le_Mou

Merci de ta réponse.
Mes lignes de code sont largement inspirées de la doc officielle de perl (qui précisait d'ailleurs d'être prudent avec ioctl :oops:)
Je vais revoir mes notes
Back to top
View user's profile Send private message
Bob_Le_Mou
Tux's lil' helper
Tux's lil' helper


Joined: 17 Jun 2004
Posts: 114
Location: Pantin, France

PostPosted: Wed Aug 22, 2007 9:54 am    Post subject: Reply with quote

Ok, j'ai regardé ton projet: vraiment trés interressant...

Je pense que tu devrais jeté un coup d'oeil à IO::Pipe, qui est une sous classe de IO::Handle.


AMHA, en utilisant des headers perl "bas niveau", tu risques de rencontrer pas mal de problèmes, même si c'est techniquement très intéressant, je pense que c'est moins "portable", mais... Ce n'est que mon avis.


/edit
après consultation de pas mal de docs, je crois que la consultation de la doc "perlipc" pourra t'interresser, notamment le paragraphe Bidirectional Communication with Yourself :

Code:
perldoc perlipc


J'espère que çà pourra t'aider.
/edit
_________________
Rimouski, c'est loin-in d'ici...
Back to top
View user's profile Send private message
razer
l33t
l33t


Joined: 08 Oct 2004
Posts: 893
Location: Paris - France

PostPosted: Thu Aug 23, 2007 10:11 pm    Post subject: Reply with quote

Merci pour ton aide et ton encouragement concernant mon projet.
Ma principale source de documentation est justement celle que tu cites.
L'usage de ioctl m'est nécessaire pour intercepter l'arrivée de nouvelles données dans le handle du processus fils de mon programme. Le but est de mettre à jour en temps réel une fenêtre gtk avec l'avancement des opérations effectuées (resizing d'images, création d'une archive...)
En clair, je fais comme çà (j'imagine que tu as un peu regardé mon code) :
Code:
# Forking main process in read handle and catch end of child
   $pid = open (CHLDLOG,"-|") ;
   $SIG{CHLD} = \&catch_child;

   # Child make core stuff
   if ($pid == 0) {
      # Open Handle for writing in autoflush mode
      my $childlog = select CHLDLOG; $| = 1; select ($childlog);
                ////
                je code ce que fait le process fils
               ////
      # Very important exit : catching end process doesn't work without
      exit 0;
      }


Il y a ensuite dans le process principal une routine exécutée toutes les 150ms par une glib::timeout, et qui se charge d'intercepter les nouveaux messages dans le handle quand ils existent :

Code:
# Redraw progress status
sub get_progress {
   # We do something only if processing
   if ($processing == TRUE) {
      # Get a message from child handle if something new happend
      my ($chldmsg, $size, @msg);
      $size = pack("L", 0);
          ioctl(CHLDLOG, FIONREAD(), $size) or die "Couldn't call ioctl: $!\n";
          $size = unpack("L", $size);
      if ($size) {
         sysread (CHLDLOG, $chldmsg, $size);
         # Set gtk label with new message
         @msg = split ("\n", $chldmsg);
         foreach (@msg) {
            if ($_ =~ m/GTKMSG_/) {
               $_ =~ s/GTKMSG_//g;
               $progress_bar->set_text("$_");
               printf "GTKMSG : $_\n";
               }
            else { printf "$_\n" }
            }
         }
      $progress_bar->pulse();
      }
   # Very important
   return (1);
   }


Les lignes importantes :
$size = pack("L", 0);
ioctl(CHLDLOG, FIONREAD(), $size) or die "Couldn't call ioctl: $!\n";
$size = unpack("L", $size);

$size est <> 0 lorqu'un nouveau message arrive, je n'ai pas réussi à trouver une technique différente pour réaliser çà, mais j'avoue ne pas tout comprendre à 100% dans la doc. que je lis...
Le reste de la routine me permet simplement de faire le tri entre les messages destinés à l'interface (précédés de GTKMSG) et les infos de debugging.
En plus des problèmes d'intégration de code C qu'implique l'usage de ioctl, la stratégie n'est pas parfaite : j'ai des messages dupliqués, provenant sans doute d'un remplissage du handle lorsque la dernière routine est en cours d'exécution. Cela m'impose d'ajouter des "sleep" dans mon programme fils, et bien sûr c'est moche, bourrin, pas du tout optimisé.
L'idéal serait de créer une interruption provoquée lorsque que le tube reçoit de nouvelles données, et d'exécuter alors une routine ultra simple sans risque de doublons.

Mais encore une fois, je débute en programmation :oops:
Il me faut encore un peu de temps pour digérer tous ces concepts, ce projet me permet de le faire de manière ludique et utile :)
Back to top
View user's profile Send private message
Bob_Le_Mou
Tux's lil' helper
Tux's lil' helper


Joined: 17 Jun 2004
Posts: 114
Location: Pantin, France

PostPosted: Sat Aug 25, 2007 12:03 pm    Post subject: Reply with quote

En fait, je ne connait pas trés bien la bibliothèque GTK2, pas plus le modules perl qui l'exploite.
Ceci dit, j'ai une nette préférence pour l'utilisation de threads pour la programmation de tâche parallèles.

Ce lien pourra te donner quelques indications pour la programmation des threads.

Mais je dois avouer que je bloque pour ton problème.
_________________
Rimouski, c'est loin-in d'ici...
Back to top
View user's profile Send private message
razer
l33t
l33t


Joined: 08 Oct 2004
Posts: 893
Location: Paris - France

PostPosted: Sat Aug 25, 2007 10:35 pm    Post subject: Reply with quote

Bob_Le_Mou wrote:
En fait, je ne connait pas trés bien la bibliothèque GTK2, pas plus le modules perl qui l'exploite.
Ceci dit, j'ai une nette préférence pour l'utilisation de threads pour la programmation de tâche parallèles.

Ce lien pourra te donner quelques indications pour la programmation des threads.

Mais je dois avouer que je bloque pour ton problème.


Toutes ces informations sont très intéressantes, merci à toi.
J'avais déjà en fait eu la curiosité de lire le chapitre sur les threads dans la doc officielle de perl : le lien que tu cites semble être un bon exemple concrêt de leur application avec les GUI.
Malgré le peu de recul à l'état actuel de mon apprentissage, j'estime (naïvement peut être) qu'il vaut mieux apprendre à bien maîtriser les processus avant d'attaquer les threads, je vais donc persister dans ma voie encore un peu avant de franchir le pas.
Le module perl proposé dans le lien et son exemple d'utilisation a biensûr pris place sur mon disque

Encore merci
Back to top
View user's profile Send private message
Bob_Le_Mou
Tux's lil' helper
Tux's lil' helper


Joined: 17 Jun 2004
Posts: 114
Location: Pantin, France

PostPosted: Sun Aug 26, 2007 7:41 am    Post subject: Reply with quote

En fait, d'après ce que j'ai compris, les threads sont en quelque sorte des forks de "fork"...
Mais bon, je comprend bien que tu n'aies pas envie de réecrire cette partie de ton projet.

Existe-t-il un Ebuild de ton projet quelque part. Afin que je teste si j'ai le même problème ici, je suis en ARCH ?
_________________
Rimouski, c'est loin-in d'ici...
Back to top
View user's profile Send private message
avendesora
Veteran
Veteran


Joined: 16 Aug 2002
Posts: 1739
Location: Betelgeuse vicinity

PostPosted: Sun Aug 26, 2007 8:42 am    Post subject: Reply with quote

Salut,

ESt-ce que tu as essayé avec l'approche O_NONBLOCK?
En gros comme ceci:

Code:

#! /usr/bin/perl -w

use strict;
use warnings;
# pour la constant EAGAIN
use POSIX qw(:errno_h);
# pour la constant O_NONBLOCK
use Fcntl;

open(STATUS, "./slow.sh 2>&1 |") || die "can't fork: $!";
my $flags = $flags = fcntl(STATUS, F_GETFL, 0) || die "Peut pas lire les flags: $!";
fcntl(STATUS, F_SETFL, $flags| O_NONBLOCK) || die "Peut pas mettre nonblock: $!";

my $stuff;
my $cont = 1;
while ($cont) {
        my $ret = read(STATUS, $stuff, 128);
        if (!$ret && $! == EAGAIN) {
                # ici: rien a lire sur le FD, mais le FD est pas ferme
                # on attend un peu, ou on passe au FD suivant, ou ...
                print "waiting\n";
                sleep(1);
        } elsif (!$ret) {
                # ici: le FD est sans doute mort (ferme).
                print "out: $!\n";
                $cont = 0;
        } else {
                # reussi a lire au moins 1 byte
                print "Lu:   $stuff   --\n";
        }
}
close STATUS;


C'est un peu plus compliqué à gérer vu que tu ne lis que ce qui est dispo dans le buffer au moment
de l'appel, donc il faut gerer les lectures incompletes. Mais il y a de bonnes chances que ce soit plus
portable que les ioctl.
Back to top
View user's profile Send private message
Bob_Le_Mou
Tux's lil' helper
Tux's lil' helper


Joined: 17 Jun 2004
Posts: 114
Location: Pantin, France

PostPosted: Sun Aug 26, 2007 10:24 am    Post subject: Reply with quote

Le code suivant, me donne le même résultats ( warnings et erreur ) que toi, et je suis en ARCH :

Code:

#!/usr/bin/perl -w
#
use warnings; use strict;
require "sys/ioctl.ph";

print "test\n";

exit 0;


On peut éliminer le problème de ~ARCH
_________________
Rimouski, c'est loin-in d'ici...
Back to top
View user's profile Send private message
razer
l33t
l33t


Joined: 08 Oct 2004
Posts: 893
Location: Paris - France

PostPosted: Sun Aug 26, 2007 2:53 pm    Post subject: Reply with quote

Bob_Le_Mou wrote:

Existe-t-il un Ebuild de ton projet quelque part. Afin que je teste si j'ai le même problème ici, je suis en ARCH ?


Non : pour l'instant c'est un tarball qui ne requiert qu'une install de type user (le tout s'installe dans ~/.gnome2/mailpictures)
Des script d'install et d'uninstall sont fournis et c'est ici

Merci pour ton test en ARCH, ce que je sais pour en avoir fait l'usage dans un précédent projet que ce problème ioctl est nouveau...

@mseigneurin
Merci pour ta contribution, je digère actuellement tes lignes de code :roll:
Back to top
View user's profile Send private message
avendesora
Veteran
Veteran


Joined: 16 Aug 2002
Posts: 1739
Location: Betelgeuse vicinity

PostPosted: Sun Aug 26, 2007 3:30 pm    Post subject: Reply with quote

C'est pas bien compliqué et ca collerait bien avec ce que tu as déjà.
Le principe c'est qu'un "read" sur un fd en mode nonblock ne bloque jamais. 8O
S'il y a des choses à lire, il te les donne.
S'il y a rien, il rend tout de suite la main et positionne errno à EAGAIN (essaye-encore-une-fois).

Il te suffirait de faire les fnctl après que tu aies "forké" (dans le père), et dans ton
get_process, tu fais juste:
Code:

my $size = read(CHLDLOG, $chldmsg, 4096);
if ($size >0) {
  # y'a eu des donnes => gtk_machin
} elsif ($! == EAGAIN) {
  # le fils a rien dit, mais il tourne encore => progess_bar->clignotte("rouge");
} else {
  # le fils est terminé => progess_bar->tout_vert();
}
Back to top
View user's profile Send private message
razer
l33t
l33t


Joined: 08 Oct 2004
Posts: 893
Location: Paris - France

PostPosted: Sun Aug 26, 2007 7:44 pm    Post subject: Reply with quote

mseigneurin wrote:
C'est pas bien compliqué et ca collerait bien avec ce que tu as déjà.
Le principe c'est qu'un "read" sur un fd en mode nonblock ne bloque jamais. 8O
S'il y a des choses à lire, il te les donne.
S'il y a rien, il rend tout de suite la main et positionne errno à EAGAIN (essaye-encore-une-fois).

Il te suffirait de faire les fnctl après que tu aies "forké" (dans le père), et dans ton
get_process, tu fais juste:
Code:

my $size = read(CHLDLOG, $chldmsg, 4096);
if ($size >0) {
  # y'a eu des donnes => gtk_machin
} elsif ($! == EAGAIN) {
  # le fils a rien dit, mais il tourne encore => progess_bar->clignotte("rouge");
} else {
  # le fils est terminé => progess_bar->tout_vert();
}


Merci bcp pour ton aide, je vais essayer çà dès que j'aurais un moment.
Juste un truc qui m'intrigue :
Code:
my $flags = $flags = fcntl(STATUS, F_GETFL, 0) || die "Peut pas lire les flags: $!";

équivalent à :
Code:
my $flags= fcntl(STATUS, F_GETFL, 0) || die "Peut pas lire les flags: $!";

Je présume :?: :?:
Back to top
View user's profile Send private message
Bob_Le_Mou
Tux's lil' helper
Tux's lil' helper


Joined: 17 Jun 2004
Posts: 114
Location: Pantin, France

PostPosted: Mon Aug 27, 2007 1:54 pm    Post subject: Reply with quote

Une solution à ce problème peut aussi être d'utiliser les possibilités offerte par le module Gtk2::Helper qui va te permettre de faire gérer par GTK2, l'accès et l'attente en sortie du pipe par la création d'un watch spécifique.

Malheureusement je ne peux pas tester ce code (pour l'instant), aussi, tu peux consulter ce lien , vers la fin du code inclus dans le paragraphe : GUI for converting flash videos in xvid dans lequel il y a un exemple de son utilisation.

\edit
Ce lien donne une autre manière permettant d'effectuer de la mise à jour de widget en temps réel, il y est expliqué que Gtk2::Helper ne serait qu'un wrapper de Glib::IO et l'auteur du thread y donne un exemple...
edit\
_________________
Rimouski, c'est loin-in d'ici...
Back to top
View user's profile Send private message
avendesora
Veteran
Veteran


Joined: 16 Aug 2002
Posts: 1739
Location: Betelgeuse vicinity

PostPosted: Mon Aug 27, 2007 4:13 pm    Post subject: Reply with quote

razer wrote:
mseigneurin wrote:

Code:
my $flags = $flags = fcntl(STATUS, F_GETFL, 0) || die "Peut pas lire les flags: $!";



Tu présumes bien... ca sent le copier/co'coller bégayeur... désolé.
Back to top
View user's profile Send private message
razer
l33t
l33t


Joined: 08 Oct 2004
Posts: 893
Location: Paris - France

PostPosted: Thu Aug 30, 2007 8:05 pm    Post subject: Reply with quote

De retour après quelques jours de vacances au bout du monde, je suis rassuré par la richesse des posteurs de ce forum.
J'ai vaguement testé la technique de mseigneurin sur mon laptop dans l'avion sans parvenir à éliminer un méchant plantage du process
Je manquais biensûr à ce moment de sources de doc et d'attention.
La piste de Bob_Le_Mou semble aussi intéressante, et même si rien n'est encore fonctionnel sur mon programme sans ioctl, je pense avoir suffisament de possibilités pour classer "résolu" ce thread.
Je vous informerais bien sûr lors de mes prochains progrets
Merci à vous
Back to top
View user's profile Send private message
Bob_Le_Mou
Tux's lil' helper
Tux's lil' helper


Joined: 17 Jun 2004
Posts: 114
Location: Pantin, France

PostPosted: Thu Aug 30, 2007 9:29 pm    Post subject: Reply with quote

Salut,

Un exemple en perl/Tk pas finalisé du tout qui peut (mal) illustrer le principe, ici, on utilise la méthode fileevent qui va "surveiller" le handle passé en paramètre et exécuter un callback:

$mw->fileevent($H, 'readable', [\&fill_text_widget, $t]);
On associe au widget $mw l'event file associé au filehandle $H lorsque celui-ci devient "lisible" executer "fill_text_widget($t)" ...

Le principe est quasi le même pour Gtk2::Helper->add_watch ...

Procédure appelée "compteur.pl" :

Code:
#!/usr/bin/perl -w
#
use strict; use warnings;
use IO::Handle;

STDOUT->autoflush(1);

for my $i (1..15)
{
   sleep 1;
   print "$i) I print this $i\n";
}
exit 0;


Procédure appelante : extkfilevent.pl
Code:

#!/usr/bin/perl

use strict; use warnings;
use IO::Handle;
use Tk;

my $H=IO::Handle->new;

open($H, "./compteur.pl |") or die "Nope: $!";

my $mw=new MainWindow;
$H->autoflush(1);

my $t = $mw->Text(-width => 80, -height => 25, -wrap => 'none');
$t->pack(-expand => 1);
$mw->fileevent($H, 'readable', [\&fill_text_widget, $t]);
MainLoop;
 

sub fill_text_widget {
 
    my($widget) = @_;
 
    my($stat, $data);
    $stat = sysread $H, $data, 4096;
    die "sysread error:  $!" unless defined $stat;
    $widget->insert('end', $data);
    $widget->yview('end');
 
}


Sur ce, bon courage...
_________________
Rimouski, c'est loin-in d'ici...
Back to top
View user's profile Send private message
razer
l33t
l33t


Joined: 08 Oct 2004
Posts: 893
Location: Paris - France

PostPosted: Fri Aug 31, 2007 4:03 pm    Post subject: Reply with quote

Encore merci, la solution Glib::IO->add_watch fonctionne parfaitement.
C'est nettement plus propre et efficace, de nombreuses lignes de code en moins (dont le require à l'origine du problème), et cela crée bien une interruption comme je le souhaitais.
J'ai maintenant une solution générique pour les barres de progression
Back to top
View user's profile Send private message
Bob_Le_Mou
Tux's lil' helper
Tux's lil' helper


Joined: 17 Jun 2004
Posts: 114
Location: Pantin, France

PostPosted: Fri Aug 31, 2007 4:31 pm    Post subject: Reply with quote

Salut,

Pourrais-je (entre)voir le code de ton projet ( ou du moins la partie concernant ce problème) ?
Parce que je suis curieux... Et j'ai un peu de mal avec les processus & les widgets...

\edit

Dans mon premier Post, je t'avais conseillé d'utiliser IO::Handle : ce n'est pas bien, le développeur de cette classe semble nous en décourager fortement :
Quote:
"IO::Handle" is the base class for all other IO handle classes. It is
not intended that objects of "IO::Handle" would be created directly,
but instead "IO::Handle" is inherited from by several other classes in
the IO hierarchy.

If you are reading this documentation, looking for a replacement for
the "FileHandle" package, then I suggest you read the documentation for
"IO::File" too.



J'ai tendance à faire confiance aux devs.

Et OUI, c'est vrai, j'avoue, je suis un GRAND fan du perl...
edit\
_________________
Rimouski, c'est loin-in d'ici...
Back to top
View user's profile Send private message
Display posts from previous:   
Reply to topic    Gentoo Forums Forum Index French All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum