fam
[Top] [All Lists]

[fam] client keeps on dying

To: fam@xxxxxxxxxxx
Subject: [fam] client keeps on dying
From: "kennys@xxxxxxxxxxxxxxxxxxxxx" <kennys@xxxxxxxxxxxxxxxxxxxxx>
Date: Wed, 09 Jan 2002 12:37:20 +1100
Sender: owner-fam@xxxxxxxxxxx
User-agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:0.9.7) Gecko/20011221
I am fiddling around with the test program that comes with the download,
but at some point in time, the client stops for no obvious reasons.

So, I need to understand this little piece of code.

for ( ;  FAMPending(&fc); ) {
  if( FAMNextEvent(&fc, &fe) < 0 ) {
      printf("Gahh, FAMNextEvent() returned < 0 ! \n");
      exit(1);
  }
  processDirEvents(&fe);
  fflush(stdout);
}


okay what i need is to know
1. why the purpose of the if statement,
2. why it comes true as in what happens..
3. is there anyway to make sure that if statement never comes true

any help is much appreciated


attached is the complete source .


#include <sys/types.h>
#include <sys/time.h>
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>
#include <stdarg.h>
//#include <fcntl.h>
#include "fam.h"
#include <stdlib.h>
//#include "Boolean.h"
/* 

FILE test.c - simple fam test program

                 Usage: test [-r] [-f <file>] [-d <directory>]
                 ex.  test -f /etc/hosts -d /tmp

-r        includes request IDs in output (if you use this, put it first)
-f [file] monitors the given file
-d [dir]  monitors the given directory

*/


void processDirEvents(FAMEvent* fe);

bool suspend = false;
bool cont = false;
bool intr = false;
bool usr1 = false;
bool usr2 = false;
bool showReqIDs = false;
//int  lockfd = -1;
//FILE *fout;

void handle_stop(int) {
    printf("Suspended!\n");
    suspend = true;
}

void handle_cont(int) {
    printf("Resumed!\n");
    signal(SIGCONT, handle_cont);
    cont = true;
}

void handle_int(int) 
{
    printf("Interupted!\n");
    signal(SIGINT, handle_int);
    intr = true;
}

void handle_usr1(int) 
{
    printf("Got USR1!\n");
    signal(SIGUSR1, handle_usr1);
    usr1 = true;
}

void handle_usr2(int) 
{
    printf("Got USR2!\n");
    signal(SIGUSR2, handle_usr2);
    usr2 = true;
}

struct TestRequest
{
    FAMRequest fr;
    char path[PATH_MAX];
    char userData[PATH_MAX];
    bool isDir;
};

void sendRequests(FAMConnection &fc, TestRequest tr[], int trlen)
{
    for (int ii = 0; ii < trlen; ++ii) {
        if (tr[ii].isDir) {
            printf("FAMMonitorDirectory(\"%s\")\n", tr[ii].path);
            if (FAMMonitorDirectory(&fc, tr[ii].path, &(tr[ii].fr), 
tr[ii].userData) < 0) {
                fprintf(stderr, "FAMMonitorDirectory error\n");
                exit(1);
            }
            if (showReqIDs) printf("req %d: ", tr[ii].fr.reqnum);
            printf("FAMMonitorDirectory(\"%s\")\n", tr[ii].path);
            
        } else {
        
            printf("FAMMonitorFile(\"%s\")\n", tr[ii].path);
            if (FAMMonitorFile(&fc, tr[ii].path, &(tr[ii].fr), tr[ii].userData) 
< 0) {
                fprintf(stderr, "FAMMonitorFile error\n");
                exit(1);
            }
            if (showReqIDs) printf("req %d: ", tr[ii].fr.reqnum);
            printf("FAMMonitorFile(\"%s\")\n", tr[ii].path);
        }
    }
}


void
main(int argc, char **argv)
{
    /* Create fam test */
    FAMConnection fc;
    TestRequest tr[100];
    int requests = 0;
    FAMEvent fe;
    fd_set readfds;
    fd_set readfdscpy;
    setbuf(stdout, NULL);

    if (argc < 2) {
        printf("usage: %s [-r] [-f <filename>] [-d <dirname>]\n", argv[0]);
        exit(1);
    }
    
    int arg;
    extern char *optarg;
    extern int optind;
    
    if(FAMOpen(&fc) < 0)
    {
        fprintf(stderr, "FAMOpen failed!\n");
        exit(1);
    }
    
    FD_ZERO(&readfds);
    FD_SET(fc.fd, &readfds);
    while ((arg = getopt(argc, argv, "f:d:r")) != -1) 
    {
        switch (arg) 
        {
        case 'd':
        case 'f':
            snprintf(tr[requests].userData, PATH_MAX, "%s %s: ",
                     (arg == 'd') ? "DIR blablabla" : "FILE", optarg);
            snprintf(tr[requests].path, PATH_MAX, "%s", optarg);
            tr[requests].isDir = (arg == 'd');
            ++requests;  // just don't use more than 100, OK?
            break;
        case 'r':
            showReqIDs = true;
            break;
        }
    }
    
    signal(SIGTSTP, handle_stop);
    signal(SIGCONT, handle_cont);
    signal(SIGINT, handle_int);
    signal(SIGUSR1, handle_usr1);
    signal(SIGUSR2, handle_usr2);
    
    sendRequests(fc, tr, requests);

    while (1) {
        if (suspend) {
            for (int ii  = 0; ii < requests; ii++) 
            {
                FAMSuspendMonitor(&fc, &(tr[ii].fr));
                printf("Suspended monitoring of request %i\n", ii);
            }
            fflush(stdout);
            suspend = false;
            kill(getpid(),SIGTSTP);
            signal(SIGTSTP, handle_stop);
        }
        if (cont) {
            for (int ii  = 0; ii < requests; ii++) 
            {
                FAMResumeMonitor(&fc, &(tr[ii].fr));
                printf("Resumed monitoring of request %i\n", ii);
            }
            fflush(stdout);
            cont = false;
        }
        if (intr) {
            // Cancel monitoring of every other request.  This makes
            // sure fam can handle the case where the connection goes
            // down with requests outstanding.
            for (int ii  = 0; ii < requests ; ii++) 
            {
                if (ii % 2 == 0) continue;
                FAMCancelMonitor(&fc, &(tr[ii].fr));
                printf("Canceled monitoring of request %i\n", ii);
            }
            FAMClose(&fc);
            exit(0);
        }
        if (usr1) {
            // Cancel all requests, close the connection, and reopen it.
            // This makes sure long-lived clients can connect, monitor, and
            // disconnect repeatedly without leaking.
            usr1 = false;
            int sleeptime = 1;
            for (int ii  = 0; ii < requests ; ii++)
            {
                FAMCancelMonitor(&fc, &(tr[ii].fr));
                printf("Canceled monitoring of request %i\n", ii);
            }
            FAMClose(&fc);
            printf("Closed connection, sleeping %d...\n", sleeptime);
            sleep(sleeptime);

            //  Now reconnect and resend the requests.
            if(FAMOpen(&fc) < 0)
            {
                fprintf(stderr, "FAMOpen failed!\n");
                exit(1);
            }
            FD_ZERO(&readfds);
            FD_SET(fc.fd, &readfds);
            sendRequests(fc, tr, requests);
        }
        if (usr2) {
            // Clean things up like a well-behaved client and exit.
            for (int ii  = 0; ii < requests ; ii++)
            {
                FAMCancelMonitor(&fc, &(tr[ii].fr));
                printf("Canceled monitoring of request %i\n", ii);
            }
            FAMClose(&fc);
            printf("Closed connection\n");
            exit(0);
        }

        readfdscpy = readfds;
        if (select(FD_SETSIZE, &readfdscpy, NULL, NULL, NULL) < 0) {
            if (errno == EINTR) 
            {
                continue;
            }
            break;
        }
        for (; FAMPending(&fc); ) {
            if (FAMNextEvent(&fc, &fe) < 0) {
                printf("Gahh, FAMNextEvent() returned < 0!\n");
                exit(1);
            }
                processDirEvents(&fe);
            fflush(stdout);
            }
    }
}



void
processDirEvents(FAMEvent* fe)
{
    if (fe->userdata) printf("%s  ", (char *)fe->userdata); 
    if (showReqIDs) printf("req %d: ", fe->fr.reqnum);
    switch (fe->code) {
        case FAMExists:
            printf("%s Exists\n", fe->filename);
            break;
        case FAMEndExist:
            printf("%s EndExist\n", fe->filename);
            break;
        case FAMChanged:
            printf("%s Changed\n", fe->filename);
            break;
        case FAMDeleted:
            printf("%s was deleted\n", fe->filename);
            break;
        case FAMStartExecuting:
            printf("%s started executing\n", fe->filename);
            break;
        case FAMStopExecuting:
            printf("%s stopped executing\n", fe->filename);
            break;
        case FAMCreated:
            printf("'%s' was created\n", fe->filename);
            break;
        case FAMMoved:
            printf("%s was moved\n", fe->filename);
            break;
        default:
            printf("(unknown event %d on %s)\n", fe->code, fe->filename);
    }
}



<Prev in Thread] Current Thread [Next in Thread>