Alternative au printf pour une fonction.

Résolu
glupidon -  
 glupidon -
Bonjour,

c'est de nouveau moi avec de nouveau une question bien tiré par les cheveux !

je cherche à créé une fonction qui exécutera des commande Linux tel que "pwd", "ls", "cd" ...

pour ce faire j'ai une fonction qui stocke dans une chaine de caractères (str) la commande à exécuter et je voudrais que la fonction ci-dessous se charge de l'exécuter.


int execut(char *str)
{
size_t size;
int status;
pid_t f;

my_putstr(str);
if ((read[strlen(str)-1] = '\0') <= 0)
{
my_putstr("error whith read in execut\n");
exit (1);
}
printf("%s\n" , read);
if((f = fork()) == 0)
{
execvp(read , &read);
exit(0);
}
else
wait(&status);
}


donc la c'est bien beau tout ça, mais le problème est là justement ...

je voudrais remplacer le printf par autre chose .

(je ne dois pas utilisé printf )

j'attends vos idées et conseilles avec impatiente ;-) !
A voir également:

3 réponses

fiddy Messages postés 11653 Statut Contributeur 1 847
 
Bonjour,

printf() n'est pas une commande linux. Tu confirmes que tu ne dois quand même pas l'utiliser ?
Si oui, tu peux utiliser write pour écrire sur la sortie standard.
0
glupidon
 
bonjour,
je confirme , pas de printf() !

ton idée concernant write() me plait bien, mais je ne vois pas trop comment faire pour que ce qui soit tapé au clavier soit intégré à ma chaine de caractère ...

tu peux me laisser un exemple ?

je pense se serait même super comme technique !

impatient de voir ce que ça donne
0
[Dal] Messages postés 6373 Statut Contributeur 1 106
 
Pardon de faire irruption dans votre échange, mais quelque chose me dit que la fonction my_putstr que tu utilises pour afficher la chaîne de caractères "error whith read in execut\n" doit utiliser cette même technique.

dans ton code le seul printf est celui-ci
printf("%s\n" , read);
et il affiche une chaîne de caractères

ton code ne permet pas de savoir exactement ce qu'il y a dans read, mais le code de my_putstr n'est-il pas adapté pour faire cela ?

Dal
0
glupidon
 
Bonjour [Dal]

le my_putstr() etait la pour m'aider lors de mon codage mais j'ai oublier de le retiré donc il ne faut pas le compter comme appartenant a ma fonction enfaite ...
merci de me le faire remarqué !

je cherche pas a afficher enfaite , je voudrais que ce que je tape au clavier soit direct stocker dans une string .
0
glupidon
 
j'ai pas mal modifier mon code donc voici la version 2.0 qui n'est toujours pas aboutis sur du concret pour le moment ...


int my_request()
{
char *str;

if ((str = malloc(sizeof(str))) <= 0)
eromalloc();
my_putstr("\n=> ");
if (read(0, str, 1000) <= 0)
eroread();
if (str == NULL)
my_request();
execute(str);
return (0);
}

int execute(char *str)
{
if ((read[strlen(str)-1] = '\0') <= 0)
eroread();

if ((f = fork()) == 0)
{
execve();
exit (0);
}
else
sleep (2);
}


la fonction my_request affiche un prompt et attend une commande
la fonction exécute va exécuter la commande taper dans my_request !

j'utilise expré "execve()" mais j'ai du mal avec ...
le man me dit :

int execve(const char *filename, char *const argv[], char *const envp[]);

ont peu exécuter des commande avec ?
filename correspond a quoi du coup?

je voudrais que mon programme soit exécutable sur d'autre environnement que le mien avec sa ....
je commence a être un peu perdue ....
0
fiddy Messages postés 11653 Statut Contributeur 1 847
 
Ce n'est pas en utilisant des fonctions POSIX (comme read()) que ton programme fonctionnera sur d'autres environnements. C'est là tout l'intérêt des fonctions ISO que tu ne peux pas utiliser.
Néanmoins, bon nombres d'OS sont POSIX.
Pour écrire sur stdout :
write(STDOUT_FILENO, "Coucou\n", 7);
0
glupidon
 
Bonjour Fiddy ,

les fonctions POSIX ne poseront pas de problème , les environnements en question sont tous basé Linux.

d'après toi comment je devrez m'y prendre ?
uniquement pour les deux fonctions posté plus haut .

je ne parvient pas a comprendre comment faire pour que une fois ma string remplie avec ce qui est tapé aux clavier , elle puisse être exécuter sans l'aide de printf() .
(avec bien entendu de multiple contrôles qui me reste a coder en amont)

une idée ?
je continue de cherché de mon coté !
0
glupidon
 
enfin du code concret mais pas encore compilable .
voici la version 3.0 ou du moins ce que je suis parvenue a faire pour réaliser le but de ce topique ...


int my_request()
{
char *str;

if ((str = malloc(sizeof(str))) == 0)
eromalloc();
my_putstr("\n=> ");
if (read(0, str, 1000) <= 0)
eroread();
if (str == NULL)
my_request();
life_time(str);
return (0);
}

int life_time(char *str)
{
int i;
char *variable;

variable = getenv(str);
if (!variable)
not_found();
else
find_path(str);
return (0);
}

int find_path(char *str)
{
int i;
int j;
char way[20];
char name[10];

i = 0;
j = 8;
way[20] = "/usr/bin/";
while (str[i] != '\0')
{
if (str[i] == ' ')
{
name[i] = '\0';
way[j] = '\0';
execute(way, str, name);
}
name[i] = str[i];
way[j] = str[i];
i++;
j++;
}
}

int execute(char way[20], char *str, char name[10])
{
execve(way, name, envp);
}
0
glupidon
 
dans l'ordre donné .
j'attends une commande, je vérifie sont existence, je crée une string qui contient son chemin et une autre avec son nom , puis je l'exécute .

seulement je bloque sur exécute car le dernier paramètre a donner a execve() me laisse sur ma faim .

d'après le man je doit lui donner sa
char *const envp[]

mais je voie pas trop a quoi sa correspond
0
glupidon
 
j'ai corriger les quelques petit erreurs qui rester dessus
maintenant quand je compile il me dit que je peut pas intégrer des chaines de caractère en tant que paramètre pour execve() ...

es vraiment impossible ?
0
[Dal] Messages postés 6373 Statut Contributeur 1 106
 
Juste sur ta question relative à
char *const envp[]
. C'est un tableau de chaînes de caractères (donc un tableau de pointeurs pointant sur des chars terminés par \0), terminé par NULL.

Les variables d'environnement sous Linux sont du type
USER=dal
.

Alors, tu peux :

1- passer NULL si tu n'as pas besoin de variables d'environnement particulières,
2- ou définir la liste de variables d'environnement qui sont nécessaires à ton programme,
3- ou emprunter celles de ton programme en utilisant la variable environ définie par unistd.h

Voilà un code illustrant les façons de faire 2 et 3 (la 1 est triviale), et affichant le contenu du tableau de chaînes de caractères dans les deux cas :

#include <stdio.h>
#include <unistd.h>

int main(void)
{
    int n;
    char *const envp[] = {"USER=dal","USERNAME=dal", "PATH=/usr/local/bin:/usr/bin:/bin", "LANG=fr_FR.UTF-8", NULL};
    extern char **environ;

    /* énumération de envp */
    printf("Mon environnement concocté :\n\n");
    n=0;
    while(envp[n]) {
        printf("%s\n", envp[n]);
        n++;
    }

    /* énumération de environ */
    printf("\nL'environnement de lancement de mon exécutable:\n\n");                                                                                                                                               
    n=0;
    while(environ[n]) {
        printf("%s\n", environ[n]);
        n++;
    }

    return 0;
}


note que
char *const argv[]
(2ème paramètre) a la même nature et doit contenir le nom de l'exécutable suivi de ses arguments et terminé par NULL

par exemple :
char *const my_argv[] = {"/bin/ls", "-l", "/home/dal", NULL};
...

Enfin, execve ne retourne pas (sauf erreur). Si tu veux que ton programme exécute plus d'une commande, il faudra utiliser fork.

Vois : http://geoffgarside.co.uk/2009/08/28/using-execve-for-the-first-time/ pour une explication de ce qui arrive sans et avec fork

et plein d'autres ressources sur Internet expliquant comment utiliser execve ou des fonctions de cette famille pour fabriquer un mini shell en utilisant ces fonctions

execvp serait peut-être moins difficile à utiliser car elle va rechercher le nom de l'exécutable passé dans le PATH pour toi, ce que ne fait pas execvp


Dal
0
Utilisateur anonyme
 
parfait !
vraiment bien comme explication !
je te remercie Dal !
je vais regarder tout sa avec attention !

(oui j'ai changer de pseudo glupidon == astrocurieux)
la différence c'est que je suis inscris a présent !
0
Utilisateur anonyme
 
donc d'après ce que je comprend : la solution 3 me permet de prendre automatiquement la variable d'environnement de la machine qui a lancer mon programme ! sa c'est super cool !

note que
char *const argv[]
(2ème paramètre) a la même nature et doit contenir le nom de l'exécutable suivi de ses arguments et terminé par NULL


effectivement je l'avait pas vue tel qu'elle de mon coté !
mais qu'elle sont les arguments ? je ne comprend pas ...
0