示例#1
0
void watch_limit()
{
    ENTER
    verify((0 == mkdir(TEST_DIR, 0700)) || (EEXIST == errno));

    INFO("Warning, this test may take a while\n");
#define INNER_LIMIT 16000
#define OUTER_LIMIT 5

    verify(inotifytools_initialize());
    inotifytools_initialize_stats();

    for (int j = 0; j < OUTER_LIMIT; ++j)
    {
        char fn[1024];
        int max = 0;
        for (int i = 0; i < INNER_LIMIT; ++i)
        {
            snprintf(fn, 1023, "%s/%d", TEST_DIR, i);
            int fd = creat(fn, 0700);
            verify(-1 != fd);
            verify(0 == close(fd));
            int ret = inotifytools_watch_file(fn, IN_ALL_EVENTS);
            verify(ret || inotifytools_error() == ENOSPC);
            if (ret)
            {
                max = i + 1;
                int wd = inotifytools_wd_from_filename(fn);
                verify(wd > 0);
                verify(!strcmp(fn, inotifytools_filename_from_wd(wd)));
            }
        }

        compare(inotifytools_get_num_watches(), max);

        for (int i = 0; i < max; ++i)
        {
            snprintf(fn, 1023, "%s/%d", TEST_DIR, i);
            verify(inotifytools_remove_watch_by_filename(fn));
        }
    }
    EXIT
}
示例#2
0
int main(int argc, char ** argv)
{
	events = 0;
	int timeout = 0;
	int verbose = 0;
	zero = 0;
	int recursive = 0;
	char * fromfile = 0;
	sort = -1;
	done = false;
	char * regex = NULL;
	char * iregex = NULL;

	signal( SIGINT, handle_impatient_user );

	// Parse commandline options, aborting if something goes wrong
	if ( !parse_opts( &argc, &argv, &events, &timeout, &verbose, &zero, &sort,
	                 &recursive, &fromfile, &regex, &iregex ) ) {
		return EXIT_FAILURE;
	}

	if (
		(regex && !inotifytools_ignore_events_by_regex(regex, REG_EXTENDED) ) ||
		(iregex && !inotifytools_ignore_events_by_regex(iregex, REG_EXTENDED|
		                                                        REG_ICASE))
	) {
		fprintf(stderr, "Error in `exclude' regular expression.\n");
		return EXIT_FAILURE;
	}

	if ( !inotifytools_initialize() ) {
		fprintf(stderr, "Couldn't initialize inotify.  Are you running Linux "
		                "2.6.13 or later, and was the\n"
		                "CONFIG_INOTIFY option enabled when your kernel was "
		                "compiled?  If so, \n"
		                "something mysterious has gone wrong.  Please e-mail "
		                PACKAGE_BUGREPORT "\n"
		                " and mention that you saw this message.\n");
		return EXIT_FAILURE;
	}

	// Attempt to watch file
	// If events is still 0, make it all events.
	if ( !events )
		events = IN_ALL_EVENTS;

	FileList list = construct_path_list( argc, argv, fromfile );

	if (0 == list.watch_files[0]) {
		fprintf(stderr, "No files specified to watch!\n");
		return EXIT_FAILURE;
	}

	unsigned int num_watches = 0;
	unsigned int status;
	fprintf( stderr, "Establishing watches...\n" );
  int i;
	for ( i = 0; list.watch_files[i]; ++i ) {
		char const *this_file = list.watch_files[i];
		if ( recursive && verbose ) {
			fprintf( stderr, "Setting up watch(es) on %s\n", this_file );
		}

		if ( recursive ) {
			status = inotifytools_watch_recursively_with_exclude(
			                               this_file,
			                               events,
			                               list.exclude_files );
		}
		else {
			status = inotifytools_watch_file( this_file, events );
		}
		if ( !status ) {
			if ( inotifytools_error() == ENOSPC ) {
				fprintf(stderr, "Failed to watch %s; upper limit on inotify "
				                "watches reached!\n", this_file );
				fprintf(stderr, "Please increase the amount of inotify watches "
				        "allowed per user via `/proc/sys/fs/inotify/"
				        "max_user_watches'.\n");
			}
			else {
				fprintf(stderr, "Failed to watch %s: %s\n", this_file,
				        strerror( inotifytools_error() ) );
			}
			return EXIT_FAILURE;
		}
		if ( recursive && verbose ) {
			fprintf( stderr, "OK, %s is now being watched.\n", this_file );
		}
	}
	num_watches = inotifytools_get_num_watches();

	if ( verbose ) {
		fprintf( stderr, "Total of %d watches.\n",
		         num_watches );
	}
	fprintf( stderr, "Finished establishing watches, now collecting statistics.\n" );

	if ( timeout && verbose ) {
		fprintf( stderr, "Will listen for events for %d seconds.\n", timeout );
	}

	signal( SIGINT, handle_signal );
	signal( SIGHUP, handle_signal );
	signal( SIGTERM, handle_signal );
	if ( timeout ) {
		signal( SIGALRM, handle_signal );
		alarm( timeout );
	}
        signal( SIGUSR1, print_info_now );

	inotifytools_initialize_stats();
	// Now wait till we get event
	struct inotify_event * event;
	char * moved_from = 0;

	do {
		event = inotifytools_next_event( 0 );
		if ( !event ) {
			if ( !inotifytools_error() ) {
				return EXIT_TIMEOUT;
			}
			else if ( inotifytools_error() != EINTR ) {
				fprintf(stderr, "%s\n", strerror( inotifytools_error() ) );
				return EXIT_FAILURE;
			}
			else {
				continue;
			}
		}

		// if we last had MOVED_FROM and don't currently have MOVED_TO,
		// moved_from file must have been moved outside of tree - so unwatch it.
		if ( moved_from && !(event->mask & IN_MOVED_TO) ) {
			if ( !inotifytools_remove_watch_by_filename( moved_from ) ) {
				fprintf( stderr, "Error removing watch on %s: %s\n",
				         moved_from, strerror(inotifytools_error()) );
			}
			free( moved_from );
			moved_from = 0;
		}

		if ( recursive ) {
			if ((event->mask & IN_CREATE) ||
			    (!moved_from && (event->mask & IN_MOVED_TO))) {
				// New file - if it is a directory, watch it
				static char * new_file;

				nasprintf( &new_file, "%s%s",
				           inotifytools_filename_from_wd( event->wd ),
				           event->name );

				if ( isdir(new_file) &&
				    !inotifytools_watch_recursively( new_file, events ) ) {
					fprintf( stderr, "Couldn't watch new directory %s: %s\n",
					         new_file, strerror( inotifytools_error() ) );
				}
				free( new_file );
			} // IN_CREATE
			else if (event->mask & IN_MOVED_FROM) {
				nasprintf( &moved_from, "%s%s/",
				           inotifytools_filename_from_wd( event->wd ),
				           event->name );
				// if not watched...
				if ( inotifytools_wd_from_filename(moved_from) == -1 ) {
					free( moved_from );
					moved_from = 0;
				}
			} // IN_MOVED_FROM
			else if (event->mask & IN_MOVED_TO) {
				if ( moved_from ) {
					static char * new_name;
					nasprintf( &new_name, "%s%s/",
					           inotifytools_filename_from_wd( event->wd ),
					           event->name );
					inotifytools_replace_filename( moved_from, new_name );
					free( moved_from );
					moved_from = 0;
				} // moved_from
			}
		}

	} while ( !done );
        return print_info();
}