From: Eric Wong <e@80x24.org>
To: meta@public-inbox.org
Subject: [PATCH 3/6] umask: hoist out of InboxWritable
Date: Fri, 7 Apr 2023 12:40:50 +0000 [thread overview]
Message-ID: <20230407124053.2233988-4-e@80x24.org> (raw)
In-Reply-To: <20230407124053.2233988-1-e@80x24.org>
Since CodeSearchIdx doesn't deal with inboxes, it makes sense
to split it out from inbox-specific code and start moving
towards using OnDestroy to restore the umask at the end of
scope and reducing extra functions.
---
MANIFEST | 1 +
lib/PublicInbox/CodeSearchIdx.pm | 28 ++++---------
lib/PublicInbox/ExtSearchIdx.pm | 3 +-
lib/PublicInbox/InboxWritable.pm | 70 +-------------------------------
lib/PublicInbox/SearchIdx.pm | 6 ++-
lib/PublicInbox/Umask.pm | 70 ++++++++++++++++++++++++++++++++
t/search.t | 7 ++--
7 files changed, 91 insertions(+), 94 deletions(-)
create mode 100644 lib/PublicInbox/Umask.pm
diff --git a/MANIFEST b/MANIFEST
index a0e64c6a..c338f0f4 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -340,6 +340,7 @@ lib/PublicInbox/TestCommon.pm
lib/PublicInbox/Tmpfile.pm
lib/PublicInbox/URIimap.pm
lib/PublicInbox/URInntps.pm
+lib/PublicInbox/Umask.pm
lib/PublicInbox/Unsubscribe.pm
lib/PublicInbox/UserContent.pm
lib/PublicInbox/V2Writable.pm
diff --git a/lib/PublicInbox/CodeSearchIdx.pm b/lib/PublicInbox/CodeSearchIdx.pm
index 3a3fc03e..78032c00 100644
--- a/lib/PublicInbox/CodeSearchIdx.pm
+++ b/lib/PublicInbox/CodeSearchIdx.pm
@@ -770,28 +770,23 @@ sub init_tmp_git_dir ($) {
sub prep_umask ($) {
my ($self) = @_;
- my $um;
- my $cur = umask;
if ($self->{-cidx_internal}) { # respect core.sharedRepository
@{$self->{git_dirs}} == 1 or die 'BUG: only for GIT_DIR';
- # yuck, FIXME move umask handling out of inbox-specific stuff
- require PublicInbox::InboxWritable;
- my $git = PublicInbox::Git->new($self->{git_dirs}->[0]);
- chomp($um = $git->qx('config', 'core.sharedRepository') // '');
- $um = PublicInbox::InboxWritable::_git_config_perm(undef, $um);
- $um = PublicInbox::InboxWritable::_umask_for($um);
- umask == $um or progress($self, 'umask from git: ',
- sprintf('0%03o', $um));
+ local $self->{git} =
+ PublicInbox::Git->new($self->{git_dirs}->[0]);
+ $self->with_umask;
} elsif (-d $self->{cidx_dir}) { # respect existing perms
my @st = stat(_);
- $um = (~$st[2] & 0777);
+ my $um = (~$st[2] & 0777);
+ $self->{umask} = $um; # for SearchIdx->with_umask
umask == $um or progress($self, 'using umask from ',
$self->{cidx_dir}, ': ',
sprintf('0%03o', $um));
- }
- defined($um) ?
- PublicInbox::OnDestroy->new(\&CORE::umask, umask($um)) :
+ PublicInbox::OnDestroy->new($$, \&CORE::umask, umask($um));
+ } else {
+ $self->{umask} = umask; # for SearchIdx->with_umask
undef;
+ }
}
sub start_prune ($) {
@@ -896,9 +891,4 @@ sub shard_done_wait { # awaitpid cb via ipc_worker_reap
PublicInbox::DS::enqueue_reap() if !shards_active(); # once more for PLC
}
-sub with_umask { # TODO get rid of this treewide and rely on OnDestroy
- my ($self, $cb, @arg) = @_;
- $cb->(@arg);
-}
-
1;
diff --git a/lib/PublicInbox/ExtSearchIdx.pm b/lib/PublicInbox/ExtSearchIdx.pm
index 5445b156..6f3711ba 100644
--- a/lib/PublicInbox/ExtSearchIdx.pm
+++ b/lib/PublicInbox/ExtSearchIdx.pm
@@ -16,7 +16,7 @@
package PublicInbox::ExtSearchIdx;
use strict;
use v5.10.1;
-use parent qw(PublicInbox::ExtSearch PublicInbox::Lock);
+use parent qw(PublicInbox::ExtSearch PublicInbox::Umask PublicInbox::Lock);
use Carp qw(croak carp);
use Scalar::Util qw(blessed);
use Sys::Hostname qw(hostname);
@@ -1397,7 +1397,6 @@ sub eidx_watch { # public-inbox-extindex --watch main loop
no warnings 'once';
*done = \&PublicInbox::V2Writable::done;
-*with_umask = \&PublicInbox::InboxWritable::with_umask;
*parallel_init = \&PublicInbox::V2Writable::parallel_init;
*nproc_shards = \&PublicInbox::V2Writable::nproc_shards;
*sync_prepare = \&PublicInbox::V2Writable::sync_prepare;
diff --git a/lib/PublicInbox/InboxWritable.pm b/lib/PublicInbox/InboxWritable.pm
index 022e2a69..65952aa2 100644
--- a/lib/PublicInbox/InboxWritable.pm
+++ b/lib/PublicInbox/InboxWritable.pm
@@ -1,25 +1,17 @@
-# Copyright (C) 2018-2021 all contributors <meta@public-inbox.org>
+# Copyright (C) all contributors <meta@public-inbox.org>
# License: AGPL-3.0+ <https://www.gnu.org/licenses/agpl-3.0.txt>
# Extends read-only Inbox for writing
package PublicInbox::InboxWritable;
use strict;
use v5.10.1;
-use parent qw(PublicInbox::Inbox Exporter);
+use parent qw(PublicInbox::Inbox PublicInbox::Umask Exporter);
use PublicInbox::Import;
use PublicInbox::Filter::Base qw(REJECT);
use Errno qw(ENOENT);
our @EXPORT_OK = qw(eml_from_path);
use Fcntl qw(O_RDONLY O_NONBLOCK);
-use constant {
- PERM_UMASK => 0,
- OLD_PERM_GROUP => 1,
- OLD_PERM_EVERYBODY => 2,
- PERM_GROUP => 0660,
- PERM_EVERYBODY => 0664,
-};
-
sub new {
my ($class, $ibx, $creat_opt) = @_;
return $ibx if ref($ibx) eq $class;
@@ -176,64 +168,6 @@ sub import_mbox {
$im->done;
}
-sub _read_git_config_perm {
- my ($self) = @_;
- chomp(my $perm = $self->git->qx('config', 'core.sharedRepository'));
- $perm;
-}
-
-sub _git_config_perm {
- my $self = shift;
- my $perm = scalar @_ ? $_[0] : _read_git_config_perm($self);
- return PERM_UMASK if (!defined($perm) || $perm eq '');
- return PERM_UMASK if ($perm eq 'umask');
- return PERM_GROUP if ($perm eq 'group');
- if ($perm =~ /\A(?:all|world|everybody)\z/) {
- return PERM_EVERYBODY;
- }
- return PERM_GROUP if ($perm =~ /\A(?:true|yes|on|1)\z/);
- return PERM_UMASK if ($perm =~ /\A(?:false|no|off|0)\z/);
-
- my $i = oct($perm);
- return PERM_UMASK if ($i == PERM_UMASK);
- return PERM_GROUP if ($i == OLD_PERM_GROUP);
- return PERM_EVERYBODY if ($i == OLD_PERM_EVERYBODY);
-
- if (($i & 0600) != 0600) {
- die "core.sharedRepository mode invalid: ".
- sprintf('%.3o', $i) . "\nOwner must have permissions\n";
- }
- ($i & 0666);
-}
-
-sub _umask_for {
- my ($perm) = @_; # _git_config_perm return value
- my $rv = $perm;
- return umask if $rv == 0;
-
- # set +x bit if +r or +w were set
- $rv |= 0100 if ($rv & 0600);
- $rv |= 0010 if ($rv & 0060);
- $rv |= 0001 if ($rv & 0006);
- (~$rv & 0777);
-}
-
-sub with_umask {
- my ($self, $cb, @arg) = @_;
- my $old = umask($self->{umask} //= umask_prepare($self));
- my $rv = eval { $cb->(@arg) };
- my $err = $@;
- umask $old;
- die $err if $err;
- $rv;
-}
-
-sub umask_prepare {
- my ($self) = @_;
- my $perm = _git_config_perm($self);
- _umask_for($perm);
-}
-
sub cleanup ($) {
delete @{$_[0]}{qw(over mm git search)};
}
diff --git a/lib/PublicInbox/SearchIdx.pm b/lib/PublicInbox/SearchIdx.pm
index 699af432..69ab30e6 100644
--- a/lib/PublicInbox/SearchIdx.pm
+++ b/lib/PublicInbox/SearchIdx.pm
@@ -9,7 +9,8 @@
package PublicInbox::SearchIdx;
use strict;
use v5.10.1;
-use parent qw(PublicInbox::Search PublicInbox::Lock Exporter);
+use parent qw(PublicInbox::Search PublicInbox::Lock PublicInbox::Umask
+ Exporter);
use PublicInbox::Eml;
use PublicInbox::Search qw(xap_terms);
use PublicInbox::InboxWritable;
@@ -821,7 +822,8 @@ sub unindex_both { # git->cat_async callback
sub with_umask {
my $self = shift;
- ($self->{ibx} // $self->{eidx})->with_umask(@_);
+ my $owner = $self->{ibx} // $self->{eidx};
+ $owner ? $owner->with_umask(@_) : $self->SUPER::with_umask(@_)
}
# called by public-inbox-index
diff --git a/lib/PublicInbox/Umask.pm b/lib/PublicInbox/Umask.pm
new file mode 100644
index 00000000..00772ce5
--- /dev/null
+++ b/lib/PublicInbox/Umask.pm
@@ -0,0 +1,70 @@
+# Copyright (C) all contributors <meta@public-inbox.org>
+# License: AGPL-3.0+ <https://www.gnu.org/licenses/agpl-3.0.txt>
+
+# base class to ensures Xapian||SQLite files respect core.sharedRepository
+# of git repos
+package PublicInbox::Umask;
+use v5.12;
+use PublicInbox::OnDestroy;
+
+use constant {
+ PERM_UMASK => 0,
+ OLD_PERM_GROUP => 1,
+ OLD_PERM_EVERYBODY => 2,
+ PERM_GROUP => 0660,
+ PERM_EVERYBODY => 0664,
+};
+
+sub _read_git_config_perm {
+ my ($self) = @_;
+ chomp(my $perm = $self->git->qx('config', 'core.sharedRepository'));
+ $perm;
+}
+
+sub _git_config_perm {
+ my $self = shift;
+ my $perm = scalar @_ ? $_[0] : _read_git_config_perm($self);
+ $perm //= '';
+ return PERM_UMASK if $perm eq '' || $perm eq 'umask';
+ return PERM_GROUP if $perm eq 'group';
+ return PERM_EVERYBODY if $perm =~ /\A(?:all|world|everybody)\z/;
+ return PERM_GROUP if ($perm =~ /\A(?:true|yes|on|1)\z/);
+ return PERM_UMASK if ($perm =~ /\A(?:false|no|off|0)\z/);
+
+ my $i = oct($perm);
+ return PERM_UMASK if $i == PERM_UMASK;
+ return PERM_GROUP if $i == OLD_PERM_GROUP;
+ return PERM_EVERYBODY if $i == OLD_PERM_EVERYBODY;
+
+ if (($i & 0600) != 0600) {
+ die "core.sharedRepository mode invalid: ".
+ sprintf('%.3o', $i) . "\nOwner must have permissions\n";
+ }
+ ($i & 0666);
+}
+
+sub _umask_for {
+ my ($perm) = @_; # _git_config_perm return value
+ my $rv = $perm;
+ return umask if $rv == 0;
+
+ # set +x bit if +r or +w were set
+ $rv |= 0100 if ($rv & 0600);
+ $rv |= 0010 if ($rv & 0060);
+ $rv |= 0001 if ($rv & 0006);
+ (~$rv & 0777);
+}
+
+sub with_umask {
+ my ($self, $cb, @arg) = @_;
+ my $old = umask($self->{umask} //= umask_prepare($self));
+ my $restore = PublicInbox::OnDestroy->new($$, \&CORE::umask, $old);
+ $cb ? $cb->(@arg) : $restore;
+}
+
+sub umask_prepare {
+ my ($self) = @_;
+ _umask_for(_git_config_perm($self));
+}
+
+1;
diff --git a/t/search.t b/t/search.t
index cf639a6d..ea5a2a5a 100644
--- a/t/search.t
+++ b/t/search.t
@@ -41,8 +41,9 @@ sub oct_is ($$$) {
{
# git repository perms
+ use_ok 'PublicInbox::Umask';
oct_is($ibx->_git_config_perm(),
- &PublicInbox::InboxWritable::PERM_GROUP,
+ PublicInbox::Umask::PERM_GROUP(),
'undefined permission is group');
my @t = (
[ '0644', 0022, '644 => umask(0022)' ],
@@ -54,8 +55,8 @@ sub oct_is ($$$) {
);
for (@t) {
my ($perm, $exp, $msg) = @$_;
- my $got = PublicInbox::InboxWritable::_umask_for(
- PublicInbox::InboxWritable->_git_config_perm($perm));
+ my $got = PublicInbox::Umask::_umask_for(
+ PublicInbox::Umask->_git_config_perm($perm));
oct_is($got, $exp, $msg);
}
}
next prev parent reply other threads:[~2023-04-07 12:40 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-04-07 12:40 [PATCH 0/6] cindex fixes, and some spring cleaning Eric Wong
2023-04-07 12:40 ` [PATCH 1/6] cindex: improve progress display Eric Wong
2023-04-07 12:40 ` [PATCH 2/6] cindex: preserve indexlevel across invocations Eric Wong
2023-04-07 12:40 ` Eric Wong [this message]
2023-04-07 12:40 ` [PATCH 4/6] umask: rely on the OnDestroy-based call where applicable Eric Wong
2023-04-07 12:40 ` [PATCH 5/6] searchidx: use vstring to improve readability Eric Wong
2023-04-07 12:40 ` [PATCH 6/6] switch git version comparisons to vstrings, too Eric Wong
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://public-inbox.org/README
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230407124053.2233988-4-e@80x24.org \
--to=e@80x24.org \
--cc=meta@public-inbox.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://80x24.org/public-inbox.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).