+sub tick (;$) {
+ my $tick = shift // 0.1;
+ select undef, undef, undef, $tick;
+ 1;
+}
+
+sub wait_for_tail ($;$) {
+ my ($tail_pid, $want) = @_;
+ my $wait = 2;
+ if ($^O eq 'linux') { # GNU tail may use inotify
+ state $tail_has_inotify;
+ return tick if $want < 0 && $tail_has_inotify;
+ my $end = time + $wait;
+ my @ino;
+ do {
+ @ino = grep {
+ readlink($_) =~ /\binotify\b/
+ } glob("/proc/$tail_pid/fd/*");
+ } while (!@ino && time <= $end and tick);
+ return if !@ino;
+ $tail_has_inotify = 1;
+ $ino[0] =~ s!/fd/!/fdinfo/!;
+ my @info;
+ do {
+ if (open my $fh, '<', $ino[0]) {
+ local $/ = "\n";
+ @info = grep(/^inotify wd:/, <$fh>);
+ }
+ } while (scalar(@info) < $want && time <= $end and tick);
+ } else {
+ sleep($wait);
+ }
+}