Gentoo Forums
Gentoo Forums
Gentoo Forums
Quick Search: in
[Programmation] Créer un démon
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
DidgeriDude
Guru
Guru


Joined: 30 Jan 2005
Posts: 347

PostPosted: Wed Apr 04, 2007 7:12 am    Post subject: [Programmation] Créer un démon Reply with quote

Bonjour à tous.

Je ne sais pas si le titre correspond à ce que je veux mais il en fallait un...

Je cherche à créer un script qui lance une ou plusieurs application (par exemple amule) dès que la machine est "idle" depuis un certain temps.

J'ai trouvé sur le net un script en C nommé xprintidle basé sur les librairies de Xscreensaver permettant de récupérer le temps pendant lequel il n'y a eu aucune utilisation du clavier ou de la souris (ou tout autre activité sur les /dev/input*, si j'ai bien compris).
Malgré mes maigres connaissances en C, j'arrive tout doucement à le modifier afin qu'il lance une application (j'utiliserai amule comme exemple par la suite).
J'aimerais savoir s'il est possible de faire de ce script une sorte de démon qui tourne en fond dès que je me loggue sous X, ou que j'utilise startx, et qui, à intervalles réguliers, teste l' "idle time", vérifie si amule tourne déjà, et le lance ou le stoppe le cas échéant, ou ne fait rien.

En détails :
  • Si idle > XX minutes et amule pas lancé -> Lance amule.
  • Si idle > XX minutes et amule lancé -> Ne fait rien.
  • Si idle <= XX minutes et amule lancé -> Stoppe amule.
  • Si idle <= XX minutes et amule pas lancé -> Ne fait rien.

En fait, suivant la fréquence à laquelle ces tests sont effectués, certains ne seront pas utiles car le cas ne figure ne se présentera peut-être pas...

Voilà pourquoi j'ai pensé utiliser une sorte de démon bien que je n'aie pas la moindre idée de leur mode de fonctionnement, et encore moins de leur programmation...
J'ai également pensé à l'utilisation de crontab pour mon user, mais si j'ai bien compris, même si je ne suis pas en mode graphique, il va quand même lancer mon script... et j'aime pas faire faire à la machine quelque chose qui n'est pas logique.

Quelques questions pour finir :
  1. Peut-on m'expliquer la partie **argv, ou *argv[] pour passer des arguments à un programme en C ? (pour info, c'est OK pour moi les chaînes de carctères comme pointeur sur tableau de char).
  2. Comment tester dans un programme en C si une application est en train de tourner ? J'ai pensé à l'utilisation d'un fichier .pid, mais pour tester son existence en C, là je vois pas... Peut-on récupérer la sortie de la commande system si on fait un test, ou un cat ? A moins que des outils soient intégrés en C...
  3. J'aurais peut-être dû commencer par là : y a-t-il un autre moyen pour obtenir l' "idle time" de ma machine sans passer par ce soft en C et les librairies de Xscreensaver ? Si oui, cela me permettrait d'uiliser le bash, mais bon, refaire de la prog c'est bien aussi...
  4. Enfin, quel est le principe d'un démon, comment fonctionne-t-il pour exécuter certaines tâches périodiquement ?

Merci d'avance pour tout éclaircissement.
Fab.
Back to top
View user's profile Send private message
kwenspc
Advocate
Advocate


Joined: 21 Sep 2003
Posts: 4954

PostPosted: Wed Apr 04, 2007 7:43 am    Post subject: Reply with quote

1 - argv est un tableau de chaine comportant chacun des arguments passés à ton programme. (le tout premier indice étant le nom de ton programme). Tu as autant d'éléments qu'indique la variable argc. Pour la manipulation des arguments je te renvois directement sur getopt() et getopt_long() déclarés dans unistd.h (voir la page de man, suffisamment détaillée)

2 - popen() serait plus adéquat que system() [edit] ah sinon tester l'existence d'un fichier en C sous nux: stat() voir man 2 stat [/edit]

3 - sans doute :|

4 - principe d'un démon: un processus père lance un sous procéssus et quitte. Le sous-process est donc détaché du père et est récupéré par init. Le sous processus démarre une nouvelle session (appel setsid si mes souvenirs sont bons), il est alors détaché de la session parente initiale (le bash qui a executé le père par ex). Et là il peut tourner en tâche de fond indéfiniment même si tu te logges/delogges et tout. Pour le teste periodique si t'es pas à la recherche d'une précision digne d'une horloge suisse, tu endors le process via sleep(), et au réveil tu lui fait faire le boulot. (c'est vraiment le truc le plus basique qui soit, mais il est clair que c'est pas précis du tout)
_________________
membre officieux du SAV Ati GEntoo


Last edited by kwenspc on Wed Apr 04, 2007 7:52 am; edited 1 time in total
Back to top
View user's profile Send private message
Magic Banana
Veteran
Veteran


Joined: 13 Dec 2005
Posts: 1907
Location: Belo Horizonte, Minas Gerais, Brasil

PostPosted: Wed Apr 04, 2007 7:44 am    Post subject: Reply with quote

amule existe sans X. D'ailleurs tu peux le compiler en USE="-X". Regarde un peu sa documentation (mode daemon).

En testant en début de programme si X est bien lancé, tu peux sans problème utiliser un daemon cron.

1. La fonction main est du type "int main(int argc, char* arg[])" car elle reçoit en paramètre les arguments de la ligne de commande. argc est le nombre d'argument. arg est le tableau (de taille argc + 1) contenant en 0 le nom de la commande et, ensuite, les options.
2. Tester l'ouverture d'un fichier en C je ne sais pas trop mais en C++, rien de plus simple (intputFileName est un char*) :
Code:
ifstream inputFile;
intputFile.open(intputFileName);
if (intputFile.is_open())
  {
    // Ton code
  }

3. Je ne sais pas.
4. Tu peux, peut-être, utiliser la commande sleep.
Back to top
View user's profile Send private message
Ezka
Guru
Guru


Joined: 17 Feb 2005
Posts: 352
Location: par là, mais vraiment ...

PostPosted: Wed Apr 04, 2007 7:56 am    Post subject: Reply with quote

1) **argv = *argv[] l'un et l'autre sont des pointeur de pointeur. Par exemple : L'argument 0 de ton prog est à l'adresse argv[0], et cette adresse pointe sur un tableau contenant le nom de ton programme.

2) Le .pid c'est pas mal, tu testes juste l'ouverture du fichier : fopen(...) (man fopen)
Si l'ouverture echoue alors le fichier n'existe pas donc ton prog ne tourne pas. Il faut être propre sur le lancement et l'arret de ton prog est retirer ce fichier quand ton prog s'arrète.

3) Je ne sais pas :roll:
4) non plus :D

NB : amule comme le dit Magic a un mode demon :wink: man amule 8)
_________________
Ez.


Last edited by Ezka on Wed Apr 04, 2007 7:58 am; edited 1 time in total
Back to top
View user's profile Send private message
_droop_
l33t
l33t


Joined: 30 May 2004
Posts: 957

PostPosted: Wed Apr 04, 2007 7:57 am    Post subject: Reply with quote

Salut,

un script bash tout simple devrait le faire...

Par exemple :
Code:

while true
do
  #on dort pour ne pas user le processeur pour rien
  sleep 10
  #pas sur pour la sortie de xprintidle
  IDLETIME=`xprintidle`
  if [ $IDLETIME -gt 15 ]
  then
    pgrep amule &>/dev/null
    if [ "$?" == "0" ]
    then
      #on quitte amule : pkill c'est peut être pas très propre
      pkill amule
    fi
  else
    pgrep amule &>/dev/null
    if [ "$?" != "0" ]
    then
      #amule n'est pas lancé
      amule &
    fi
  fi
done


Après en lancant le script avec nohup ça fait un démon simple qui fait ce qu'il te faut...
Back to top
View user's profile Send private message
DidgeriDude
Guru
Guru


Joined: 30 Jan 2005
Posts: 347

PostPosted: Wed Apr 04, 2007 8:34 am    Post subject: Reply with quote

Merci à tous pour vos réponses.

@_droop_ : J'avais créé un script dans le genre... Mais ne connaisant pas pgrep, j'utilisais ps ax | grep ...., mais c'est moins propre...
Ce qui me gênait dans cette démarche, c'est que j'utilisais xprintidle à l'intérieur de mon script bash. Etant donné que j'avais les sources de celui-ci, autant tout faire dans le même fichier. Et puis c'était un challenge plus intéressant en C :D


@Magic Banana et Ezka : Je savais pour le mode démon d'amule mais c'était ici juste un exemple. Mon idée est de créer un soft permettant de lancer différentes applications en fonction d'un certain temps d'idle de la machine (D'ailleurs je passe le temps d'idle et le nom du prog en arguments...)

Concernant **argv, ou *argv[] qui sont la même chose, je pense avoir à peu près compris... Une question demeure :
Pourquoi des pointeurs de pointeurs afin de récupérer les différents arguments de la ligne de commande ? Est-ce lié au fait qu'on considère les arguments comme des éléments d'un tableau donc un pointeur sur leur ensemble, et comme chacun d'entre eux est succeptible d'être une chaîne de caractères, soit des pointeurs sur des tableaux de char, cela donne des pointeurs de pointeurs ? Mais alors dans ce cas, quel mécanisme impose que les différents arguments doivent être séparés par des espaces ? Peut-on protéger les arguments avec des espaces par des guillemets doubles, comme en bash ?
Back to top
View user's profile Send private message
Ezka
Guru
Guru


Joined: 17 Feb 2005
Posts: 352
Location: par là, mais vraiment ...

PostPosted: Wed Apr 04, 2007 9:49 am    Post subject: Reply with quote

Pour **argv :
tu peux protéger les espaces pour un \ ou utiliser les "" :
Code:
#include <stdio.h>
int main(int argc, char **argv)
{
  printf("Nb argument : %d\n", (argc-1));/*Pour ne pas compter l'argument 0 : nom du prog*/
}


tu compiles lance le tout et essaye avec :
1)
Code:
prog test des arguments

2)
Code:
prog "test des arguments"

3)
Code:
prog test\ des\ arguments


Dans l'exemple 1 le systeme passe l'adresse contenant la chaine de caractere "prog" en mémoire, au tableau de pointeur argv à l'indice 0, la chaine de char "des" à l'indice 1 etc ...
Ainsi ton tableau de pointeur argv contient les poitneurs sur les tableaux de char contenant tes argumens. Pense que si tu passes un chiffre en argument il devient un charactère, et qu'il te faudra le transformé en int/float/double... avant de t'en servir :wink:

Voila si ça peut t'aider :)
_________________
Ez.
Back to top
View user's profile Send private message
DidgeriDude
Guru
Guru


Joined: 30 Jan 2005
Posts: 347

PostPosted: Wed Apr 04, 2007 9:56 am    Post subject: Reply with quote

Ezka wrote:
Ainsi ton tableau de pointeur argv contient les poitneurs sur les tableaux de char contenant tes argumens. Pense que si tu passes un chiffre en argument il devient un charactère, et qu'il te faudra le transformé en int/float/double... avant de t'en servir :wink:


Ben justement, j'ai un warning à ce propos lors de la compilation de ce code :
C'est un brouillon, car j'en suis encore à la phase de compréhension du code et de la syntaxe C. Mes connaissances en programmation se limitant au pascal et au bash...

Code:
#include <X11/Xlib.h>
#include <X11/extensions/scrnsaver.h>
#include <stdio.h>

int main(int argc, char **argv)
{
    XScreenSaverInfo ssi;
    Display *dpy;
    int event_basep, error_basep, idle;
    char *prog = NULL;
   
    idle = argv[1];
    prog = argv[2];
    strcat(prog," &");

  dpy = XOpenDisplay(NULL);
  if (dpy == NULL) {
    fprintf(stderr, "couldn't open display\n");
    return 1;
  }
 
  if (!XScreenSaverQueryExtension(dpy, &event_basep, &error_basep)) {
    fprintf(stderr, "screen saver extension not supported\n");
    return 1;
  }
 
  if (!XScreenSaverQueryInfo(dpy, DefaultRootWindow(dpy), &ssi)) {
    fprintf(stderr, "couldn't query screen saver info\n");
    return 1;
  }
 
  printf("%lu\n%d", ssi.idle, idle);
  system(prog);
 
  XCloseDisplay(dpy);
  return 0;
}


Code:
$ make
testidle.c:32: attention : assignment makes integer from pointer without a cast
testidle.c:34: attention : incompatible implicit declaration of built-in function 'strcat'
Back to top
View user's profile Send private message
Ezka
Guru
Guru


Joined: 17 Feb 2005
Posts: 352
Location: par là, mais vraiment ...

PostPosted: Wed Apr 04, 2007 10:06 am    Post subject: Reply with quote

Pour
Code:
testidle.c:34: attention : incompatible implicit declaration of built-in function 'strcat'

Code:
#include <string.h>

:wink: il devrait comprendre strcat aprés ça. (man strcat)


Par contre pour :
Code:
testidle.c:32: attention : assignment makes integer from pointer without a cast

La tel que c'est : tu met dans idle, qui est un int, argv[1] qui est une chaine de char (-> un pointeur).

Si idle doit contenir un int il te faut "parser" ce que contient argv[1] pour en faire un int. Faire un truc comme ça : idle=(int)strtod(argv[1],NULL);

voilip

EDIT/ Tu as aussi : idle=atoi(argv[1]); ça va te convertir ton char en entier :wink: (man stdlib.h) ... mais pas sur que ça marche si tu lui passe autre chose qu'un chiffre (0...9)
_________________
Ez.
Back to top
View user's profile Send private message
Magic Banana
Veteran
Veteran


Joined: 13 Dec 2005
Posts: 1907
Location: Belo Horizonte, Minas Gerais, Brasil

PostPosted: Wed Apr 04, 2007 10:52 am    Post subject: Reply with quote

La fonction classique pour transformer un char* en un entier est atoi :
Code:
idle = atoi(argv[1]);


En fait il semble aussi qu'il y est une méthode strtoI encore plus mieux...

EDIT : Explication concernant le double pointeur sur argv. C'est une liste de chaînes de caractères (le pointeur le plus externe est le pointeur sur le premier élément) et ces chaînes de caractères sont, elles-mêmes, des listes de caractère (le pointeur le plus interne est le pointeur sur le premier caractère d'une chaîne).
Back to top
View user's profile Send private message
_droop_
l33t
l33t


Joined: 30 May 2004
Posts: 957

PostPosted: Wed Apr 04, 2007 11:12 am    Post subject: Reply with quote

DidgeriDude wrote:
@_droop_ : J'avais créé un script dans le genre... Mais ne connaisant pas pgrep, j'utilisais ps ax | grep ...., mais c'est moins propre...
Ce qui me gênait dans cette démarche, c'est que j'utilisais xprintidle à l'intérieur de mon script bash. Etant donné que j'avais les sources de celui-ci, autant tout faire dans le même fichier. Et puis c'était un challenge plus intéressant en C :D


En effet, le script me semble plus adapté. Après si tu t'interesses plus au challenge qu'à l'efficacité (de développement) : fais toi plaisir :wink:
Back to top
View user's profile Send private message
Ezka
Guru
Guru


Joined: 17 Feb 2005
Posts: 352
Location: par là, mais vraiment ...

PostPosted: Wed Apr 04, 2007 11:48 am    Post subject: Reply with quote

Magic Banana wrote:
En fait il semble aussi qu'il y est une méthode strtoI encore plus mieux...

Je la trouve pas celle-ci ! Enfin bon avec strtod ça crée donne en sortie un double ... "qui peut le plus, peut le moins" :roll:
_________________
Ez.
Back to top
View user's profile Send private message
nemo13
Veteran
Veteran


Joined: 08 Oct 2004
Posts: 1016
Location: France/Istres

PostPosted: Wed Apr 04, 2007 2:59 pm    Post subject: Reply with quote

_droop_ wrote:
En effet, le script me semble plus adapté. Après si tu t'interesses plus au challenge qu'à l'efficacité (de développement) : fais toi plaisir :wink:

je ne connais rien en script mais pourquoi tuer le processus ( qui peut mourrir +- salement ); ne serait-il pas suffisant de jouer sur la priorité ?
si je bosse sur mon clavier , amule --> nice d'escargot! sinon nice de ferrari ( bon pas troller sur la marque ) usw.
A+
Back to top
View user's profile Send private message
DidgeriDude
Guru
Guru


Joined: 30 Jan 2005
Posts: 347

PostPosted: Wed Apr 04, 2007 3:53 pm    Post subject: Reply with quote

Héhé, j'aurais dû prendre un autre exemple qu'amule...

Bon, si j'ai parlé d'amule, c'est parce qu'il bouffe toute ma bande passante montante (128Kb seulement). Malgré un QoS sur ma passerelle-firewall afin d'avoir une priorité maximale pour les paquets avec un drapeau ACK, la navigation internet est très très lente.

Mais je répète qu'amule est un exemple d'utilisation de ce script, que je veux plus général, même si l'idée m'est venue à propos d'amule...

J'avance un peu grâce à vos conseils, mais c'est lent (faut dire 2 marmots à la maison pour programmer ne permettent pas la plus grande assiduité au travail... Vivement qu'ils comprennent le C :lol:)
Back to top
View user's profile Send private message
dapsaille
Advocate
Advocate


Joined: 02 Aug 2004
Posts: 2366
Location: Paris

PostPosted: Wed Apr 04, 2007 4:03 pm    Post subject: Reply with quote

RHollaalalaalaaaa dire que j'avais pondu un truc comme ca ...

en bash et cron :p

top et ps -A était mes amis avec du grep cut awk explode et tout le bordel :p
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