Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

78 lines
1.7 KiB

  1. package FileCache;
  2. =head1 NAME
  3. FileCache - keep more files open than the system permits
  4. =head1 SYNOPSIS
  5. cacheout $path;
  6. print $path @data;
  7. =head1 DESCRIPTION
  8. The C<cacheout> function will make sure that there's a filehandle open
  9. for writing available as the pathname you give it. It automatically
  10. closes and re-opens files if you exceed your system file descriptor
  11. maximum.
  12. =head1 BUGS
  13. F<sys/param.h> lies with its C<NOFILE> define on some systems,
  14. so you may have to set $FileCache::cacheout_maxopen yourself.
  15. =cut
  16. require 5.000;
  17. use Carp;
  18. use Exporter;
  19. @ISA = qw(Exporter);
  20. @EXPORT = qw(
  21. cacheout
  22. );
  23. # Open in their package.
  24. sub cacheout_open {
  25. my $pack = caller(1);
  26. open(*{$pack . '::' . $_[0]}, $_[1]);
  27. }
  28. sub cacheout_close {
  29. my $pack = caller(1);
  30. close(*{$pack . '::' . $_[0]});
  31. }
  32. # But only this sub name is visible to them.
  33. $cacheout_seq = 0;
  34. $cacheout_numopen = 0;
  35. sub cacheout {
  36. ($file) = @_;
  37. unless (defined $cacheout_maxopen) {
  38. if (open(PARAM,'/usr/include/sys/param.h')) {
  39. local ($_, $.);
  40. while (<PARAM>) {
  41. $cacheout_maxopen = $1 - 4
  42. if /^\s*#\s*define\s+NOFILE\s+(\d+)/;
  43. }
  44. close PARAM;
  45. }
  46. $cacheout_maxopen = 16 unless $cacheout_maxopen;
  47. }
  48. if (!$isopen{$file}) {
  49. if (++$cacheout_numopen > $cacheout_maxopen) {
  50. my @lru = sort {$isopen{$a} <=> $isopen{$b};} keys(%isopen);
  51. splice(@lru, $cacheout_maxopen / 3);
  52. $cacheout_numopen -= @lru;
  53. for (@lru) { &cacheout_close($_); delete $isopen{$_}; }
  54. }
  55. cacheout_open($file, ($saw{$file}++ ? '>>' : '>') . $file)
  56. or croak("Can't create $file: $!");
  57. }
  58. $isopen{$file} = ++$cacheout_seq;
  59. }
  60. 1;