Rediriger stderr vers une fonction

Le
cLx
Bonjour,

J'ai dans mon programme et pas mal de ses modules des messages d'erreurs qui
sont envoyés avec fprintf(stderr, );.

Le truc c'est que maintenant qu'on fait une belle interface avec Curses, on
voudrait afficher les messages d'erreur dans une fenêtre pour. Serait-il
possible de rediriger stderr (et stdout) vers une fonction, même via un pipe,
un peu comme freopen mais pas vers une fichier ?

Merci,

--
cLx
Vidéos High-Tech et Jeu Vidéo
Téléchargements
Vos réponses
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
Jean-Marc Bourguet
Le #23676991
cLx
J'ai dans mon programme et pas mal de ses modules des messages d'erreurs qui
sont envoyés avec fprintf(stderr, ...);.

Le truc c'est que maintenant qu'on fait une belle interface avec Curses, on
voudrait afficher les messages d'erreur dans une fenêtre pour. Serai t-il
possible de rediriger stderr (et stdout) vers une fonction, même via un pipe,
un peu comme freopen mais pas vers une fichier ?



Rien en standard. Glibc a une notion de "custom stream" (voir le
manuel) mais c'est donc pratiquement que sous Linux et je n'ai pas le
souvenir de quelquechose d'equivalent ailleurs.

A+

--
Jean-Marc
FAQ de fclc: http://www.levenez.com/lang/c/faq
Site de usenet-fr: http://www.usenet-fr.news.eu.org
Xavier Roche
Le #23677121
Le 23/08/2011 14:20, cLx a écrit :
Le truc c'est que maintenant qu'on fait une belle interface avec Curses, on
voudrait afficher les messages d'erreur dans une fenêtre pour. Serait-il
possible de rediriger stderr (et stdout) vers une fonction, même via un pipe,
un peu comme freopen mais pas vers une fichier ?



Il suffit de reassigner le handle 2 (pour stderr - ou 1 pour stdout)
vers autre chose, comme.. un pipe, et de créer un thread qui ira lire
dessus:

const int errFd = 2;
int pipeFds[2];
if (pipe(pipeFds) == 0) {
const int rFd = pipeFds[0];
const int wFd = pipeFds[1];
if (dup2(wFd, errFd) == 0) {
.. créer un thread de fond pour lire les données depuis rFd
} else {
.. blah
}
} else {
.. blah
}
Xavier Roche
Le #23677241
Le 23/08/2011 14:20, cLx a écrit :
Le truc c'est que maintenant qu'on fait une belle interface avec Curses, on
voudrait afficher les messages d'erreur dans une fenêtre pour. Serait-il
possible de rediriger stderr (et stdout) vers une fonction, même via un pipe,
un peu comme freopen mais pas vers une fichier ?



Il suffit de reassigner le handle 2 (pour stderr - ou 1 pour stdout)
vers autre chose, comme.. un pipe, et de créer un thread qui ira lire
dessus:

const int errFd = 2;
int pipeFds[2];
if (pipe(pipeFds) == 0) {
const int rFd = pipeFds[0];
const int wFd = pipeFds[1];
if (dup2(wFd, errFd) == 0) {
close(wFd);
.. créer un thread de fond pour lire les données depuis rFd
} else {
.. blah
}
} else {
.. blah
}
Xavier Roche
Le #23677231
Le 23/08/2011 14:20, cLx a écrit :
Le truc c'est que maintenant qu'on fait une belle interface avec Curses, on
voudrait afficher les messages d'erreur dans une fenêtre pour. Serait-il
possible de rediriger stderr (et stdout) vers une fonction, même via un pipe,
un peu comme freopen mais pas vers une fichier ?



Il suffit de reassigner le handle 2 (pour stderr - ou 1 pour stdout)
vers autre chose, comme.. un pipe, et de créer un thread qui ira lire
dessus:

const int errFd = fileno(stderr); /* en théorie 2 :) */
int pipeFds[2];
if (pipe(pipeFds) == 0) {
const int rFd = pipeFds[0];
const int wFd = pipeFds[1];
if (dup2(wFd, errFd) == 0) {
close(wFd);
.. créer un thread de fond pour lire les données depuis rFd
} else {
.. blah
}
} else {
.. blah
}
cLx
Le #23677221
On 23/08/2011 14:41, Jean-Marc Bourguet wrote:
Rien en standard. Glibc a une notion de "custom stream" (voir le
manuel) mais c'est donc pratiquement que sous Linux et je n'ai pas le
souvenir de quelquechose d'equivalent ailleurs.



OK, donc pas trop portable.. Merci.
cLx
Le #23677331
On 23/08/2011 15:23, Xavier Roche wrote:
Le 23/08/2011 14:20, cLx a écrit :
Le truc c'est que maintenant qu'on fait une belle interface avec Curses, on
voudrait afficher les messages d'erreur dans une fenêtre pour. Serait-il
possible de rediriger stderr (et stdout) vers une fonction, même via un pipe,
un peu comme freopen mais pas vers une fichier ?



Il suffit de reassigner le handle 2 (pour stderr - ou 1 pour stdout)
vers autre chose, comme.. un pipe, et de créer un thread qui ira lire
dessus:

const int errFd = fileno(stderr); /* en théorie 2 :) */
int pipeFds[2];
if (pipe(pipeFds) == 0) {
const int rFd = pipeFds[0];
const int wFd = pipeFds[1];
if (dup2(wFd, errFd) == 0) {
close(wFd);
.. créer un thread de fond pour lire les données depuis rFd
} else {
.. blah
}
} else {
.. blah
}




Merci pour votre réponse.

Sous Linux et NetBST ça marche ! mais sous windows (gcc et sans gygwin), il
me manque cruellement pipe().
Xavier Roche
Le #23677321
Le 23/08/2011 15:37, cLx a écrit :
Sous Linux et NetBST ça marche ! mais sous windows (gcc et sans gygwin), il
me manque cruellement pipe().



Il faut utiliser la variante _pipe()
http://msdn.microsoft.com/en-us/library/edze9h7e%28v=vs.71%29.aspx
Antoine Leca
Le #23677441
Xavier Roche écrivit :
const int errFd = fileno(stderr); /* en théorie 2 :) */



On peut aussi alourdir (?) avec STDERR_FILENO }:->


Antoine
Mickaël Wolff
Le #23694611
On 23/08/11 14:20, cLx wrote:
Bonjour,

J'ai dans mon programme et pas mal de ses modules des messages d'erreurs qui
sont envoyés avec fprintf(stderr, ...);.



Si l'ensemble des appels à fprintf sur stderr doivent aterrir dans
une fenêtre de log, peut-être que tu pourrais simplement faire un grep
sur l'ensemble du projet :


find . -name '*.c' -exec
sed -i 's/bfprintf(stderr, /log_error(/' {} ;

Bien sûr il faut une fonction dans ce style là (implémentation naïve,
je ne suis pas convaincu que ce soit canonique, les variadiques à la C
me rendent nerveuses) :

int log_error(char * fmt, ...)
{
int ret = 0 ;
va_list args ;
va_start(args, fmt) ;
ret = vfprintf(stderr, fmt, args) ;
va_end(args) ;
return ret ;
}
Publicité
Poster une réponse
Anonyme