Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » GNU/Linux » Workaround für C-Problem gesucht

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 < [ 2 ]
000
19.06.2004, 17:44 Uhr
~Gwar
Gast


Hallo zusammen,

ich habe ein kleines Problem in C und frage mich, ob jemand die Lösung dafür weiss:

Folgendes Programm simuliert das Problem:

C++:
#include <stdio.h>
#include <signal.h>
#include <fcntl.h>
#include <stdlib.h>

int main(void)
{
   int fd;
   FILE *f;
   char *befehl;

   void alrmHndlr(int sig)
   {
      signal(SIGALRM, SIG_DFL);
      printf(" :-( \n");
      free(befehl);

      /*Kritischer Punkt*/
      fclose (f);
      close(fd);

      exit(0);
   } /* of Handler */

   fd = 0;
   f = fdopen (fd, "r+");

   printf(" :-) \n");

   befehl = malloc(1024);
   signal(SIGALRM, alrmHndlr);

   alarm(2);

   while(fgets(befehl, 1024, f) != 0)
   {

      printf("Befehl:%s\n", befehl);

   } /* of while */
}/* of main */




Die while-Schleife wartet auf die Standardeingabe.
Währenddessen wird aber alarm() ausgeführt und der Stream f soll geschlossen werden. Dieser scheint aber vom System nicht als bereit zum Schließen markiert zu sein, so dass Valgrind folgenden Fehler anzeigt:


Code:
valgrind: the `impossible' happened:
poll_for_ready_fds: select failed?!
Basic block ctr is approximately 150000

sched status:

Thread 1: status = Runnable, associated_mx = 0x0, associated_cv = 0x0
==3190== at 0x4017DF64: vgPlain___libc_freeres_wrapper (vg_intercept.c:870)
==3190== by 0x804A10D: alrmHndlr.0 (command.c:141)
==3190== by 0x4017C7EF: ??? (vg_hashtable.c:213)
==3190== by 0x402BEFE7: _IO_file_underflow@@GLIBC_2.1 (in /lib/libc-2.3.2.so)



Was ich bräuchte währe als entweder eine Möglichkeit, die while-Schleife zu verlassen oder zu signalisieren, dass das Programm nicht mehr auf fgets warten soll.

Danke im Vorraus,
Gwar
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
19.06.2004, 18:00 Uhr
typecast
aka loddab
(Operator)


Das ist leider kein ANSI, sondern Linux spezifisch. Deshalb

Ich schau mir den Code nach dem Spiel an :-)
--
All parts should go together without forcing. ... By all means, do not use a hammer. (IBM maintenance manual, 1925)

Dieser Post wurde am 19.06.2004 um 18:02 Uhr von typecast editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
19.06.2004, 18:15 Uhr
~Gwar
Gast


Ok, danke und sorry für's Posten in das Falsche Forum.

Gruß,
Gwar
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
19.06.2004, 20:09 Uhr
typecast
aka loddab
(Operator)


Nicht weiter schlimm.

Was willst du denn machen? Der Filedescriptor mit der Nummer 0 ist der stdin-Kanal. Das heißt du brauchst den nicht extra mit fdopen an einen stream zu binden.

Du kannst auch direkt mit stdin arbeiten. Entweder mit

C++:
scanf(..);


oder mit

C++:
fscanf(stdin, ...);



Schließen, so wie du mit close(fd) vorhast darfst du nicht machen. Du willst den stdin nicht zumachen (oder solltest es nicht wollen :-)).

Außerdem ist es afaik gar nicht möglich das zu machen.
--
All parts should go together without forcing. ... By all means, do not use a hammer. (IBM maintenance manual, 1925)
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
19.06.2004, 20:18 Uhr
~Gwar
Gast


Hi,

Ich hätte natürlich erwähnen sollen, dass das hier nur eine Abbildung des eigentlichen Programms ist.
Im realen Programm wird ein Filedeskriptor übergeben - ein anderer als die Standard Eingabe. Da der Quellcode des realen Programms aber zu lang ist um das Problem darzustellen habe ich ein Programm geschrieben, das den Fehler auf die gleiche Art und Weise reproduziert.

Man könnte im Prinzip jeden beliebigen Filedescriptor nehmen um den Fehler zu verursachen.

Um die Frage zu beantworten, was ich im realen Programm machen will:

Ich möchte einen Pop 3 Server programmieren. Da wird über eine Socketanbindung ein FD an eine Methode übergeben. Die while - Schleife mit dem fgets() dient dem Einlesen der Befehle. Der alarm dient dazu, dass die Verbindung nach einem Festgelegten Timeout wieder getrennt wird.

Dank und Gruß,
Gwar
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
19.06.2004, 20:42 Uhr
typecast
aka loddab
(Operator)


Könntest du dann mal kurz eine kurze Auflistung geben was alles für Fildeskriptoren und streams offen sind und welche nach dem SIGALARM geschlossen werden.
Hilfreich wäre auch, wenn du schreibst, welche auf die selbe Datei zeigen.
--
All parts should go together without forcing. ... By all means, do not use a hammer. (IBM maintenance manual, 1925)

Dieser Post wurde am 19.06.2004 um 20:42 Uhr von typecast editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
19.06.2004, 20:51 Uhr
typecast
aka loddab
(Operator)


Übrigens mir fällt gerade was besseres ein:

Überprüfe einfach mal, ob irgendwelche Dateien vom System gesperrt wurden
(ungetestet)

C++:
#include <fcntl.h>
...
struct flock lock
fcntl(fd, F_GETLK, &lock);
if(lock.l_type==F_UNLCK)
    fprintf(stderr, "Datei nicht gesperrt");
else if(lock.l_type==F_RDLCK)
    fprintf(stderr, "Lesesperre");
else if(lock.l_type==F_WRLCK)
    fprintf(stderr, "Schreibsperre");
...


--
All parts should go together without forcing. ... By all means, do not use a hammer. (IBM maintenance manual, 1925)
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
007
19.06.2004, 20:57 Uhr
~Gwar
Gast


klar...

Der Methodenkopf sieht so aus:

Code:
int popcmd(int infd, int outfd)



um zeilenweise einlesen zu können folgt in der Methode dann:


Code:
FILE *infile;
(...)
infile = fdopen(infd, "r");
assert(infile);    



Das war es an Filedescriptoren und Streams.

Übergeben wird der Methode popcmd sowohl für infd als auch für outfd der von der TCP Socketanbindung erzeugte Filedescriptor (ist ja möglich, da TCP Voll-Duplexfähig ist).

Im Sigalarm soll dann infile geschlossen werden. Soweit ich weiß wird dadurch dann auch infd und outfd da infile ja durch fdopen erzeugt wird.

Ich hoffe das waren die Infos, die Du brauchtest.

Gruß,
Gwar
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
008
19.06.2004, 20:58 Uhr
~Gwar
Gast


Danke für den Tip!!

Muss ich dann am Linux Rechner mal testen... ich werde Dich über die Ergebnisse am Laufen halten.

Gruß
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
009
19.06.2004, 21:08 Uhr
typecast
aka loddab
(Operator)


Eins hab ich noch nicht verstanden: Du sagst, dass infd und outfd von einer TCP-Verbindung kommen. Wie soll ich das verstehen? Hast du eine Verbindung zum lesen und eine um schreiben geöffnet (geht das überhaupt?) oder hat du zwei Verbindungen zum Server geöffnet?

Sowohl den Sinn des einen als auch des anderen könnte ich nicht verstehen. Deshlab vermute ich, dass ich dich nicht richtig verstanden habe.
--
All parts should go together without forcing. ... By all means, do not use a hammer. (IBM maintenance manual, 1925)
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 < [ 2 ]     [ GNU/Linux ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: