summaryrefslogtreecommitdiff
path: root/vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2
diff options
context:
space:
mode:
authorBenjamin Sanders <ben@Benjamins-MacBook-Pro.local>2025-10-11 10:34:24 -0400
committerBenjamin Sanders <ben@Benjamins-MacBook-Pro.local>2025-10-11 10:34:24 -0400
commit5571dc766e2143e39762ff0b47c41d1c2e154f4c (patch)
treef4f124d314a7e76c04484515aa0fd1f2e271a601 /vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2
parent359f3309c97fc894b63e0a295c76ab298504d635 (diff)
Vendor bundled gems for deployment
Diffstat (limited to 'vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2')
-rw-r--r--vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/.gitignore13
-rw-r--r--vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/Gemfile3
-rw-r--r--vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/Guardfile8
-rw-r--r--vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/LICENSE.txt22
-rw-r--r--vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/README.md260
-rw-r--r--vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/Rakefile33
-rwxr-xr-xvendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/bin/fsevent_watchbin0 -> 127962 bytes
-rw-r--r--vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/ext/LICENSE21
-rw-r--r--vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/ext/fsevent_watch/FSEventsFix.c626
-rw-r--r--vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/ext/fsevent_watch/FSEventsFix.h105
-rw-r--r--vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/ext/fsevent_watch/TSICTString.c373
-rw-r--r--vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/ext/fsevent_watch/TSICTString.h74
-rw-r--r--vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/ext/fsevent_watch/cli.c201
-rw-r--r--vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/ext/fsevent_watch/cli.h45
-rw-r--r--vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/ext/fsevent_watch/common.h22
-rw-r--r--vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/ext/fsevent_watch/compat.c41
-rw-r--r--vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/ext/fsevent_watch/compat.h100
-rw-r--r--vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/ext/fsevent_watch/defines.h42
-rw-r--r--vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/ext/fsevent_watch/main.c548
-rw-r--r--vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/ext/fsevent_watch/signal_handlers.c66
-rw-r--r--vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/ext/fsevent_watch/signal_handlers.h16
-rw-r--r--vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/ext/rakefile.rb231
-rw-r--r--vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/lib/otnetstring.rb85
-rw-r--r--vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/lib/rb-fsevent.rb3
-rw-r--r--vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/lib/rb-fsevent/fsevent.rb157
-rw-r--r--vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/lib/rb-fsevent/version.rb5
-rw-r--r--vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/rb-fsevent.gemspec26
27 files changed, 3126 insertions, 0 deletions
diff --git a/vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/.gitignore b/vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/.gitignore
new file mode 100644
index 0000000..25a0e9a
--- /dev/null
+++ b/vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/.gitignore
@@ -0,0 +1,13 @@
+*.gem
+.DS_Store
+.Trashes
+.bundle
+.com.apple.timemachine.supported
+.fseventsd
+.idea
+.rbx
+/ext/build
+Desktop DB
+Desktop DF
+Gemfile.lock
+pkg/*
diff --git a/vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/Gemfile b/vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/Gemfile
new file mode 100644
index 0000000..b4e2a20
--- /dev/null
+++ b/vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/Gemfile
@@ -0,0 +1,3 @@
+source "https://rubygems.org"
+
+gemspec
diff --git a/vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/Guardfile b/vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/Guardfile
new file mode 100644
index 0000000..63a666e
--- /dev/null
+++ b/vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/Guardfile
@@ -0,0 +1,8 @@
+# A sample Guardfile
+# More info at http://github.com/guard/guard#readme
+
+guard :rspec do
+ watch(%r(^spec/(.*)_spec.rb))
+ watch(%r(^lib/(.*)\.rb)) { |m| "spec/#{m[1]}_spec.rb" }
+ watch('spec/spec_helper.rb') { 'spec' }
+end
diff --git a/vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/LICENSE.txt b/vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/LICENSE.txt
new file mode 100644
index 0000000..b083ecd
--- /dev/null
+++ b/vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/LICENSE.txt
@@ -0,0 +1,22 @@
+Copyright (c) 2010-2014 Thibaud Guillaume-Gentil & Travis Tilley
+
+MIT License
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/README.md b/vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/README.md
new file mode 100644
index 0000000..3d87bcc
--- /dev/null
+++ b/vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/README.md
@@ -0,0 +1,260 @@
+[![Code Climate](https://codeclimate.com/badge.png)](https://codeclimate.com/github/thibaudgg/rb-fsevent)
+[![endorse](https://api.coderwall.com/ttilley/endorsecount.png)](https://coderwall.com/ttilley)
+
+# rb-fsevent
+
+Very simple & usable Mac OSX FSEvents API
+
+* Signals are working (really)
+* Tested on MRI 2.4.1, RBX 3.72, JRuby 1.7.26 and 9.1.8.0
+* Tested on 10.8
+
+## HFS+ filename corruption bug
+
+There is a _very_ long-standing (since 2011) OSX bug where sometimes the filename metadata for HFS+ filesystems will get corrupted, resulting in some APIs returning one case for a file, and other APIs returning another. The result is that sometimes, _for no visible reason to the user_, fsevents would simply not work. As of rb-fsevent 0.9.5 this issue is properly detected and an insanely hacky (but effective) workaround is used that replaces the system `realpath()` with a custom implementation that should almost always return the same value as the kernel reporting (thus fixing fsevents). The major flaw in the workaround is that it may return the wrong path for hard links.
+
+Please note that this doesn't repair the underlying issue on disk. Other apps and libraries using fsevents will continue to break with no warning. There may be other issues unrelated to fsevents.
+
+__This bug is resolved in MacOS 10.12 and all users are strongly encouraged to upgrade.__
+
+## Install
+
+ gem install rb-fsevent
+
+### re-compilation
+
+rb-fsevent comes with a pre-compiled fsevent\_watch binary supporting x86\_64 on 10.9 and above. The binary is codesigned with my (Travis Tilley) Developer ID as an extra precaution when distributing pre-compiled code and contains an embedded plist describing its build environment. This should be sufficient for most users, but if you need to use rb-fsevent on 10.8 or lower then recompilation is necessary. This can be done by entering the installed gem's ext directory and running:
+
+ MACOSX_DEPLOYMENT_TARGET="10.7" rake replace_exe
+
+The following ENV vars are recognized:
+
+* CC
+* CFLAGS
+* ARCHFLAGS
+* MACOSX\_DEPLOYMENT\_TARGET
+* FWDEBUG (enables debug mode, printing an obscene number of informational
+ messages to STDERR)
+
+### embedded plist
+
+You can retrieve the values in the embedded plist via the CLI:
+
+ fsevent_watch --show-plist
+
+The output is essentially formatted as `"#{key}:\n #{value}\n"` to make it easier to read than plist style xml. The result looks like this:
+
+ DTSDKName:
+ macosx10.5
+ FSEWBuildTriple:
+ i386-apple-darwin10.8.0
+ FSEWCC:
+ /usr/bin/gcc-4.2
+ DTSDKPath:
+ /Developer/SDKs/MacOSX10.5.sdk
+ FSEWCCVersion:
+ i686-apple-darwin10-gcc-4.2.1 (GCC) 4.2.1 (Apple Inc. build 5666) (dot 3)
+ FSEWCFLAGS:
+ -fconstant-cfstrings -fno-strict-aliasing -Wall -mmacosx-version-min=10.5 -O3
+
+If, for some perverse reason, you prefer to look at the xml... it can be retrieved via:
+
+ otool -s __TEXT __info_plist ./bin/fsevent_watch | grep ^0 | xxd -r -
+
+### codesign
+
+You can verify code signing information for a specific fsevent\_watch via:
+
+ codesign -d -vvv ./bin/fsevent_watch
+
+If you're using the pre-compiled binary, then the output should contain something to the effect of:
+
+ Authority=Developer ID Application: Travis Tilley
+ Authority=Developer ID Certification Authority
+ Authority=Apple Root CA
+ Timestamp=Dec 31, 2012 12:49:13 PM
+
+## Usage
+
+### Singular path
+
+```ruby
+require 'rb-fsevent'
+
+fsevent = FSEvent.new
+fsevent.watch Dir.pwd do |directories|
+ puts "Detected change inside: #{directories.inspect}"
+end
+fsevent.run
+```
+
+### Multiple paths
+
+```ruby
+require 'rb-fsevent'
+
+paths = ['/tmp/path/one', '/tmp/path/two', Dir.pwd]
+
+fsevent = FSEvent.new
+fsevent.watch paths do |directories|
+ puts "Detected change inside: #{directories.inspect}"
+end
+fsevent.run
+```
+
+### Multiple paths and additional options as a Hash
+
+```ruby
+require 'rb-fsevent'
+
+paths = ['/tmp/path/one', '/tmp/path/two', Dir.pwd]
+options = {:latency => 1.5, :no_defer => true }
+
+fsevent = FSEvent.new
+fsevent.watch paths, options do |directories|
+ puts "Detected change inside: #{directories.inspect}"
+end
+fsevent.run
+```
+
+### Multiple paths and additional options as an Array
+
+```ruby
+require 'rb-fsevent'
+
+paths = ['/tmp/path/one', '/tmp/path/two', Dir.pwd]
+options = ['--latency', 1.5, '--no-defer']
+
+fsevent = FSEvent.new
+fsevent.watch paths, options do |directories|
+ puts "Detected change inside: #{directories.inspect}"
+end
+fsevent.run
+```
+
+### Using _full_ event information
+
+```ruby
+require 'rb-fsevent'
+fsevent = FSEvent.new
+fsevent.watch Dir.pwd do |paths, event_meta|
+ event_meta['events'].each do |event|
+ puts "event ID: #{event['id']}"
+ puts "path: #{event['path']}"
+ puts "c flags: #{event['cflags']}"
+ puts "named flags: #{event['flags'].join(', ')}"
+ # named flags will include strings such as `ItemInodeMetaMod` or `OwnEvent`
+ end
+end
+fsevent.run
+```
+
+## Options
+
+When defining options using a hash or hash-like object, it gets checked for validity and converted to the appropriate fsevent\_watch commandline arguments array when the FSEvent class is instantiated. This is obviously the safest and preferred method of passing in options.
+
+You may, however, choose to pass in an array of commandline arguments as your options value and it will be passed on, unmodified, to the fsevent\_watch binary when called.
+
+So far, the following options are supported:
+
+* :latency => 0.5 # in seconds
+* :no\_defer => true
+* :watch\_root => true
+* :since\_when => 18446744073709551615 # an FSEventStreamEventId
+* :file\_events => true
+
+### Latency
+
+The :latency parameter determines how long the service should wait after the first event before passing that information along to the client. If your latency is set to 4 seconds, and 300 changes occur in the first three, then the callback will be fired only once. If latency is set to 0.1 in the exact same scenario, you will see that callback fire somewhere closer to between 25 and 30 times.
+
+Setting a higher latency value allows for more effective temporal coalescing, resulting in fewer callbacks and greater overall efficiency... at the cost of apparent responsiveness. Setting this to a reasonably high value (and NOT setting :no\_defer) is particularly well suited for background, daemon, or batch processing applications.
+
+Implementation note: It appears that FSEvents will only coalesce events from a maximum of 32 distinct subpaths, making the above completely accurate only when events are to fewer than 32 subpaths. Creating 300 files in one directory, for example, or 30 files in 10 subdirectories, but not 300 files within 300 subdirectories. In the latter case, you may receive 31 callbacks in one go after the latency period. As this appears to be an implementation detail, the number could potentially differ across OS revisions. It is entirely possible that this number is somehow configurable, but I have not yet discovered an accepted method of doing so.
+
+### NoDefer
+
+The :no\_defer option changes the behavior of the latency parameter completely. Rather than waiting for $latency period of time before sending along events in an attempt to coalesce a potential deluge ahead of time, that first event is sent along to the client immediately and is followed by a $latency period of silence before sending along any additional events that occurred within that period.
+
+This behavior is particularly useful for interactive applications where that feeling of apparent responsiveness is most important, but you still don't want to get overwhelmed by a series of events that occur in rapid succession.
+
+### WatchRoot
+
+The :watch\_root option allows for catching the scenario where you start watching "~/src/demo\_project" and either it is later renamed to "~/src/awesome\_sauce\_3000" or the path changes in such a manner that the original directory is now at "~/clients/foo/iteration4/demo\_project".
+
+Unfortunately, while this behavior is somewhat supported in the fsevent\_watch binary built as part of this project, support for passing across detailed metadata is not (yet). As a result, you would not receive the appropriate RootChanged event and be able to react appropriately. Also, since the C code doesn't open watched directories and retain that file descriptor as part of path-specific callback metadata, we are unable to issue an F\_GETPATH fcntl() to determine the directory's new path.
+
+Please do not use this option until proper support is added (or, even better, add it and submit a pull request).
+
+### SinceWhen
+
+The FSEventStreamEventId passed in to :since\_when is used as a base for reacting to historic events. Unfortunately, not only is the metadata for transitioning from historic to live events not currently passed along, but it is incorrectly passed as a change event on the root path, and only per-host event streams are currently supported. When using per-host event streams, the event IDs are not guaranteed to be unique or contiguous when shared volumes (firewire/USB/net/etc) are used on multiple macs.
+
+Please do not use this option until proper support is added, unless it's acceptable for you to receive that one fake event that's handled incorrectly when events transition from historical to live. Even in that scenario, there's no metadata available for determining the FSEventStreamEventId of the last received event.
+
+WARNING: passing in 0 as the parameter to :since\_when will return events for every directory modified since "the beginning of time".
+
+### FileEvents ###
+
+Prepare yourself for an obscene number of callbacks. Realistically, an "Atomic Save" could easily fire maybe 6 events for the combination of creating the new file, changing metadata/permissions, writing content, swapping out the old file for the new may itself result in multiple events being fired, and so forth. By the time you get the event for the temporary file being created as part of the atomic save, it will already be gone and swapped with the original file. This and issues of a similar nature have prevented me from adding the option to the ruby code despite the fsevent\_watch binary supporting file level events for quite some time now. Mountain Lion seems to be better at coalescing needless events, but that might just be my imagination.
+
+## Debugging output
+
+If the gem is re-compiled with the environment variable FWDEBUG set, then fsevent\_watch will be built with its various DEBUG sections defined, and the output to STDERR is truly verbose (and hopefully helpful in debugging your application and not just fsevent\_watch itself). If enough people find this to be directly useful when developing code that makes use of rb-fsevent, then it wouldn't be hard to clean this up and make it a feature enabled by a commandline argument instead. Until somebody files an issue, however, I will assume otherwise.
+
+ append_path called for: /tmp/moo/cow/
+ resolved path to: /private/tmp/moo/cow
+
+ config.sinceWhen 18446744073709551615
+ config.latency 0.300000
+ config.flags 00000000
+ config.paths
+ /private/tmp/moo/cow
+
+ FSEventStreamRef @ 0x100108540:
+ allocator = 0x7fff705a4ee0
+ callback = 0x10000151e
+ context = {0, 0x0, 0x0, 0x0, 0x0}
+ numPathsToWatch = 1
+ pathsToWatch = 0x7fff705a4ee0
+ pathsToWatch[0] = '/private/tmp/moo/cow'
+ latestEventId = -1
+ latency = 300000 (microseconds)
+ flags = 0x00000000
+ runLoop = 0x0
+ runLoopMode = 0x0
+
+ FSEventStreamCallback fired!
+ numEvents: 32
+ event path: /private/tmp/moo/cow/1/a/
+ event flags: 00000000
+ event ID: 1023767
+ event path: /private/tmp/moo/cow/1/b/
+ event flags: 00000000
+ event ID: 1023782
+ event path: /private/tmp/moo/cow/1/c/
+ event flags: 00000000
+ event ID: 1023797
+ event path: /private/tmp/moo/cow/1/d/
+ event flags: 00000000
+ event ID: 1023812
+ [etc]
+
+
+## Development
+
+* Source hosted at [GitHub](http://github.com/thibaudgg/rb-fsevent)
+* Report issues/Questions/Feature requests on [GitHub Issues](http://github.com/thibaudgg/rb-fsevent/issues)
+
+Pull requests are quite welcome! Please ensure that your commits are in a topic branch for each individual changeset that can be reasonably isolated. It is also important to ensure that your changes are well tested... whether that means new tests, modified tests, or fixing a scenario where the existing tests currently fail. If you have rbenv and ruby-build, we have a helper task for running the testsuite in all of them:
+
+ rake spec:portability
+
+The list of tested targets is currently:
+
+ %w[2.4.1 rbx-3.72 jruby-1.7.26 jruby-9.1.8.0]
+
+## Authors
+
+* [Travis Tilley](http://github.com/ttilley)
+* [Thibaud Guillaume-Gentil](http://github.com/thibaudgg)
+* [Andrey Tarantsov](https://github.com/andreyvit)
diff --git a/vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/Rakefile b/vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/Rakefile
new file mode 100644
index 0000000..53a08a1
--- /dev/null
+++ b/vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/Rakefile
@@ -0,0 +1,33 @@
+# -*- encoding: utf-8 -*-
+require 'bundler'
+Bundler::GemHelper.install_tasks
+
+require 'rspec/core/rake_task'
+RSpec::Core::RakeTask.new(:spec)
+task :default => :spec
+
+namespace(:spec) do
+ desc "Run all specs on multiple ruby versions"
+ task(:portability) do
+ versions = %w[2.4.1 rbx-3.72 jruby-1.7.26 jruby-9.1.8.0]
+ versions.each do |version|
+ # system <<-BASH
+ # bash -c 'source ~/.rvm/scripts/rvm;
+ # rvm #{version};
+ # echo "--------- version #{version} ----------\n";
+ # bundle install;
+ # rake spec'
+ # BASH
+ system <<-BASH
+ bash -c 'export PATH="$HOME/.rbenv/bin:$PATH";
+ [[ `which rbenv` ]] && eval "$(rbenv init -)";
+ [[ ! -a $HOME/.rbenv/versions/#{version} ]] && rbenv install #{version};
+ rbenv shell #{version};
+ rbenv which bundle 2> /dev/null || gem install bundler;
+ rm Gemfile.lock;
+ bundle install;
+ rake spec;'
+ BASH
+ end
+ end
+end
diff --git a/vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/bin/fsevent_watch b/vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/bin/fsevent_watch
new file mode 100755
index 0000000..4fb821d
--- /dev/null
+++ b/vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/bin/fsevent_watch
Binary files differ
diff --git a/vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/ext/LICENSE b/vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/ext/LICENSE
new file mode 100644
index 0000000..a35e195
--- /dev/null
+++ b/vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/ext/LICENSE
@@ -0,0 +1,21 @@
+Copyright (c) 2011-2013 Travis Tilley
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
diff --git a/vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/ext/fsevent_watch/FSEventsFix.c b/vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/ext/fsevent_watch/FSEventsFix.c
new file mode 100644
index 0000000..60e3d37
--- /dev/null
+++ b/vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/ext/fsevent_watch/FSEventsFix.c
@@ -0,0 +1,626 @@
+/*
+ * FSEventsFix
+ *
+ * Resolves a long-standing bug in realpath() that prevents FSEvents API from
+ * monitoring certain folders on a wide range of OS X released (10.6-10.10 at least).
+ *
+ * The underlying issue is that for some folders, realpath() call starts returning
+ * a path with incorrect casing (e.g. "/users/smt" instead of "/Users/smt").
+ * FSEvents is case-sensitive and calls realpath() on the paths you pass in, so
+ * an incorrect value returned by realpath() prevents FSEvents from seeing any
+ * change events.
+ *
+ * See the discussion at https://github.com/thibaudgg/rb-fsevent/issues/10 about
+ * the history of this bug and how this library came to exist.
+ *
+ * This library uses Facebook's fishhook to replace a custom implementation of
+ * realpath in place of the system realpath; FSEvents will then invoke our custom
+ * implementation (which does not screw up the names) and will thus work correctly.
+ *
+ * Our implementation of realpath is based on the open-source implementation from
+ * OS X 10.10, with a single change applied (enclosed in "BEGIN WORKAROUND FOR
+ * OS X BUG" ... "END WORKAROUND FOR OS X BUG").
+ *
+ * Include FSEventsFix.{h,c} into your project and call FSEventsFixInstall().
+ *
+ * It is recommended that you install FSEventsFix on demand, using FSEventsFixIsBroken
+ * to check if the folder you're about to pass to FSEventStreamCreate needs the fix.
+ * Note that the fix must be applied before calling FSEventStreamCreate.
+ *
+ * FSEventsFixIsBroken requires a path that uses the correct case for all folder names,
+ * i.e. a path provided by the system APIs or constructed from folder names provided
+ * by the directory enumeration APIs.
+ *
+ * Copyright (c) 2015 Andrey Tarantsov <andrey@tarantsov.com>
+ * Copyright (c) 2003 Constantin S. Svintsoff <kostik@iclub.nsu.ru>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * Based on a realpath implementation from Apple libc 498.1.7, taken from
+ * http://www.opensource.apple.com/source/Libc/Libc-498.1.7/stdlib/FreeBSD/realpath.c
+ * and provided under the following license:
+ *
+ * Copyright (c) 2003 Constantin S. Svintsoff <kostik@iclub.nsu.ru>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The names of the authors may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+
+#include "FSEventsFix.h"
+
+#include <dispatch/dispatch.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <ctype.h>
+#include <dlfcn.h>
+
+
+const char *const FSEventsFixVersionString = "0.11.0";
+
+
+#pragma mark - Forward declarations
+
+static char *(*orig_realpath)(const char *restrict file_name, char resolved_name[PATH_MAX]);
+static char *CFURL_realpath(const char *restrict file_name, char resolved_name[PATH_MAX]);
+static char *FSEventsFix_realpath_wrapper(const char *restrict src, char *restrict dst);
+
+static void _FSEventsFixHookInstall();
+static void _FSEventsFixHookUninstall();
+
+
+#pragma mark - Internal state
+
+static dispatch_queue_t g_queue = NULL;
+
+static int64_t g_enable_refcount = 0;
+
+static bool g_in_self_test = false;
+static bool g_hook_operational = false;
+
+static void(^g_logging_block)(FSEventsFixMessageType type, const char *message);
+static FSEventsFixDebugOptions g_debug_opt = 0;
+
+typedef struct {
+ char *name;
+ void *replacement;
+ void *original;
+ uint hooked_symbols;
+} rebinding_t;
+
+static rebinding_t g_rebindings[] = {
+ { "_realpath$DARWIN_EXTSN", (void *) &FSEventsFix_realpath_wrapper, (void *) &realpath, 0 }
+};
+static const uint g_rebindings_nel = sizeof(g_rebindings) / sizeof(g_rebindings[0]);
+
+
+#pragma mark - Logging
+
+static void _FSEventsFixLog(FSEventsFixMessageType type, const char *__restrict fmt, ...) __attribute__((__format__ (__printf__, 2, 3)));
+
+static void _FSEventsFixLog(FSEventsFixMessageType type, const char *__restrict fmt, ...) {
+ if (g_logging_block) {
+ char *message = NULL;
+ va_list va;
+ va_start(va, fmt);
+ vasprintf(&message, fmt, va);
+ va_end(va);
+
+ if (message) {
+ if (!!(g_debug_opt & FSEventsFixDebugOptionLogToStderr)) {
+ fprintf(stderr, "FSEventsFix: %s\n", message);
+ }
+ if (g_logging_block) {
+ g_logging_block(type, message);
+ }
+ free(message);
+ }
+ }
+}
+
+
+#pragma mark - API
+
+void _FSEventsFixInitialize() {
+ static dispatch_once_t onceToken;
+ dispatch_once(&onceToken, ^{
+ g_queue = dispatch_queue_create("FSEventsFix", DISPATCH_QUEUE_SERIAL);
+ });
+}
+
+void FSEventsFixConfigure(FSEventsFixDebugOptions debugOptions, void(^loggingBlock)(FSEventsFixMessageType severity, const char *message)) {
+ _FSEventsFixInitialize();
+ loggingBlock = Block_copy(loggingBlock);
+ dispatch_sync(g_queue, ^{
+ g_debug_opt = debugOptions;
+ g_logging_block = loggingBlock;
+ });
+}
+
+// Must be called from the private serial queue.
+void _FSEventsFixSelfTest() {
+ g_in_self_test = true;
+ g_hook_operational = false;
+ static char result[1024];
+ realpath("/Etc/__!FSEventsFixSelfTest!__", result);
+ g_in_self_test = false;
+}
+
+void FSEventsFixEnable() {
+ _FSEventsFixInitialize();
+ dispatch_sync(g_queue, ^{
+ if (++g_enable_refcount == 1) {
+ orig_realpath = dlsym(RTLD_DEFAULT, "realpath");
+ _FSEventsFixHookInstall();
+ _FSEventsFixSelfTest();
+ if (g_hook_operational) {
+ _FSEventsFixLog(FSEventsFixMessageTypeStatusChange, "Enabled");
+ } else {
+ _FSEventsFixLog(FSEventsFixMessageTypeFatalError, "Failed to enable (hook not called)");
+ }
+ }
+ });
+}
+
+void FSEventsFixDisable() {
+ _FSEventsFixInitialize();
+ dispatch_sync(g_queue, ^{
+ if (g_enable_refcount == 0) {
+ abort();
+ }
+ if (--g_enable_refcount == 0) {
+ _FSEventsFixHookUninstall();
+ _FSEventsFixSelfTest();
+ if (!g_hook_operational) {
+ _FSEventsFixLog(FSEventsFixMessageTypeStatusChange, "Disabled");
+ } else {
+ _FSEventsFixLog(FSEventsFixMessageTypeFatalError, "Failed to disable (hook still called)");
+ }
+ }
+ });
+}
+
+bool FSEventsFixIsOperational() {
+ _FSEventsFixInitialize();
+ __block bool result = false;
+ dispatch_sync(g_queue, ^{
+ result = g_hook_operational;
+ });
+ return result;
+}
+
+bool _FSEventsFixIsBroken_noresolve(const char *resolved) {
+ if (!!(g_debug_opt & FSEventsFixDebugOptionSimulateBroken)) {
+ if (strstr(resolved, FSEventsFixSimulatedBrokenFolderMarker)) {
+ return true;
+ }
+ }
+
+ char *reresolved = realpath(resolved, NULL);
+ if (reresolved) {
+ bool broken = (0 != strcmp(resolved, reresolved));
+ free(reresolved);
+ return broken;
+ } else {
+ return true;
+ }
+}
+
+bool FSEventsFixIsBroken(const char *path) {
+ char *resolved = CFURL_realpath(path, NULL);
+ if (!resolved) {
+ return true;
+ }
+ bool broken = _FSEventsFixIsBroken_noresolve(resolved);
+ free(resolved);
+ return broken;
+}
+
+char *FSEventsFixCopyRootBrokenFolderPath(const char *inpath) {
+ if (!FSEventsFixIsBroken(inpath)) {
+ return NULL;
+ }
+
+ // get a mutable copy of an absolute path
+ char *path = CFURL_realpath(inpath, NULL);
+ if (!path) {
+ return NULL;
+ }
+
+ for (;;) {
+ char *sep = strrchr(path, '/');
+ if ((sep == NULL) || (sep == path)) {
+ break;
+ }
+ *sep = 0;
+ if (!_FSEventsFixIsBroken_noresolve(path)) {
+ *sep = '/';
+ break;
+ }
+ }
+
+ return path;
+}
+
+static void _FSEventsFixAttemptRepair(const char *folder) {
+ int rv = rename(folder, folder);
+
+ if (!!(g_debug_opt & FSEventsFixDebugOptionSimulateRepair)) {
+ const char *pos = strstr(folder, FSEventsFixSimulatedBrokenFolderMarker);
+ if (pos) {
+ char *fixed = strdup(folder);
+ fixed[pos - folder] = 0;
+ strcat(fixed, pos + strlen(FSEventsFixSimulatedBrokenFolderMarker));
+
+ rv = rename(folder, fixed);
+ free(fixed);
+ }
+ }
+
+ if (rv != 0) {
+ if (errno == EPERM) {
+ _FSEventsFixLog(FSEventsFixMessageTypeResult, "Permission error when trying to repair '%s'", folder);
+ } else {
+ _FSEventsFixLog(FSEventsFixMessageTypeExpectedFailure, "Unknown error when trying to repair '%s': errno = %d", folder, errno);
+ }
+ }
+}
+
+FSEventsFixRepairStatus FSEventsFixRepairIfNeeded(const char *inpath) {
+ char *root = FSEventsFixCopyRootBrokenFolderPath(inpath);
+ if (root == NULL) {
+ return FSEventsFixRepairStatusNotBroken;
+ }
+
+ for (;;) {
+ _FSEventsFixAttemptRepair(root);
+ char *newRoot = FSEventsFixCopyRootBrokenFolderPath(inpath);
+ if (newRoot == NULL) {
+ _FSEventsFixLog(FSEventsFixMessageTypeResult, "Repaired '%s' in '%s'", root, inpath);
+ free(root);
+ return FSEventsFixRepairStatusRepaired;
+ }
+ if (0 == strcmp(root, newRoot)) {
+ _FSEventsFixLog(FSEventsFixMessageTypeResult, "Failed to repair '%s' in '%s'", root, inpath);
+ free(root);
+ free(newRoot);
+ return FSEventsFixRepairStatusFailed;
+ }
+ _FSEventsFixLog(FSEventsFixMessageTypeResult, "Partial success, repaired '%s' in '%s'", root, inpath);
+ free(root);
+ root = newRoot;
+ }
+}
+
+
+#pragma mark - FSEventsFix realpath wrapper
+
+static char *FSEventsFix_realpath_wrapper(const char * __restrict src, char * __restrict dst) {
+ if (g_in_self_test) {
+ if (strstr(src, "__!FSEventsFixSelfTest!__")) {
+ g_hook_operational = true;
+ }
+ }
+
+ // CFURL_realpath doesn't support putting where resolution failed into the
+ // dst buffer, so we call the original realpath here first and if it gets a
+ // result, replace that with the output of CFURL_realpath. that way all the
+ // features of the original realpath are available.
+ char *rv = NULL;
+ char *orv = orig_realpath(src, dst);
+ if (orv != NULL) { rv = CFURL_realpath(src, dst); }
+
+ if (!!(g_debug_opt & FSEventsFixDebugOptionLogCalls)) {
+ char *result = rv ?: dst;
+ _FSEventsFixLog(FSEventsFixMessageTypeCall, "realpath(%s) => %s\n", src, result);
+ }
+
+ if (!!(g_debug_opt & FSEventsFixDebugOptionUppercaseReturn)) {
+ char *result = rv ?: dst;
+ if (result) {
+ for (char *pch = result; *pch; ++pch) {
+ *pch = (char)toupper(*pch);
+ }
+ }
+ }
+
+ return rv;
+}
+
+
+#pragma mark - realpath
+
+// naive implementation of realpath on top of CFURL
+// NOTE: doesn't quite support the full range of errno results one would
+// expect here, in part because some of these functions just return a boolean,
+// and in part because i'm not dealing with messy CFErrorRef objects and
+// attempting to translate those to sane errno values.
+// NOTE: the OSX realpath will return _where_ resolution failed in resolved_name
+// if passed in and return NULL. we can't properly support that extension here
+// since the resolution happens entirely behind the scenes to us in CFURL.
+static char* CFURL_realpath(const char *file_name, char resolved_name[PATH_MAX])
+{
+ char* resolved;
+ CFURLRef url1;
+ CFURLRef url2;
+ CFStringRef path;
+
+ if (file_name == NULL) {
+ errno = EINVAL;
+ return (NULL);
+ }
+
+#if __DARWIN_UNIX03
+ if (*file_name == 0) {
+ errno = ENOENT;
+ return (NULL);
+ }
+#endif
+
+ // create a buffer to store our result if we weren't passed one
+ if (!resolved_name) {
+ if ((resolved = malloc(PATH_MAX)) == NULL) return (NULL);
+ } else {
+ resolved = resolved_name;
+ }
+
+ url1 = CFURLCreateFromFileSystemRepresentation(NULL, (const UInt8*)file_name, (CFIndex)strlen(file_name), false);
+ if (url1 == NULL) { goto error_return; }
+
+ url2 = CFURLCopyAbsoluteURL(url1);
+ CFRelease(url1);
+ if (url2 == NULL) { goto error_return; }
+
+ url1 = CFURLCreateFileReferenceURL(NULL, url2, NULL);
+ CFRelease(url2);
+ if (url1 == NULL) { goto error_return; }
+
+ // if there are multiple hard links to the original path, this may end up
+ // being _completely_ different from what was intended
+ url2 = CFURLCreateFilePathURL(NULL, url1, NULL);
+ CFRelease(url1);
+ if (url2 == NULL) { goto error_return; }
+
+ path = CFURLCopyFileSystemPath(url2, kCFURLPOSIXPathStyle);
+ CFRelease(url2);
+ if (path == NULL) { goto error_return; }
+
+ bool success = CFStringGetCString(path, resolved, PATH_MAX, kCFStringEncodingUTF8);
+ CFRelease(path);
+ if (!success) { goto error_return; }
+
+ return resolved;
+
+error_return:
+ if (!resolved_name) {
+ // we weren't passed in an output buffer and created our own. free it
+ int e = errno;
+ free(resolved);
+ errno = e;
+ }
+ return (NULL);
+}
+
+
+#pragma mark - fishhook
+
+// Copyright (c) 2013, Facebook, Inc.
+// All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+// * Neither the name Facebook nor the names of its contributors may be used to
+// endorse or promote products derived from this software without specific
+// prior written permission.
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#import <stdlib.h>
+#import <string.h>
+#import <sys/types.h>
+#import <mach-o/dyld.h>
+#import <mach-o/loader.h>
+#import <mach-o/nlist.h>
+
+#ifdef __LP64__
+typedef struct mach_header_64 mach_header_t;
+typedef struct segment_command_64 segment_command_t;
+typedef struct section_64 section_t;
+typedef struct nlist_64 nlist_t;
+#define LC_SEGMENT_ARCH_DEPENDENT LC_SEGMENT_64
+#else
+typedef struct mach_header mach_header_t;
+typedef struct segment_command segment_command_t;
+typedef struct section section_t;
+typedef struct nlist nlist_t;
+#define LC_SEGMENT_ARCH_DEPENDENT LC_SEGMENT
+#endif
+
+static volatile bool g_hook_installed = false;
+
+static void _FSEventsFixHookUpdateSection(section_t *section, intptr_t slide, nlist_t *symtab, char *strtab, uint32_t *indirect_symtab)
+{
+ uint32_t *indirect_symbol_indices = indirect_symtab + section->reserved1;
+ void **indirect_symbol_bindings = (void **)((uintptr_t)slide + section->addr);
+ for (uint i = 0; i < section->size / sizeof(void *); i++) {
+ uint32_t symtab_index = indirect_symbol_indices[i];
+ if (symtab_index == INDIRECT_SYMBOL_ABS || symtab_index == INDIRECT_SYMBOL_LOCAL ||
+ symtab_index == (INDIRECT_SYMBOL_LOCAL | INDIRECT_SYMBOL_ABS)) {
+ continue;
+ }
+ uint32_t strtab_offset = symtab[symtab_index].n_un.n_strx;
+ char *symbol_name = strtab + strtab_offset;
+ for (rebinding_t *cur = g_rebindings, *end = g_rebindings + g_rebindings_nel; cur < end; ++cur) {
+ if (strcmp(symbol_name, cur->name) == 0) {
+ if (g_hook_installed) {
+ if (indirect_symbol_bindings[i] != cur->replacement) {
+ indirect_symbol_bindings[i] = cur->replacement;
+ ++cur->hooked_symbols;
+ }
+ } else if (cur->original != NULL) {
+ if (indirect_symbol_bindings[i] == cur->replacement) {
+ indirect_symbol_bindings[i] = cur->original;
+ if (cur->hooked_symbols > 0) {
+ --cur->hooked_symbols;
+ }
+ }
+ }
+ goto symbol_loop;
+ }
+ }
+ symbol_loop:;
+ }
+}
+
+static void _FSEventsFixHookUpdateImage(const struct mach_header *header, intptr_t slide) {
+ Dl_info info;
+ if (dladdr(header, &info) == 0) {
+ return;
+ }
+
+ segment_command_t *cur_seg_cmd;
+ segment_command_t *linkedit_segment = NULL;
+ struct symtab_command* symtab_cmd = NULL;
+ struct dysymtab_command* dysymtab_cmd = NULL;
+
+ uintptr_t cur = (uintptr_t)header + sizeof(mach_header_t);
+ for (uint i = 0; i < header->ncmds; i++, cur += cur_seg_cmd->cmdsize) {
+ cur_seg_cmd = (segment_command_t *)cur;
+ if (cur_seg_cmd->cmd == LC_SEGMENT_ARCH_DEPENDENT) {
+ if (strcmp(cur_seg_cmd->segname, SEG_LINKEDIT) == 0) {
+ linkedit_segment = cur_seg_cmd;
+ }
+ } else if (cur_seg_cmd->cmd == LC_SYMTAB) {
+ symtab_cmd = (struct symtab_command*)cur_seg_cmd;
+ } else if (cur_seg_cmd->cmd == LC_DYSYMTAB) {
+ dysymtab_cmd = (struct dysymtab_command*)cur_seg_cmd;
+ }
+ }
+
+ if (!symtab_cmd || !dysymtab_cmd || !linkedit_segment ||
+ !dysymtab_cmd->nindirectsyms) {
+ return;
+ }
+
+ // Find base symbol/string table addresses
+ uintptr_t linkedit_base = (uintptr_t)slide + linkedit_segment->vmaddr - linkedit_segment->fileoff;
+ nlist_t *symtab = (nlist_t *)(linkedit_base + symtab_cmd->symoff);
+ char *strtab = (char *)(linkedit_base + symtab_cmd->stroff);
+
+ // Get indirect symbol table (array of uint32_t indices into symbol table)
+ uint32_t *indirect_symtab = (uint32_t *)(linkedit_base + dysymtab_cmd->indirectsymoff);
+
+ cur = (uintptr_t)header + sizeof(mach_header_t);
+ for (uint i = 0; i < header->ncmds; i++, cur += cur_seg_cmd->cmdsize) {
+ cur_seg_cmd = (segment_command_t *)cur;
+ if (cur_seg_cmd->cmd == LC_SEGMENT_ARCH_DEPENDENT) {
+ if (strcmp(cur_seg_cmd->segname, SEG_DATA) != 0) {
+ continue;
+ }
+ for (uint j = 0; j < cur_seg_cmd->nsects; j++) {
+ section_t *sect =
+ (section_t *)(cur + sizeof(segment_command_t)) + j;
+ if ((sect->flags & SECTION_TYPE) == S_LAZY_SYMBOL_POINTERS) {
+ _FSEventsFixHookUpdateSection(sect, slide, symtab, strtab, indirect_symtab);
+ }
+ if ((sect->flags & SECTION_TYPE) == S_NON_LAZY_SYMBOL_POINTERS) {
+ _FSEventsFixHookUpdateSection(sect, slide, symtab, strtab, indirect_symtab);
+ }
+ }
+ }
+ }
+}
+
+static void _FSEventsFixHookSaveOriginals() {
+ for (rebinding_t *cur = g_rebindings, *end = g_rebindings + g_rebindings_nel; cur < end; ++cur) {
+ void *original = cur->original = dlsym(RTLD_DEFAULT, cur->name+1);
+ if (!original) {
+ const char *error = dlerror();
+ _FSEventsFixLog(FSEventsFixMessageTypeFatalError, "Cannot find symbol %s, dlsym says: %s\n", cur->name, error);
+ }
+ }
+}
+
+static void _FSEventsFixHookUpdate() {
+ uint32_t c = _dyld_image_count();
+ for (uint32_t i = 0; i < c; i++) {
+ _FSEventsFixHookUpdateImage(_dyld_get_image_header(i), _dyld_get_image_vmaddr_slide(i));
+ }
+}
+
+static void _FSEventsFixHookInstall() {
+ static bool first_rebinding_done = false;
+
+ if (!g_hook_installed) {
+ g_hook_installed = true;
+
+ if (!first_rebinding_done) {
+ first_rebinding_done = true;
+ _FSEventsFixHookSaveOriginals();
+ _dyld_register_func_for_add_image(_FSEventsFixHookUpdateImage);
+ } else {
+ _FSEventsFixHookUpdate();
+ }
+ }
+}
+
+static void _FSEventsFixHookUninstall() {
+ if (g_hook_installed) {
+ g_hook_installed = false;
+ _FSEventsFixHookUpdate();
+ }
+}
diff --git a/vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/ext/fsevent_watch/FSEventsFix.h b/vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/ext/fsevent_watch/FSEventsFix.h
new file mode 100644
index 0000000..b70b880
--- /dev/null
+++ b/vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/ext/fsevent_watch/FSEventsFix.h
@@ -0,0 +1,105 @@
+/*
+ * FSEventsFix
+ *
+ * Works around a long-standing bug in realpath() that prevents FSEvents API from
+ * monitoring certain folders on a wide range of OS X releases (10.6-10.10 at least).
+ *
+ * The underlying issue is that for some folders, realpath() call starts returning
+ * a path with incorrect casing (e.g. "/users/smt" instead of "/Users/smt").
+ * FSEvents is case-sensitive and calls realpath() on the paths you pass in, so
+ * an incorrect value returned by realpath() prevents FSEvents from seeing any
+ * change events.
+ *
+ * See the discussion at https://github.com/thibaudgg/rb-fsevent/issues/10 about
+ * the history of this bug and how this library came to exist.
+ *
+ * This library uses Facebook's fishhook to replace a custom implementation of
+ * realpath in place of the system realpath; FSEvents will then invoke our custom
+ * implementation (which does not screw up the names) and will thus work correctly.
+ *
+ * Our implementation of realpath is based on the open-source implementation from
+ * OS X 10.10, with a single change applied (enclosed in "BEGIN WORKAROUND FOR
+ * OS X BUG" ... "END WORKAROUND FOR OS X BUG").
+ *
+ * Include FSEventsFix.{h,c} into your project and call FSEventsFixInstall().
+ *
+ * It is recommended that you install FSEventsFix on demand, using FSEventsFixIsBroken
+ * to check if the folder you're about to pass to FSEventStreamCreate needs the fix.
+ * Note that the fix must be applied before calling FSEventStreamCreate.
+ *
+ * FSEventsFixIsBroken requires a path that uses the correct case for all folder names,
+ * i.e. a path provided by the system APIs or constructed from folder names provided
+ * by the directory enumeration APIs.
+ *
+ * See .c file for license & copyrights, but basically this is available under a mix
+ * of MIT and BSD licenses.
+ */
+
+#ifndef __FSEventsFix__
+#define __FSEventsFix__
+
+#include <CoreFoundation/CoreFoundation.h>
+
+/// A library version string (e.g. 1.2.3) for displaying and logging purposes
+extern const char *const FSEventsFixVersionString;
+
+/// See FSEventsFixDebugOptionSimulateBroken
+#define FSEventsFixSimulatedBrokenFolderMarker "__!FSEventsBroken!__"
+
+typedef CF_OPTIONS(unsigned, FSEventsFixDebugOptions) {
+ /// Always return an uppercase string from realpath
+ FSEventsFixDebugOptionUppercaseReturn = 0x01,
+
+ /// Log all calls to realpath using the logger configured via FSEventsFixConfigure
+ FSEventsFixDebugOptionLogCalls = 0x02,
+
+ /// In addition to the logging block (if any), log everything to stderr
+ FSEventsFixDebugOptionLogToStderr = 0x08,
+
+ /// Report paths containing FSEventsFixSimulatedBrokenFolderMarker as broken
+ FSEventsFixDebugOptionSimulateBroken = 0x10,
+
+ /// Repair paths containing FSEventsFixSimulatedBrokenFolderMarker by renaming them
+ FSEventsFixDebugOptionSimulateRepair = 0x20,
+};
+
+typedef CF_ENUM(int, FSEventsFixMessageType) {
+ /// Call logging requested via FSEventsFixDebugOptionLogCalls
+ FSEventsFixMessageTypeCall,
+
+ /// Results of actions like repair, and other pretty verbose, but notable, stuff.
+ FSEventsFixMessageTypeResult,
+
+ /// Enabled/disabled status change
+ FSEventsFixMessageTypeStatusChange,
+
+ /// Expected failure (treat as a warning)
+ FSEventsFixMessageTypeExpectedFailure,
+
+ /// Severe failure that most likely means that the library won't work
+ FSEventsFixMessageTypeFatalError
+};
+
+typedef CF_ENUM(int, FSEventsFixRepairStatus) {
+ FSEventsFixRepairStatusNotBroken,
+ FSEventsFixRepairStatusRepaired,
+ FSEventsFixRepairStatusFailed,
+};
+
+/// Note that the logging block can be called on any dispatch queue.
+void FSEventsFixConfigure(FSEventsFixDebugOptions debugOptions, void(^loggingBlock)(FSEventsFixMessageType type, const char *message));
+
+void FSEventsFixEnable();
+void FSEventsFixDisable();
+
+bool FSEventsFixIsOperational();
+
+bool FSEventsFixIsBroken(const char *path);
+
+/// If the path is broken, returns a string identifying the root broken folder,
+/// otherwise, returns NULL. You need to free() the returned string.
+char *FSEventsFixCopyRootBrokenFolderPath(const char *path);
+
+FSEventsFixRepairStatus FSEventsFixRepairIfNeeded(const char *path);
+
+#endif
diff --git a/vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/ext/fsevent_watch/TSICTString.c b/vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/ext/fsevent_watch/TSICTString.c
new file mode 100644
index 0000000..6e033d0
--- /dev/null
+++ b/vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/ext/fsevent_watch/TSICTString.c
@@ -0,0 +1,373 @@
+//
+// TSICTString.c
+// TSITString
+//
+// Created by Travis Tilley on 9/27/11.
+//
+
+#include "TSICTString.h"
+
+
+const char* const TNetstringTypes = ",#^!~}]Z";
+const char* const OTNetstringTypes = ",#^!~{[Z";
+const UInt8 TNetstringSeparator = ':';
+
+TSITStringFormat TSITStringDefaultFormat = kTSITStringFormatTNetstring;
+
+static const CFRange BeginningRange = {0,0};
+
+static CFTypeID kCFDataTypeID = -1UL;
+static CFTypeID kCFStringTypeID = -1UL;
+static CFTypeID kCFNumberTypeID = -1UL;
+static CFTypeID kCFBooleanTypeID = -1UL;
+static CFTypeID kCFNullTypeID = -1UL;
+static CFTypeID kCFArrayTypeID = -1UL;
+static CFTypeID kCFDictionaryTypeID = -1UL;
+
+
+__attribute__((constructor)) void Init_TSICTString(void)
+{
+ kCFDataTypeID = CFDataGetTypeID();
+ kCFStringTypeID = CFStringGetTypeID();
+ kCFNumberTypeID = CFNumberGetTypeID();
+ kCFBooleanTypeID = CFBooleanGetTypeID();
+ kCFNullTypeID = CFNullGetTypeID();
+ kCFArrayTypeID = CFArrayGetTypeID();
+ kCFDictionaryTypeID = CFDictionaryGetTypeID();
+}
+
+
+void TSICTStringSetDefaultFormat(TSITStringFormat format)
+{
+ if (format == kTSITStringFormatDefault) {
+ TSITStringDefaultFormat = kTSITStringFormatTNetstring;
+ } else {
+ TSITStringDefaultFormat = format;
+ }
+}
+
+TSITStringFormat TSICTStringGetDefaultFormat(void)
+{
+ return TSITStringDefaultFormat;
+}
+
+
+void TSICTStringDestroy(TStringIRep* rep)
+{
+ CFRelease(rep->data);
+ free(rep->length);
+ free(rep);
+}
+
+
+static inline TStringIRep* TSICTStringCreateWithDataOfTypeAndFormat(CFDataRef data, TSITStringTag type, TSITStringFormat format)
+{
+ if (format == kTSITStringFormatDefault) {
+ format = TSICTStringGetDefaultFormat();
+ }
+
+ TStringIRep* rep = calloc(1, sizeof(TStringIRep));
+ rep->data = CFDataCreateCopy(kCFAllocatorDefault, data);
+ rep->type = type;
+ rep->format = format;
+ rep->length = calloc(10, sizeof(char));
+
+ CFIndex len = CFDataGetLength(rep->data);
+ if (snprintf(rep->length, 10, "%lu", len)) {
+ return rep;
+ } else {
+ TSICTStringDestroy(rep);
+ return NULL;
+ }
+}
+
+static inline CFDataRef TSICTStringCreateDataFromIntermediateRepresentation(TStringIRep* rep)
+{
+ CFIndex len = CFDataGetLength(rep->data);
+ CFMutableDataRef buffer = CFDataCreateMutableCopy(kCFAllocatorDefault, (len + 12), rep->data);
+ UInt8* bufferBytes = CFDataGetMutableBytePtr(buffer);
+
+ size_t prefixLength = strlen(rep->length) + 1;
+ CFDataReplaceBytes(buffer, BeginningRange, (const UInt8*)rep->length, (CFIndex)prefixLength);
+
+ if (rep->format == kTSITStringFormatTNetstring) {
+ const UInt8 ftag = (UInt8)TNetstringTypes[rep->type];
+ CFDataAppendBytes(buffer, &ftag, 1);
+ bufferBytes[(prefixLength - 1)] = TNetstringSeparator;
+ } else if (rep->format == kTSITStringFormatOTNetstring) {
+ const UInt8 ftag = (UInt8)OTNetstringTypes[rep->type];
+ bufferBytes[(prefixLength - 1)] = ftag;
+ }
+
+ CFDataRef dataRep = CFDataCreateCopy(kCFAllocatorDefault, buffer);
+ CFRelease(buffer);
+
+ return dataRep;
+}
+
+static inline CFStringRef TSICTStringCreateStringFromIntermediateRepresentation(TStringIRep* rep)
+{
+ CFDataRef data = TSICTStringCreateDataFromIntermediateRepresentation(rep);
+ CFStringRef string = CFStringCreateFromExternalRepresentation(kCFAllocatorDefault, data, kCFStringEncodingUTF8);
+ CFRelease(data);
+ return string;
+}
+
+static inline void TSICTStringAppendObjectToMutableDataWithFormat(CFTypeRef object, CFMutableDataRef buffer, TSITStringFormat format)
+{
+ if (object == NULL) {
+ object = kCFNull;
+ }
+
+ CFRetain(object);
+
+ TStringIRep* objRep = TSICTStringCreateWithObjectAndFormat(object, format);
+ CFDataRef objData = TSICTStringCreateDataFromIntermediateRepresentation(objRep);
+ CFDataAppendBytes(buffer, (CFDataGetBytePtr(objData)), CFDataGetLength(objData));
+ CFRelease(objData);
+ TSICTStringDestroy(objRep);
+
+ CFRelease(object);
+}
+
+static void ArrayBufferAppendCallback(const void* item, void* context)
+{
+ TStringCollectionCallbackContext* cx = (TStringCollectionCallbackContext*)context;
+ CFMutableDataRef buffer = cx->buffer;
+ TSITStringFormat format = cx->format;
+
+ TSICTStringAppendObjectToMutableDataWithFormat(item, buffer, format);
+}
+
+static void DictionaryBufferAppendCallback(const void* key, const void* value, void* context)
+{
+ TStringCollectionCallbackContext* cx = (TStringCollectionCallbackContext*)context;
+ CFMutableDataRef buffer = cx->buffer;
+ TSITStringFormat format = cx->format;
+
+ TSICTStringAppendObjectToMutableDataWithFormat(key, buffer, format);
+ TSICTStringAppendObjectToMutableDataWithFormat(value, buffer, format);
+}
+
+
+CFDataRef TSICTStringCreateRenderedData(TStringIRep* rep)
+{
+ return TSICTStringCreateDataFromIntermediateRepresentation(rep);
+}
+
+CFDataRef TSICTStringCreateRenderedDataFromObjectWithFormat(CFTypeRef object, TSITStringFormat format)
+{
+ if (object == NULL) {
+ object = kCFNull;
+ }
+
+ CFRetain(object);
+
+ TStringIRep* rep = TSICTStringCreateWithObjectAndFormat(object, format);
+ CFDataRef data = TSICTStringCreateDataFromIntermediateRepresentation(rep);
+
+ TSICTStringDestroy(rep);
+ CFRelease(object);
+
+ return data;
+}
+
+CFStringRef TSICTStringCreateRenderedString(TStringIRep* rep)
+{
+ return TSICTStringCreateStringFromIntermediateRepresentation(rep);
+}
+
+CFStringRef TSICTStringCreateRenderedStringFromObjectWithFormat(CFTypeRef object, TSITStringFormat format)
+{
+ if (object == NULL) {
+ object = kCFNull;
+ }
+
+ CFRetain(object);
+
+ TStringIRep* rep = TSICTStringCreateWithObjectAndFormat(object, format);
+ CFStringRef string = TSICTStringCreateStringFromIntermediateRepresentation(rep);
+
+ TSICTStringDestroy(rep);
+ CFRelease(object);
+
+ return string;
+}
+
+
+TStringIRep* TSICTStringCreateWithObjectAndFormat(CFTypeRef object, TSITStringFormat format)
+{
+ if (object == NULL) {
+ return TSICTStringCreateNullWithFormat(format);
+ }
+ CFRetain(object);
+
+ CFTypeID cfType = CFGetTypeID(object);
+ TStringIRep* rep = NULL;
+
+ if (cfType == kCFDataTypeID) {
+ rep = TSICTStringCreateWithDataOfTypeAndFormat(object, kTSITStringTagString, format);
+ } else if (cfType == kCFStringTypeID) {
+ rep = TSICTStringCreateWithStringAndFormat(object, format);
+ } else if (cfType == kCFNumberTypeID) {
+ rep = TSICTStringCreateWithNumberAndFormat(object, format);
+ } else if (cfType == kCFBooleanTypeID) {
+ if (CFBooleanGetValue(object)) {
+ rep = TSICTStringCreateTrueWithFormat(format);
+ } else {
+ rep = TSICTStringCreateFalseWithFormat(format);
+ }
+ } else if (cfType == kCFNullTypeID) {
+ rep = TSICTStringCreateNullWithFormat(format);
+ } else if (cfType == kCFArrayTypeID) {
+ rep = TSICTStringCreateWithArrayAndFormat(object, format);
+ } else if (cfType == kCFDictionaryTypeID) {
+ rep = TSICTStringCreateWithDictionaryAndFormat(object, format);
+ } else {
+ rep = TSICTStringCreateInvalidWithFormat(format);
+ }
+
+ CFRelease(object);
+ return rep;
+}
+
+TStringIRep* TSICTStringCreateWithStringAndFormat(CFStringRef string, TSITStringFormat format)
+{
+ CFRetain(string);
+ CFDataRef data = CFStringCreateExternalRepresentation(kCFAllocatorDefault, string, kCFStringEncodingUTF8, '?');
+ TStringIRep* rep = TSICTStringCreateWithDataOfTypeAndFormat(data, kTSITStringTagString, format);
+ CFRelease(data);
+ CFRelease(string);
+ return rep;
+}
+
+TStringIRep* TSICTStringCreateWithNumberAndFormat(CFNumberRef number, TSITStringFormat format)
+{
+ CFRetain(number);
+ TSITStringTag tag = kTSITStringTagNumber;
+ CFDataRef data;
+ CFNumberType numType = CFNumberGetType(number);
+
+ switch(numType) {
+ case kCFNumberCharType:
+ {
+ int value;
+ if (CFNumberGetValue(number, kCFNumberIntType, &value)) {
+ if (value == 0 || value == 1) {
+ tag = kTSITStringTagBool;
+ } else {
+ tag = kTSITStringTagString;
+ }
+ }
+ break;
+ }
+ case kCFNumberFloat32Type:
+ case kCFNumberFloat64Type:
+ case kCFNumberFloatType:
+ case kCFNumberDoubleType:
+ {
+ tag = kTSITStringTagFloat;
+ break;
+ }
+ }
+
+ if (tag == kTSITStringTagBool) {
+ bool value;
+ CFNumberGetValue(number, kCFNumberIntType, &value);
+ if (value) {
+ data = CFDataCreate(kCFAllocatorDefault, (UInt8*)"true", 4);
+ } else {
+ data = CFDataCreate(kCFAllocatorDefault, (UInt8*)"false", 5);
+ }
+ } else if (tag == kTSITStringTagFloat) {
+ char buf[32];
+ char *p, *e;
+ double value;
+
+ CFNumberGetValue(number, numType, &value);
+ sprintf(buf, "%#.15g", value);
+
+ e = buf + strlen(buf);
+ p = e;
+ while (p[-1]=='0' && ('0' <= p[-2] && p[-2] <= '9')) {
+ p--;
+ }
+ memmove(p, e, strlen(e)+1);
+
+ data = CFDataCreate(kCFAllocatorDefault, (UInt8*)buf, (CFIndex)strlen(buf));
+ } else {
+ char buf[32];
+ SInt64 value;
+ CFNumberGetValue(number, numType, &value);
+ sprintf(buf, "%lli", value);
+ data = CFDataCreate(kCFAllocatorDefault, (UInt8*)buf, (CFIndex)strlen(buf));
+ }
+
+ TStringIRep* rep = TSICTStringCreateWithDataOfTypeAndFormat(data, tag, format);
+ CFRelease(data);
+ CFRelease(number);
+ return rep;
+}
+
+TStringIRep* TSICTStringCreateTrueWithFormat(TSITStringFormat format)
+{
+ CFDataRef data = CFDataCreate(kCFAllocatorDefault, (UInt8*)"true", 4);
+ TStringIRep* rep = TSICTStringCreateWithDataOfTypeAndFormat(data, kTSITStringTagBool, format);
+ CFRelease(data);
+ return rep;
+}
+
+TStringIRep* TSICTStringCreateFalseWithFormat(TSITStringFormat format)
+{
+ CFDataRef data = CFDataCreate(kCFAllocatorDefault, (UInt8*)"false", 5);
+ TStringIRep* rep = TSICTStringCreateWithDataOfTypeAndFormat(data, kTSITStringTagBool, format);
+ CFRelease(data);
+ return rep;
+}
+
+TStringIRep* TSICTStringCreateNullWithFormat(TSITStringFormat format)
+{
+ CFDataRef data = CFDataCreate(kCFAllocatorDefault, NULL, 0);
+ TStringIRep* rep = TSICTStringCreateWithDataOfTypeAndFormat(data, kTSITStringTagNull, format);
+ CFRelease(data);
+ return rep;
+}
+
+TStringIRep* TSICTStringCreateInvalidWithFormat(TSITStringFormat format)
+{
+ CFDataRef data = CFDataCreate(kCFAllocatorDefault, NULL, 0);
+ TStringIRep* rep = TSICTStringCreateWithDataOfTypeAndFormat(data, kTSITStringTagInvalid, format);
+ CFRelease(data);
+ return rep;
+}
+
+TStringIRep* TSICTStringCreateWithArrayAndFormat(CFArrayRef array, TSITStringFormat format)
+{
+ CFRetain(array);
+
+ CFMutableDataRef buffer = CFDataCreateMutable(kCFAllocatorDefault, 0);
+
+ CFRange all = CFRangeMake(0, CFArrayGetCount(array));
+ TStringCollectionCallbackContext cx = {buffer, format};
+ CFArrayApplyFunction(array, all, ArrayBufferAppendCallback, &cx);
+
+ TStringIRep* rep = TSICTStringCreateWithDataOfTypeAndFormat(buffer, kTSITStringTagList, format);
+ CFRelease(buffer);
+ CFRelease(array);
+ return rep;
+}
+
+TStringIRep* TSICTStringCreateWithDictionaryAndFormat(CFDictionaryRef dictionary, TSITStringFormat format)
+{
+ CFRetain(dictionary);
+
+ CFMutableDataRef buffer = CFDataCreateMutable(kCFAllocatorDefault, 0);
+
+ TStringCollectionCallbackContext cx = {buffer, format};
+ CFDictionaryApplyFunction(dictionary, DictionaryBufferAppendCallback, &cx);
+
+ TStringIRep* rep = TSICTStringCreateWithDataOfTypeAndFormat(buffer, kTSITStringTagDict, format);
+ CFRelease(buffer);
+ CFRelease(dictionary);
+ return rep;
+}
diff --git a/vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/ext/fsevent_watch/TSICTString.h b/vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/ext/fsevent_watch/TSICTString.h
new file mode 100644
index 0000000..daf085c
--- /dev/null
+++ b/vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/ext/fsevent_watch/TSICTString.h
@@ -0,0 +1,74 @@
+//
+// TSICTString.h
+// TSITString
+//
+// Created by Travis Tilley on 9/27/11.
+//
+
+#ifndef TSICTString_H
+#define TSICTString_H
+
+#include <CoreFoundation/CoreFoundation.h>
+
+
+typedef enum {
+ kTSITStringTagString = 0,
+ kTSITStringTagNumber = 1,
+ kTSITStringTagFloat = 2,
+ kTSITStringTagBool = 3,
+ kTSITStringTagNull = 4,
+ kTSITStringTagDict = 5,
+ kTSITStringTagList = 6,
+ kTSITStringTagInvalid = 7,
+} TSITStringTag;
+
+extern const char* const TNetstringTypes;
+extern const char* const OTNetstringTypes;
+extern const UInt8 TNetstringSeparator;
+
+typedef enum {
+ kTSITStringFormatDefault = 0,
+ kTSITStringFormatOTNetstring = 1,
+ kTSITStringFormatTNetstring = 2,
+} TSITStringFormat;
+
+extern TSITStringFormat TSITStringDefaultFormat;
+
+typedef struct TSITStringIntermediate {
+ CFDataRef data;
+ char* length;
+ TSITStringTag type;
+ TSITStringFormat format;
+} TStringIRep;
+
+typedef struct {
+ CFMutableDataRef buffer;
+ TSITStringFormat format;
+} TStringCollectionCallbackContext;
+
+
+void Init_TSICTString(void);
+
+void TSICTStringSetDefaultFormat(TSITStringFormat format);
+TSITStringFormat TSICTStringGetDefaultFormat(void);
+
+void TSICTStringDestroy(TStringIRep* rep);
+
+CFDataRef TSICTStringCreateRenderedData(TStringIRep* rep);
+CFDataRef TSICTStringCreateRenderedDataFromObjectWithFormat(CFTypeRef object, TSITStringFormat format);
+
+CFStringRef TSICTStringCreateRenderedString(TStringIRep* rep);
+CFStringRef TSICTStringCreateRenderedStringFromObjectWithFormat(CFTypeRef object, TSITStringFormat format);
+
+TStringIRep* TSICTStringCreateWithObjectAndFormat(CFTypeRef object, TSITStringFormat format);
+TStringIRep* TSICTStringCreateWithStringAndFormat(CFStringRef string, TSITStringFormat format);
+TStringIRep* TSICTStringCreateWithNumberAndFormat(CFNumberRef number, TSITStringFormat format);
+TStringIRep* TSICTStringCreateTrueWithFormat(TSITStringFormat format);
+TStringIRep* TSICTStringCreateFalseWithFormat(TSITStringFormat format);
+TStringIRep* TSICTStringCreateNullWithFormat(TSITStringFormat format);
+TStringIRep* TSICTStringCreateInvalidWithFormat(TSITStringFormat format);
+TStringIRep* TSICTStringCreateWithArrayAndFormat(CFArrayRef array, TSITStringFormat format);
+TStringIRep* TSICTStringCreateWithDictionaryAndFormat(CFDictionaryRef dictionary, TSITStringFormat format);
+
+
+#endif
diff --git a/vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/ext/fsevent_watch/cli.c b/vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/ext/fsevent_watch/cli.c
new file mode 100644
index 0000000..6d36dd1
--- /dev/null
+++ b/vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/ext/fsevent_watch/cli.c
@@ -0,0 +1,201 @@
+#include <getopt.h>
+#include "cli.h"
+
+const char* cli_info_purpose = "A flexible command-line interface for the FSEvents API";
+const char* cli_info_usage = "Usage: fsevent_watch [OPTIONS]... [PATHS]...";
+const char* cli_info_help[] = {
+ " -h, --help you're looking at it",
+ " -V, --version print version number and exit",
+ " -p, --show-plist display the embedded Info.plist values",
+ " -s, --since-when=EventID fire historical events since ID",
+ " -l, --latency=seconds latency period (default='0.5')",
+ " -n, --no-defer enable no-defer latency modifier",
+ " -r, --watch-root watch for when the root path has changed",
+ // " -i, --ignore-self ignore current process",
+ " -F, --file-events provide file level event data",
+ " -f, --format=name output format (classic, niw, \n"
+ " tnetstring, otnetstring)",
+ 0
+};
+
+static void default_args (struct cli_info* args_info)
+{
+ args_info->since_when_arg = kFSEventStreamEventIdSinceNow;
+ args_info->latency_arg = 0.5;
+ args_info->no_defer_flag = false;
+ args_info->watch_root_flag = false;
+ args_info->ignore_self_flag = false;
+ args_info->file_events_flag = false;
+ args_info->mark_self_flag = false;
+ args_info->format_arg = kFSEventWatchOutputFormatOTNetstring;
+}
+
+static void cli_parser_release (struct cli_info* args_info)
+{
+ unsigned int i;
+
+ for (i=0; i < args_info->inputs_num; ++i) {
+ free(args_info->inputs[i]);
+ }
+
+ if (args_info->inputs_num) {
+ free(args_info->inputs);
+ }
+
+ args_info->inputs_num = 0;
+}
+
+void cli_parser_init (struct cli_info* args_info)
+{
+ default_args(args_info);
+
+ args_info->inputs = 0;
+ args_info->inputs_num = 0;
+}
+
+void cli_parser_free (struct cli_info* args_info)
+{
+ cli_parser_release(args_info);
+}
+
+static void cli_print_info_dict (const void *key,
+ const void *value,
+ void *context)
+{
+ CFStringRef entry = CFStringCreateWithFormat(NULL, NULL,
+ CFSTR("%@:\n %@"), key, value);
+ if (entry) {
+ CFShow(entry);
+ CFRelease(entry);
+ }
+}
+
+void cli_show_plist (void)
+{
+ CFBundleRef mainBundle = CFBundleGetMainBundle();
+ CFRetain(mainBundle);
+ CFDictionaryRef mainBundleDict = CFBundleGetInfoDictionary(mainBundle);
+ if (mainBundleDict) {
+ CFRetain(mainBundleDict);
+ printf("Embedded Info.plist metadata:\n\n");
+ CFDictionaryApplyFunction(mainBundleDict, cli_print_info_dict, NULL);
+ CFRelease(mainBundleDict);
+ }
+ CFRelease(mainBundle);
+ printf("\n");
+}
+
+void cli_print_version (void)
+{
+ printf("%s %s\n\n", CLI_NAME, CLI_VERSION);
+#ifdef COMPILED_AT
+ printf("Compiled at: %s\n", COMPILED_AT);
+#endif
+#ifdef COMPILER
+ printf("Compiled with: %s\n", COMPILER);
+#endif
+#ifdef TARGET_CPU
+ printf("Compiled for: %s\n", TARGET_CPU);
+#endif
+ printf("\n");
+}
+
+void cli_print_help (void)
+{
+ cli_print_version();
+
+ printf("\n%s\n", cli_info_purpose);
+ printf("\n%s\n", cli_info_usage);
+ printf("\n");
+
+ int i = 0;
+ while (cli_info_help[i]) {
+ printf("%s\n", cli_info_help[i++]);
+ }
+}
+
+int cli_parser (int argc, const char** argv, struct cli_info* args_info)
+{
+ static struct option longopts[] = {
+ { "help", no_argument, NULL, 'h' },
+ { "version", no_argument, NULL, 'V' },
+ { "show-plist", no_argument, NULL, 'p' },
+ { "since-when", required_argument, NULL, 's' },
+ { "latency", required_argument, NULL, 'l' },
+ { "no-defer", no_argument, NULL, 'n' },
+ { "watch-root", no_argument, NULL, 'r' },
+ { "ignore-self", no_argument, NULL, 'i' },
+ { "file-events", no_argument, NULL, 'F' },
+ { "mark-self", no_argument, NULL, 'm' },
+ { "format", required_argument, NULL, 'f' },
+ { 0, 0, 0, 0 }
+ };
+
+ const char* shortopts = "hVps:l:nriFf:";
+
+ int c = -1;
+
+ while ((c = getopt_long(argc, (char * const*)argv, shortopts, longopts, NULL)) != -1) {
+ switch(c) {
+ case 's': // since-when
+ args_info->since_when_arg = strtoull(optarg, NULL, 0);
+ break;
+ case 'l': // latency
+ args_info->latency_arg = strtod(optarg, NULL);
+ break;
+ case 'n': // no-defer
+ args_info->no_defer_flag = true;
+ break;
+ case 'r': // watch-root
+ args_info->watch_root_flag = true;
+ break;
+ case 'i': // ignore-self
+ args_info->ignore_self_flag = true;
+ break;
+ case 'F': // file-events
+ args_info->file_events_flag = true;
+ break;
+ case 'm': // mark-self
+ args_info->mark_self_flag = true;
+ break;
+ case 'f': // format
+ if (strcmp(optarg, "classic") == 0) {
+ args_info->format_arg = kFSEventWatchOutputFormatClassic;
+ } else if (strcmp(optarg, "niw") == 0) {
+ args_info->format_arg = kFSEventWatchOutputFormatNIW;
+ } else if (strcmp(optarg, "tnetstring") == 0) {
+ args_info->format_arg = kFSEventWatchOutputFormatTNetstring;
+ } else if (strcmp(optarg, "otnetstring") == 0) {
+ args_info->format_arg = kFSEventWatchOutputFormatOTNetstring;
+ } else {
+ fprintf(stderr, "Unknown output format: %s\n", optarg);
+ exit(EXIT_FAILURE);
+ }
+ break;
+ case 'V': // version
+ cli_print_version();
+ exit(EXIT_SUCCESS);
+ case 'p': // show-plist
+ cli_show_plist();
+ exit(EXIT_SUCCESS);
+ case 'h': // help
+ case '?': // invalid option
+ case ':': // missing argument
+ cli_print_help();
+ exit((c == 'h') ? EXIT_SUCCESS : EXIT_FAILURE);
+ }
+ }
+
+ if (optind < argc) {
+ int i = 0;
+ args_info->inputs_num = (unsigned int)(argc - optind);
+ args_info->inputs =
+ (char**)(malloc ((args_info->inputs_num)*sizeof(char*)));
+ while (optind < argc)
+ if (argv[optind++] != argv[0]) {
+ args_info->inputs[i++] = strdup(argv[optind-1]);
+ }
+ }
+
+ return EXIT_SUCCESS;
+}
diff --git a/vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/ext/fsevent_watch/cli.h b/vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/ext/fsevent_watch/cli.h
new file mode 100644
index 0000000..2164995
--- /dev/null
+++ b/vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/ext/fsevent_watch/cli.h
@@ -0,0 +1,45 @@
+#ifndef CLI_H
+#define CLI_H
+
+#include "common.h"
+
+#ifndef CLI_NAME
+#define CLI_NAME "fsevent_watch"
+#endif /* CLI_NAME */
+
+#ifndef PROJECT_VERSION
+#error "PROJECT_VERSION not set"
+#endif /* PROJECT_VERSION */
+
+#ifndef CLI_VERSION
+#define CLI_VERSION _xstr(PROJECT_VERSION)
+#endif /* CLI_VERSION */
+
+
+struct cli_info {
+ UInt64 since_when_arg;
+ double latency_arg;
+ bool no_defer_flag;
+ bool watch_root_flag;
+ bool ignore_self_flag;
+ bool file_events_flag;
+ bool mark_self_flag;
+ enum FSEventWatchOutputFormat format_arg;
+
+ char** inputs;
+ unsigned inputs_num;
+};
+
+extern const char* cli_info_purpose;
+extern const char* cli_info_usage;
+extern const char* cli_info_help[];
+
+void cli_print_help(void);
+void cli_print_version(void);
+
+int cli_parser (int argc, const char** argv, struct cli_info* args_info);
+void cli_parser_init (struct cli_info* args_info);
+void cli_parser_free (struct cli_info* args_info);
+
+
+#endif /* CLI_H */
diff --git a/vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/ext/fsevent_watch/common.h b/vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/ext/fsevent_watch/common.h
new file mode 100644
index 0000000..b2d3e4e
--- /dev/null
+++ b/vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/ext/fsevent_watch/common.h
@@ -0,0 +1,22 @@
+#ifndef fsevent_watch_common_h
+#define fsevent_watch_common_h
+
+#include <CoreFoundation/CoreFoundation.h>
+#ifdef __OBJC__
+#import <Foundation/Foundation.h>
+#endif
+
+#include <CoreServices/CoreServices.h>
+#include <unistd.h>
+#include "compat.h"
+#include "defines.h"
+#include "TSICTString.h"
+
+enum FSEventWatchOutputFormat {
+ kFSEventWatchOutputFormatClassic,
+ kFSEventWatchOutputFormatNIW,
+ kFSEventWatchOutputFormatTNetstring,
+ kFSEventWatchOutputFormatOTNetstring
+};
+
+#endif /* fsevent_watch_common_h */
diff --git a/vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/ext/fsevent_watch/compat.c b/vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/ext/fsevent_watch/compat.c
new file mode 100644
index 0000000..5f51baf
--- /dev/null
+++ b/vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/ext/fsevent_watch/compat.c
@@ -0,0 +1,41 @@
+#include "compat.h"
+
+
+#if (defined(MAC_OS_X_VERSION_MAX_ALLOWED) && MAC_OS_X_VERSION_MAX_ALLOWED < __MAC_10_6) || \
+ (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED < __IPHONE_6_0)
+FSEventStreamCreateFlags kFSEventStreamCreateFlagIgnoreSelf = 0x00000008;
+#endif
+
+#if (defined(MAC_OS_X_VERSION_MAX_ALLOWED) && MAC_OS_X_VERSION_MAX_ALLOWED < __MAC_10_7) || \
+ (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED < __IPHONE_6_0)
+FSEventStreamCreateFlags kFSEventStreamCreateFlagFileEvents = 0x00000010;
+FSEventStreamEventFlags kFSEventStreamEventFlagItemCreated = 0x00000100;
+FSEventStreamEventFlags kFSEventStreamEventFlagItemRemoved = 0x00000200;
+FSEventStreamEventFlags kFSEventStreamEventFlagItemInodeMetaMod = 0x00000400;
+FSEventStreamEventFlags kFSEventStreamEventFlagItemRenamed = 0x00000800;
+FSEventStreamEventFlags kFSEventStreamEventFlagItemModified = 0x00001000;
+FSEventStreamEventFlags kFSEventStreamEventFlagItemFinderInfoMod = 0x00002000;
+FSEventStreamEventFlags kFSEventStreamEventFlagItemChangeOwner = 0x00004000;
+FSEventStreamEventFlags kFSEventStreamEventFlagItemXattrMod = 0x00008000;
+FSEventStreamEventFlags kFSEventStreamEventFlagItemIsFile = 0x00010000;
+FSEventStreamEventFlags kFSEventStreamEventFlagItemIsDir = 0x00020000;
+FSEventStreamEventFlags kFSEventStreamEventFlagItemIsSymlink = 0x00040000;
+#endif
+
+#if (defined(MAC_OS_X_VERSION_MAX_ALLOWED) && MAC_OS_X_VERSION_MAX_ALLOWED < __MAC_10_9) || \
+ (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED < __IPHONE_7_0)
+FSEventStreamCreateFlags kFSEventStreamCreateFlagMarkSelf = 0x00000020;
+FSEventStreamEventFlags kFSEventStreamEventFlagOwnEvent = 0x00080000;
+#endif
+
+#if (defined(MAC_OS_X_VERSION_MAX_ALLOWED) && MAC_OS_X_VERSION_MAX_ALLOWED < __MAC_10_10) || \
+ (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED < __IPHONE_9_0)
+FSEventStreamEventFlags kFSEventStreamEventFlagItemIsHardlink = 0x00100000;
+FSEventStreamEventFlags kFSEventStreamEventFlagItemIsLastHardlink = 0x00200000;
+#endif
+
+#if (defined(MAC_OS_X_VERSION_MAX_ALLOWED) && MAC_OS_X_VERSION_MAX_ALLOWED < __MAC_10_13) || \
+ (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED < __IPHONE_11_0)
+FSEventStreamCreateFlags kFSEventStreamCreateFlagUseExtendedData = 0x00000040;
+FSEventStreamEventFlags kFSEventStreamEventFlagItemCloned = 0x00400000;
+#endif
diff --git a/vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/ext/fsevent_watch/compat.h b/vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/ext/fsevent_watch/compat.h
new file mode 100644
index 0000000..757b413
--- /dev/null
+++ b/vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/ext/fsevent_watch/compat.h
@@ -0,0 +1,100 @@
+/**
+ * @headerfile compat.h
+ * FSEventStream flag compatibility shim
+ *
+ * In order to compile a binary against an older SDK yet still support the
+ * features present in later OS releases, we need to define any missing enum
+ * constants not present in the older SDK. This allows us to safely defer
+ * feature detection to runtime (and avoid recompilation).
+ */
+
+
+#ifndef listen_fsevents_compat_h
+#define listen_fsevents_compat_h
+
+#ifndef __CORESERVICES__
+#include <CoreServices/CoreServices.h>
+#endif // __CORESERVICES__
+
+#ifndef __AVAILABILITY__
+#include <Availability.h>
+#endif // __AVAILABILITY__
+
+#ifndef __MAC_10_6
+#define __MAC_10_6 1060
+#endif
+#ifndef __MAC_10_7
+#define __MAC_10_7 1070
+#endif
+#ifndef __MAC_10_9
+#define __MAC_10_9 1090
+#endif
+#ifndef __MAC_10_10
+#define __MAC_10_10 101000
+#endif
+#ifndef __MAC_10_13
+#define __MAC_10_13 101300
+#endif
+#ifndef __IPHONE_6_0
+#define __IPHONE_6_0 60000
+#endif
+#ifndef __IPHONE_7_0
+#define __IPHONE_7_0 70000
+#endif
+#ifndef __IPHONE_9_0
+#define __IPHONE_9_0 90000
+#endif
+#ifndef __IPHONE_11_0
+#define __IPHONE_11_0 110000
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#if (defined(MAC_OS_X_VERSION_MAX_ALLOWED) && MAC_OS_X_VERSION_MAX_ALLOWED < __MAC_10_6) || \
+ (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED < __IPHONE_6_0)
+extern FSEventStreamCreateFlags kFSEventStreamCreateFlagIgnoreSelf;
+#endif
+
+#if (defined(MAC_OS_X_VERSION_MAX_ALLOWED) && MAC_OS_X_VERSION_MAX_ALLOWED < __MAC_10_7) || \
+ (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED < __IPHONE_6_0)
+extern FSEventStreamCreateFlags kFSEventStreamCreateFlagFileEvents;
+extern FSEventStreamEventFlags kFSEventStreamEventFlagItemCreated,
+ kFSEventStreamEventFlagItemRemoved,
+ kFSEventStreamEventFlagItemInodeMetaMod,
+ kFSEventStreamEventFlagItemRenamed,
+ kFSEventStreamEventFlagItemModified,
+ kFSEventStreamEventFlagItemFinderInfoMod,
+ kFSEventStreamEventFlagItemChangeOwner,
+ kFSEventStreamEventFlagItemXattrMod,
+ kFSEventStreamEventFlagItemIsFile,
+ kFSEventStreamEventFlagItemIsDir,
+ kFSEventStreamEventFlagItemIsSymlink;
+#endif
+
+#if (defined(MAC_OS_X_VERSION_MAX_ALLOWED) && MAC_OS_X_VERSION_MAX_ALLOWED < __MAC_10_9) || \
+ (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED < __IPHONE_7_0)
+extern FSEventStreamCreateFlags kFSEventStreamCreateFlagMarkSelf;
+extern FSEventStreamEventFlags kFSEventStreamEventFlagOwnEvent;
+#endif
+
+#if (defined(MAC_OS_X_VERSION_MAX_ALLOWED) && MAC_OS_X_VERSION_MAX_ALLOWED < __MAC_10_10) || \
+ (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED < __IPHONE_9_0)
+extern FSEventStreamEventFlags kFSEventStreamEventFlagItemIsHardlink,
+ kFSEventStreamEventFlagItemIsLastHardlink;
+#endif
+
+#if (defined(MAC_OS_X_VERSION_MAX_ALLOWED) && MAC_OS_X_VERSION_MAX_ALLOWED < __MAC_10_13) || \
+ (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED < __IPHONE_11_0)
+extern FSEventStreamCreateFlags kFSEventStreamCreateFlagUseExtendedData;
+extern FSEventStreamEventFlags kFSEventStreamEventFlagItemCloned;
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // listen_fsevents_compat_h
diff --git a/vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/ext/fsevent_watch/defines.h b/vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/ext/fsevent_watch/defines.h
new file mode 100644
index 0000000..34879c5
--- /dev/null
+++ b/vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/ext/fsevent_watch/defines.h
@@ -0,0 +1,42 @@
+#ifndef fsevent_watch_defines_h
+#define fsevent_watch_defines_h
+
+#define _str(s) #s
+#define _xstr(s) _str(s)
+
+#define COMPILED_AT __DATE__ " " __TIME__
+
+#if defined (__clang__)
+#define COMPILER "clang " __clang_version__
+#elif defined (__GNUC__)
+#define COMPILER "gcc " __VERSION__
+#else
+#define COMPILER "unknown"
+#endif
+
+#if defined(__ppc__)
+#define TARGET_CPU "ppc"
+#elif defined(__ppc64__)
+#define TARGET_CPU "ppc64"
+#elif defined(__i386__)
+#define TARGET_CPU "i386"
+#elif defined(__x86_64__)
+#define TARGET_CPU "x86_64"
+#elif defined(__arm64__)
+#define TARGET_CPU "arm64"
+#else
+#define TARGET_CPU "unknown"
+#endif
+
+#define FLAG_CHECK(flags, flag) ((flags) & (flag))
+
+#define FPRINTF_FLAG_CHECK(flags, flag, msg, fd) \
+ do { \
+ if (FLAG_CHECK(flags, flag)) { \
+ fprintf(fd, "%s", msg "\n"); } } \
+ while (0)
+
+#define FLAG_CHECK_STDERR(flags, flag, msg) \
+ FPRINTF_FLAG_CHECK(flags, flag, msg, stderr)
+
+#endif /* fsevent_watch_defines_h */
diff --git a/vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/ext/fsevent_watch/main.c b/vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/ext/fsevent_watch/main.c
new file mode 100644
index 0000000..b18596a
--- /dev/null
+++ b/vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/ext/fsevent_watch/main.c
@@ -0,0 +1,548 @@
+#include "common.h"
+#include "signal_handlers.h"
+#include "cli.h"
+#include "FSEventsFix.h"
+
+// TODO: set on fire. cli.{h,c} handle both parsing and defaults, so there's
+// no need to set those here. also, in order to scope metadata by path,
+// each stream will need its own configuration... so this won't work as
+// a global any more. In the end the goal is to make the output format
+// able to declare not just that something happened and what flags were
+// attached, but what path it was watching that caused those events (so
+// that the path itself can be used for routing that information to the
+// relevant callback).
+//
+// Structure for storing metadata parsed from the commandline
+static struct {
+ FSEventStreamEventId sinceWhen;
+ CFTimeInterval latency;
+ FSEventStreamCreateFlags flags;
+ CFMutableArrayRef paths;
+ enum FSEventWatchOutputFormat format;
+} config = {
+ (UInt64) kFSEventStreamEventIdSinceNow,
+ (double) 0.3,
+ (CFOptionFlags) kFSEventStreamCreateFlagNone,
+ NULL,
+ kFSEventWatchOutputFormatOTNetstring
+};
+
+// Prototypes
+static void append_path(const char* path);
+static inline void parse_cli_settings(int argc, const char* argv[]);
+static void callback(FSEventStreamRef streamRef,
+ void* clientCallBackInfo,
+ size_t numEvents,
+ void* eventPaths,
+ const FSEventStreamEventFlags eventFlags[],
+ const FSEventStreamEventId eventIds[]);
+static bool needs_fsevents_fix = false;
+
+// Resolve a path and append it to the CLI settings structure
+// The FSEvents API will, internally, resolve paths using a similar scheme.
+// Performing this ahead of time makes things less confusing, IMHO.
+static void append_path(const char* path)
+{
+#ifdef DEBUG
+ fprintf(stderr, "\n");
+ fprintf(stderr, "append_path called for: %s\n", path);
+#endif
+
+#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
+
+#ifdef DEBUG
+ fprintf(stderr, "compiled against 10.6+, using CFURLCreateFileReferenceURL\n");
+#endif
+
+ CFURLRef url = CFURLCreateFromFileSystemRepresentation(NULL, (const UInt8*)path, (CFIndex)strlen(path), false);
+ CFURLRef placeholder = CFURLCopyAbsoluteURL(url);
+ CFRelease(url);
+
+ CFMutableArrayRef imaginary = NULL;
+
+ // if we don't have an existing url, spin until we get to a parent that
+ // does exist, saving any imaginary components for appending back later
+ while(!CFURLResourceIsReachable(placeholder, NULL)) {
+#ifdef DEBUG
+ fprintf(stderr, "path does not exist\n");
+#endif
+
+ CFStringRef child;
+
+ if (imaginary == NULL) {
+ imaginary = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+ }
+
+ child = CFURLCopyLastPathComponent(placeholder);
+ CFArrayInsertValueAtIndex(imaginary, 0, child);
+ CFRelease(child);
+
+ url = CFURLCreateCopyDeletingLastPathComponent(NULL, placeholder);
+ CFRelease(placeholder);
+ placeholder = url;
+
+#ifdef DEBUG
+ fprintf(stderr, "parent: ");
+ CFShow(placeholder);
+#endif
+ }
+
+#ifdef DEBUG
+ fprintf(stderr, "path exists\n");
+#endif
+
+ // realpath() doesn't always return the correct case for a path, so this
+ // is a funky workaround that converts a path into a (volId/inodeId) pair
+ // and asks what the path should be for that. since it looks at the actual
+ // inode instead of returning the same case passed in like realpath()
+ // appears to do for HFS+, it should always be correct.
+ url = CFURLCreateFileReferenceURL(NULL, placeholder, NULL);
+ CFRelease(placeholder);
+ placeholder = CFURLCreateFilePathURL(NULL, url, NULL);
+ CFRelease(url);
+
+#ifdef DEBUG
+ fprintf(stderr, "path resolved to: ");
+ CFShow(placeholder);
+#endif
+
+ // if we stripped off any imaginary path components, append them back on
+ if (imaginary != NULL) {
+ CFIndex count = CFArrayGetCount(imaginary);
+ for (CFIndex i = 0; i<count; i++) {
+ CFStringRef component = CFArrayGetValueAtIndex(imaginary, i);
+#ifdef DEBUG
+ fprintf(stderr, "appending component: ");
+ CFShow(component);
+#endif
+ url = CFURLCreateCopyAppendingPathComponent(NULL, placeholder, component, false);
+ CFRelease(placeholder);
+ placeholder = url;
+ }
+ CFRelease(imaginary);
+ }
+
+#ifdef DEBUG
+ fprintf(stderr, "result: ");
+ CFShow(placeholder);
+#endif
+
+ CFStringRef cfPath = CFURLCopyFileSystemPath(placeholder, kCFURLPOSIXPathStyle);
+ CFRelease(placeholder);
+
+ char cPath[PATH_MAX];
+ if (CFStringGetCString(cfPath, cPath, PATH_MAX, kCFStringEncodingUTF8)) {
+ FSEventsFixRepairStatus status = FSEventsFixRepairIfNeeded(cPath);
+ if (status == FSEventsFixRepairStatusFailed) {
+ needs_fsevents_fix = true;
+ }
+ }
+
+ CFArrayAppendValue(config.paths, cfPath);
+ CFRelease(cfPath);
+
+#else
+
+#ifdef DEBUG
+ fprintf(stderr, "compiled against 10.5, using realpath()\n");
+#endif
+
+ char fullPath[PATH_MAX + 1];
+
+ if (realpath(path, fullPath) == NULL) {
+#ifdef DEBUG
+ fprintf(stderr, " realpath not directly resolvable from path\n");
+#endif
+
+ if (path[0] != '/') {
+#ifdef DEBUG
+ fprintf(stderr, " passed path is not absolute\n");
+#endif
+ size_t len;
+ getcwd(fullPath, sizeof(fullPath));
+#ifdef DEBUG
+ fprintf(stderr, " result of getcwd: %s\n", fullPath);
+#endif
+ len = strlen(fullPath);
+ fullPath[len] = '/';
+ strlcpy(&fullPath[len + 1], path, sizeof(fullPath) - (len + 1));
+ } else {
+#ifdef DEBUG
+ fprintf(stderr, " assuming path does not YET exist\n");
+#endif
+ strlcpy(fullPath, path, sizeof(fullPath));
+ }
+ }
+
+#ifdef DEBUG
+ fprintf(stderr, " resolved path to: %s\n", fullPath);
+ fprintf(stderr, "\n");
+#endif
+
+ CFStringRef pathRef = CFStringCreateWithCString(kCFAllocatorDefault,
+ fullPath,
+ kCFStringEncodingUTF8);
+ CFArrayAppendValue(config.paths, pathRef);
+ CFRelease(pathRef);
+
+#endif
+}
+
+// Parse commandline settings
+static inline void parse_cli_settings(int argc, const char* argv[])
+{
+ // runtime os version detection
+ SInt32 osMajorVersion, osMinorVersion;
+ if (!(Gestalt(gestaltSystemVersionMajor, &osMajorVersion) == noErr)) {
+ osMajorVersion = 0;
+ }
+ if (!(Gestalt(gestaltSystemVersionMinor, &osMinorVersion) == noErr)) {
+ osMinorVersion = 0;
+ }
+
+ if ((osMajorVersion == 10) & (osMinorVersion < 5)) {
+ fprintf(stderr, "The FSEvents API is unavailable on this version of macos!\n");
+ exit(EXIT_FAILURE);
+ }
+
+ struct cli_info args_info;
+ cli_parser_init(&args_info);
+
+ if (cli_parser(argc, argv, &args_info) != 0) {
+ exit(EXIT_FAILURE);
+ }
+
+ config.paths = CFArrayCreateMutable(NULL,
+ (CFIndex)0,
+ &kCFTypeArrayCallBacks);
+
+ config.sinceWhen = args_info.since_when_arg;
+ config.latency = args_info.latency_arg;
+ config.format = args_info.format_arg;
+
+ if (args_info.no_defer_flag) {
+ config.flags |= kFSEventStreamCreateFlagNoDefer;
+ }
+ if (args_info.watch_root_flag) {
+ config.flags |= kFSEventStreamCreateFlagWatchRoot;
+ }
+
+ if (args_info.ignore_self_flag) {
+ if ((osMajorVersion == 10) & (osMinorVersion >= 6)) {
+ config.flags |= kFSEventStreamCreateFlagIgnoreSelf;
+ } else {
+ fprintf(stderr, "MacOSX 10.6 or later is required for --ignore-self\n");
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ if (args_info.file_events_flag) {
+ if ((osMajorVersion == 10) & (osMinorVersion >= 7)) {
+ config.flags |= kFSEventStreamCreateFlagFileEvents;
+ } else {
+ fprintf(stderr, "MacOSX 10.7 or later required for --file-events\n");
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ if (args_info.mark_self_flag) {
+ if ((osMajorVersion == 10) & (osMinorVersion >= 9)) {
+ config.flags |= kFSEventStreamCreateFlagMarkSelf;
+ } else {
+ fprintf(stderr, "MacOSX 10.9 or later required for --mark-self\n");
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ if (args_info.inputs_num == 0) {
+ append_path(".");
+ } else {
+ for (unsigned int i=0; i < args_info.inputs_num; ++i) {
+ append_path(args_info.inputs[i]);
+ }
+ }
+
+ cli_parser_free(&args_info);
+
+#ifdef DEBUG
+ fprintf(stderr, "config.sinceWhen %llu\n", config.sinceWhen);
+ fprintf(stderr, "config.latency %f\n", config.latency);
+
+// STFU clang
+#if defined(__LP64__)
+ fprintf(stderr, "config.flags %#.8x\n", config.flags);
+#else
+ fprintf(stderr, "config.flags %#.8lx\n", config.flags);
+#endif
+
+ FLAG_CHECK_STDERR(config.flags, kFSEventStreamCreateFlagUseCFTypes,
+ " Using CF instead of C types");
+ FLAG_CHECK_STDERR(config.flags, kFSEventStreamCreateFlagNoDefer,
+ " NoDefer latency modifier enabled");
+ FLAG_CHECK_STDERR(config.flags, kFSEventStreamCreateFlagWatchRoot,
+ " WatchRoot notifications enabled");
+ FLAG_CHECK_STDERR(config.flags, kFSEventStreamCreateFlagIgnoreSelf,
+ " IgnoreSelf enabled");
+ FLAG_CHECK_STDERR(config.flags, kFSEventStreamCreateFlagFileEvents,
+ " FileEvents enabled");
+
+ fprintf(stderr, "config.paths\n");
+
+ long numpaths = CFArrayGetCount(config.paths);
+
+ for (long i = 0; i < numpaths; i++) {
+ char path[PATH_MAX];
+ CFStringGetCString(CFArrayGetValueAtIndex(config.paths, i),
+ path,
+ PATH_MAX,
+ kCFStringEncodingUTF8);
+ fprintf(stderr, " %s\n", path);
+ }
+
+ fprintf(stderr, "\n");
+#endif
+}
+
+// original output format for rb-fsevent
+static void classic_output_format(size_t numEvents,
+ char** paths)
+{
+ for (size_t i = 0; i < numEvents; i++) {
+ fprintf(stdout, "%s:", paths[i]);
+ }
+ fprintf(stdout, "\n");
+}
+
+// output format used in the Yoshimasa Niwa branch of rb-fsevent
+static void niw_output_format(size_t numEvents,
+ char** paths,
+ const FSEventStreamEventFlags eventFlags[],
+ const FSEventStreamEventId eventIds[])
+{
+ for (size_t i = 0; i < numEvents; i++) {
+ fprintf(stdout, "%lu:%llu:%s\n",
+ (unsigned long)eventFlags[i],
+ (unsigned long long)eventIds[i],
+ paths[i]);
+ }
+ fprintf(stdout, "\n");
+}
+
+static void tstring_output_format(size_t numEvents,
+ char** paths,
+ const FSEventStreamEventFlags eventFlags[],
+ const FSEventStreamEventId eventIds[],
+ TSITStringFormat format)
+{
+ CFMutableArrayRef events = CFArrayCreateMutable(kCFAllocatorDefault,
+ 0, &kCFTypeArrayCallBacks);
+
+ for (size_t i = 0; i < numEvents; i++) {
+ CFMutableDictionaryRef event = CFDictionaryCreateMutable(kCFAllocatorDefault,
+ 0,
+ &kCFTypeDictionaryKeyCallBacks,
+ &kCFTypeDictionaryValueCallBacks);
+
+ CFStringRef path = CFStringCreateWithBytes(kCFAllocatorDefault,
+ (const UInt8*)paths[i],
+ (CFIndex)strlen(paths[i]),
+ kCFStringEncodingUTF8,
+ false);
+ CFDictionarySetValue(event, CFSTR("path"), path);
+
+ CFNumberRef ident = CFNumberCreate(kCFAllocatorDefault, kCFNumberLongLongType, &eventIds[i]);
+ CFDictionarySetValue(event, CFSTR("id"), ident);
+
+ CFNumberRef cflags = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &eventFlags[i]);
+ CFDictionarySetValue(event, CFSTR("cflags"), cflags);
+
+ CFMutableArrayRef flags = CFArrayCreateMutable(kCFAllocatorDefault,
+ 0, &kCFTypeArrayCallBacks);
+
+#define FLAG_ADD_NAME(flagsnum, flagnum, flagname, flagarray) \
+ do { \
+ if (FLAG_CHECK(flagsnum, flagnum)) { \
+ CFArrayAppendValue(flagarray, CFSTR(flagname)); } } \
+ while(0)
+
+ FLAG_ADD_NAME(eventFlags[i], kFSEventStreamEventFlagMustScanSubDirs, "MustScanSubDirs", flags);
+ FLAG_ADD_NAME(eventFlags[i], kFSEventStreamEventFlagUserDropped, "UserDropped", flags);
+ FLAG_ADD_NAME(eventFlags[i], kFSEventStreamEventFlagKernelDropped, "KernelDropped", flags);
+ FLAG_ADD_NAME(eventFlags[i], kFSEventStreamEventFlagEventIdsWrapped, "EventIdsWrapped", flags);
+ FLAG_ADD_NAME(eventFlags[i], kFSEventStreamEventFlagHistoryDone, "HistoryDone", flags);
+ FLAG_ADD_NAME(eventFlags[i], kFSEventStreamEventFlagRootChanged, "RootChanged", flags);
+ FLAG_ADD_NAME(eventFlags[i], kFSEventStreamEventFlagMount, "Mount", flags);
+ FLAG_ADD_NAME(eventFlags[i], kFSEventStreamEventFlagUnmount, "Unmount", flags);
+ FLAG_ADD_NAME(eventFlags[i], kFSEventStreamEventFlagItemCreated, "ItemCreated", flags);
+ FLAG_ADD_NAME(eventFlags[i], kFSEventStreamEventFlagItemRemoved, "ItemRemoved", flags);
+ FLAG_ADD_NAME(eventFlags[i], kFSEventStreamEventFlagItemInodeMetaMod, "ItemInodeMetaMod", flags);
+ FLAG_ADD_NAME(eventFlags[i], kFSEventStreamEventFlagItemRenamed, "ItemRenamed", flags);
+ FLAG_ADD_NAME(eventFlags[i], kFSEventStreamEventFlagItemModified, "ItemModified", flags);
+ FLAG_ADD_NAME(eventFlags[i], kFSEventStreamEventFlagItemFinderInfoMod, "ItemFinderInfoMod", flags);
+ FLAG_ADD_NAME(eventFlags[i], kFSEventStreamEventFlagItemChangeOwner, "ItemChangeOwner", flags);
+ FLAG_ADD_NAME(eventFlags[i], kFSEventStreamEventFlagItemXattrMod, "ItemXattrMod", flags);
+ FLAG_ADD_NAME(eventFlags[i], kFSEventStreamEventFlagItemIsFile, "ItemIsFile", flags);
+ FLAG_ADD_NAME(eventFlags[i], kFSEventStreamEventFlagItemIsDir, "ItemIsDir", flags);
+ FLAG_ADD_NAME(eventFlags[i], kFSEventStreamEventFlagItemIsSymlink, "ItemIsSymlink", flags);
+ FLAG_ADD_NAME(eventFlags[i], kFSEventStreamEventFlagOwnEvent, "OwnEvent", flags);
+ FLAG_ADD_NAME(eventFlags[i], kFSEventStreamEventFlagItemIsHardlink, "ItemIsHardLink", flags);
+ FLAG_ADD_NAME(eventFlags[i], kFSEventStreamEventFlagItemIsLastHardlink, "ItemIsLastHardLink", flags);
+
+ CFDictionarySetValue(event, CFSTR("flags"), flags);
+
+
+ CFArrayAppendValue(events, event);
+
+ CFRelease(event);
+ CFRelease(path);
+ CFRelease(ident);
+ CFRelease(cflags);
+ CFRelease(flags);
+ }
+
+ CFMutableDictionaryRef meta = CFDictionaryCreateMutable(kCFAllocatorDefault,
+ 0,
+ &kCFTypeDictionaryKeyCallBacks,
+ &kCFTypeDictionaryValueCallBacks);
+ CFDictionarySetValue(meta, CFSTR("events"), events);
+
+ CFNumberRef num = CFNumberCreate(kCFAllocatorDefault, kCFNumberCFIndexType, &numEvents);
+ CFDictionarySetValue(meta, CFSTR("numEvents"), num);
+
+ CFDataRef data = TSICTStringCreateRenderedDataFromObjectWithFormat(meta, format);
+ fprintf(stdout, "%s", CFDataGetBytePtr(data));
+
+ CFRelease(events);
+ CFRelease(num);
+ CFRelease(meta);
+ CFRelease(data);
+}
+
+static void callback(__attribute__((unused)) FSEventStreamRef streamRef,
+ __attribute__((unused)) void* clientCallBackInfo,
+ size_t numEvents,
+ void* eventPaths,
+ const FSEventStreamEventFlags eventFlags[],
+ const FSEventStreamEventId eventIds[])
+{
+ char** paths = eventPaths;
+
+
+#ifdef DEBUG
+ fprintf(stderr, "\n");
+ fprintf(stderr, "FSEventStreamCallback fired!\n");
+ fprintf(stderr, " numEvents: %lu\n", numEvents);
+
+ for (size_t i = 0; i < numEvents; i++) {
+ fprintf(stderr, "\n");
+ fprintf(stderr, " event ID: %llu\n", eventIds[i]);
+
+// STFU clang
+#if defined(__LP64__)
+ fprintf(stderr, " event flags: %#.8x\n", eventFlags[i]);
+#else
+ fprintf(stderr, " event flags: %#.8lx\n", eventFlags[i]);
+#endif
+
+ FLAG_CHECK_STDERR(eventFlags[i], kFSEventStreamEventFlagMustScanSubDirs,
+ " Recursive scanning of directory required");
+ FLAG_CHECK_STDERR(eventFlags[i], kFSEventStreamEventFlagUserDropped,
+ " Buffering problem: events dropped user-side");
+ FLAG_CHECK_STDERR(eventFlags[i], kFSEventStreamEventFlagKernelDropped,
+ " Buffering problem: events dropped kernel-side");
+ FLAG_CHECK_STDERR(eventFlags[i], kFSEventStreamEventFlagEventIdsWrapped,
+ " Event IDs have wrapped");
+ FLAG_CHECK_STDERR(eventFlags[i], kFSEventStreamEventFlagHistoryDone,
+ " All historical events have been processed");
+ FLAG_CHECK_STDERR(eventFlags[i], kFSEventStreamEventFlagRootChanged,
+ " Root path has changed");
+ FLAG_CHECK_STDERR(eventFlags[i], kFSEventStreamEventFlagMount,
+ " A new volume was mounted at this path");
+ FLAG_CHECK_STDERR(eventFlags[i], kFSEventStreamEventFlagUnmount,
+ " A volume was unmounted from this path");
+ FLAG_CHECK_STDERR(eventFlags[i], kFSEventStreamEventFlagItemCreated,
+ " Item created");
+ FLAG_CHECK_STDERR(eventFlags[i], kFSEventStreamEventFlagItemRemoved,
+ " Item removed");
+ FLAG_CHECK_STDERR(eventFlags[i], kFSEventStreamEventFlagItemInodeMetaMod,
+ " Item metadata modified");
+ FLAG_CHECK_STDERR(eventFlags[i], kFSEventStreamEventFlagItemRenamed,
+ " Item renamed");
+ FLAG_CHECK_STDERR(eventFlags[i], kFSEventStreamEventFlagItemModified,
+ " Item modified");
+ FLAG_CHECK_STDERR(eventFlags[i], kFSEventStreamEventFlagItemFinderInfoMod,
+ " Item Finder Info modified");
+ FLAG_CHECK_STDERR(eventFlags[i], kFSEventStreamEventFlagItemChangeOwner,
+ " Item changed ownership");
+ FLAG_CHECK_STDERR(eventFlags[i], kFSEventStreamEventFlagItemXattrMod,
+ " Item extended attributes modified");
+ FLAG_CHECK_STDERR(eventFlags[i], kFSEventStreamEventFlagItemIsFile,
+ " Item is a file");
+ FLAG_CHECK_STDERR(eventFlags[i], kFSEventStreamEventFlagItemIsDir,
+ " Item is a directory");
+ FLAG_CHECK_STDERR(eventFlags[i], kFSEventStreamEventFlagItemIsSymlink,
+ " Item is a symbolic link");
+ FLAG_CHECK_STDERR(eventFlags[i], kFSEventStreamEventFlagItemIsHardlink,
+ " Item is a hard link");
+ FLAG_CHECK_STDERR(eventFlags[i], kFSEventStreamEventFlagItemIsLastHardlink,
+ " Item is the last hard link");
+ fprintf(stderr, " event path: %s\n", paths[i]);
+ fprintf(stderr, "\n");
+ }
+
+ fprintf(stderr, "\n");
+#endif
+
+ if (config.format == kFSEventWatchOutputFormatClassic) {
+ classic_output_format(numEvents, paths);
+ } else if (config.format == kFSEventWatchOutputFormatNIW) {
+ niw_output_format(numEvents, paths, eventFlags, eventIds);
+ } else if (config.format == kFSEventWatchOutputFormatTNetstring) {
+ tstring_output_format(numEvents, paths, eventFlags, eventIds,
+ kTSITStringFormatTNetstring);
+ } else if (config.format == kFSEventWatchOutputFormatOTNetstring) {
+ tstring_output_format(numEvents, paths, eventFlags, eventIds,
+ kTSITStringFormatOTNetstring);
+ }
+
+ fflush(stdout);
+}
+
+int main(int argc, const char* argv[])
+{
+ install_signal_handlers();
+ parse_cli_settings(argc, argv);
+
+ if (needs_fsevents_fix) {
+ FSEventsFixEnable();
+ }
+
+ FSEventStreamContext context = {0, NULL, NULL, NULL, NULL};
+ FSEventStreamRef stream;
+ stream = FSEventStreamCreate(kCFAllocatorDefault,
+ (FSEventStreamCallback)&callback,
+ &context,
+ config.paths,
+ config.sinceWhen,
+ config.latency,
+ config.flags);
+
+#ifdef DEBUG
+ FSEventStreamShow(stream);
+ fprintf(stderr, "\n");
+#endif
+
+ if (needs_fsevents_fix) {
+ FSEventsFixDisable();
+ }
+
+ FSEventStreamScheduleWithRunLoop(stream,
+ CFRunLoopGetCurrent(),
+ kCFRunLoopDefaultMode);
+ FSEventStreamStart(stream);
+ CFRunLoopRun();
+ FSEventStreamFlushSync(stream);
+ FSEventStreamStop(stream);
+
+ return 0;
+}
diff --git a/vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/ext/fsevent_watch/signal_handlers.c b/vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/ext/fsevent_watch/signal_handlers.c
new file mode 100644
index 0000000..b20da3f
--- /dev/null
+++ b/vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/ext/fsevent_watch/signal_handlers.c
@@ -0,0 +1,66 @@
+#include "signal_handlers.h"
+#include <fcntl.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/time.h>
+#include <unistd.h>
+
+
+#define PPID_ALARM_INTERVAL 2 // send SIGALRM every this seconds
+
+
+static pid_t orig_ppid;
+
+
+static void signal_handler(int _) {
+ exit(EXIT_FAILURE);
+}
+
+static void check_ppid(void) {
+ if (getppid() != orig_ppid) {
+ exit(EXIT_FAILURE);
+ }
+}
+
+static void check_stdout_open(void) {
+ if (fcntl(STDOUT_FILENO, F_GETFD) < 0) {
+ exit(EXIT_FAILURE);
+ }
+}
+
+static void alarm_handler(int _) {
+ check_ppid();
+ check_stdout_open();
+ alarm(PPID_ALARM_INTERVAL);
+ signal(SIGALRM, alarm_handler);
+}
+
+static void die(const char *msg) {
+ fprintf(stderr, "\nFATAL: %s\n", msg);
+ abort();
+}
+
+static void install_signal_handler(int sig, void (*handler)(int)) {
+ if (signal(sig, handler) == SIG_ERR) {
+ die("Could not install signal handler");
+ }
+}
+
+void install_signal_handlers(void) {
+ // check pipe is still connected
+ check_stdout_open();
+
+ // watch getppid() every PPID_ALARM_INTERVAL seconds
+ orig_ppid = getppid();
+ if (orig_ppid <= 1) {
+ die("prematurely zombied");
+ }
+ install_signal_handler(SIGALRM, alarm_handler);
+ alarm(PPID_ALARM_INTERVAL);
+
+ // be sure to exit on SIGHUP, SIGPIPE
+ install_signal_handler(SIGHUP, signal_handler);
+ install_signal_handler(SIGPIPE, signal_handler);
+}
+
diff --git a/vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/ext/fsevent_watch/signal_handlers.h b/vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/ext/fsevent_watch/signal_handlers.h
new file mode 100644
index 0000000..c31685d
--- /dev/null
+++ b/vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/ext/fsevent_watch/signal_handlers.h
@@ -0,0 +1,16 @@
+/**
+ * @headerfile signal_handlers.h
+ * Signal handlers to stop the zombie hordes
+ *
+ * Catch and handle signals better so that we die faster like a good meat puppet.
+ */
+
+
+#ifndef fsevent_watch_signal_handlers_h
+#define fsevent_watch_signal_handlers_h
+
+
+void install_signal_handlers(void);
+
+
+#endif // fsevent_watch_signal_handlers_h
diff --git a/vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/ext/rakefile.rb b/vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/ext/rakefile.rb
new file mode 100644
index 0000000..e50e888
--- /dev/null
+++ b/vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/ext/rakefile.rb
@@ -0,0 +1,231 @@
+# -*- encoding: utf-8 -*-
+require 'rubygems' unless defined?(Gem)
+require 'pathname'
+require 'date'
+require 'time'
+require 'rake/clean'
+
+raise "unable to find xcodebuild" unless system('which', 'xcodebuild')
+
+
+FSEVENT_WATCH_EXE_VERSION = '0.1.5'
+
+$this_dir = Pathname.new(__FILE__).dirname.expand_path
+$final_exe = $this_dir.parent.join('bin/fsevent_watch')
+
+$src_dir = $this_dir.join('fsevent_watch')
+$obj_dir = $this_dir.join('build')
+
+SRC = Pathname.glob("#{$src_dir}/*.c")
+OBJ = SRC.map {|s| $obj_dir.join("#{s.basename('.c')}.o")}
+
+$now = DateTime.now.xmlschema rescue Time.now.xmlschema
+
+$CC = ENV['CC'] || `which clang || which gcc`.strip
+$CFLAGS = ENV['CFLAGS'] || '-fconstant-cfstrings -fasm-blocks -fstrict-aliasing -Wall'
+$ARCHFLAGS = ENV['ARCHFLAGS'] || '-arch x86_64'
+$DEFINES = "-DNS_BUILD_32_LIKE_64 -DNS_BLOCK_ASSERTIONS -DPROJECT_VERSION=#{FSEVENT_WATCH_EXE_VERSION}"
+
+$GCC_C_LANGUAGE_STANDARD = ENV['GCC_C_LANGUAGE_STANDARD'] || 'gnu11'
+
+# generic developer id name so it'll match correctly for anyone who has only
+# one developer id in their keychain (not that I expect anyone else to bother)
+$CODE_SIGN_IDENTITY = 'Developer ID Application'
+
+$arch = `uname -m`.strip
+$os_release = `uname -r`.strip
+$BUILD_TRIPLE = "#{$arch}-apple-darwin#{$os_release}"
+
+$CCVersion = `#{$CC} --version | head -n 1`.strip
+
+
+CLEAN.include OBJ.map(&:to_s)
+CLEAN.include $obj_dir.join('Info.plist').to_s
+CLEAN.include $obj_dir.join('fsevent_watch').to_s
+CLOBBER.include $final_exe.to_s
+
+
+task :sw_vers do
+ $mac_product_version = `sw_vers -productVersion`.strip
+ $mac_build_version = `sw_vers -buildVersion`.strip
+ $MACOSX_DEPLOYMENT_TARGET = ENV['MACOSX_DEPLOYMENT_TARGET'] || $mac_product_version.sub(/\.\d*$/, '')
+ $CFLAGS = "#{$CFLAGS} -mmacosx-version-min=#{$MACOSX_DEPLOYMENT_TARGET}"
+end
+
+task :get_sdk_info => :sw_vers do
+ $SDK_INFO = {}
+ version_info = `xcodebuild -version -sdk macosx#{$MACOSX_DEPLOYMENT_TARGET}`
+ raise "invalid SDK" unless !!$?.exitstatus
+ version_info.strip.each_line do |line|
+ next if line.strip.empty?
+ next unless line.include?(':')
+ match = line.match(/([^:]*): (.*)/)
+ next unless match
+ $SDK_INFO[match[1]] = match[2]
+ end
+end
+
+task :debug => :sw_vers do
+ $DEFINES = "-DDEBUG #{$DEFINES}"
+ $CFLAGS = "#{$CFLAGS} -O0 -fno-omit-frame-pointer -g"
+end
+
+task :release => :sw_vers do
+ $DEFINES = "-DNDEBUG #{$DEFINES}"
+ $CFLAGS = "#{$CFLAGS} -Ofast"
+end
+
+desc 'configure build type depending on whether ENV var FWDEBUG is set'
+task :set_build_type => :sw_vers do
+ if ENV['FWDEBUG']
+ Rake::Task[:debug].invoke
+ else
+ Rake::Task[:release].invoke
+ end
+end
+
+desc 'set build arch to ppc'
+task :ppc do
+ $ARCHFLAGS = '-arch ppc'
+end
+
+desc 'set build arch to x86_64'
+task :x86_64 do
+ $ARCHFLAGS = '-arch x86_64'
+end
+
+desc 'set build arch to i386'
+task :x86 do
+ $ARCHFLAGS = '-arch i386'
+end
+
+desc 'set build arch to arm64'
+task :arm64 do
+ $ARCHFLAGS = '-arch arm64'
+end
+
+task :setup_env => [:set_build_type, :sw_vers, :get_sdk_info]
+
+directory $obj_dir.to_s
+file $obj_dir.to_s => :setup_env
+
+SRC.zip(OBJ).each do |source, object|
+ file object.to_s => [source.to_s, $obj_dir.to_s] do
+ cmd = [
+ $CC,
+ $ARCHFLAGS,
+ "-std=#{$GCC_C_LANGUAGE_STANDARD}",
+ $CFLAGS,
+ $DEFINES,
+ "-I#{$src_dir}",
+ '-isysroot',
+ $SDK_INFO['Path'],
+ '-c', source,
+ '-o', object
+ ]
+ sh(cmd.map {|s| s.to_s}.join(' '))
+ end
+end
+
+file $obj_dir.join('Info.plist').to_s => [$obj_dir.to_s, :setup_env] do
+ File.open($obj_dir.join('Info.plist').to_s, 'w+') do |file|
+ indentation = ''
+ indent = lambda {|num| indentation = ' ' * num }
+ add = lambda {|str| file << "#{indentation}#{str}\n" }
+ key = lambda {|str| add["<key>#{str}</key>"] }
+ string = lambda {|str| add["<string>#{str}</string>"] }
+
+
+ add['<?xml version="1.0" encoding="UTF-8"?>']
+ add['<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">']
+ add['<plist version="1.0">']
+
+ indent[2]
+ add['<dict>']
+ indent[4]
+
+ key['CFBundleExecutable']
+ string['fsevent_watch']
+ key['CFBundleIdentifier']
+ string['com.teaspoonofinsanity.fsevent_watch']
+ key['CFBundleName']
+ string['fsevent_watch']
+ key['CFBundleDisplayName']
+ string['FSEvent Watch CLI']
+ key['NSHumanReadableCopyright']
+ string['Copyright (C) 2011-2017 Travis Tilley']
+
+ key['CFBundleVersion']
+ string["#{FSEVENT_WATCH_EXE_VERSION}"]
+ key['LSMinimumSystemVersion']
+ string["#{$MACOSX_DEPLOYMENT_TARGET}"]
+ key['DTSDKBuild']
+ string["#{$SDK_INFO['ProductBuildVersion']}"]
+ key['DTSDKName']
+ string["macosx#{$SDK_INFO['SDKVersion']}"]
+ key['DTSDKPath']
+ string["#{$SDK_INFO['Path']}"]
+ key['BuildMachineOSBuild']
+ string["#{$mac_build_version}"]
+ key['BuildMachineOSVersion']
+ string["#{$mac_product_version}"]
+ key['FSEWCompiledAt']
+ string["#{$now}"]
+ key['FSEWVersionInfoBuilder']
+ string["#{`whoami`.strip}"]
+ key['FSEWBuildTriple']
+ string["#{$BUILD_TRIPLE}"]
+ key['FSEWCC']
+ string["#{$CC}"]
+ key['FSEWCCVersion']
+ string["#{$CCVersion}"]
+ key['FSEWCFLAGS']
+ string["#{$CFLAGS}"]
+
+ indent[2]
+ add['</dict>']
+ indent[0]
+
+ add['</plist>']
+ end
+end
+
+desc 'generate an Info.plist used for code signing as well as embedding build settings into the resulting binary'
+task :plist => $obj_dir.join('Info.plist').to_s
+
+
+file $obj_dir.join('fsevent_watch').to_s => [$obj_dir.to_s, $obj_dir.join('Info.plist').to_s] + OBJ.map(&:to_s) do
+ cmd = [
+ $CC,
+ $ARCHFLAGS,
+ "-std=#{$GCC_C_LANGUAGE_STANDARD}",
+ $CFLAGS,
+ $DEFINES,
+ "-I#{$src_dir}",
+ '-isysroot',
+ $SDK_INFO['Path'],
+ '-framework CoreFoundation -framework CoreServices',
+ '-sectcreate __TEXT __info_plist',
+ $obj_dir.join('Info.plist')
+ ] + OBJ + [
+ '-o', $obj_dir.join('fsevent_watch')
+ ]
+ sh(cmd.map {|s| s.to_s}.join(' '))
+end
+
+desc 'compile and link build/fsevent_watch'
+task :build => $obj_dir.join('fsevent_watch').to_s
+
+desc 'codesign build/fsevent_watch binary'
+task :codesign => :build do
+ sh "codesign -s '#{$CODE_SIGN_IDENTITY}' #{$obj_dir.join('fsevent_watch')}"
+end
+
+directory $this_dir.parent.join('bin')
+
+desc 'replace bundled fsevent_watch binary with build/fsevent_watch'
+task :replace_exe => [$this_dir.parent.join('bin'), :build] do
+ sh "mv #{$obj_dir.join('fsevent_watch')} #{$final_exe}"
+end
+
+task :default => [:replace_exe, :clean]
diff --git a/vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/lib/otnetstring.rb b/vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/lib/otnetstring.rb
new file mode 100644
index 0000000..7623d67
--- /dev/null
+++ b/vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/lib/otnetstring.rb
@@ -0,0 +1,85 @@
+# Copyright (c) 2011 Konstantin Haase
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+
+
+require 'stringio'
+
+module OTNetstring
+ class Error < StandardError; end
+
+ class << self
+ def parse(io, encoding = 'internal', fallback_encoding = nil)
+ fallback_encoding = io.encoding if io.respond_to? :encoding
+ io = StringIO.new(io) if io.respond_to? :to_str
+ length, byte = String.new, nil
+
+ while byte.nil? || byte =~ /\d/
+ length << byte if byte
+ byte = io.read(1)
+ end
+
+ if length.size > 9
+ raise Error, "#{length} is longer than 9 digits"
+ elsif length !~ /\d+/
+ raise Error, "Expected '#{byte}' to be a digit"
+ end
+ length = Integer(length)
+
+ case byte
+ when '#' then Integer io.read(length)
+ when ',' then with_encoding io.read(length), encoding, fallback_encoding
+ when '~' then
+ raise Error, "nil has length of 0, #{length} given" unless length == 0
+ when '!' then io.read(length) == 'true'
+ when '[', '{'
+ array = []
+ start = io.pos
+ array << parse(io, encoding, fallback_encoding) while io.pos - start < length
+ raise Error, 'Nested element longer than container' if io.pos - start != length
+ byte == "{" ? Hash[*array] : array
+ else
+ raise Error, "Unknown type '#{byte}'"
+ end
+ end
+
+ def encode(obj, string_sep = ',')
+ case obj
+ when String then with_encoding "#{obj.bytesize}#{string_sep}#{obj}", "binary"
+ when Integer then encode(obj.inspect, '#')
+ when NilClass then "0~"
+ when Array then encode(obj.map { |e| encode(e) }.join, '[')
+ when Hash then encode(obj.map { |a,b| encode(a)+encode(b) }.join, '{')
+ when FalseClass, TrueClass then encode(obj.inspect, '!')
+ else raise Error, 'cannot encode %p' % obj
+ end
+ end
+
+ private
+
+ def with_encoding(str, encoding, fallback = nil)
+ return str unless str.respond_to? :encode
+ encoding = Encoding.find encoding if encoding.respond_to? :to_str
+ encoding ||= fallback
+ encoding ? str.encode(encoding) : str
+ rescue EncodingError
+ str.force_encoding(encoding)
+ end
+ end
+end
diff --git a/vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/lib/rb-fsevent.rb b/vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/lib/rb-fsevent.rb
new file mode 100644
index 0000000..1ff68a3
--- /dev/null
+++ b/vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/lib/rb-fsevent.rb
@@ -0,0 +1,3 @@
+# -*- encoding: utf-8 -*-
+require 'rb-fsevent/fsevent'
+require 'rb-fsevent/version'
diff --git a/vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/lib/rb-fsevent/fsevent.rb b/vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/lib/rb-fsevent/fsevent.rb
new file mode 100644
index 0000000..fac2364
--- /dev/null
+++ b/vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/lib/rb-fsevent/fsevent.rb
@@ -0,0 +1,157 @@
+# -*- encoding: utf-8 -*-
+
+require 'otnetstring'
+
+class FSEvent
+ class << self
+ class_eval <<-END
+ def root_path
+ "#{File.expand_path(File.join(File.dirname(__FILE__), '..', '..'))}"
+ end
+ END
+ class_eval <<-END
+ def watcher_path
+ "#{File.join(FSEvent.root_path, 'bin', 'fsevent_watch')}"
+ end
+ END
+ end
+
+ attr_reader :paths, :callback
+
+ def initialize args = nil, &block
+ watch(args, &block) unless args.nil?
+ end
+
+ def watch(watch_paths, options=nil, &block)
+ @paths = watch_paths.kind_of?(Array) ? watch_paths : [watch_paths]
+ @callback = block
+
+ if options.kind_of?(Hash)
+ @options = parse_options(options)
+ elsif options.kind_of?(Array)
+ @options = options
+ else
+ @options = []
+ end
+ end
+
+ def run
+ @pipe = open_pipe
+ @running = true
+
+ # please note the use of IO::select() here, as it is used specifically to
+ # preserve correct signal handling behavior in ruby 1.8.
+ while @running && IO::select([@pipe], nil, nil, nil)
+ # managing the IO ourselves allows us to be careful and never pass an
+ # incomplete message to OTNetstring.parse()
+ message = String.new
+ length = String.new
+ byte = nil
+
+ reading_length = true
+ found_length = false
+
+ while reading_length
+ byte = @pipe.read_nonblock(1)
+ if "#{byte}" =~ /\d/
+ length << byte
+ found_length = true
+ elsif found_length == false
+ next
+ else
+ reading_length = false
+ end
+ end
+ length = Integer(length, 10)
+ type = byte
+
+ message << "#{length}#{type}"
+ message << @pipe.read(length)
+
+ decoded = OTNetstring.parse(message)
+ modified_paths = decoded["events"].map {|event| event["path"]}
+ # passing the full info as a second block param feels icky, but such is
+ # the trap of backward compatibility.
+ case callback.arity
+ when 1
+ callback.call(modified_paths)
+ when 2
+ callback.call(modified_paths, decoded)
+ end
+ end
+ rescue Interrupt, IOError, Errno::EBADF
+ ensure
+ stop
+ end
+
+ def stop
+ unless @pipe.nil?
+ Process.kill('KILL', @pipe.pid) if process_running?(@pipe.pid)
+ @pipe.close
+ end
+ rescue IOError, Errno::EBADF
+ ensure
+ @running = false
+ end
+
+ def process_running?(pid)
+ begin
+ Process.kill(0, pid)
+ true
+ rescue Errno::ESRCH
+ false
+ end
+ end
+
+ if RUBY_VERSION < '1.9'
+ def open_pipe
+ IO.popen("'#{self.class.watcher_path}' #{options_string} #{shellescaped_paths}")
+ end
+
+ private
+
+ def options_string
+ @options.join(' ')
+ end
+
+ def shellescaped_paths
+ @paths.map {|path| shellescape(path)}.join(' ')
+ end
+
+ # for Ruby 1.8.6 support
+ def shellescape(str)
+ # An empty argument will be skipped, so return empty quotes.
+ return "''" if str.empty?
+
+ str = str.dup
+
+ # Process as a single byte sequence because not all shell
+ # implementations are multibyte aware.
+ str.gsub!(/([^A-Za-z0-9_\-.,:\/@\n])/n, "\\\\\\1")
+
+ # A LF cannot be escaped with a backslash because a backslash + LF
+ # combo is regarded as line continuation and simply ignored.
+ str.gsub!(/\n/, "'\n'")
+
+ return str
+ end
+ else
+ def open_pipe
+ IO.popen([self.class.watcher_path] + @options + @paths)
+ end
+ end
+
+ private
+
+ def parse_options(options={})
+ opts = ['--format=otnetstring']
+ opts.concat(['--since-when', options[:since_when]]) if options[:since_when]
+ opts.concat(['--latency', options[:latency]]) if options[:latency]
+ opts.push('--no-defer') if options[:no_defer]
+ opts.push('--watch-root') if options[:watch_root]
+ opts.push('--file-events') if options[:file_events]
+ # ruby 1.9's IO.popen(array-of-stuff) syntax requires all items to be strings
+ opts.map {|opt| "#{opt}"}
+ end
+
+end
diff --git a/vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/lib/rb-fsevent/version.rb b/vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/lib/rb-fsevent/version.rb
new file mode 100644
index 0000000..332be3b
--- /dev/null
+++ b/vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/lib/rb-fsevent/version.rb
@@ -0,0 +1,5 @@
+# -*- encoding: utf-8 -*-
+
+class FSEvent
+ VERSION = '0.11.2'
+end
diff --git a/vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/rb-fsevent.gemspec b/vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/rb-fsevent.gemspec
new file mode 100644
index 0000000..8f1e5aa
--- /dev/null
+++ b/vendor/bundle/ruby/3.4.0/gems/rb-fsevent-0.11.2/rb-fsevent.gemspec
@@ -0,0 +1,26 @@
+# coding: utf-8
+lib = File.expand_path('../lib', __FILE__)
+$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
+require 'rb-fsevent/version'
+
+Gem::Specification.new do |s|
+ s.name = 'rb-fsevent'
+ s.version = FSEvent::VERSION
+ s.authors = ['Thibaud Guillaume-Gentil', 'Travis Tilley']
+ s.email = ['thibaud@thibaud.gg', 'ttilley@gmail.com']
+ s.homepage = 'http://rubygems.org/gems/rb-fsevent'
+ s.summary = 'Very simple & usable FSEvents API'
+ s.description = 'FSEvents API with Signals catching (without RubyCocoa)'
+ s.license = 'MIT'
+
+ s.metadata = {
+ 'source_code_uri' => 'https://github.com/thibaudgg/rb-fsevent'
+ }
+
+ s.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^spec/}) }
+ s.require_path = 'lib'
+
+ s.add_development_dependency 'rspec', '~> 3.6'
+ s.add_development_dependency 'guard-rspec', '~> 4.2'
+ s.add_development_dependency 'rake', '~> 12.0'
+end