Exemplo n.º 1
0
Arquivo: gamin.c Projeto: GNOME/gamin
static void
check_event(FAMConnection * fc)
{
    int ret;
    FAMEvent fe;

    ret = FAMPending(fc);
    if (ret < 0) {
        fprintf(stderr, "FAMPending() failed\n");
        exit(1);
    }
    while (ret > 0) {
        ret = FAMNextEvent(fc, &fe);
        if (ret < 0) {
            fprintf(stderr, "FAMNextEvent() failed\n");
            exit(1);
        }
        print_event(&fe);
        ret = FAMPending(fc);
        if (ret < 0) {
            fprintf(stderr, "FAMPending() failed\n");
            exit(1);
        }
    }
}
Exemplo n.º 2
0
static int
printEvents(int no)
{
    int ret;

    ret = FAMPending(&(testState.fc));
    if (ret < 0) {
        fprintf(stderr, "events line %d: FAMPending failed\n", no);
        return (-1);
    }
    if (ret == 0) {
        printf("no events\n");
    }
    while (ret != 0) {
        ret = printEvent(no);
        if (ret < 0)
            return (-1);

        ret = FAMPending(&(testState.fc));
        if (ret < 0) {
            fprintf(stderr, "events line %d: FAMPending failed\n", no);
            return (-1);
        }
    }
    return (0);
}
Exemplo n.º 3
0
static void viewer_fam_input(viewer_t *viewer, int fd, GdkInputCondition condition)
{
  FAMEvent fe;

  while ( FAMPending(&(viewer->fc)) > 0 ) {
    if ( FAMNextEvent(&(viewer->fc), &fe) < 0 ) {
      fprintf(stderr, NAME ": WARNING: Failed to retrieve FAM event: %s\n", FamErrlist[FAMErrno]);
      fprintf(stderr, NAME ": WARNING: Disabling file update detection.\n");
      viewer_fam_close(viewer);
      return;
    }

    switch ( fe.code ) {
    case FAMDeleted:
    case FAMMoved:
      viewer_clear(viewer);
      break;

    case FAMChanged:
    case FAMCreated:
      viewer_follow(viewer, 0);
      break;

    default:
      break;
    }
  }
}
Exemplo n.º 4
0
static void* fhs_event_process(void *data)
{
        struct fe_handler *feh = (struct fe_handler*)data;
        FAMEvent fe;
        FAMRequest fr;
        FAMConnection fc;
        char*  root_path;

        root_path = g_hash_table_lookup(feh->ohh->config, "root_path");

        FAMOpen(&fc);
        FAMMonitorDirectory(&fc, root_path, &fr, REQ_RES);

        while(!feh->closing) { 
/*
        The old code is:
               FAMNextEvent(&fc, &fe);
        The new code is
                if (1 == FAMPending(&fc)) {
                        FAMNextEvent(&fc, &fe);
                }else  continue;

        In the old code, if this thread is processing FAMNextEvent and 
        then feh->closing is set by another thread, this thread is still
        hung up. so the synchronized call is changed as asychronized call
        (polling call) though I don't like this mode.
 
*/  
                if (1 == FAMPending(&fc)) {
                        FAMNextEvent(&fc, &fe);
                }else  continue; 

                if ((fe.userdata == REQ_RES) &&
                    ((fe.code == FAMCreated) || (fe.code == FAMExists))) {
                        if (!IS_DIR(fe.filename))
                                fhs_event_add_resource(feh, fe.filename, &fe);
                }else if ((fe.userdata == REQ_RDR) && (fe.code == FAMDeleted)) {
                     	if (!IS_DIR(fe.filename))
                             	fhs_event_remove_resource(feh, &fe);
                      	else
                  		printf("faint! why delete root path\n");
                }else if (fe.userdata == REQ_RDR) {
                        if (((fe.code == FAMChanged) || (fe.code == FAMExists))&&
                            ((!strcmp(fe.filename, "reading"))||
                             (!strcmp(fe.filename, "thres")))) {
                                fhs_event_sensor_update(feh, &fe);
                        }
                }
        } 
        FAMClose(&fc);

        return 0;
}
Exemplo n.º 5
0
static int
debugLoop(int timeoutms) {
    fd_set read_set;
    struct timeval tv;
    int avail;
    int fd;

    if (interactive)
	debugPrompt();

retry:
    FD_ZERO(&read_set);
    FD_SET(0, &read_set);
    fd = 0;
    if (testState.connected) {
        FD_SET(testState.fc.fd, &read_set);
	fd = testState.fc.fd;
    }
    if (timeoutms >= 0) {
        tv.tv_sec = timeoutms / 1000;
        tv.tv_usec = (timeoutms % 1000) * 1000;
	avail = select(fd + 1, &read_set, NULL, NULL, &tv);
	if (avail == 0)
	    return(0);
    } else {
	avail = select(fd + 1, &read_set, NULL, NULL, NULL);
    }
    if (avail < 0) {
        if (errno == EINTR)
	    goto retry;
	fprintf(stderr, "debugLoop: select() failed \n");
	return (-1);
    }
    if (testState.connected) {
        if (FD_ISSET(testState.fc.fd, &read_set)) {
	    if (FAMPending(&(testState.fc)) > 0) {
		if (interactive)
		    printf("\n");
	        printEvents(0);
		if (interactive)
		    debugPrompt();
	    }
	}
    }
    if (timeoutms >= 0)
        return(0);
    if (!(FD_ISSET(0, &read_set)))
        goto retry;
    return(0);
}
Exemplo n.º 6
0
handler_t stat_cache_handle_fdevent(server *srv, void *_fce, int revent) {
	size_t i;
	stat_cache *sc = srv->stat_cache;
	size_t events;

	UNUSED(_fce);
	/* */

	if (revent & FDEVENT_IN) {
		events = FAMPending(&sc->fam);

		for (i = 0; i < events; i++) {
			FAMEvent fe;
			fam_dir_entry *fam_dir;
			splay_tree *node;
			int ndx, j;

			FAMNextEvent(&sc->fam, &fe);

			/* handle event */

			switch(fe.code) {
			case FAMChanged:
			case FAMDeleted:
			case FAMMoved:
				/* if the filename is a directory remove the entry */

				fam_dir = fe.userdata;
				fam_dir->version++;

				/* file/dir is still here */
				if (fe.code == FAMChanged) break;

				/* we have 2 versions, follow and no-follow-symlink */

				for (j = 0; j < 2; j++) {
					buffer_copy_string(sc->hash_key, fe.filename);
					buffer_append_int(sc->hash_key, j);

					ndx = hashme(sc->hash_key);

					sc->dirs = splaytree_splay(sc->dirs, ndx);
					node = sc->dirs;

					if (node && (node->key == ndx)) {
						int osize = splaytree_size(sc->dirs);

						fam_dir_entry_free(&sc->fam, node->data);
						sc->dirs = splaytree_delete(sc->dirs, ndx);

						force_assert(osize - 1 == splaytree_size(sc->dirs));
					}
				}
				break;
			default:
				break;
			}
		}
	}

	if (revent & FDEVENT_HUP) {
		/* fam closed the connection */
		fdevent_event_del(srv->ev, &(sc->fam_fcce_ndx), FAMCONNECTION_GETFD(&sc->fam));
		fdevent_unregister(srv->ev, FAMCONNECTION_GETFD(&sc->fam));

		FAMClose(&sc->fam);
	}

	return HANDLER_GO_ON;
}
Exemplo n.º 7
0
/* event handler of all FAM events */
static gboolean on_fam_event( GIOChannel * channel,
                              GIOCondition cond,
                              gpointer user_data )
{
#ifdef USE_INOTIFY /* Linux inootify */
#define BUF_LEN (1024 * (sizeof (struct inotify_event) + 16))
    char buf[ BUF_LEN ];
    int i, len;
#else /* FAM|gamin */
    FAMEvent evt;
#endif

    VFSFileMonitor* monitor = NULL;

    if ( cond & (G_IO_HUP | G_IO_ERR) )
    {
        disconnect_from_fam();
        if ( g_hash_table_size ( monitor_hash ) > 0 )
        {
            /*
              Disconnected from FAM server, but there are still monitors.
              This may be caused by crash of FAM server.
              So we have to reconnect to FAM server.
            */
            connect_to_fam();
            g_hash_table_foreach( monitor_hash, ( GHFunc ) reconnect_fam, NULL );
        }
        return TRUE; /* don't need to remove the event source since
                                    it has been removed by disconnect_from_fam(). */
    }

#ifdef USE_INOTIFY /* Linux inotify */
    while ( ( len = read ( inotify_fd, buf, BUF_LEN ) ) < 0
            && errno == EINTR );
    if ( len < 0 )
    {
        g_warning ( "Error reading inotify event: %s",
                    g_strerror ( errno ) );
        /* goto error_cancel; */
        return FALSE;
    }

    if ( len == 0 )
    {
        /*
        * FIXME: handle this better?
        */
        g_warning ( "Error reading inotify event: supplied buffer was too small" );
        /* goto error_cancel; */
        return FALSE;
    }
    i = 0;
    while ( i < len )
    {
        struct inotify_event * ievent = ( struct inotify_event * ) & buf [ i ];
        /* FIXME: 2 different paths can have the same wd because of link */
        monitor = ( VFSFileMonitor* ) g_hash_table_find(
                      monitor_hash,
                      find_monitor,
                      GINT_TO_POINTER( ievent->wd ) );
        if( G_LIKELY(monitor) )
        {
            const char* file_name;
            file_name = ievent->len > 0 ? ievent->name : monitor->path;
/*
//MOD for debug output only
char* desc;
if ( ievent->mask & ( IN_CREATE | IN_MOVED_TO ) )
    desc = "CREATE";
else if ( ievent->mask & ( IN_DELETE | IN_MOVED_FROM | IN_DELETE_SELF | IN_UNMOUNT ) )
    desc = "DELETE";
else if ( ievent->mask & ( IN_MODIFY | IN_ATTRIB ) )
    desc = "CHANGE";
if ( !strcmp( monitor->path, "/tmp" ) && g_str_has_prefix( file_name, "vte" ) )
{ } // due to current vte scroll problems creating and deleting massive numbers of 
// /tmp/vte8CBO7V types of files, ignore these (creates feedback loop when
// spacefm is run in terminal because each printf triggers a scroll,
// which triggers another printf below, which triggers another file change)
// https://bugs.launchpad.net/ubuntu/+source/vte/+bug/778872
else
    printf("inotify-event %s: %s///%s\n", desc, monitor->path, file_name);
//g_debug("inotify (%d) :%s", ievent->mask, file_name);
*/
            dispatch_event( monitor,
                            translate_inotify_event( ievent->mask ),
                            file_name );
        }
        i += sizeof ( struct inotify_event ) + ievent->len;
    }
#else /* FAM|gamin */
    while ( FAMPending( &fam ) )
    {
        if ( FAMNextEvent( &fam, &evt ) > 0 )
        {
            monitor = ( VFSFileMonitor* ) evt.userdata;
            switch ( evt.code )
            {
            case FAMCreated:
            case FAMDeleted:
            case FAMChanged:
                /* FIXME: There exists a possibility that a file can accidentally become
                          a directory, and a directory can become a file when using chmod.
                          Should we delete original request, and create a new one when this happens?
                */
                /* g_debug("FAM event(%d): %s", evt.code, evt.filename); */
                /* Call the callback functions */
                dispatch_event( monitor, evt.code, evt.filename );
                break;
                /* Other events are not supported */
            default:
                break;
            }
        }
    }
#endif
    return TRUE;
}
Exemplo n.º 8
0
static int
processCommand(char *line, int no)
{
    int ret, args;
    char *command = NULL;
    char *arg = NULL;
    char *arg2 = NULL;

    if (line == NULL)
        return (-1);
    if (line[0] == '#')
        return (0);

    args = scanCommand(line, &command, &arg, &arg2);
    if (args < 0)
        return (-1);
    if (args == 0)
        return (0);

    if (!strcmp(command, "connect")) {
        if (testState.connected) {
            fprintf(stderr, "connect line %d: already connected\n", no);
            return (-1);
        }
        if (arg != NULL) {
#ifdef HAVE_SETENV
            setenv("GAM_CLIENT_ID", arg, 1);
#elif HAVE_PUTENV
            char *client_id = malloc (strlen (arg) + sizeof "GAM_CLIENT_ID=");
              if (client_id)
              {
                strcpy (client_id, "GAM_CLIENT_ID=");
                strcat (client_id, arg);
                putenv (client_id);
              }
#endif /* HAVE_SETENV */
        }
        ret = FAMOpen(&(testState.fc));
        if (ret < 0) {
            fprintf(stderr, "connect line %d: failed to connect\n", no);
            return (-1);
        }
        testState.connected = 1;
        if (arg != NULL)
            printf("connected to %s\n", arg);
        else
            printf("connected\n");
    } else if (!strcmp(command, "kill")) {
        /*
         * okay, it's heavy but that's the simplest way since we do not have
         * the pid(s) of the servers running.
         */
        ret = system("killall gam_server");
        if (ret < 0) {
            fprintf(stderr, "kill line %d: failed to killall gam_server\n",
                    no);
            return (-1);
        }
        printf("killall gam_server\n");
    } else if (!strcmp(command, "disconnect")) {
        if (testState.connected == 0) {
            fprintf(stderr, "disconnect line %d: not connected\n", no);
            return (-1);
        }
        ret = FAMClose(&(testState.fc));
        if (ret < 0) {
            fprintf(stderr, "connect line %d: failed to disconnect\n", no);
            return (-1);
        }
        testState.connected = 0;
        printf("disconnected\n");
    } else if (!strcmp(command, "mondir")) {
        if (args >= 2) {
            if (arg[0] != '/')
                snprintf(filename, sizeof(filename), "%s/%s", pwd, arg);
            else
                snprintf(filename, sizeof(filename), "%s", arg);
        }
        if (args == 2) {
            ret = FAMMonitorDirectory(&(testState.fc), filename,
                                      &(testState.
                                        fr[testState.nb_requests]), NULL);
        } else if (args == 3) {
            int index;

            if (sscanf(arg2, "%d", &index) <= 0) {
                fprintf(stderr, "mondir line %d: invalid index value %s\n",
                        no, arg2);
                return (-1);
            }
            testState.fr[testState.nb_requests].reqnum = index;
            ret = FAMMonitorDirectory2(&(testState.fc), filename,
                                       &(testState.
                                         fr[testState.nb_requests]));
        } else {
            fprintf(stderr, "mondir line %d: invalid format\n", no);
            return (-1);
        }
        if (ret < 0) {
            fprintf(stderr, "mondir line %d: failed to monitor %s\n", no,
                    arg);
            return (-1);
        }
        printf("mondir %s %d\n", arg, testState.nb_requests);
        testState.nb_requests++;
    } else if (!strcmp(command, "monfile")) {
        if (args != 2) {
            fprintf(stderr, "monfile line %d: lacks name\n", no);
            return (-1);
        }
        if (arg[0] != '/')
            snprintf(filename, sizeof(filename), "%s/%s", pwd, arg);
        else
            snprintf(filename, sizeof(filename), "%s", arg);
        ret = FAMMonitorFile(&(testState.fc), filename,
                             &(testState.fr[testState.nb_requests]), NULL);
        if (ret < 0) {
            fprintf(stderr, "monfile line %d: failed to monitor %s\n", no,
                    arg);
            return (-1);
        }
        printf("monfile %s %d\n", arg, testState.nb_requests);
        testState.nb_requests++;
    } else if (!strcmp(command, "pending")) {
        if (args != 1) {
            fprintf(stderr, "pending line %d: extra argument %s\n", no,
                    arg);
            return (-1);
        }
        ret = FAMPending(&(testState.fc));
        if (ret < 0) {
            fprintf(stderr, "pending line %d: failed\n", no);
            return (-1);
        }
        printf("pending %d\n", ret);
    } else if (!strcmp(command, "mkdir")) {
        if (args != 2) {
            fprintf(stderr, "mkdir line %d: lacks name\n", no);
            return (-1);
        }
        ret = mkdir(arg, 0755);
        if (ret < 0) {
            fprintf(stderr, "mkdir line %d: failed to create %s\n", no,
                    arg);
            return (-1);
        }
        printf("mkdir %s\n", arg);
    } else if (!strcmp(command, "chmod")) {
        if (args != 3) {
            fprintf(stderr, "chmod line %d: lacks path and mode\n", no);
            return (-1);
        }
        ret = chmod(arg, strtol (arg2, NULL, 8));
        if (ret < 0) {
            fprintf(stderr, "chmod line %d: failed to chmod %s to %s\n", no,
                    arg, arg2);
            return (-1);
        }
        printf("chmod %s to %s\n", arg, arg2);
    } else if (!strcmp(command, "chown")) {
        if (args != 3) {
            fprintf(stderr, "chown line %d: lacks path and owner\n", no);
            return (-1);
        }
		struct stat sb;
		if (!lstat (arg, &sb)) {
			ret = (S_ISLNK (sb.st_mode)) ?
				lchown(arg, strtol(arg2, NULL, 10), -1) :
				chown(arg, strtol(arg2, NULL, 10), -1);
		} else
			ret=-1;
        if (ret < 0) {
            fprintf(stderr, "chown line %d: failed to chown %s to %s\n", no,
                    arg, arg2);
            return (-1);
        }
        printf("chown %s to %s\n", arg, arg2);
    } else if (!strcmp(command, "mkfile")) {
        if (args != 2) {
            fprintf(stderr, "mkfile line %d: lacks name\n", no);
            return (-1);
        }
        ret = open(arg, O_CREAT | O_WRONLY, 0666);
        if (ret < 0) {
            fprintf(stderr, "mkfile line %d: failed to open %s\n", no,
                    arg);
            return (-1);
        }
        close(ret);
        printf("mkfile %s\n", arg);
    } else if (!strcmp(command, "append")) {
        if (args != 2) {
            fprintf(stderr, "mkfile line %d: lacks name\n", no);
            return (-1);
        }
        ret = open(arg, O_RDWR | O_APPEND);
        if (ret < 0) {
            fprintf(stderr, "append line %d: failed to open %s\n", no,
                    arg);
            return (-1);
        }
        write(ret, "a", 1);
        close(ret);
        printf("append %s\n", arg);
    } else if (!strcmp(command, "rmdir")) {
        if (args != 2) {
            fprintf(stderr, "rmdir line %d: lacks name\n", no);
            return (-1);
        }
        ret = rmdir(arg);
        if (ret < 0) {
            fprintf(stderr, "rmdir line %d: failed to remove %s\n", no,
                    arg);
            return (-1);
        }
        printf("rmdir %s\n", arg);
    } else if (!strcmp(command, "rmfile")) {
        if (args != 2) {
            fprintf(stderr, "rmfile line %d: lacks name\n", no);
            return (-1);
        }
        ret = unlink(arg);
        if (ret < 0) {
            fprintf(stderr, "rmfile line %d: failed to unlink %s\n", no,
                    arg);
            return (-1);
        }
        printf("rmfile %s\n", arg);
	} else if (!strcmp(command, "move")) {
		if (args != 3)
		{
			fprintf(stderr, "move line %d: lacks something\n", no);
			return (-1);
		}
		ret = rename(arg, arg2);
		if (ret < 0) {
			fprintf(stderr, "move line %d: failed to move %s\n", no, arg);
			return (-1);
		}
		printf("move %s %s\n", arg, arg2);
	} else if (!strcmp(command, "link")) {
		if (args != 3) {
		fprintf(stderr, "link line %d: lacks target and name\n", no); return (-1);
		}
		ret = symlink(arg, arg2);
		if (ret < 0) {
			fprintf(stderr, "link line %d: failed to link to %s\n", no, arg);
			return (-1);
		}
		printf("link %s to %s\n", arg2, arg);
    } else if (!strcmp(command, "event")) {
        printEvent(no);
    } else if (!strcmp(command, "events")) {
        printEvents(no);
    } else if (!strcmp(command, "expect")) {
        int count;
        int delay = 0;
        int nb_events = testState.nb_events;

        if (args != 2) {
            fprintf(stderr, "expect line %d: lacks number\n", no);
            return (-1);
        }

        if (sscanf(arg, "%d", &count) <= 0) {
            fprintf(stderr, "expect line %d: invalid number value %s\n",
                    no, arg);
            return (-1);
        }
        /*
         * wait at most 3 secs before declaring failure
         */
        while ((delay < 30) && (testState.nb_events < nb_events + count)) {
            debugLoop(100);

/*	    printf("+"); fflush(stdout); */
            delay++;
        }
        if (testState.nb_events < nb_events + count) {
            printf("expect line %d: got %d of %d expected events\n",
                   no, testState.nb_events - nb_events, count);
            return (-1);
        }
    } else if (!strcmp(command, "sleep")) {
        int i;

        for (i = 0; (i < 30) && (FAMPending(&(testState.fc)) == 0); i++)
            usleep(50000);
    } else if (!strcmp(command, "wait")) {
        sleep(1);
    } else if (!strcmp(command, "cancel")) {
        if (args == 2) {
            int req_index = 0;

            if (sscanf(arg, "%d", &req_index) <= 0
                || req_index >= testState.nb_requests) {
                fprintf(stderr,
                        "cancel line %d: invalid req_index value %s\n", no,
                        arg);
                return (-1);
            }
            ret = FAMCancelMonitor(&(testState.fc),
                                   &(testState.fr[req_index]));

        } else {
            fprintf(stderr, "cancel line %d: invalid format\n", no);
            return (-1);
        }
        if (ret < 0) {
            fprintf(stderr,
                    "cancel line %d: failed to cancel req_index %s\n", no,
                    arg);
            return (-1);
        }
        printf("cancel %s %d\n", arg, testState.nb_requests);
    } else {
        fprintf(stderr, "Unable to parse line %d: %s\n", no, line);
        return (-1);
    }
    return (0);
}
Exemplo n.º 9
0
static gboolean
g_fam_file_monitor_callback (gint         fd,
                             GIOCondition condition,
                             gpointer     user_data)
{
  gint64 now = g_source_get_time (fam_source);

  g_mutex_lock (&fam_lock);

  while (FAMPending (&fam_connection))
    {
      const gchar *child;
      FAMEvent ev;

      if (FAMNextEvent (&fam_connection, &ev) != 1)
        {
          /* The daemon died.  We're in a really bad situation now
           * because we potentially have a bunch of request structures
           * outstanding which no longer make any sense to anyone.
           *
           * The best thing that we can do is do nothing.  Notification
           * won't work anymore for this process.
           */
          g_mutex_unlock (&fam_lock);

          g_warning ("Lost connection to FAM (file monitoring) service.  Expect no further file monitor events.");

          return FALSE;
        }

      /* We expect ev.filename to be a relative path for children in a
       * monitored directory, and an absolute path for a monitored file
       * or the directory itself.
       */
      if (ev.filename[0] != '/')
        child = ev.filename;
      else
        child = NULL;

      switch (ev.code)
        {
        case FAMAcknowledge:
          g_source_unref (ev.userdata);
          break;

        case FAMChanged:
          g_file_monitor_source_handle_event (ev.userdata, G_FILE_MONITOR_EVENT_CHANGED, child, NULL, NULL, now);
          break;

        case FAMDeleted:
          g_file_monitor_source_handle_event (ev.userdata, G_FILE_MONITOR_EVENT_DELETED, child, NULL, NULL, now);
          break;

        case FAMCreated:
          g_file_monitor_source_handle_event (ev.userdata, G_FILE_MONITOR_EVENT_CREATED, child, NULL, NULL, now);
          break;

        default:
          /* unknown type */
          break;
        }
    }

  g_mutex_unlock (&fam_lock);

  return TRUE;
}
Exemplo n.º 10
0
/**
 * Process all pending events.
 * Helper thread for the worker thread.  Just there
 * to process FAM events.  Puts all events into the
 * queue for the main worker.
 */
static void * processEvents(void * arg) {
  DIC * cls = arg;
  FAMEvent fe;
  fd_set r;
  fd_set w;
  fd_set e;
  int fd = cls->fc.fd;
  int i;

  cls->log(cls->logContext,
	   DOODLE_LOG_VERY_VERBOSE,
	   _("Event processing thread created.\n"));
  while ( (0 == testShutdown()) &&
	  (cls->continueRunning) ) {
    char * name;

    FD_ZERO(&r);
    FD_ZERO(&w);
    FD_ZERO(&e);
    FD_SET(fd, &r);
    i = select(fd+1, &r, &w, &e, NULL);
    if (i == -1) {
      if (errno == EINTR)
	continue;
      cls->log(cls->logContext,
	       DOODLE_LOG_CRITICAL,
	       _("Call to '%s' failed: %s\n"),
	       "select",
	       strerror(errno));
    }
    if (!FD_ISSET(fd, &r))
      continue;

    if (! FAMPending(&cls->fc)) {
      /* this should only happen if there was a problem with
	 select, and in this case we better add some artificial
	 delay (busy waiting) */
      sleep(1);
      continue;
    }

    MUTEX_LOCK(&cls->lock);
    if (-1 == FAMNextEvent(&cls->fc, &fe)) {
      cls->log(cls->logContext,
	       DOODLE_LOG_CRITICAL,
	       _("Call to '%s' failed: %s\n"),
	       "FAMNextEvent",
	       FamErrlist[FAMErrno]);
      /* avoid fast, persistent errors */
      sleep(1);
      continue;
    }
    name = malloc(strlen(fe.filename) + strlen((char*) fe.userdata) + 2);
    if (fe.filename[0] == '/') {
      strcpy(name, fe.filename);
    } else {
      strcpy(name, (char*) fe.userdata);
      if ( (strlen((char*)fe.userdata) > 0) &&
	   (((char*)fe.userdata)[strlen(fe.userdata)-1] != DIR_SEPARATOR) )
	strcat(name, DIR_SEPARATOR_STR);
      strcat(name, fe.filename);
    }
    /* never process the doodle database itself... */
    if (0 == strncmp(name,
		     cls->ename,
		     strlen(cls->ename))) {
      free(name);
      MUTEX_UNLOCK(&cls->lock);
      continue;
    }


    cls->log(cls->logContext,
	     DOODLE_LOG_INSANELY_VERBOSE,
	     "FAM EVENT (%d,%s,%s) on file '%s'.\n",
	     fe.code,
	     fe.userdata,
	     fe.filename,
	     name);
    switch (fe.code) {
    case FAMCreated:
    case FAMChanged:	
    case FAMDeleted:
    case FAMMoved:
    case FAMAcknowledge:
    case FAMExists:
    case FAMEndExist:
      GROW(cls->events,
	   cls->eventCount,
	   cls->eventCount+1);
      cls->events[cls->eventCount-1] = strdup(name);
      SEMAPHORE_UP(cls->signal);
      break;	
    default:
      break;
    } /* end switch */
    free(name);
    MUTEX_UNLOCK(&cls->lock);
  } /* if event */
  cls->continueRunning = 0;
  SEMAPHORE_UP(cls->signal);

  return NULL;
}
Exemplo n.º 11
0
int main(int argc, char **argv)
{
  vector<string> cfg;
  size_t cfg_num = 0;
  if(argc==2) {
    cfg.push_back(argv[1]);
  } else if(argc==3) {
    cfg.push_back(argv[1]);
    cfg.push_back(argv[2]);
  } else {
    cfg.push_back(CONFIG_FILE);
  }
  time_t mtime;
  struct stat s;
  if (stat(cfg[cfg_num].c_str(), &s) == 0) {
    mtime = s.st_mtime;
  } else {
    mtime = 0;
  }
  cout << "BBC MDI Generator Rev " << svn_version()
       << ", using libsdixml Rev " << libsdixml::svn_version() << endl
       << "Implementing SDI Schema version " << libsdixml::SDI_Schema_version()
       << endl << "Reading config from " << cfg[cfg_num] << endl; cout.flush();
  Mdigen mdigen;
  /*
  DcpIn dcpin;
  dcpin.ReConfigure("dcp.udp://:9998");
  tagpacketlist t;
  dcpin.getFrame(t);
  for(tagpacketlist::iterator i=t.begin(); i!=t.end(); i++)
    cout << i->first << " " << i->second.size() << endl;
  */
#ifdef WIN32
 int iResult;
 WSADATA wsaData;
 // Initialize Winsock

 iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
 if (iResult != 0) {
    printf("WSAStartup failed: %d\n", iResult);
    exit(1);
 }
#else
  struct sigaction sa;
  sa.sa_flags = SA_SIGINFO;
  sigemptyset(&sa.sa_mask);
  sa.sa_sigaction = signal_handler;
  if (sigaction(SIGHUP, &sa, NULL) == -1)
  {
  	cerr << "error assigning signal handler" << endl;
	exit(1);
  }
  FAMConnection fc;
  if(FAMOpen(&fc)==0)
  {
    FAMRequest fr;
	if(cfg[0][0]!='/')
	{
			string path = getenv("PWD");
			cerr << path << endl;
			cfg[0] = path + "/" + cfg[0];
	}
    if(FAMMonitorFile(&fc, cfg[0].c_str(), &fr, NULL))
      cerr << "can't monitor " << cfg[0] << endl;
    else
      cout << "FAM Monitoring " << cfg[0] << endl;
  } else {
      cerr << "can't connect to file alteration monitor " << endl;
  }

#endif
  bool ok = true;
  int max_frames = -1;
  int reconf_interval = 32;
  int reconf = reconf_interval;
  ReConfigure(mdigen, cfg[cfg_num], ok, max_frames);
  while(ok) {
    try {
      mdigen.eachframe();
	  //cout << "Frame: " << mdigen.transmitted_frames << endl;
#ifndef WIN32
  while(FAMPending(&fc))
  {
    FAMEvent fe;
    FAMNextEvent(&fc, &fe);
	switch(fe.code)
	{
	case FAMDeleted:
	  break;
    case FAMChanged:
          cout << "file alteration monitor detected config change" << endl;
          reconfiguration_requested = true;
	  break;
    case FAMCreated:
    case FAMExists:
	  break;
    case FAMEndExist:
	  cout << "FAM initialised " << fe.filename << endl;
	  break;
    case FAMAcknowledge:
	  cout << "FAM cancel acknowledged " << fe.filename << endl;
	  break;
    case FAMStartExecuting:
    case FAMStopExecuting:
    case FAMMoved:
	  cout << "unexpected fam event " << fe.code << " '" << fe.filename << "'" << endl;
	  break;
    default:
	  cout << "unknown fam event " << fe.code << " '" << fe.filename << "'" << endl;
}
}
#endif
    }
    catch(char const* e) {
      cerr << e << endl; cerr.flush();
    }
    if(reconfiguration_requested) {
      ReConfigure(mdigen, cfg[cfg_num], ok, max_frames);
    }
	if(cfg.size()>1)
	{
	  reconf--;
	  if(reconf==0)
	  {
	    cfg_num = 1 - cfg_num;
        ReConfigure(mdigen, cfg[cfg_num], ok, max_frames);
		reconf = reconf_interval;
	  }
	}
    if(max_frames!=-1 && mdigen.transmitted_frames > max_frames)
      break;
  }
}