Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (GNU/Linux, *NIX, *BSD und Co) » Userabhängige Reaktion

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 <
000
21.05.2007, 14:28 Uhr
~dadevelopa
Gast


Hallo zusammen,
ich habe ein kleines Problem mit einem Programm welches Username, Hostname und Zeit in welcher der User nicht an der Maschine war ausliest.
Das ganze Programm läuft als Daemon und soll in bestimmten Intervallen die ausgelesenen Daten an einen Server senden. Soweit so gut, das funktioniert auch, wenn ich mich Remote auf einer Maschine einlogge und den Daemon starte.
Jedoch wenn die Person, welche nun Physisch an dieser Maschine sitzt den Daemon startet, landet dieser zwar in meiner endlosen schleife, fliegt dann aber wieder irgendwo raus und das Programm wird ohne Nachricht, ohne core dump, ohne segmentation fault beendet.
Das Programm scheint sich offensichtlich in folgender Funktion selbst zu beenden:


C++:
/*
* Return the idleTime of the user.
* At the moment there are two methods supported to get the idleTime.
* The first and precise one is to check, if the XScreenSaver extension is available.
* If this is the case, we can ask the the extension to give us the idleTime.
* If this extension is not available, we have to check the tty's and stat the files they
* belong to.
*/

int my_getidletime (char *idleString, char *user) {
    int idleTime;
    int event_base, error_base;
    struct stat f_info;
    const char *standardFileName = "/dev/mouse";
    static XScreenSaverInfo *mit_info = NULL;
  
    if(isConsoleUser(user)){
        if (XScreenSaverQueryExtension(GDK_DISPLAY(), &event_base, &error_base)) {
            if (mit_info == NULL) {
                mit_info = XScreenSaverAllocInfo();
            }
            XScreenSaverQueryInfo(GDK_DISPLAY(), GDK_ROOT_WINDOW(), mit_info);
            idleTime = (mit_info->idle);
        } else {
            idleTime = idleFromTty(user);
        }
    } else {
        idleTime = idleFromTty(user);
    }
    sprintf(idleString, "%i", idleTime);
    return 1;
}

/*
* Returns Idle Time from the tty in milliseconds
*/

int idleFromTty(char *user){
    int idleTime = INT_MAX;
    int newIdleTime = INT_MAX;
    utmpx_t *u;
    setutxent();
    for (;;) {
        u = getutxent();
        if (u == NULL) break;
        if(u->ut_type == USER_PROCESS){
            if(strcmp(user, u->ut_user) == 0){
                newIdleTime = getidletime(u);
                if(newIdleTime < idleTime){
                    idleTime = newIdleTime;
                }
            }
        }
    }
    endutxent();
    return idleTime * 1000;
}

static int getidletime(utmpx_t *u) {
    /* AP want to send in info and get the idle time in seconds */
    unsigned i;
    char tty[5 + sizeof u->ut_line + 1] = "/dev/";
    for (i=0; i < sizeof(u->ut_line); i++)    /* clean up tty if garbled */
        if (isalnum(u->ut_line[i]) || (u->ut_line[i]=='/'))
            tty[i+5] = u->ut_line[i];
        else
                tty[i+5] = '\0';
    return idletime(tty);
}

/**** stat the device file to get an idle time */
static time_t idletime(char *tty) {
    struct stat sbuf;
    if (stat(tty, &sbuf) != 0)
        return 0;
    return time(NULL) - sbuf.st_atime;
}

/*
* Check if the user, which has started the client is only remote logged in
* on the host, or if he is the one who sits physically in front of the monitor.
* This is checked by the name of the tty. If the user which owns the tty "console" is the
* same user, which is logged in, he is the console user.
*/

int isConsoleUser(char *username){
    utmpx_t *u;
    setutxent();
    for (;;) {
        u = getutxent();
        if (u == NULL) break;
        if((strcmp(u->ut_line, "console") == 0) || (strcmp(u->ut_line, ":0") == 0)){
            if(strcmp(username, u->ut_user) == 0){
                endutent();
                return 1;
            }
        }
    }
    endutxent();
    return 0;
}



Ich nehme an, das ganze hängt mit XScreenSaver zusammen. Ich habe jedoch keine Ahnung warum, wieso, wesshalb.
Ich hoffe irgendjemand von euch hat eine Idee wie ich das Problem umgehen kann.

Danke im voraus.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
21.05.2007, 14:56 Uhr
0xdeadbeef
Gott
(Operator)


Das hier:

C++:
    for (;;) {
        u = getutxent();
        if (u == NULL) break;


sieht mir verdächtig aus. Was machen die *utxent-Funktionen?
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
21.05.2007, 15:11 Uhr
~dadevelopa
Gast


setutxent setzt den input stream auf den ersten Eintrag der utmpx Datenbank
getutxent liest den nächsten Eintrag aus der utmpx Datenbank.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
21.05.2007, 15:36 Uhr
0xdeadbeef
Gott
(Operator)


...und wenn in der utmpx-Datenbank nichts drin ist?

Lass das Ding doch mal in Vordergrund, also nicht als daemon laufen, und häng gdb dran, um zu sehen, wo er aus der Schleife rausspringt.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
21.05.2007, 16:09 Uhr
~dadevelopa
Gast


Wenn in der utmpx-DB nichts drinn ist dann wird hald 0 in der Funktion zurückgegeben, sprich der User ist kein Console User.

gdb meint, nachdem er rausgeflogen ist:

#0 0xfeb9d840 in XQueryExtension () from /usr/lib/libX11.so.4
#1 0xfeb9d714 in XInitExtension () from /usr/lib/libX11.so.4
#2 0xfefb3cb4 in XextAddDisplay () from /usr/lib/libXext.so.0
#3 0xfefbd8c4 in XScreenSaverQueryExtension () from /usr/lib/libXext.so.0
#4 0x00014728 in my_getidletime ()
#5 0x00013708 in get_time ()
#6 0x0001368c in main ()

Scheint also am XScreenSaverQueryExtension zu liegen.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
21.05.2007, 16:55 Uhr
0xdeadbeef
Gott
(Operator)


...das heißt, er kommt garnicht erst in die Schleife in idleFromTty rein. Ohne den Code von main und get_time wird sich da nicht viel machen lassen :P
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
22.05.2007, 10:19 Uhr
~dadevelopa
Gast


So, ich habe ein kleines Programm geschrieben, welches nur mal die XScreensaver Extension testen soll:


C++:
#include <stdio.h>
#include <gdk/gdkx.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/extensions/scrnsaver.h>

int main(void){
    int event_base, error_base;
    static XScreenSaverInfo *mit_info = NULL;

    if (XScreenSaverQueryExtension(GDK_DISPLAY(), &event_base, &error_base)) {
        printf("XScreenSaverQueryExtension vorhanden.");
    } else {
        printf("XScreenSaverQueryExtension nicht vorhanden.");
    }
    return 0;
}



Leider bricht dieses Programm jedoch mit einem Segmentation Fault ab.
gdb meint dazu folgendes:
#0 0xb76a8187 in XQueryExtension () from /usr/lib/libX11.so.6
#1 0xb769caab in XInitExtension () from /usr/lib/libX11.so.6
#2 0xb79a90f3 in XextAddDisplay () from /usr/lib/libXext.so.6
#3 0xb7999b7d in ?? () from /usr/lib/libXss.so.1
#4 0xb799c0d0 in ?? () from /usr/lib/libXss.so.1
#5 0x00000000 in ?? ()


Sind da wohl irgendwelche Probleme mit xscreensaver vorhanden. Muss ich einen Workaround suchen um die Idletime herauszufinden? Hat jemand eine Idee dafür?
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
007
22.05.2007, 13:14 Uhr
FloSoft
Medialer Over-Flow
(Administrator)


evtl liefert dein GDK_DISPLAY irgendnen mist, wodurch dann der intern irgendwo abschmiert
--
class God : public ChuckNorris { };
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
008
22.05.2007, 15:03 Uhr
0xdeadbeef
Gott
(Operator)


Wenn mich nicht alles täuscht, muss vor der Verwendung von GDK_DISPLAY libgdk erst initialisiert werden. Ich weiß, dass das bei GTK-Programmen mit

C++:
gtk_init(&argc, &argv);


geht. Ich glaube, dass das im GDK direkt mit gdk_init funktioniert, und dass gtk_init das im Backend aufruft, aber das müsst ich jetzt erst nachschlagen.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ C / C++ (GNU/Linux, *NIX, *BSD und Co) ]  


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: