2010-09-07 5 views
0

J'utilise appel select() pour détecter la présence d'entrée dans le cycle principal de mon programme. Cela me fait utiliser le descripteur de fichier brut (0) au lieu de stdin. En travaillant dans ce mode, j'ai remarqué que mon logiciel perd parfois une partie de l'entrée au début. Je soupçonne que stdin en consomme une partie au démarrage du programme. Est-il possible d'empêcher ce comportement de stdin ou d'obtenir toutes les données d'entrée?Comment empêcher le flux stdin de lire les données du descripteur de fichier associé au démarrage du programme?

L'effet décrit ne peut être reproduit qu'avec certaines données sur l'entrée standard au moment même du démarrage du programme. Mon exécutable doit être utilisé en tant que service xinetd de manière à avoir toujours une entrée au démarrage.

entrée standard est lu de la façon suivante:

Error processInput() { 
    struct timeval ktimeout; 
    int fd=fileno(stdin); 
    int maxFd=fd+1; 
    FD_ZERO(&fdset); 
    FD_SET(fd, &fdset); 
    ktimeout.tv_sec = 0; 
    ktimeout.tv_usec = 1; 
    int selectRv=-1; 
    while ((selectRv=select(maxFd, &fdset, NULL, NULL, &ktimeout)) > 0) { 
    int left=MAX_BUFFER_SIZE-position-1; 
    assert(left>0); 
    int bytesCount=read(fd, buffer+position, left); 
    //Input processing goes here 
    } 
} 
+1

Pouvez-vous poster du code pertinent? – Hasturkun

+0

Un pseudocode a été ajouté pour illustrer un processus de lecture d'entrée. – Basilevs

+1

Pourquoi même référence 'stdin' du tout? Pourquoi ne pas utiliser 'int fd = 0', ou peut-être' int fd = STDIN_FILENO'? –

Répondre

1

Ne pas mélanger la viande crue et cuite ensemble. Essayez de remplacer l'appel read() par l'appel fread() équivalent.

Il est très probable que fileno(stdin) initialise l'objet stdin, l'amenant à lire et à mettre en tampon certaines entrées. Ou peut-être appelez-vous quelque chose qui l'initialise (scanf(), getchar(), etc ...).

+0

Peut-être qu'il devrait aller dans l'autre sens, et éviter Fileno (stdin). Au lieu de cela, utilisez le nombre fd bien connu de zéro pour stdin. – Darron

+0

Juliano, vous voulez dire qu'il y a une interface asynchrone pour les flux en C? Pouvez-vous s'il vous plaît référencer un manuel à ce sujet? – Basilevs

+0

@Basilevs: C'est la même interface, en fait. Utilisez fread() uniquement si vous savez qu'il y a quelque chose à lire (après un retour réussi de select()) et que vous allez effectuer une communication asynchrone. Vous pouvez également définir O_NONBLOCK dans le descripteur de fichier en utilisant fctrl(), pour garantir que fread() retournera EAGAIN s'il n'y a rien à lire à partir de ce descripteur. – Juliano

Questions connexes