Skip to content

Commit

Permalink
Set FD_CLOEXEC flag on cache files when opened
Browse files Browse the repository at this point in the history
  • Loading branch information
robmueller committed Jun 1, 2016
1 parent 9da1df9 commit d285115
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 2 deletions.
7 changes: 7 additions & 0 deletions Changes
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
Revision history for Perl extension Cache::FastMmap.

1.44 Wed Jun 1 21:45 2016
- Set FD_CLOEXEC flag on cache files when opened.
Particularly useful in Net::Server where
HUPing a process causes it to exec() itself.
Unless you undef the cache references, you'll
leak fd's after each HUP

1.43 Fri Oct 23 14:00 2015
- Update copyright + version correctly everywhere

Expand Down
2 changes: 1 addition & 1 deletion META.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# http://module-build.sourceforge.net/META-spec.html
#XXXXXXX This is a prototype!!! It will change in the future!!! XXXXX#
name: Cache-FastMmap
version: 1.43
version: 1.44
version_from: FastMmap.pm
installdirs: site
requires:
Expand Down
2 changes: 1 addition & 1 deletion lib/Cache/FastMmap.pm
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,7 @@ use strict;
use warnings;
use bytes;

our $VERSION = '1.43';
our $VERSION = '1.44';

require XSLoader;
XSLoader::load('Cache::FastMmap', $VERSION);
Expand Down
63 changes: 63 additions & 0 deletions t/18.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@

#########################

use Test::More;

BEGIN {
if ($^O eq "MSWin32") {
plan skip_all => 'No FD_CLOEXEC tests, running on Windows';
}
if (!-d "/proc/$$") {
plan skip_all => 'No FD_CLOEXEC tests, no /proc filesystem';
}
}


use strict;
use Fcntl;

#########################

# Test fd's are closed on exec

if (@ARGV) {
my $PipeFd = shift @ARGV;
my $FdCount = scalar(() = glob "/proc/$$/fd/*");
open(my $PipeFh, ">&=$PipeFd")
|| die "Could not reopen fd: $!";
print($PipeFh "$FdCount\n")
|| die "Could not print to pipe: $!";
exit(0);
}

require Cache::FastMmap;
my @Caches = map {
Cache::FastMmap->new(
page_size => 4096,
num_pages => 1,
init_file => 1,
raw_values => 1,
);
} (1 .. 20);
my $CacheCount = @Caches;

my $FdCount = scalar(() = glob "/proc/$$/fd/*");
ok($FdCount > $CacheCount, "More fd's than caches: $FdCount > $CacheCount");

pipe(my $ReadPipeFh, my $WritePipeFh)
|| die "pipe failed: $!";

fcntl($ReadPipeFh, F_SETFD, 0);
fcntl($WritePipeFh, F_SETFD, 0);

if (!fork) {
exec $^X, $0, fileno($WritePipeFh)
|| die "exec failed: $!";
}

my $ChildFdCount = <$ReadPipeFh>;
chomp $ChildFdCount;
ok($ChildFdCount < $CacheCount, "Less fd's in child than caches: $ChildFdCount < $CacheCount");

done_testing(2);

3 changes: 3 additions & 0 deletions unix.c
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,9 @@ int mmc_open_cache_file(mmap_cache* cache, int * do_init) {
return -1;
}

/* Automatically close cache fd on exec */
fcntl(fh, F_SETFD, FD_CLOEXEC);

cache->fh = fh;

return 0;
Expand Down

0 comments on commit d285115

Please sign in to comment.