[Mono-dev] FileSystemWatcher Issue?

Rick Tillery rtillerywork at gmail.com
Tue Aug 1 20:18:07 UTC 2017


After some additional tests, I found that the order the watches are enabled
makes a difference.  After modifying the following line of code in
EnableWatches():

       foreach (KeyValuePair<string, FileSystemWatcher> watch in watches)

to

       foreach (KeyValuePair<string, FileSystemWatcher> watch in
watches.Reverse())

(and adding "using System.Linq"), which causes the target file (bar) watch
to be enabled before the link file (foo) watch, I found that copying over
the link file with another file (mv foobar foo) does not register an event
(it did before), but copying over the target (mv foobar bar) does (it did
not before).

I haven't found a way to make both work at the same time, yet.  But I have
not found another combination that fails to generate an event, no matter
which one is enabled first.
(e.g. "cp foobar foo", "cp foobar bar", "rm foo", "rm bar", "mv foo
foobar", "mv bar foobar", "echo >foo 'test'", "echo >bar 'test'", "echo
>>foo 'test'", "echo >>bar 'test'", "touch foo", "touch bar", "ln -s foobar
bar", "vi foo" :w, "vi bar" :w, "nano foo" ctrl-o, "nano bar" ctrl-o,
"gedit foo" save, "gedit bar" save, etc.)

Is there something I'm doing wrong here?

Rick


On Mon, Jul 31, 2017 at 1:22 PM, Rick Tillery <rtillerywork at gmail.com>
wrote:

> I'm sorry, I neglected to specify the environments:
>
> mono 5.0.1.1
> CentOS 7 & Ubuntu 16.04
>
> Rick
>
> On Mon, Jul 31, 2017 at 11:46 AM, Rick Tillery <rtillerywork at gmail.com>
> wrote:
>
>> In conjunction with "Sync of mono Cert Store," I'm trying to utilize
>> FileSystemWatcher to monitor the system certificate file for changes (which
>> will trigger a cert-sync).
>>
>> Since some distros use the legacy address (/etc/pki/tls/certs/ca-bundle.crt)
>> as a symbolic link, and modification of the system cert store appears to be
>> a free-for-all between using the update-ca-trust
>> <http://www.unix.com/man-page/centos/8/update-ca-trust/> or
>> update-ca-certificates
>> <http://manpages.ubuntu.com/manpages/precise/man8/update-ca-certificates.8.html>
>> scripts, running other utilities
>> <https://access.redhat.com/documentation/en-US/Red_Hat_Certificate_System/8.1/html/Admin_Guide/Managing_the_Certificate_Database.html>,
>> modifying the file directly
>> <https://www.happyassassin.net/2015/01/14/trusting-additional-cas-in-fedora-rhel-centos-dont-append-to-etcpkitlscertsca-bundle-crt-or-etcpkitlscert-pem/>,
>> and even replacing the file completely
>> <https://techjourney.net/update-add-ca-certificates-bundle-in-redhat-centos/>,
>> I have been testing as many file manipulation combinations as I can
>> imagine, to ensure FileSystemWatcher catches them all.
>>
>> In doing so, I found an issue in FileSystemWatcher.
>>
>> To handle the symbolic link case, FileSystemWatcher objects are set up
>> for each file in the chain, symbolic link and target alike.  In one test,
>> the target of a symbolic link is replaced by another file using mv.  But
>> FileSystemWatcher does not register the change.  Oddly, if only a watch of
>> the target file is registered, FileSystemWatcher registers the change.
>>
>> The code I'm using is attached.  Here is what I see on command line:
>>
>> (console1) ~$ echo >bar "test"
>> (console1) ~$ echo >foobar "test1"
>> (console1) ~$ ln -s bar foo
>> (console1) ~$ ll
>> total 24
>> -rw-rw-r--. 1 rtillery rtillery      5 Jul 31 11:06 bar
>> lrwxrwxrwx. 1 rtillery rtillery      3 Jul 31 11:06 foo -> bar
>> -rw-rw-r--. 1 rtillery rtillery      6 Jul 31 11:06 foobar
>> -rwxrwxr-x. 1 rtillery rtillery   5632 Jul 31 11:05 fsw.exe
>> (console1) ~$ mono fsw.exe ./bar
>> Watching: /home/rtillery/bar
>> bar watching ENABLED
>> Press 'Q' to quit
>>
>> (console2) ~$ mv foobar bar
>>
>> (console1)
>> File: /home/rtillery/foobar renamed to /home/rtillery/bar
>>
>> ...
>>
>> (console1) ~$ mono fsw.exe ./foo
>> Watching: /home/rtillery/foo
>> Watching: /home/rtillery/bar
>> foo watching ENABLED
>> bar watching ENABLED
>> Press 'Q' to quit
>>
>> (console2) ~$ echo >foobar "test"
>> (console2) ~$ mv foobar bar
>>
>>
>> Nothing appears on console 1 in the second case, but I don't really see
>> why.  I believe I'm setting up the watches in exactly the same way, except
>> that there are two instead of one.  Is this a problem with
>> FileSystemWatcher?  Code is below.
>>
>> Thanks,
>> Rick
>>
>> using System;
>> using System.Collections.Generic;
>> using System.IO;
>> using Mono.Unix;
>>
>> // Compile with "mcs fsw.cs /r:Mono.Posix.dll"
>>
>> public class FSW
>> {
>>     private static IDictionary<string, FileSystemWatcher> watches = new
>> Dictionary<string, FileSystemWatcher>();
>>
>>     public static void Main()
>>     {
>>         string[] args = System.Environment.GetCommandLineArgs();
>>         if (args.Length != 2)
>>         {
>>             System.Console.WriteLine("USAGE: (mono) fswtest(.exe)
>> file_to_watch");
>>             goto Error;
>>         }
>>
>>         SetUpWatch(args[1]);
>>
>>         Console.WriteLine("Press \'Q\' to quit.");
>>         while(Console.Read() != 'q')
>>             ;
>>
>>     Error:
>>         ;
>>     }
>>
>>     private static void SetUpWatch(string file)
>>     {
>>         do
>>         {
>>             AddWatch(file);
>>             file = GetSymbolicLinkTarget(file);
>>         }
>>         while (file != null);
>>         EnableWatches();
>>     }
>>
>>     private static void AddWatch(string file)
>>     {
>>         FileSystemWatcher watcher = new FileSystemWatcher();
>>         watcher.Path = Path.GetDirectoryName(file);
>>         watcher.NotifyFilter = 0
>> //          | NotifyFilters.Attributes
>> //          | NotifyFilters.CreationTime
>>           | NotifyFilters.DirectoryName
>>           | NotifyFilters.FileName
>>           | NotifyFilters.LastAccess
>>           | NotifyFilters.LastWrite
>> //          | NotifyFilters.Security
>> //          | NotifyFilters.Size
>>           ;
>>         watcher.Filter = Path.GetFileName(file);
>>         watcher.Changed += new FileSystemEventHandler(OnChanged);
>>         watcher.Created += new FileSystemEventHandler(OnChanged);
>>         watcher.Deleted += new FileSystemEventHandler(OnChanged);
>> //        watcher.Disposed // Occurs when the component is disposed by a
>> call to the Dispose method. (Inherited from Component.)
>> //        watcher.Error // Occurs when the instance of FileSystemWatcher
>> is unable to continue monitoring changes or when the internal buffer
>> overflows.
>>         watcher.Renamed += new RenamedEventHandler(OnRenamed);
>>         watches.Add(Path.GetFullPath(file), watcher);
>> Console.WriteLine("Watching: " + Path.GetFullPath(file));
>>     }
>>
>>     private static string GetSymbolicLinkTarget(string file)
>>     {
>>         UnixSymbolicLinkInfo link = new UnixSymbolicLinkInfo(file);
>>         return link.HasContents ? link.GetContents().FullName : null;
>>     }
>>
>>     private static void EnableWatches()
>>     {
>>         foreach (KeyValuePair<string, FileSystemWatcher> watch in watches)
>>         {
>>             watch.Value.EnableRaisingEvents = true;
>> Console.WriteLine("" + watch.Value.Filter + " watching ENABLED");
>>         }
>>     }
>>
>>     private static void OnChanged(object source, FileSystemEventArgs
>> eventargs)
>>     {
>>         Console.WriteLine("File: \"" + eventargs.FullPath + "\" -- " +
>> eventargs.ChangeType);
>>     }
>>
>>     private static void OnRenamed(object source, RenamedEventArgs
>> eventargs)
>>     {
>>         Console.WriteLine("File: {0} renamed to {1}",
>> eventargs.OldFullPath, eventargs.FullPath);
>>     }
>> }
>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.dot.net/pipermail/mono-devel-list/attachments/20170801/7340d348/attachment.html>


More information about the Mono-devel-list mailing list