Forum Programmation.c ecrire la liste des processus utilisateurs dans un fichier texte

Posté par  .
Étiquettes : aucune
0
8
août
2004
Salut à tous,
j'ai un problème, j'aimerai écrire la liste des processus d'un utilisateur dans un fichier et recuperer aléatoirement deux de ces numeros. je suis bloqué au niveau de la création du fichier. J'utilise le code suivant:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>

int main ()
{
/* Liste des arguments passés à l'appel system execvp*/
char* arg_list[] = {
"ps", /* nom du programme.*/
"-u",
"gadiri", //nom d'un utilisateur
"-o",
"pid",
"--no-headers",
">id_proc.txt", /* redirection vers le fichier où je veux mettre les resultats */
};
/*Le processus courant execute l'appel system qui va executer
la commande ps en lui passant arg_list*/
execvp("ps", arg_list) ;
return 0;
}

ce programme compile mais n'exécute pas, je pense que c'est du à la redirection, mais je ne vois pas comment proceder autrement. Si qcqu'un peut m'aider je lui en serai très reconnaissant
merci
gadiri
  • # Utiliser un shell

    Posté par  (site web personnel) . Évalué à 2.

    Au lieu de ps tu appelles sh et tu lui fais executer ps.
    Pourquoi passer par un programme en C pour faire ça ?
    • [^] # Re: Utiliser un shell

      Posté par  . Évalué à 1.

      je veux implementer un appel systeme qui, qd il sera invoqué, ira ecrire la liste des processus du user dans le fichier spécifié.
      merci encore pour l'aide
      • [^] # Re: Utiliser un shell

        Posté par  (site web personnel) . Évalué à 2.

        un appel système ne devrait ni passer par sh (tu en as besoin si tu veux rediriger la sortie, comme dit pterjan - sinon tu dois ouvrir et écrire toi même le fichier) ni par ps, mais se servir des informations données par le noyau directement.
  • # J'ai réussi à l'exécuter,

    Posté par  . Évalué à 1.

    en changeant la ligne
    "ps", /* nom du programme.*/
    en
    "/bin/ps", /*nom du programme.*/

    Et en changeant la liste des options :
    ">id_proc.txt", /* redirection vers le fichier où je veux mettre les resultats */
    };

    est devenu :

    ">id_proc.txt", /* redirection vers le fichier où je veux mettre les resultats */
    NULL
    };
    En effet, la page de man des fonctions exec indique :
    "The list of arguments must be terminated by a NULL pointe"

    Pour autant, ça ne donne pas le résultat escompté puisque le >id_proc.txt est compris pas la commande ps comme une option, et on se retrouve à l'exécution de l'affichage de l'aide de base de la commande ps. Aux gourous de faire mieux, ça me dépasse, pour l'instant (le coup de récupérer la sortie standard, je ne sais pas trop non plus comment faire).

    Une autre piste serait peut-être d'exploiter le répertoire /proc, non ?
  • # Youpla tu a lu trop vite mon gars

    Posté par  (site web personnel) . Évalué à 5.

    Les redirections de flux E/S via les symboles > < sont une specificité du SHELL.
    Donc soit tu fait un script shell, ce qui soit dit en passant serait bien plus logique qu'un programme en C,
    soit tu fait un script shell que tu passe en parametre a un shell (ex via bash -e) dans ton programme C (encore plus ridicule que le programme en C),
    soit tu utilise une librairie genre libgtop ou autre si tu a vraiment besoin de code en C ce dont je doute,
    soit tu utilise les appels systemes directement pour faire cela.
  • # System

    Posté par  . Évalué à 2.

    Hello, tu peux aussi te simplifier la vie en utilisant la commande "system" !
    (cf. http://www.rt.com/man/system.3.html(...))

    system("ps -u gadiri -o pid --no-headers > id_proc.txt");

    Simplissime, non ?

    La seule contrainte, c'est de ne pas le faire dans un programme multi-thread, car ce n'est pas une fonction sûre...

    Euh, éventuellement, il faudra préciser les chemins complets, pour ps et pour ton fichier... A tester !

    @++
    • [^] # Re: System

      Posté par  . Évalué à 1.

      ça marche très bien. C'est pas une application multithreads. donc tt va bien
      merci
      a+
      • [^] # Re: System

        Posté par  . Évalué à 2.

        Toutefois je ne recommenderais cette solution qu'en dernier recours : en effet system ce fork puis exec un shell qui va lui executer ta commande.

        Ce qui est vraiment lourd vu l'effet recherché !

        La "bonne" méthode serait surrement de faire un fork puis de closer la sortie standard (handle 1) et de la rouvrir en utilisant le fichier de sortie, puis de faire un exec. (c'est ce que le shell fait après avoir parsé la commande)
        • [^] # Re: System

          Posté par  . Évalué à 2.

          J'ai déjà fait une fois un code de ce genre-là, malheureusement je ne l'ai pas sous la main. La solution que j'avais employé, et qui était très efficace, était de parcourir bêtement /proc. Dans ton cas, tu n'auras qu'à faire :

          int i;
          struct stat buffer;
          #define MAX_PID 32768
          #define UID_UTILISATEUR /* ha ben je ne sais pas, moi! tape "id" dans un shell */
          for(i=&;i<MAX_PID;i++){
          sprintf(chemin,"/proc/%d",i);
          if((stat(chemin,&buffer)!=-1) && (buffer.st_uid==UID_UTILISATEUR)){
          mettre_dans_fichier(i);
          }
          }

          Bon, c'est juste un code sale, pour te montrer comment ça marche, pour faire cela proprement, il faudrait par exemple récupérer MAX_PID au niveau des symboles exportés par le noyau (je crois qu'il se trouve là...).


          • [^] # Re: System

            Posté par  . Évalué à 2.

            Ca c'est marrant, le CoinKoin a oublié la balise fermante < / p r e >. On le condamne à aller au Coin?
          • [^] # Re: System

            Posté par  . Évalué à 1.

            merci pour cette solution, vous m'avez bien aidé.
          • [^] # Re: System

            Posté par  . Évalué à 1.

            j'ai essayé mais j'ai pas reussi à obtenir qcqchose. mais je ne maitrise pas très bien le c. J'ai utilisé un malloc pour allouer de la mémoire au struct, mais y'a pleins d'erreurs. j'essaye encore.
            • [^] # Re: System

              Posté par  . Évalué à 2.

              >J'ai utilisé un malloc pour allouer de la mémoire au struct, mais y'a pleins d'erreurs. j'essaye encore.

              Pas besoin de malloc! A mon avis, le code que je t'ai donné est "sale", c'est-à-dire qu'il n'est pas codé proprement (par exemple, le chemin "/proc" ne devrait pas s'y trouver en dur, mais faire l'objet d'un #define, lui aussi), mais il est parfaitement fonctionnel.

              En revanche, il faut que tu effectues les #include nécessaires, et je pense que c'est ça que tu as oublié. Ces #include sont décrits en détail en haut des pages de "man" correspondant aux appels système employés, ici stat() (et sprintf(), même si ce n'est pas un vrai appel-système).

              "man 2 stat" donne :
               #include <sys/types.h>
              #include <sys/stat.h>
              #include <unistd.h>

              ("man 2 stat", parce que man stat, c'est juste pour la commande shell "stat").

              Pour sprintf, il faut sans doute ajouter #include <stdio.h> , et peut-être #include <string.h> (je n'ai pas de man 3 installé, actuellement, or sprintf est décrite dans une page de la section 3 du man, donc je ne suis pas sûr).

              Sache aussi que ces #include doivent être placés au tout début de ton fichier.

              En conclusion, si tu es débutant en C, sache que les pages de man, man 2 et man 3 surtout, sont particulièrement utiles à la programmation dans ce langage. Même si leur lecture, au début, est fastidieuse...
              • [^] # Re: System

                Posté par  . Évalué à 1.

                merci beaucoups, j'ai pu le faire fonctionner
                a+

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.