The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.
CONTRIBUTING 0213
Changes 1061
LICENSE 0379
MANIFEST 328
META.json 093
META.yml 948
Makefile.PL 578
README 0208
chmod.pm 6470
lib/File/chmod.pm 0583
perlcritic.rc 06
t/00-compile.t 051
t/00-report-prereqs.dd 047
t/00-report-prereqs.t 0183
t/author-critic.t 020
t/author-eol.t 042
t/executable.t 022
t/load_chmod.t 029
t/read.t 041
t/release-cpan-changes.t 019
t/release-dist-manifest.t 016
t/release-meta-json.t 014
t/release-minimum-version.t 016
t/release-pod-coverage.t 015
t/release-pod-syntax.t 014
t/release-portability.t 020
t/release-test-version.t 030
t/release-unused-vars.t 022
t/remove-write-from-other.t 020
t/sticky-bit.t 039
t/write.t 023
test.pl 290
32 files changed (This is a version diff) 7032380
@@ -0,0 +1,213 @@
+Checklist
+
+(and a short version for the impatient):
+
+Commits:
+
+* make commits of logical units
+* check for unnecessary whitespace with "git diff --check" before committing
+* do not check in commented out code or unneeded files
+* the first line of the commit message should be a short description and
+  should skip the full stop
+* the body should provide a meaningful commit message, which:
+	* uses the imperative, present tense: "change", not "changed" or "changes".
+	* includes motivation for the change, and contrasts its implementation with
+	  previous behaviour
+* if you want your work included in the main repository, add a "Signed-off-by:
+  Your Name <you@example.com>" line to the commit message (or just use the
+  option "-s" when committing) to confirm that you agree to the Developer's
+  Certificate of Origin
+* make sure that you have tests for the bug you are fixing
+* make sure that the test suite passes after your commit. This distribution
+  is built with Dist::Zilla ensure that running `dzil test` passes. You are
+  responsible for ensuring that generated, hand written and author tests pass.
+
+Patch:
+
+* if you change, add, or remove any features or make some other user
+  interface change, the associated documentation should be updated as well.
+* if your name is not writable in ASCII, make sure that you send the
+  patch in the correct encoding.
+
+Long version:
+
+I started reading over the SubmittingPatches document for git,
+primarily because I wanted to have a document similar to it for
+my projects to make sure people understand what they are doing
+when they write "Signed-off-by" line.
+
+But the patch submission requirements are a lot more relaxed
+here on the technical/contents front, because my projects are
+thousand times smaller ;-).  So here is only the relevant bits.
+
+
+(0) Decide what to base your work on.
+
+In general, always base your work on the oldest branch that your
+change is relevant to.
+
+* A bugfix should be based on 'maint' in general. If the bug is not
+present in 'maint', base it on 'master'. For a bug that's not yet
+in 'master', find the topic that introduces the regression, and
+base your work on the tip of the topic. If a 'maint' branch is not present
+base it on master.
+
+* A new feature should be based on 'master' in general. If the new
+feature depends on a topic that is in 'pu', but not in 'master', base your
+work on the tip of that topic.
+
+* Corrections and enhancements to a topic not yet in 'master' should be
+based on the tip of that topic. If the topic has not been merged to 'next',
+it's alright to add a note to squash minor corrections into the series.
+
+* In the exceptional case that a new feature depends on several topics
+not in 'master', start working on 'next' or 'pu' privately and send out
+patches for discussion. Before the final merge, you may have to wait until
+some of the dependent topics graduate to 'master', and rebase your work.
+
+To find the tip of a topic branch, run "git log --first-parent
+master..pu" and look for the merge commit. The second parent of this
+commit is the tip of the topic branch.
+
+
+(1) Make separate commits for logically separate changes.
+
+Unless your patch is really trivial, you should not be sending
+out a patch that was generated between your working tree and
+your commit head.  Instead, always make a commit with complete
+commit message and generate a series of patches from your
+repository.  It is a good discipline.
+
+Describe the technical detail of the change(s).
+
+If your description starts to get too long, that's a sign that you
+probably need to split up your commit to finer grained pieces.
+That being said, patches which plainly describe the things that
+help reviewers check the patch, and future maintainers understand
+the code, are the most beautiful patches.  Descriptions that summarise
+the point in the subject well, and describe the motivation for the
+change, the approach taken by the change, and if relevant how this
+differs substantially from the prior version, can be found on Usenet
+archives back into the late 80's.  Consider it like good Netiquette,
+but for code.
+
+Oh, another thing.  I am picky about whitespaces.  Make sure your
+changes do not trigger errors with the sample pre-commit hook shipped
+in templates/hooks--pre-commit.  To help ensure this does not happen,
+run git diff --check on your changes before you commit.
+
+
+(2) Generate your patch using git tools out of your commits.
+
+git based diff tools (git, Cogito, and StGIT included) generate
+unidiff which is the preferred format.
+
+You do not have to be afraid to use -M option to "git diff" or
+"git format-patch", if your patch involves file renames.  The
+receiving end can handle them just fine.
+
+Please make sure your patch does not include any extra files
+which do not belong in a patch submission.  Make sure to review
+your patch after generating it, to ensure accuracy.  Before
+sending out, please make sure it cleanly applies to the "master"
+branch head.  If you are preparing a work based on "next" branch,
+that is fine, but please mark it as such.
+
+(4) Sign your work
+
+To improve tracking of who did what, we've borrowed the
+"sign-off" procedure from the Linux kernel project on patches
+that are being emailed around.  Although this project is a lot
+smaller it is a good discipline to follow it.
+
+The sign-off is a simple line at the end of the explanation for
+the patch, which certifies that you wrote it or otherwise have
+the right to pass it on as a open-source patch.  The rules are
+pretty simple: if you can certify the below:
+
+        Developer's Certificate of Origin 1.1
+
+        By making a contribution to this project, I certify that:
+
+        (a) The contribution was created in whole or in part by me and I
+            have the right to submit it under the open source license
+            indicated in the file; or
+
+        (b) The contribution is based upon previous work that, to the best
+            of my knowledge, is covered under an appropriate open source
+            license and I have the right under that license to submit that
+            work with modifications, whether created in whole or in part
+            by me, under the same open source license (unless I am
+            permitted to submit under a different license), as indicated
+            in the file; or
+
+        (c) The contribution was provided directly to me by some other
+            person who certified (a), (b) or (c) and I have not modified
+            it.
+
+        (d) I understand and agree that this project and the contribution
+            are public and that a record of the contribution (including all
+            personal information I submit with it, including my sign-off) is
+            maintained indefinitely and may be redistributed consistent with
+            this project or the open source license(s) involved.
+
+then you just add a line saying
+
+	Signed-off-by: Random J Developer <random@developer.example.org>
+
+This line can be automatically added by git if you run the git-commit
+command with the -s option.
+
+Notice that you can place your own Signed-off-by: line when
+forwarding somebody else's patch with the above rules for
+D-C-O.  Indeed you are encouraged to do so.
+
+Also notice that a real name is used in the Signed-off-by: line. Please
+don't hide your real name.
+
+Some people also put extra tags at the end.
+
+"Acked-by:" says that the patch was reviewed by the person who
+is more familiar with the issues and the area the patch attempts
+to modify.  "Tested-by:" says the patch was tested by the person
+and found to have the desired effect.
+
+
+An ideal patch flow
+
+Here is an ideal patch flow for this project the current maintainer
+suggests to the contributors:
+
+0. You come up with an itch.  You code it up.
+1. Send it to the bug tracker and cc people who may need to know about
+   the change.
+
+   The people who may need to know are the ones whose
+   code you are butchering.  These people happen to be the ones who are most
+   likely to be knowledgeable enough to help you, but they have no obligation to
+   help you (i.e. you ask for help, don't demand).  "git log -p --
+   $area_you_are_modifying" would help you find out who they are.
+
+2. You get comments and suggestions for improvements.  You may even
+   get them in a "on top of your change" patch form.
+
+3. Polish, refine, and re-send to the the people who spend their
+   time to improve your patch.  Go back to step (2).
+
+4. A topic branch is created with the patch and is merged to 'next',
+   and cooked further and eventually graduates to 'master'.
+
+In any time between the (2)-(3) cycle, the maintainer may pick it up
+from the list and queue it to 'pu', in order to make it easier for
+people play with it without having to pick up and apply the patch to
+their trees themselves.
+
+
+Know the status of your patch after submission
+
+* You can use Git itself to find out when your patch is merged in
+master. 'git pull --rebase' will automatically skip already-applied
+patches, and will let you know. This works only if you rebase on top
+of the branch in which your patch has been merged (i.e. it will not
+tell you if your patch is merged in pu if you rebase on top of
+master).
@@ -1,11 +1,62 @@
-Revision history for Perl extension File::chmod.
+Revision history for Perl extension File-chmod.
 
-0.32  Sat Jul 28 18:40:00 2007
+0.42      2015-02-14
+	- improve deprecation docs
+
+0.41      2015-02-14
+	[DEPRECATIONS]
+	- revert the decision to not deprecate UMASK=0, re-deprecating GH #5
+
+0.40      2013-11-15
+	- fix prototype mismatch with chmod() when autodie is used. GH #3 (arrestee)
+	[DEPRECATIONS]
+	- undeprecating the default of $UMASK is true
+	  tested against my local chmod and it does obey umask. This will no
+	  longer be removed.
+
+0.39      2013-09-14
+	- fix tests failing to run as user with override privileges
+	  RT #88543 ( zefram )
+	- add more tests
+
+0.38      2013-09-09
+	- fix sticky bit tests for BSD ( Slaven Rezić )
+	- disable windows tests
+
+0.37      2013-09-08
+	- verify and fix RT #78107 chmod('o+t') should set sticky-bit like unix
+	  chmod o+t
+
+0.36      2013-09-08
+	- improve Pod using Pod::Weaver, this will allow better linking on web
+	  interfaces
+
+0.35      2013-09-08
+	- add read/write tests
+	- remove REVISIONS from pod
+	- add Test::PodSpelling, and fix spelling errors
+
+0.34      2013-09-08
+	- fix basic.t to not fail on windows
+
+0.33      2013-09-07
+	[DEPRECATIONS]
+	- $UMASK is true, this behavior is surprising if you're used to UNIX chmod
+	[NEWS]
+	- new maintainer Caleb Cushing
+	- migrate to Dist::Zilla
+	- add tests (note test failures are likely to be a result of new tests,
+	  the code hasn't really changed)
+
+0.32  2007-07-28
 	- added copyright and license
 
-0.31  DAMMIT!
+0.31  1999-07-21
+	- fixed getsymchmod() bug
+	- was using map() incorrectly in getmod().
+	- condensed lschmod()
 
-0.30  Wed Jul 21 15:00:00 1999
+0.30  1999-07-21
 	- added umask() honoring for symchmod()
 	- function name changes
 	- fixed debugging bugs
@@ -15,20 +66,20 @@ Revision history for Perl extension File::chmod.
 	- compacted code
 	- see the new REVISIONS section in the docs for explanations
 
-0.22  Sat Apr 24 11:08:27 1999
+0.22  1999-04-24
 	- refixed the untarring error (now it works nicely)
 
-0.20  Sat Apr  3 16:24:14 1999
+0.20  1999-04-03
 	- fixed the untarring error (didn't appear in a directory)
 
-0.12  Sat Feb 13 09:24:56 1999
+0.12  1999-02-13
 	- fixed determine_mode() method for determining mode
 
-0.11  Fri Feb 12 20:21:37 1999
+0.11  1999-02-12
 	- fixed determine_mode() bug
 
-0.10  Fri Feb 12 19:15:04 1999
+0.10  1999-02-12
 	- changed @EXPORT and @EXPORT_OK functions
 
-0.01  Sat Feb  6 17:36:42 1999
+0.01  1999-02-06
 	- original version; created by h2xs 1.18
@@ -0,0 +1,379 @@
+This software is copyright (c) 2015 by Caleb Cushing and Jeff Pinyan.
+
+This is free software; you can redistribute it and/or modify it under
+the same terms as the Perl 5 programming language system itself.
+
+Terms of the Perl programming language system itself
+
+a) the GNU General Public License as published by the Free
+   Software Foundation; either version 1, or (at your option) any
+   later version, or
+b) the "Artistic License"
+
+--- The GNU General Public License, Version 1, February 1989 ---
+
+This software is Copyright (c) 2015 by Caleb Cushing and Jeff Pinyan.
+
+This is free software, licensed under:
+
+  The GNU General Public License, Version 1, February 1989
+
+                    GNU GENERAL PUBLIC LICENSE
+                     Version 1, February 1989
+
+ Copyright (C) 1989 Free Software Foundation, Inc.
+ 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The license agreements of most software companies try to keep users
+at the mercy of those companies.  By contrast, our General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  The
+General Public License applies to the Free Software Foundation's
+software and to any other program whose authors commit to using it.
+You can use it for your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Specifically, the General Public License is designed to make
+sure that you have the freedom to give away or sell copies of free
+software, that you receive source code or can get it if you want it,
+that you can change the software or use pieces of it in new free
+programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of a such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must tell them their rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License Agreement applies to any program or other work which
+contains a notice placed by the copyright holder saying it may be
+distributed under the terms of this General Public License.  The
+"Program", below, refers to any such program or work, and a "work based
+on the Program" means either the Program or any work containing the
+Program or a portion of it, either verbatim or with modifications.  Each
+licensee is addressed as "you".
+
+  1. You may copy and distribute verbatim copies of the Program's source
+code as you receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice and
+disclaimer of warranty; keep intact all the notices that refer to this
+General Public License and to the absence of any warranty; and give any
+other recipients of the Program a copy of this General Public License
+along with the Program.  You may charge a fee for the physical act of
+transferring a copy.
+
+  2. You may modify your copy or copies of the Program or any portion of
+it, and copy and distribute such modifications under the terms of Paragraph
+1 above, provided that you also do the following:
+
+    a) cause the modified files to carry prominent notices stating that
+    you changed the files and the date of any change; and
+
+    b) cause the whole of any work that you distribute or publish, that
+    in whole or in part contains the Program or any part thereof, either
+    with or without modifications, to be licensed at no charge to all
+    third parties under the terms of this General Public License (except
+    that you may choose to grant warranty protection to some or all
+    third parties, at your option).
+
+    c) If the modified program normally reads commands interactively when
+    run, you must cause it, when started running for such interactive use
+    in the simplest and most usual way, to print or display an
+    announcement including an appropriate copyright notice and a notice
+    that there is no warranty (or else, saying that you provide a
+    warranty) and that users may redistribute the program under these
+    conditions, and telling the user how to view a copy of this General
+    Public License.
+
+    d) You may charge a fee for the physical act of transferring a
+    copy, and you may at your option offer warranty protection in
+    exchange for a fee.
+
+Mere aggregation of another independent work with the Program (or its
+derivative) on a volume of a storage or distribution medium does not bring
+the other work under the scope of these terms.
+
+  3. You may copy and distribute the Program (or a portion or derivative of
+it, under Paragraph 2) in object code or executable form under the terms of
+Paragraphs 1 and 2 above provided that you also do one of the following:
+
+    a) accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of
+    Paragraphs 1 and 2 above; or,
+
+    b) accompany it with a written offer, valid for at least three
+    years, to give any third party free (except for a nominal charge
+    for the cost of distribution) a complete machine-readable copy of the
+    corresponding source code, to be distributed under the terms of
+    Paragraphs 1 and 2 above; or,
+
+    c) accompany it with the information you received as to where the
+    corresponding source code may be obtained.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form alone.)
+
+Source code for a work means the preferred form of the work for making
+modifications to it.  For an executable file, complete source code means
+all the source code for all modules it contains; but, as a special
+exception, it need not include source code for modules which are standard
+libraries that accompany the operating system on which the executable
+file runs, or for standard header files or definitions files that
+accompany that operating system.
+
+  4. You may not copy, modify, sublicense, distribute or transfer the
+Program except as expressly provided under this General Public License.
+Any attempt otherwise to copy, modify, sublicense, distribute or transfer
+the Program is void, and will automatically terminate your rights to use
+the Program under this License.  However, parties who have received
+copies, or rights to use copies, from you under this General Public
+License will not have their licenses terminated so long as such parties
+remain in full compliance.
+
+  5. By copying, distributing or modifying the Program (or any work based
+on the Program) you indicate your acceptance of this license to do so,
+and all its terms and conditions.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the original
+licensor to copy, distribute or modify the Program subject to these
+terms and conditions.  You may not impose any further restrictions on the
+recipients' exercise of the rights granted herein.
+
+  7. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of the license which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+the license, you may choose any version ever published by the Free Software
+Foundation.
+
+  8. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+                            NO WARRANTY
+
+  9. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  10. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+                     END OF TERMS AND CONDITIONS
+
+        Appendix: How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to humanity, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these
+terms.
+
+  To do so, attach the following notices to the program.  It is safest to
+attach them to the start of each source file to most effectively convey
+the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) 19yy  <name of author>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 1, or (at your option)
+    any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA  02110-1301 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) 19xx name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the
+appropriate parts of the General Public License.  Of course, the
+commands you use may be called something other than `show w' and `show
+c'; they could even be mouse-clicks or menu items--whatever suits your
+program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the
+  program `Gnomovision' (a program to direct compilers to make passes
+  at assemblers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+That's all there is to it!
+
+
+--- The Artistic License 1.0 ---
+
+This software is Copyright (c) 2015 by Caleb Cushing and Jeff Pinyan.
+
+This is free software, licensed under:
+
+  The Artistic License 1.0
+
+The Artistic License
+
+Preamble
+
+The intent of this document is to state the conditions under which a Package
+may be copied, such that the Copyright Holder maintains some semblance of
+artistic control over the development of the package, while giving the users of
+the package the right to use and distribute the Package in a more-or-less
+customary fashion, plus the right to make reasonable modifications.
+
+Definitions:
+
+  - "Package" refers to the collection of files distributed by the Copyright
+    Holder, and derivatives of that collection of files created through
+    textual modification. 
+  - "Standard Version" refers to such a Package if it has not been modified,
+    or has been modified in accordance with the wishes of the Copyright
+    Holder. 
+  - "Copyright Holder" is whoever is named in the copyright or copyrights for
+    the package. 
+  - "You" is you, if you're thinking about copying or distributing this Package.
+  - "Reasonable copying fee" is whatever you can justify on the basis of media
+    cost, duplication charges, time of people involved, and so on. (You will
+    not be required to justify it to the Copyright Holder, but only to the
+    computing community at large as a market that must bear the fee.) 
+  - "Freely Available" means that no fee is charged for the item itself, though
+    there may be fees involved in handling the item. It also means that
+    recipients of the item may redistribute it under the same conditions they
+    received it. 
+
+1. You may make and give away verbatim copies of the source form of the
+Standard Version of this Package without restriction, provided that you
+duplicate all of the original copyright notices and associated disclaimers.
+
+2. You may apply bug fixes, portability fixes and other modifications derived
+from the Public Domain or from the Copyright Holder. A Package modified in such
+a way shall still be considered the Standard Version.
+
+3. You may otherwise modify your copy of this Package in any way, provided that
+you insert a prominent notice in each changed file stating how and when you
+changed that file, and provided that you do at least ONE of the following:
+
+  a) place your modifications in the Public Domain or otherwise make them
+     Freely Available, such as by posting said modifications to Usenet or an
+     equivalent medium, or placing the modifications on a major archive site
+     such as ftp.uu.net, or by allowing the Copyright Holder to include your
+     modifications in the Standard Version of the Package.
+
+  b) use the modified Package only within your corporation or organization.
+
+  c) rename any non-standard executables so the names do not conflict with
+     standard executables, which must also be provided, and provide a separate
+     manual page for each non-standard executable that clearly documents how it
+     differs from the Standard Version.
+
+  d) make other distribution arrangements with the Copyright Holder.
+
+4. You may distribute the programs of this Package in object code or executable
+form, provided that you do at least ONE of the following:
+
+  a) distribute a Standard Version of the executables and library files,
+     together with instructions (in the manual page or equivalent) on where to
+     get the Standard Version.
+
+  b) accompany the distribution with the machine-readable source of the Package
+     with your modifications.
+
+  c) accompany any non-standard executables with their corresponding Standard
+     Version executables, giving the non-standard executables non-standard
+     names, and clearly documenting the differences in manual pages (or
+     equivalent), together with instructions on where to get the Standard
+     Version.
+
+  d) make other distribution arrangements with the Copyright Holder.
+
+5. You may charge a reasonable copying fee for any distribution of this
+Package.  You may charge any fee you choose for support of this Package. You
+may not charge a fee for this Package itself. However, you may distribute this
+Package in aggregate with other (possibly commercial) programs as part of a
+larger (possibly commercial) software distribution provided that you do not
+advertise this Package as a product of your own.
+
+6. The scripts and library files supplied as input to or produced as output
+from the programs of this Package do not automatically fall under the copyright
+of this Package, but belong to whomever generated them, and may be sold
+commercially, and may be aggregated with this Package.
+
+7. C or perl subroutines supplied by you and linked into this Package shall not
+be considered part of this Package.
+
+8. The name of the Copyright Holder may not be used to endorse or promote
+products derived from this software without specific prior written permission.
+
+9. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+
+The End
+
@@ -1,6 +1,31 @@
+# This file was automatically generated by Dist::Zilla::Plugin::Manifest v5.031.
+CONTRIBUTING
 Changes
+LICENSE
 MANIFEST
+META.json
+META.yml
 Makefile.PL
-chmod.pm
-test.pl
-META.yml                                 Module meta-data (added by MakeMaker)
+README
+lib/File/chmod.pm
+perlcritic.rc
+t/00-compile.t
+t/00-report-prereqs.dd
+t/00-report-prereqs.t
+t/author-critic.t
+t/author-eol.t
+t/executable.t
+t/load_chmod.t
+t/read.t
+t/release-cpan-changes.t
+t/release-dist-manifest.t
+t/release-meta-json.t
+t/release-minimum-version.t
+t/release-pod-coverage.t
+t/release-pod-syntax.t
+t/release-portability.t
+t/release-test-version.t
+t/release-unused-vars.t
+t/remove-write-from-other.t
+t/sticky-bit.t
+t/write.t
@@ -0,0 +1,93 @@
+{
+   "abstract" : "Implements symbolic and ls chmod modes",
+   "author" : [
+      "Jeff Pinyan <japhy.734+CPAN@gmail.com>",
+      "Caleb Cushing <xenoterracide@gmail.com>"
+   ],
+   "dynamic_config" : 0,
+   "generated_by" : "Dist::Zilla version 5.031, CPAN::Meta::Converter version 2.143240",
+   "license" : [
+      "perl_5"
+   ],
+   "meta-spec" : {
+      "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec",
+      "version" : 2
+   },
+   "name" : "File-chmod",
+   "no_index" : {
+      "file" : [
+         "perlcritic.rc"
+      ]
+   },
+   "prereqs" : {
+      "configure" : {
+         "requires" : {
+            "ExtUtils::MakeMaker" : "0"
+         }
+      },
+      "develop" : {
+         "requires" : {
+            "Pod::Coverage::TrustPod" : "0",
+            "Test::CPAN::Changes" : "0.19",
+            "Test::EOL" : "0",
+            "Test::More" : "0.88",
+            "Test::Pod" : "1.41",
+            "Test::Pod::Coverage" : "1.08",
+            "Test::Version" : "1"
+         }
+      },
+      "runtime" : {
+         "requires" : {
+            "Carp" : "0",
+            "Exporter" : "0",
+            "base" : "0",
+            "strict" : "0",
+            "vars" : "0",
+            "warnings" : "0"
+         }
+      },
+      "test" : {
+         "recommends" : {
+            "CPAN::Meta" : "2.120900"
+         },
+         "requires" : {
+            "English" : "0",
+            "ExtUtils::MakeMaker" : "0",
+            "File::Spec" : "0",
+            "File::Temp" : "0",
+            "IO::Handle" : "0",
+            "IPC::Open3" : "0",
+            "Test::More" : "0",
+            "autodie" : "0",
+            "perl" : "5.006",
+            "utf8" : "0"
+         }
+      }
+   },
+   "provides" : {
+      "File::chmod" : {
+         "file" : "lib/File/chmod.pm",
+         "version" : "0.42"
+      }
+   },
+   "release_status" : "stable",
+   "resources" : {
+      "bugtracker" : {
+         "web" : "https://github.com/xenoterracide/file-chmod/issues"
+      },
+      "homepage" : "https://metacpan.org/dist/File-chmod",
+      "repository" : {
+         "type" : "git",
+         "url" : "git://github.com/xenoterracide/file-chmod.git",
+         "web" : "https://github.com/xenoterracide/file-chmod"
+      }
+   },
+   "version" : "0.42",
+   "x_contributors" : [
+      "David Steinbrunner <dsteinbrunner@pobox.com>",
+      "Slaven Rezic <slaven@rezic.de>",
+      "Steve Throckmorton <arrestee@gmail.com>",
+      "Tim <oylenshpeegul@gmail.com>"
+   ]
+}
+
@@ -1,10 +1,49 @@
-# http://module-build.sourceforge.net/META-spec.html
-#XXXXXXX This is a prototype!!!  It will change in the future!!! XXXXX#
-name:         File-chmod
-version:      0.32
-version_from: chmod.pm
-installdirs:  site
+---
+abstract: 'Implements symbolic and ls chmod modes'
+author:
+  - 'Jeff Pinyan <japhy.734+CPAN@gmail.com>'
+  - 'Caleb Cushing <xenoterracide@gmail.com>'
+build_requires:
+  English: '0'
+  ExtUtils::MakeMaker: '0'
+  File::Spec: '0'
+  File::Temp: '0'
+  IO::Handle: '0'
+  IPC::Open3: '0'
+  Test::More: '0'
+  autodie: '0'
+  perl: '5.006'
+  utf8: '0'
+configure_requires:
+  ExtUtils::MakeMaker: '0'
+dynamic_config: 0
+generated_by: 'Dist::Zilla version 5.031, CPAN::Meta::Converter version 2.143240'
+license: perl
+meta-spec:
+  url: http://module-build.sourceforge.net/META-spec-v1.4.html
+  version: '1.4'
+name: File-chmod
+no_index:
+  file:
+    - perlcritic.rc
+provides:
+  File::chmod:
+    file: lib/File/chmod.pm
+    version: '0.42'
 requires:
-
-distribution_type: module
-generated_by: ExtUtils::MakeMaker version 6.30
+  Carp: '0'
+  Exporter: '0'
+  base: '0'
+  strict: '0'
+  vars: '0'
+  warnings: '0'
+resources:
+  bugtracker: https://github.com/xenoterracide/file-chmod/issues
+  homepage: https://metacpan.org/dist/File-chmod
+  repository: git://github.com/xenoterracide/file-chmod.git
+version: '0.42'
+x_contributors:
+  - 'David Steinbrunner <dsteinbrunner@pobox.com>'
+  - 'Slaven Rezic <slaven@rezic.de>'
+  - 'Steve Throckmorton <arrestee@gmail.com>'
+  - 'Tim <oylenshpeegul@gmail.com>'
@@ -1,7 +1,80 @@
+
+# This file was automatically generated by Dist::Zilla::Plugin::MakeMaker v5.031.
+use strict;
+use warnings;
+
+use 5.006;
+
 use ExtUtils::MakeMaker;
-# See lib/ExtUtils/MakeMaker.pm for details of how to influence
-# the contents of the Makefile that is written.
-WriteMakefile(
-    'NAME'	=> 'File::chmod',
-    'VERSION_FROM' => 'chmod.pm', # finds $VERSION
+
+
+
+my %WriteMakefileArgs = (
+  "ABSTRACT" => "Implements symbolic and ls chmod modes",
+  "AUTHOR" => "Jeff Pinyan <japhy.734+CPAN\@gmail.com>, Caleb Cushing <xenoterracide\@gmail.com>",
+  "CONFIGURE_REQUIRES" => {
+    "ExtUtils::MakeMaker" => 0
+  },
+  "DISTNAME" => "File-chmod",
+  "EXE_FILES" => [],
+  "LICENSE" => "perl",
+  "MIN_PERL_VERSION" => "5.006",
+  "NAME" => "File::chmod",
+  "PREREQ_PM" => {
+    "Carp" => 0,
+    "Exporter" => 0,
+    "base" => 0,
+    "strict" => 0,
+    "vars" => 0,
+    "warnings" => 0
+  },
+  "TEST_REQUIRES" => {
+    "English" => 0,
+    "ExtUtils::MakeMaker" => 0,
+    "File::Spec" => 0,
+    "File::Temp" => 0,
+    "IO::Handle" => 0,
+    "IPC::Open3" => 0,
+    "Test::More" => 0,
+    "autodie" => 0,
+    "utf8" => 0
+  },
+  "VERSION" => "0.42",
+  "test" => {
+    "TESTS" => "t/*.t"
+  }
 );
+
+
+my %FallbackPrereqs = (
+  "Carp" => 0,
+  "English" => 0,
+  "Exporter" => 0,
+  "ExtUtils::MakeMaker" => 0,
+  "File::Spec" => 0,
+  "File::Temp" => 0,
+  "IO::Handle" => 0,
+  "IPC::Open3" => 0,
+  "Test::More" => 0,
+  "autodie" => 0,
+  "base" => 0,
+  "strict" => 0,
+  "utf8" => 0,
+  "vars" => 0,
+  "warnings" => 0
+);
+
+
+unless ( eval { ExtUtils::MakeMaker->VERSION(6.63_03) } ) {
+  delete $WriteMakefileArgs{TEST_REQUIRES};
+  delete $WriteMakefileArgs{BUILD_REQUIRES};
+  $WriteMakefileArgs{PREREQ_PM} = \%FallbackPrereqs;
+}
+
+delete $WriteMakefileArgs{CONFIGURE_REQUIRES}
+  unless eval { ExtUtils::MakeMaker->VERSION(6.52) };
+
+WriteMakefile(%WriteMakefileArgs);
+
+
+
@@ -0,0 +1,208 @@
+NAME
+
+    File::chmod - Implements symbolic and ls chmod modes
+
+VERSION
+
+    version 0.42
+
+SYNOPSIS
+
+      use File::chmod;
+      $File::chmod::UMASK = 0;
+      # It is recommended that you explicitly set $File::chmod::UMASK
+      # as the default will change in the future
+      #
+      # 0 is recommended to behave like system chmod
+      # 1 if you want File::chmod to apply your environment set umask.
+      # 2 is how we detect that it's internally set, undef will become the
+      # default in the future, eventually a lexicaly scoped API may be designed
+    
+      # chmod takes all three types
+      # these all do the same thing
+      chmod(0666,@files);
+      chmod("=rw",@files);
+      chmod("-rw-rw-rw-",@files);
+    
+      # or
+    
+      use File::chmod qw( symchmod lschmod );
+    
+      chmod(0666,@files);           # this is the normal chmod
+      symchmod("=rw",@files);       # takes symbolic modes only
+      lschmod("-rw-rw-rw-",@files); # takes "ls" modes only
+    
+      # more functions, read on to understand
+
+DESCRIPTION
+
+    File::chmod is a utility that allows you to bypass system calls or bit
+    processing of a file's permissions. It overloads the chmod() function
+    with its own that gets an octal mode, a symbolic mode (see below), or
+    an "ls" mode (see below). If you wish not to overload chmod(), you can
+    export symchmod() and lschmod(), which take, respectively, a symbolic
+    mode and an "ls" mode.
+
+    An added feature to version 0.30 is the $UMASK variable, explained in
+    detail below; if symchmod() is called and this variable is true, then
+    the function uses the (also new) $MASK variable (which defaults to
+    umask()) as a mask against the new mode. This mode is on by default,
+    and changes the behavior from what you would expect if you are used to
+    UNIX chmod. This may change in the future.
+
+    Symbolic modes are thoroughly described in your chmod(1) man page, but
+    here are a few examples.
+
+      chmod("+x","file1","file2");  # overloaded chmod(), that is...
+      # turns on the execute bit for all users on those two files
+    
+      chmod("o=,g-w","file1","file2");
+      # removes 'other' permissions, and the write bit for 'group'
+    
+      chmod("=u","file1","file2");
+      # sets all bits to those in 'user'
+
+    "ls" modes are the type produced on the left-hand side of an ls -l on a
+    directory. Examples are:
+
+      chmod("-rwxr-xr-x","file1","file2");
+      # the 0755 setting; user has read-write-execute, group and others
+      # have read-execute priveleges
+    
+      chmod("-rwsrws---","file1","file2");
+      # sets read-write-execute for user and group, none for others
+      # also sets set-uid and set-gid bits
+
+    The regular chmod() and lschmod() are absolute; that is, they are not
+    appending to or subtracting from the current file mode. They set it,
+    regardless of what it had been before. symchmod() is useful for
+    allowing the modifying of a file's permissions without having to run a
+    system call or determining the file's permissions, and then combining
+    that with whatever bits are appropriate. It also operates separately on
+    each file.
+
+FUNCTIONS - EXPORT
+
+ chmod(MODE,FILES)
+
+    Takes an octal, symbolic, or "ls" mode, and then chmods each file
+    appropriately.
+
+ getchmod(MODE,FILES)
+
+    Returns a list of modified permissions, without chmodding files.
+    Accepts any of the three kinds of modes.
+
+      @newmodes = getchmod("+x","file1","file2");
+      # @newmodes holds the octal permissions of the files'
+      # modes, if they were to be sent through chmod("+x"...)
+
+FUNCTIONS - EXPORT_OK
+
+ symchmod(MODE,FILES)
+
+    Takes a symbolic permissions mode, and chmods each file.
+
+ lschmod(MODE,FILES)
+
+    Takes an "ls" permissions mode, and chmods each file.
+
+ getsymchmod(MODE,FILES)
+
+    Returns a list of modified permissions, without chmodding files.
+    Accepts only symbolic permission modes.
+
+ getlschmod(MODE,FILES)
+
+    Returns a list of modified permissions, without chmodding files.
+    Accepts only "ls" permission modes.
+
+ getmod(FILES)
+
+    Returns a list of the current mode of each file.
+
+VARIABLES
+
+ $File::chmod::DEBUG
+
+    If set to a true value, it will report warnings, similar to those
+    produced by chmod() on your system. Otherwise, the functions will not
+    report errors. Example: a file can not have file-locking and the
+    set-gid bits on at the same time. If $File::chmod::DEBUG is true, the
+    function will report an error. If not, you are not warned of the
+    conflict. It is set to 1 as default.
+
+ $File::chmod::MASK
+
+    Contains the umask to apply to new file modes when using getsymchmod().
+    This defaults to the return value of umask() at compile time. Is only
+    applied if $UMASK is true.
+
+ $File::chmod::UMASK
+
+    This is a boolean which tells getsymchmod() whether or not to apply the
+    umask found in $MASK. It defaults to true.
+
+PORTING
+
+    This is only good on Unix-like boxes. I would like people to help me
+    work on File::chmod for any OS that deserves it. If you would like to
+    help, please email me (address below) with the OS and any information
+    you might have on how chmod() should work on it; if you don't have any
+    specific information, but would still like to help, hey, that's good
+    too. I have the following information (from "perlport"):
+
+    Win32
+
+      Only good for changing "owner" read-write access, "group", and
+      "other" bits are meaningless. NOTE: Win32::File and
+      Win32::FileSecurity already do this. I do not currently see a need to
+      port File::chmod.
+
+    MacOS
+
+      Only limited meaning. Disabling/enabling write permission is mapped
+      to locking/unlocking the file.
+
+    RISC OS
+
+      Only good for changing "owner" and "other" read-write access.
+
+SEE ALSO
+
+      Stat::lsMode (by Mark-James Dominus, CPAN ID: MJD)
+      chmod(1) manpage
+      perldoc -f chmod
+      perldoc -f stat
+
+BUGS
+
+    Please report any bugs or feature requests on the bugtracker website
+    https://github.com/xenoterracide/file-chmod/issues
+
+    When submitting a bug or request, please include a test-file or a patch
+    to an existing test-file that illustrates the bug or desired feature.
+
+CONTRIBUTORS
+
+      * David Steinbrunner <dsteinbrunner@pobox.com>
+
+      * Slaven Rezic <slaven@rezic.de>
+
+      * Steve Throckmorton <arrestee@gmail.com>
+
+      * Tim <oylenshpeegul@gmail.com>
+
+AUTHORS
+
+      * Jeff Pinyan <japhy.734+CPAN@gmail.com>
+
+      * Caleb Cushing <xenoterracide@gmail.com>
+
+COPYRIGHT AND LICENSE
+
+    This software is copyright (c) 2015 by Caleb Cushing and Jeff Pinyan.
+
+    This is free software; you can redistribute it and/or modify it under
+    the same terms as the Perl 5 programming language system itself.
+
@@ -1,647 +0,0 @@
-package File::chmod;
-
-use Carp;
-use strict;
-use vars qw(
-  $VERSION @ISA @EXPORT @EXPORT_OK $DEBUG
-  $UMASK $MASK $VAL $W $MODE
-);
-
-require Exporter;
-
-@ISA = qw( Exporter );
-@EXPORT = qw( chmod getchmod );
-@EXPORT_OK = qw( symchmod lschmod getsymchmod getlschmod getmod );
-
-$VERSION = '0.32';
-$DEBUG = 1;
-$UMASK = 1;
-$MASK = umask;
-
-my ($SYM,$LS) = (1,2);
-my %ERROR = (
-  EDETMOD => "use of determine_mode is deprecated",
-  ENEXLOC => "cannot set group execute on locked file",
-  ENLOCEX => "cannot set file locking on group executable file",
-  ENSGLOC => "cannot set-gid on locked file",
-  ENLOCSG => "cannot set file locking on set-gid file",
-  ENEXUID => "execute bit must be on for set-uid",
-  ENEXGID => "execute bit must be on for set-gid",
-  ENULSID => "set-id has no effect for 'others'",
-  ENULSBG => "sticky bit has no effect for 'group'",
-  ENULSBO => "sticky bit has no effect for 'others'",
-);
-
-
-sub getmod {
-  my @return = map { (stat)[2] & 07777 } @_;
-  return wantarray ? @return : $return[0];
-}
-
-
-sub chmod {
-  my $mode = shift;
-  my $how = mode($mode);
-
-  return symchmod($mode,@_) if $how == $SYM;
-  return lschmod($mode,@_) if $how == $LS;
-  return CORE::chmod($mode,@_);
-}
-
-
-sub getchmod {
-  my $mode = shift;
-  my $how = mode($mode);
-
-  return getsymchmod($mode,@_) if $how == $SYM;
-  return getlschmod($mode,@_) if $how == $LS;
-  return wantarray ? (($mode) x @_) : $mode;
-}
-
-
-sub symchmod {
-  my $mode = shift;
-  my @return = getsymchmod($mode,@_);
-  my $ret = 0;
-  for (@_){ $ret++ if CORE::chmod(shift(@return),$_) }
-  return $ret;
-}
-
-
-sub getsymchmod {
-  my $mode = shift;
-  my @return;
-
-  croak "symchmod received non-symbolic mode: $mode" if mode($mode) != $SYM;
-
-  for (@_){
-    local $VAL = getmod($_);
-
-    for my $this (split /,/, $mode){
-      local $W = 0;
-      my $or;
-
-      for (split //, $this){
-        if (not defined $or and /[augo]/){
-          /a/ and $W |= 7, next;
-          /u/ and $W |= 1, next;
-          /g/ and $W |= 2, next;
-          /o/ and $W |= 4, next;
-        }
-
-        if (/[-+=]/){
-          $W ||= 7;
-          $or = (/[=+]/ ? 1 : 0);
-          clear() if /=/;
-          next;
-        }
-
-        croak "Bad mode $this" if not defined $or;
-        croak "Unknown mode: $mode" if !/[ugorwxslt]/;
-
-        /u/ and $or ? u_or() : u_not();
-        /g/ and $or ? g_or() : g_not();
-        /o/ and $or ? o_or() : o_not();
-        /r/ and $or ? r_or() : r_not();
-        /w/ and $or ? w_or() : w_not();
-        /x/ and $or ? x_or() : x_not();
-        /s/ and $or ? s_or() : s_not();
-        /l/ and $or ? l_or() : l_not();
-        /t/ and $or ? t_or() : t_not();
-      }
-    }
-    $VAL &= ~$MASK if $UMASK;
-    push @return, $VAL;
-  }
-  return wantarray ? @return : $return[0];
-}
-
-
-sub lschmod {
-  my $mode = shift;
-  return CORE::chmod(getlschmod($mode,@_),@_);
-}
-
-
-sub getlschmod {
-  my $mode = shift;
-  my $VAL = 0;
-
-  croak "lschmod received non-ls mode: $mode" if mode($mode) != $LS;
-
-  my ($u,$g,$o) = ($mode =~ /^.(...)(...)(...)$/);
-
-  for ($u){
-    $VAL |= 0400 if /r/;
-    $VAL |= 0200 if /w/;
-    $VAL |= 0100 if /[xs]/;
-    $VAL |= 04000 if /[sS]/;
-  }
-
-  for ($g){
-    $VAL |= 0040 if /r/;
-    $VAL |= 0020 if /w/;
-    $VAL |= 0010 if /[xs]/;
-    $VAL |= 02000 if /[sS]/;
-  }
-
-  for ($o){
-    $VAL |= 0004 if /r/;
-    $VAL |= 0002 if /w/;
-    $VAL |= 0001 if /[xt]/;
-    $VAL |= 01000 if /[Tt]/;
-  }
-
-  return wantarray ? (($VAL) x @_) : $VAL;
-}
-
-
-sub mode {
-  my $mode = shift;
-  return 0 if $mode !~ /\D/;
-  return $SYM if $mode =~ /[augo=+,]/;
-  return $LS if $mode =~ /^.([r-][w-][xSs-]){2}[r-][w-][xTt-]$/;
-  return $SYM;
-}
-
-
-sub determine_mode {
-  warn $ERROR{EDECMOD};
-  mode(@_);
-}
-
-
-sub clear {
-  $W & 1 and $VAL &= 02077;
-  $W & 2 and $VAL &= 05707;
-  $W & 4 and $VAL &= 07770;
-}
-  
-
-sub u_or {
-  my $val = $VAL;
-  $W & 2 and ($VAL |= (($val & 0700)>>3 | ($val & 04000)>>1));
-  $W & 4 and ($VAL |= (($val & 0700)>>6));
-}
-
-
-sub u_not {
-  my $val = $VAL;
-  $W & 1 and $VAL &= ~(($val & 0700) | ($val & 05000));
-  $W & 2 and $VAL &= ~(($val & 0700)>>3 | ($val & 04000)>>1);
-  $W & 4 and $VAL &= ~(($val & 0700)>>6);
-}
-
-
-sub g_or {
-  my $val = $VAL;
-  $W & 1 and $VAL |= (($val & 070)<<3 | ($val & 02000)<<1);
-  $W & 4 and $VAL |= ($val & 070)>>3;
-}
-
-
-sub g_not {
-  my $val = $VAL;
-  $W & 1 and $VAL &= ~(($val & 070)<<3 | ($val & 02000)<<1);
-  $W & 2 and $VAL &= ~(($val & 070) | ($val & 02000));
-  $W & 4 and $VAL &= ~(($val & 070)>>3);
-}
-
-
-sub o_or {
-  my $val = $VAL;
-  $W & 1 and $VAL |= (($val & 07)<<6);
-  $W & 2 and $VAL |= (($val & 07)<<3);
-}
-
-
-sub o_not {
-  my $val = $VAL;
-  $W & 1 and $VAL &= ~(($val & 07)<<6);
-  $W & 2 and $VAL &= ~(($val & 07)<<3);
-  $W & 4 and $VAL &= ~($val & 07);
-}
-
-
-sub r_or {
-  $W & 1 and $VAL |= 0400;
-  $W & 2 and $VAL |= 0040;
-  $W & 4 and $VAL |= 0004;
-}
-
-
-sub r_not {
-  $W & 1 and $VAL &= ~0400;
-  $W & 2 and $VAL &= ~0040;
-  $W & 4 and $VAL &= ~0004;
-}
-
-
-sub w_or {
-  $W & 1 and $VAL |= 0200;
-  $W & 2 and $VAL |= 0020;
-  $W & 4 and $VAL |= 0002;
-}
-
-
-sub w_not {
-  $W & 1 and $VAL &= ~0200;
-  $W & 2 and $VAL &= ~0020;
-  $W & 4 and $VAL &= ~0002;
-}
-
-
-sub x_or {
-  if ($VAL & 02000){ $DEBUG and warn($ERROR{ENEXLOC}), return }
-  $W & 1 and $VAL |= 0100;
-  $W & 2 and $VAL |= 0010;
-  $W & 4 and $VAL |= 0001;
-}
-
-
-sub x_not {
-  $W & 1 and $VAL &= ~0100;
-  $W & 2 and $VAL &= ~0010;
-  $W & 4 and $VAL &= ~0001;
-}
-
-
-sub s_or {
-  if ($VAL & 02000){ $DEBUG and warn($ERROR{ENSGLOC}), return }
-  if (not $VAL & 00100){ $DEBUG and warn($ERROR{ENEXUID}), return }
-  if (not $VAL & 00010){ $DEBUG and warn($ERROR{ENEXGID}), return }
-  $W & 1 and $VAL |= 04000;
-  $W & 2 and $VAL |= 02000;
-  $W & 4 and $DEBUG and warn $ERROR{ENULSID};
-}
-
-
-sub s_not {
-  $W & 1 and $VAL &= ~04000;
-  $W & 2 and $VAL &= ~02000;
-  $W & 4 and $DEBUG and warn $ERROR{ENULSID};
-}
-
-
-sub l_or {
-  if ($VAL & 02010){ $DEBUG and warn($ERROR{ENLOCSG}), return }
-  if ($VAL & 00010){ $DEBUG and warn($ERROR{ENLOCEX}), return }
-  $VAL |= 02000;
-}
-
-
-sub l_not {
-  $VAL &= ~02000 if not $VAL & 00010;
-}
-
-
-sub t_or {
-  $W & 1 and $VAL |= 01000;
-  $W & 2 and $DEBUG and warn $ERROR{ENULSBG};
-  $W & 4 and $DEBUG and warn $ERROR{ENULSBO};
-}
-
-
-sub t_not {
-  $W & 1 and $VAL &= ~01000;
-  $W & 2 and $DEBUG and warn $ERROR{ENULSBG};
-  $W & 4 and $DEBUG and warn $ERROR{ENULSBO};
-}
-
-
-1;
-
-__END__
-
-=head1 NAME
-
-File::chmod - Implements symbolic and ls chmod modes
-
-=head1 VERSION
-
-This is File::chmod v0.32.
-
-=head1 SYNOPSIS
-
-  use File::chmod;
-
-  # chmod takes all three types
-  # these all do the same thing
-  chmod(0666,@files);
-  chmod("=rw",@files);
-  chmod("-rw-rw-rw-",@files);
-
-  # or
-
-  use File::chmod qw( symchmod lschmod );
-
-  chmod(0666,@files);		# this is the normal chmod
-  symchmod("=rw",@files);	# takes symbolic modes only
-  lschmod("-rw-rw-rw-",@files);	# takes "ls" modes only
-
-  # more functions, read on to understand
-
-=head1 DESCRIPTION
-
-File::chmod is a utility that allows you to bypass system calls or bit
-processing of a file's permissions.  It overloads the chmod() function
-with its own that gets an octal mode, a symbolic mode (see below), or
-an "ls" mode (see below).  If you wish not to overload chmod(), you can
-export symchmod() and lschmod(), which take, respectively, a symbolic
-mode and an "ls" mode.
-
-Symbolic modes are thoroughly described in your chmod(1) man page, but
-here are a few examples.
-
-  # NEW: if $UMASK is true, symchmod() applies a bit-mask found in $MASK
-
-  chmod("+x","file1","file2");	# overloaded chmod(), that is...
-  # turns on the execute bit for all users on those two files
-
-  chmod("o=,g-w","file1","file2");
-  # removes 'other' permissions, and the write bit for 'group'
-
-  chmod("=u","file1","file2");
-  # sets all bits to those in 'user'
-
-"ls" modes are the type produced on the left-hand side of an C<ls -l> on a
-directory.  Examples are:
-
-  chmod("-rwxr-xr-x","file1","file2");
-  # the 0755 setting; user has read-write-execute, group and others
-  # have read-execute priveleges
-
-  chmod("-rwsrws---","file1","file2");
-  # sets read-write-execute for user and group, none for others
-  # also sets set-uid and set-gid bits
-
-The regular chmod() and lschmod() are absolute; that is, they are not
-appending to or subtracting from the current file mode.  They set it,
-regardless of what it had been before.  symchmod() is useful for allowing
-the modifying of a file's permissions without having to run a system call
-or determining the file's permissions, and then combining that with whatever
-bits are appropriate.  It also operates separately on each file.
-
-An added feature to version 0.30 is the $UMASK variable, explained below; if
-symchmod() is called and this variable is true, then the function uses the
-(also new) $MASK variable (which defaults to umask()) as a mask against the
-new mode.  This is documented below more clearly.
-
-=head2 Functions
-
-Exported by default:
-
-=over 4
-
-=item chmod(MODE,FILES)
-
-Takes an octal, symbolic, or "ls" mode, and then chmods each file
-appropriately.
-
-=item getchmod(MODE,FILES)
-
-Returns a list of modified permissions, without chmodding files.
-Accepts any of the three kinds of modes.
-
-  @newmodes = getchmod("+x","file1","file2");
-  # @newmodes holds the octal permissons of the files'
-  # modes, if they were to be sent through chmod("+x"...)
-
-=back
-
-Exported by request:
-
-=over 4
-
-=item symchmod(MODE,FILES)
-
-Takes a symbolic permissions mode, and chmods each file.
-
-=item lschmod(MODE,FILES)
-
-Takes an "ls" permissions mode, and chmods each file.
-
-=item getsymchmod(MODE,FILES)
-
-Returns a list of modified permissions, without chmodding files.
-Accepts only symbolic permisson modes.
-
-=item getlschmod(MODE,FILES)
-
-Returns a list of modified permissions, without chmodding files.
-Accepts only "ls" permisson modes.
-
-=item getmod(FILES)
-
-Returns a list of the current mode of each file.
-
-=back
-
-=head2 Variables
-
-=over 4
-
-=item $File::chmod::DEBUG
-
-If set to a true value, it will report warnings, similar to those produced
-by chmod() on your system.  Otherwise, the functions will not report errors.
-Example: a file can not have file-locking and the set-gid bits on at the
-same time.  If $File::chmod::DEBUG is true, the function will report an
-error.  If not, you are not warned of the conflict.  It is set to 1 as
-default.
-
-=item $File::chmod::MASK
-
-Contains the umask to apply to new file modes when using getsymchmod().  This
-defaults to the return value of umask() at compile time.  Is only applied if
-$UMASK is true.
-
-=item $File::chmod::UMASK
-
-This is a boolean which tells getsymchmod() whether or not to apply the umask
-found in $MASK.  It defaults to true.
-
-=back
-
-=head1 REVISIONS
-
-I<Note: this section was started with version 0.30.>
-
-This is an in-depth look at the changes being made from version to version.
-
-=head2 0.31 to 0.32
-
-=over 4
-
-=item B<license added>
-
-I added a license to this module so that it can be used places without asking
-my permission.  Sorry, Adam.
-
-=back
-
-=head2 0.30 to 0.31
-
-=over 4
-
-=item B<fixed getsymchmod() bug>
-
-Whoa.  getsymchmod() was doing some crazy ish.  That's about all I can say.
-I did a great deal of debugging, and fixed it up.  It ALL had to do with two
-things:
-
-  $or = (/+=/ ? 1 : 0); # should have been /[+=]/
-
-  /u/ && $ok ? u_or() : u_not(); # should have been /u/ and $ok
-
-=item B<fixed getmod() bug>
-
-I was using map() incorrectly in getmod().  Fixed that.
-
-=item B<condensed lschmod()>
-
-I shorted it up, getting rid a variable.
-
-=back
-
-=head2 0.21 to 0.30
-
-=over 4
-
-=item B<added umask() honoring for symchmod()>
-
-The symchmod() function now honors the $UMASK and $MASK variables.  $UMASK is
-a boolean which indicates whether or not to honor the $MASK variable.  $MASK
-holds a umask, and it defaults to umask().  $UMASK defaults to true.  These
-variables are NOT exported.  They must explictly set (i.e. $File::chmod::UMASK
-= 0).
-
-=item B<function name changes>
-
-Renamed internal function determine_mode() to mode().  However, if you happen
-to be using determine_mode() somewhere, mode() will be called, but you'll also
-get a warning about deprecation.
-
-Renamed internal functions {or,not}_{l,s,t} to {l,s,t}_{or,not}.  This is to
-keep in standard with the OTHER 6 pairs of bitwise functions, such as r_or()
-and g_not().  I don't know WHY the others had 'not' or 'or' in the front.
-
-=item B<fixed debugging bugs>
-
-Certain calls to warn() were not guarded by the $DEBUG variable, and now they
-are.  Also, for some reason, I left a debugging check (that didn't check to
-see if $DEBUG was true) in getsymchmod(), line 118.  It printed "ENTERING /g/".
-It's gone now.
-
-=item B<fixed set-uid and set-gid bug>
-
-Heh, it seems that in the previous version of File::chmod, the following code
-went along broken:
-
-  # or_s sub, File/chmod.pm, v0.21, line 330
-  ($VAL & 00100) && do {
-    $DEBUG && warn("execute bit must be on for set-uid"); 1;
-  } && next;
-
-Aside from me using '&&' more than enough (changed in the new code), this is
-broken.  This is now fixed.
-
-=item B<fixed file lock/set-gid bug>
-
-The not_l() function (now renamed to l_not()) used to take the file mode and
-bit-wise NOT it with ~02000.  However, it did not check if the file was locked
-vs. set-gid.  Now, the function is C<$VAL &= ~02000 if not $VAL & 00010;>.
-
-=item B<removed useless data structures>
-
-I do not know why I had the $S variable, or %r, %w, and %x hashes.  In fact,
-$S was declared in C<use vars qw( ... );>, but never given a value, and the
-%r, %w, and %x hashes had a 'full' key which never got used.  And the hashes
-themselves weren't really needed anyway.  Here is a list of the variables no
-longer in use, and what they have been replaced with (if any):
-
-  $S		nothing
-  $U, $G, $O	$W
-  %r, %w, %x	octal numbers
-  @files	@_ (I had @files = @_; in nearly EVERY sub)
-  $c		$_
-
-=item B<compacted code>
-
-The first version of File::chmod that was published was 0.13, and it was
-written in approximately 10 days, being given the off-and-on treatment I end
-up having to give several projects, due to more pressing matters.  Well, since
-then, most of the code has stayed the same, although bugs were worked out.
-Well, I got rid of a lot of slow, clunky, and redundant sections of code in
-this version.  Sections include the processing of each character of the mode
-in getsymchmod(), the getmod() subroutine, um, nearly ALL of the getsymchmod()
-function, now that I look at it.
-
-Here's part of the getsymchmod() rewrite:
-
-  for ($c){
-    if (/u/){
-      u_or() if $MODE eq "+" or $MODE eq "=";
-      u_not() if $MODE eq "-";
-    }
-  ...
-  }
-
-  # changed to
-
-  /u/ && $or ? u_or() : u_and();
-  # note: operating on $_, $c isn't used anymore
-  # note: $or holds 1 if the $MODE was + or =, 0 if $MODE was -
-  # note: previous was redundant.  didn't need $MODE eq "-" check
-  #       because u_or() and u_not() both go to the next character
-
-=back
-
-=head1 PORTING
-
-This is only good on Unix-like boxes.  I would like people to help me work on
-File::chmod for any OS that deserves it.  If you would like to help, please
-email me (address below) with the OS and any information you might have on how
-chmod() should work on it; if you don't have any specific information, but
-would still like to help, hey, that's good too.  I have the following
-information (from L</perlport>):
-
-=over 4
-
-=item Win32
-
-Only good for changing "owner" read-write access, "group", and "other" bits
-are meaningless.  I<NOTE: Win32::File and Win32::FileSecurity already do
-this.  I do not currently see a need to port File::chmod.>
-
-=item MacOS
-
-Only limited meaning. Disabling/enabling write permission is mapped to
-locking/unlocking the file.
-
-=item RISC OS
-
-Only good for changing "owner" and "other" read-write access.
-
-=back
-
-=head1 AUTHOR
-
-Jeff C<japhy> Pinyan, F<japhy.734+CPAN@gmail.com>, CPAN ID: PINYAN
-
-=head1 SEE ALSO
-
-  Stat::lsMode (by Mark-James Dominus, CPAN ID: MJD)
-  chmod(1) manpage
-  perldoc -f chmod
-  perldoc -f stat
-
-=head1 COPYRIGHT AND LICENCE
-
-Copyright (C) 2007 by Jeff Pinyan
-
-This library is free software; you can redistribute it and/or modify
-it under the same terms as Perl itself, either Perl version 5.8.8 or,
-at your option, any later version of Perl 5 you may have available.
-
-=cut
@@ -0,0 +1,583 @@
+package File::chmod;
+use strict;
+use warnings;
+use Carp;
+use vars qw( $VAL $W $MODE );
+
+use base 'Exporter';
+
+our $VERSION = '0.42'; # VERSION
+
+our @EXPORT    = (qw( chmod getchmod )); ## no critic ( ProhibitAutomaticExportation )
+our @EXPORT_OK = (qw( symchmod lschmod getsymchmod getlschmod getmod ));
+
+our $DEBUG     = 1;
+our $UMASK     = 2;
+our $MASK      = umask;
+
+
+my ($SYM,$LS) = (1,2);
+my %ERROR = (
+  EDETMOD => "use of determine_mode is deprecated",
+  ENEXLOC => "cannot set group execute on locked file",
+  ENLOCEX => "cannot set file locking on group executable file",
+  ENSGLOC => "cannot set-gid on locked file",
+  ENLOCSG => "cannot set file locking on set-gid file",
+  ENEXUID => "execute bit must be on for set-uid",
+  ENEXGID => "execute bit must be on for set-gid",
+  ENULSID => "set-id has no effect for 'others'",
+  ENULSBG => "sticky bit has no effect for 'group'",
+  ENULSBU => "sticky bit has no effect for 'user'",
+);
+
+sub getmod {
+  my @return = map { (stat)[2] & 07777 } @_;
+  return wantarray ? @return : $return[0];
+}
+
+
+sub chmod (@) { ## no critic ( Subroutines::ProhibitBuiltinHomonyms Subroutines::ProhibitSubroutinePrototypes )
+  my $mode = shift;
+  my $how = mode($mode);
+
+  return symchmod($mode,@_) if $how == $SYM;
+  return lschmod($mode,@_) if $how == $LS;
+  return CORE::chmod($mode,@_);
+}
+
+
+sub getchmod {
+  my $mode = shift;
+  my $how = mode($mode);
+
+  return getsymchmod($mode,@_) if $how == $SYM;
+  return getlschmod($mode,@_) if $how == $LS;
+  return wantarray ? (($mode) x @_) : $mode;
+}
+
+
+sub symchmod {
+  my $mode = shift;
+
+warnings::warnif 'deprecated', '$UMASK being true is deprecated'
+  . ' it will be false by default in the future. This change'
+  . ' is being made because this not the behavior of the unix command'
+  . ' `chmod`. This warning can be disabled by putting explicitly'
+  . ' setting $File::chmod::UMASK to false (0) to act like system chmod,'
+  . ' or any non 2 true value see Github issue #5 '
+  if $UMASK == 2;
+
+  my @return = getsymchmod($mode,@_);
+  my $ret = 0;
+  for (@_){ $ret++ if CORE::chmod(shift(@return),$_) }
+  return $ret;
+}
+
+
+sub getsymchmod {
+  my $mode = shift;
+  my @return;
+
+  croak "symchmod received non-symbolic mode: $mode" if mode($mode) != $SYM;
+
+  for (@_){
+    local $VAL = getmod($_);
+
+    for my $this (split /,/, $mode){
+      local $W = 0;
+      my $or;
+
+      for (split //, $this){
+        if (not defined $or and /[augo]/){
+          /a/ and $W |= 7, next;
+          /u/ and $W |= 1, next;
+          /g/ and $W |= 2, next;
+          /o/ and $W |= 4, next;
+        }
+
+        if (/[-+=]/){
+          $W ||= 7;
+          $or = (/[=+]/ ? 1 : 0);
+          clear() if /=/;
+          next;
+        }
+
+        croak "Bad mode $this" if not defined $or;
+        croak "Unknown mode: $mode" if !/[ugorwxslt]/;
+
+        /u/ and $or ? u_or() : u_not();
+        /g/ and $or ? g_or() : g_not();
+        /o/ and $or ? o_or() : o_not();
+        /r/ and $or ? r_or() : r_not();
+        /w/ and $or ? w_or() : w_not();
+        /x/ and $or ? x_or() : x_not();
+        /s/ and $or ? s_or() : s_not();
+        /l/ and $or ? l_or() : l_not();
+        /t/ and $or ? t_or() : t_not();
+      }
+    }
+    $VAL &= ~$MASK if $UMASK;
+    push @return, $VAL;
+  }
+  return wantarray ? @return : $return[0];
+}
+
+
+sub lschmod {
+  my $mode = shift;
+
+  return CORE::chmod(getlschmod($mode,@_),@_);
+}
+
+
+sub getlschmod {
+  my $mode = shift;
+  my $VAL = 0;
+
+  croak "lschmod received non-ls mode: $mode" if mode($mode) != $LS;
+
+  my ($u,$g,$o) = ($mode =~ /^.(...)(...)(...)$/);
+
+  for ($u){
+    $VAL |= 0400 if /r/;
+    $VAL |= 0200 if /w/;
+    $VAL |= 0100 if /[xs]/;
+    $VAL |= 04000 if /[sS]/;
+  }
+
+  for ($g){
+    $VAL |= 0040 if /r/;
+    $VAL |= 0020 if /w/;
+    $VAL |= 0010 if /[xs]/;
+    $VAL |= 02000 if /[sS]/;
+  }
+
+  for ($o){
+    $VAL |= 0004 if /r/;
+    $VAL |= 0002 if /w/;
+    $VAL |= 0001 if /[xt]/;
+    $VAL |= 01000 if /[Tt]/;
+  }
+
+  return wantarray ? (($VAL) x @_) : $VAL;
+}
+
+
+sub mode {
+  my $mode = shift;
+  return 0 if $mode !~ /\D/;
+  return $SYM if $mode =~ /[augo=+,]/;
+  return $LS if $mode =~ /^.([r-][w-][xSs-]){2}[r-][w-][xTt-]$/;
+  return $SYM;
+}
+
+
+sub determine_mode {
+  carp $ERROR{EDECMOD};
+  mode(@_);
+}
+
+
+sub clear {
+  $W & 1 and $VAL &= 02077;
+  $W & 2 and $VAL &= 05707;
+  $W & 4 and $VAL &= 07770;
+}
+
+
+sub u_or {
+  my $val = $VAL;
+  $W & 2 and ($VAL |= (($val & 0700)>>3 | ($val & 04000)>>1));
+  $W & 4 and ($VAL |= (($val & 0700)>>6));
+}
+
+
+sub u_not {
+  my $val = $VAL;
+  $W & 1 and $VAL &= ~(($val & 0700) | ($val & 05000));
+  $W & 2 and $VAL &= ~(($val & 0700)>>3 | ($val & 04000)>>1);
+  $W & 4 and $VAL &= ~(($val & 0700)>>6);
+}
+
+
+sub g_or {
+  my $val = $VAL;
+  $W & 1 and $VAL |= (($val & 070)<<3 | ($val & 02000)<<1);
+  $W & 4 and $VAL |= ($val & 070)>>3;
+}
+
+
+sub g_not {
+  my $val = $VAL;
+  $W & 1 and $VAL &= ~(($val & 070)<<3 | ($val & 02000)<<1);
+  $W & 2 and $VAL &= ~(($val & 070) | ($val & 02000));
+  $W & 4 and $VAL &= ~(($val & 070)>>3);
+}
+
+
+sub o_or {
+  my $val = $VAL;
+  $W & 1 and $VAL |= (($val & 07)<<6);
+  $W & 2 and $VAL |= (($val & 07)<<3);
+}
+
+
+sub o_not {
+  my $val = $VAL;
+  $W & 1 and $VAL &= ~(($val & 07)<<6);
+  $W & 2 and $VAL &= ~(($val & 07)<<3);
+  $W & 4 and $VAL &= ~($val & 07);
+}
+
+
+sub r_or {
+  $W & 1 and $VAL |= 0400;
+  $W & 2 and $VAL |= 0040;
+  $W & 4 and $VAL |= 0004;
+}
+
+
+sub r_not {
+  $W & 1 and $VAL &= ~0400;
+  $W & 2 and $VAL &= ~0040;
+  $W & 4 and $VAL &= ~0004;
+}
+
+
+sub w_or {
+  $W & 1 and $VAL |= 0200;
+  $W & 2 and $VAL |= 0020;
+  $W & 4 and $VAL |= 0002;
+}
+
+
+sub w_not {
+  $W & 1 and $VAL &= ~0200;
+  $W & 2 and $VAL &= ~0020;
+  $W & 4 and $VAL &= ~0002;
+}
+
+
+sub x_or {
+  if ($VAL & 02000){ $DEBUG and carp($ERROR{ENEXLOC}), return }
+  $W & 1 and $VAL |= 0100;
+  $W & 2 and $VAL |= 0010;
+  $W & 4 and $VAL |= 0001;
+}
+
+
+sub x_not {
+  $W & 1 and $VAL &= ~0100;
+  $W & 2 and $VAL &= ~0010;
+  $W & 4 and $VAL &= ~0001;
+}
+
+
+sub s_or {
+  if ($VAL & 02000){ $DEBUG and carp($ERROR{ENSGLOC}), return }
+  if (not $VAL & 00100){ $DEBUG and carp($ERROR{ENEXUID}), return }
+  if (not $VAL & 00010){ $DEBUG and carp($ERROR{ENEXGID}), return }
+  $W & 1 and $VAL |= 04000;
+  $W & 2 and $VAL |= 02000;
+  $W & 4 and $DEBUG and carp $ERROR{ENULSID};
+}
+
+
+sub s_not {
+  $W & 1 and $VAL &= ~04000;
+  $W & 2 and $VAL &= ~02000;
+  $W & 4 and $DEBUG and carp $ERROR{ENULSID};
+}
+
+
+sub l_or {
+  if ($VAL & 02010){ $DEBUG and carp ($ERROR{ENLOCSG}), return }
+  if ($VAL & 00010){ $DEBUG and carp ($ERROR{ENLOCEX}), return }
+  $VAL |= 02000;
+}
+
+
+sub l_not {
+  $VAL &= ~02000 if not $VAL & 00010;
+}
+
+
+sub t_or {
+  $W & 1 and $DEBUG and carp $ERROR{ENULSBU};
+  $W & 2 and $DEBUG and carp $ERROR{ENULSBG};
+  $W & 4 and $VAL |= 01000;
+}
+
+
+sub t_not {
+  $W & 1 and $DEBUG and carp $ERROR{ENULSBU};
+  $W & 2 and $DEBUG and carp $ERROR{ENULSBG};
+  $W & 4 and $VAL &= ~01000;
+}
+
+
+1;
+# ABSTRACT: Implements symbolic and ls chmod modes
+
+__END__
+
+=pod
+
+=head1 NAME
+
+File::chmod - Implements symbolic and ls chmod modes
+
+=head1 VERSION
+
+version 0.42
+
+=head1 SYNOPSIS
+
+  use File::chmod;
+  $File::chmod::UMASK = 0;
+  # It is recommended that you explicitly set $File::chmod::UMASK
+  # as the default will change in the future
+  #
+  # 0 is recommended to behave like system chmod
+  # 1 if you want File::chmod to apply your environment set umask.
+  # 2 is how we detect that it's internally set, undef will become the
+  # default in the future, eventually a lexicaly scoped API may be designed
+
+  # chmod takes all three types
+  # these all do the same thing
+  chmod(0666,@files);
+  chmod("=rw",@files);
+  chmod("-rw-rw-rw-",@files);
+
+  # or
+
+  use File::chmod qw( symchmod lschmod );
+
+  chmod(0666,@files);		# this is the normal chmod
+  symchmod("=rw",@files);	# takes symbolic modes only
+  lschmod("-rw-rw-rw-",@files);	# takes "ls" modes only
+
+  # more functions, read on to understand
+
+=head1 DESCRIPTION
+
+File::chmod is a utility that allows you to bypass system calls or bit
+processing of a file's permissions.  It overloads the chmod() function
+with its own that gets an octal mode, a symbolic mode (see below), or
+an "ls" mode (see below).  If you wish not to overload chmod(), you can
+export symchmod() and lschmod(), which take, respectively, a symbolic
+mode and an "ls" mode.
+
+An added feature to version 0.30 is the C<$UMASK> variable, explained in
+detail below; if C<symchmod()> is called and this variable is true, then the
+function uses the (also new) C<$MASK> variable (which defaults to C<umask()>)
+as a mask against the new mode. This mode is on by default, and changes the
+behavior from what you would expect if you are used to UNIX C<chmod>.
+B<This may change in the future.>
+
+Symbolic modes are thoroughly described in your chmod(1) man page, but
+here are a few examples.
+
+  chmod("+x","file1","file2");	# overloaded chmod(), that is...
+  # turns on the execute bit for all users on those two files
+
+  chmod("o=,g-w","file1","file2");
+  # removes 'other' permissions, and the write bit for 'group'
+
+  chmod("=u","file1","file2");
+  # sets all bits to those in 'user'
+
+"ls" modes are the type produced on the left-hand side of an C<ls -l> on a
+directory.  Examples are:
+
+  chmod("-rwxr-xr-x","file1","file2");
+  # the 0755 setting; user has read-write-execute, group and others
+  # have read-execute priveleges
+
+  chmod("-rwsrws---","file1","file2");
+  # sets read-write-execute for user and group, none for others
+  # also sets set-uid and set-gid bits
+
+The regular chmod() and lschmod() are absolute; that is, they are not
+appending to or subtracting from the current file mode.  They set it,
+regardless of what it had been before.  symchmod() is useful for allowing
+the modifying of a file's permissions without having to run a system call
+or determining the file's permissions, and then combining that with whatever
+bits are appropriate.  It also operates separately on each file.
+
+=head1 FUNCTIONS - EXPORT
+
+=head2 chmod(MODE,FILES)
+
+Takes an octal, symbolic, or "ls" mode, and then chmods each file
+appropriately.
+
+=head2 getchmod(MODE,FILES)
+
+Returns a list of modified permissions, without chmodding files.
+Accepts any of the three kinds of modes.
+
+  @newmodes = getchmod("+x","file1","file2");
+  # @newmodes holds the octal permissions of the files'
+  # modes, if they were to be sent through chmod("+x"...)
+
+=head1 FUNCTIONS - EXPORT_OK
+
+=head2 symchmod(MODE,FILES)
+
+Takes a symbolic permissions mode, and chmods each file.
+
+=head2 lschmod(MODE,FILES)
+
+Takes an "ls" permissions mode, and chmods each file.
+
+=head2 getsymchmod(MODE,FILES)
+
+Returns a list of modified permissions, without chmodding files.
+Accepts only symbolic permission modes.
+
+=head2 getlschmod(MODE,FILES)
+
+Returns a list of modified permissions, without chmodding files.
+Accepts only "ls" permission modes.
+
+=head2 getmod(FILES)
+
+Returns a list of the current mode of each file.
+
+=head1 VARIABLES
+
+=head2 $File::chmod::DEBUG
+
+If set to a true value, it will report warnings, similar to those produced
+by chmod() on your system.  Otherwise, the functions will not report errors.
+Example: a file can not have file-locking and the set-gid bits on at the
+same time.  If $File::chmod::DEBUG is true, the function will report an
+error.  If not, you are not warned of the conflict.  It is set to 1 as
+default.
+
+=head2 $File::chmod::MASK
+
+Contains the umask to apply to new file modes when using getsymchmod().  This
+defaults to the return value of umask() at compile time.  Is only applied if
+$UMASK is true.
+
+=head2 $File::chmod::UMASK
+
+This is a boolean which tells getsymchmod() whether or not to apply the umask
+found in $MASK.  It defaults to true.
+
+=for test_synopsis my ( @files );
+
+=head1 PORTING
+
+This is only good on Unix-like boxes.  I would like people to help me work on
+L<File::chmod> for any OS that deserves it.  If you would like to help, please
+email me (address below) with the OS and any information you might have on how
+chmod() should work on it; if you don't have any specific information, but
+would still like to help, hey, that's good too.  I have the following
+information (from L</perlport>):
+
+=over 4
+
+=item Win32
+
+Only good for changing "owner" read-write access, "group", and "other" bits
+are meaningless.  I<NOTE: Win32::File and Win32::FileSecurity already do
+this.  I do not currently see a need to port File::chmod.>
+
+=item MacOS
+
+Only limited meaning. Disabling/enabling write permission is mapped to
+locking/unlocking the file.
+
+=item RISC OS
+
+Only good for changing "owner" and "other" read-write access.
+
+=back
+
+=head1 SEE ALSO
+
+  Stat::lsMode (by Mark-James Dominus, CPAN ID: MJD)
+  chmod(1) manpage
+  perldoc -f chmod
+  perldoc -f stat
+
+=for Pod::Coverage clear
+determine_mode
+g_not
+g_or
+l_not
+l_or
+mode
+o_not
+o_or
+r_not
+r_or
+s_not
+s_or
+t_not
+t_or
+u_not
+u_or
+w_not
+w_or
+x_not
+x_or
+
+=head1 BUGS
+
+Please report any bugs or feature requests on the bugtracker website
+https://github.com/xenoterracide/file-chmod/issues
+
+When submitting a bug or request, please include a test-file or a
+patch to an existing test-file that illustrates the bug or desired
+feature.
+
+=head1 CONTRIBUTORS
+
+=for stopwords David Steinbrunner Slaven Rezic Steve Throckmorton Tim
+
+=over 4
+
+=item *
+
+David Steinbrunner <dsteinbrunner@pobox.com>
+
+=item *
+
+Slaven Rezic <slaven@rezic.de>
+
+=item *
+
+Steve Throckmorton <arrestee@gmail.com>
+
+=item *
+
+Tim <oylenshpeegul@gmail.com>
+
+=back
+
+=head1 AUTHORS
+
+=over 4
+
+=item *
+
+Jeff Pinyan <japhy.734+CPAN@gmail.com>
+
+=item *
+
+Caleb Cushing <xenoterracide@gmail.com>
+
+=back
+
+=head1 COPYRIGHT AND LICENSE
+
+This software is copyright (c) 2015 by Caleb Cushing and Jeff Pinyan.
+
+This is free software; you can redistribute it and/or modify it under
+the same terms as the Perl 5 programming language system itself.
+
+=cut
@@ -0,0 +1,6 @@
+theme    = core
+severity = 3
+verbose  = 9
+exclude  = ProhibitLeadingZeros RequireFinalReturn RequireArgUnpacking ProhibitCommaSeparatedStatements RequireExtendedFormatting
+[Subroutines::ProhibitExcessComplexity]
+max_mccabe = 37
@@ -0,0 +1,51 @@
+use 5.006;
+use strict;
+use warnings;
+
+# this test was generated with Dist::Zilla::Plugin::Test::Compile 2.051
+
+use Test::More;
+
+plan tests => 1 + ($ENV{AUTHOR_TESTING} ? 1 : 0);
+
+my @module_files = (
+    'File/chmod.pm'
+);
+
+
+
+# no fake home requested
+
+my $inc_switch = -d 'blib' ? '-Mblib' : '-Ilib';
+
+use File::Spec;
+use IPC::Open3;
+use IO::Handle;
+
+open my $stdin, '<', File::Spec->devnull or die "can't open devnull: $!";
+
+my @warnings;
+for my $lib (@module_files)
+{
+    # see L<perlfaq8/How can I capture STDERR from an external command?>
+    my $stderr = IO::Handle->new;
+
+    my $pid = open3($stdin, '>&STDERR', $stderr, $^X, $inc_switch, '-e', "require q[$lib]");
+    binmode $stderr, ':crlf' if $^O eq 'MSWin32';
+    my @_warnings = <$stderr>;
+    waitpid($pid, 0);
+    is($?, 0, "$lib loaded ok");
+
+    if (@_warnings)
+    {
+        warn @_warnings;
+        push @warnings, @_warnings;
+    }
+}
+
+
+
+is(scalar(@warnings), 0, 'no warnings found')
+    or diag 'got warnings: ', ( Test::More->can('explain') ? Test::More::explain(\@warnings) : join("\n", '', @warnings) ) if $ENV{AUTHOR_TESTING};
+
+
@@ -0,0 +1,47 @@
+do { my $x = {
+       'configure' => {
+                        'requires' => {
+                                        'ExtUtils::MakeMaker' => '0'
+                                      }
+                      },
+       'develop' => {
+                      'requires' => {
+                                      'Pod::Coverage::TrustPod' => '0',
+                                      'Test::CPAN::Changes' => '0.19',
+                                      'Test::EOL' => '0',
+                                      'Test::More' => '0.88',
+                                      'Test::Pod' => '1.41',
+                                      'Test::Pod::Coverage' => '1.08',
+                                      'Test::Version' => '1'
+                                    }
+                    },
+       'runtime' => {
+                      'requires' => {
+                                      'Carp' => '0',
+                                      'Exporter' => '0',
+                                      'base' => '0',
+                                      'strict' => '0',
+                                      'vars' => '0',
+                                      'warnings' => '0'
+                                    }
+                    },
+       'test' => {
+                   'recommends' => {
+                                     'CPAN::Meta' => '2.120900'
+                                   },
+                   'requires' => {
+                                   'English' => '0',
+                                   'ExtUtils::MakeMaker' => '0',
+                                   'File::Spec' => '0',
+                                   'File::Temp' => '0',
+                                   'IO::Handle' => '0',
+                                   'IPC::Open3' => '0',
+                                   'Test::More' => '0',
+                                   'autodie' => '0',
+                                   'perl' => '5.006',
+                                   'utf8' => '0'
+                                 }
+                 }
+     };
+  $x;
+ }
\ No newline at end of file
@@ -0,0 +1,183 @@
+#!perl
+
+use strict;
+use warnings;
+
+# This test was generated by Dist::Zilla::Plugin::Test::ReportPrereqs 0.020
+
+use Test::More tests => 1;
+
+use ExtUtils::MakeMaker;
+use File::Spec;
+
+# from $version::LAX
+my $lax_version_re =
+    qr/(?: undef | (?: (?:[0-9]+) (?: \. | (?:\.[0-9]+) (?:_[0-9]+)? )?
+            |
+            (?:\.[0-9]+) (?:_[0-9]+)?
+        ) | (?:
+            v (?:[0-9]+) (?: (?:\.[0-9]+)+ (?:_[0-9]+)? )?
+            |
+            (?:[0-9]+)? (?:\.[0-9]+){2,} (?:_[0-9]+)?
+        )
+    )/x;
+
+# hide optional CPAN::Meta modules from prereq scanner
+# and check if they are available
+my $cpan_meta = "CPAN::Meta";
+my $cpan_meta_pre = "CPAN::Meta::Prereqs";
+my $HAS_CPAN_META = eval "require $cpan_meta; $cpan_meta->VERSION('2.120900')" && eval "require $cpan_meta_pre"; ## no critic
+
+# Verify requirements?
+my $DO_VERIFY_PREREQS = 1;
+
+sub _max {
+    my $max = shift;
+    $max = ( $_ > $max ) ? $_ : $max for @_;
+    return $max;
+}
+
+sub _merge_prereqs {
+    my ($collector, $prereqs) = @_;
+
+    # CPAN::Meta::Prereqs object
+    if (ref $collector eq $cpan_meta_pre) {
+        return $collector->with_merged_prereqs(
+            CPAN::Meta::Prereqs->new( $prereqs )
+        );
+    }
+
+    # Raw hashrefs
+    for my $phase ( keys %$prereqs ) {
+        for my $type ( keys %{ $prereqs->{$phase} } ) {
+            for my $module ( keys %{ $prereqs->{$phase}{$type} } ) {
+                $collector->{$phase}{$type}{$module} = $prereqs->{$phase}{$type}{$module};
+            }
+        }
+    }
+
+    return $collector;
+}
+
+my @include = qw(
+
+);
+
+my @exclude = qw(
+
+);
+
+# Add static prereqs to the included modules list
+my $static_prereqs = do 't/00-report-prereqs.dd';
+
+# Merge all prereqs (either with ::Prereqs or a hashref)
+my $full_prereqs = _merge_prereqs(
+    ( $HAS_CPAN_META ? $cpan_meta_pre->new : {} ),
+    $static_prereqs
+);
+
+# Add dynamic prereqs to the included modules list (if we can)
+my ($source) = grep { -f } 'MYMETA.json', 'MYMETA.yml';
+if ( $source && $HAS_CPAN_META ) {
+    if ( my $meta = eval { CPAN::Meta->load_file($source) } ) {
+        $full_prereqs = _merge_prereqs($full_prereqs, $meta->prereqs);
+    }
+}
+else {
+    $source = 'static metadata';
+}
+
+my @full_reports;
+my @dep_errors;
+my $req_hash = $HAS_CPAN_META ? $full_prereqs->as_string_hash : $full_prereqs;
+
+# Add static includes into a fake section
+for my $mod (@include) {
+    $req_hash->{other}{modules}{$mod} = 0;
+}
+
+for my $phase ( qw(configure build test runtime develop other) ) {
+    next unless $req_hash->{$phase};
+    next if ($phase eq 'develop' and not $ENV{AUTHOR_TESTING});
+
+    for my $type ( qw(requires recommends suggests conflicts modules) ) {
+        next unless $req_hash->{$phase}{$type};
+
+        my $title = ucfirst($phase).' '.ucfirst($type);
+        my @reports = [qw/Module Want Have/];
+
+        for my $mod ( sort keys %{ $req_hash->{$phase}{$type} } ) {
+            next if $mod eq 'perl';
+            next if grep { $_ eq $mod } @exclude;
+
+            my $file = $mod;
+            $file =~ s{::}{/}g;
+            $file .= ".pm";
+            my ($prefix) = grep { -e File::Spec->catfile($_, $file) } @INC;
+
+            my $want = $req_hash->{$phase}{$type}{$mod};
+            $want = "undef" unless defined $want;
+            $want = "any" if !$want && $want == 0;
+
+            my $req_string = $want eq 'any' ? 'any version required' : "version '$want' required";
+
+            if ($prefix) {
+                my $have = MM->parse_version( File::Spec->catfile($prefix, $file) );
+                $have = "undef" unless defined $have;
+                push @reports, [$mod, $want, $have];
+
+                if ( $DO_VERIFY_PREREQS && $HAS_CPAN_META && $type eq 'requires' ) {
+                    if ( $have !~ /\A$lax_version_re\z/ ) {
+                        push @dep_errors, "$mod version '$have' cannot be parsed ($req_string)";
+                    }
+                    elsif ( ! $full_prereqs->requirements_for( $phase, $type )->accepts_module( $mod => $have ) ) {
+                        push @dep_errors, "$mod version '$have' is not in required range '$want'";
+                    }
+                }
+            }
+            else {
+                push @reports, [$mod, $want, "missing"];
+
+                if ( $DO_VERIFY_PREREQS && $type eq 'requires' ) {
+                    push @dep_errors, "$mod is not installed ($req_string)";
+                }
+            }
+        }
+
+        if ( @reports ) {
+            push @full_reports, "=== $title ===\n\n";
+
+            my $ml = _max( map { length $_->[0] } @reports );
+            my $wl = _max( map { length $_->[1] } @reports );
+            my $hl = _max( map { length $_->[2] } @reports );
+
+            if ($type eq 'modules') {
+                splice @reports, 1, 0, ["-" x $ml, "", "-" x $hl];
+                push @full_reports, map { sprintf("    %*s %*s\n", -$ml, $_->[0], $hl, $_->[2]) } @reports;
+            }
+            else {
+                splice @reports, 1, 0, ["-" x $ml, "-" x $wl, "-" x $hl];
+                push @full_reports, map { sprintf("    %*s %*s %*s\n", -$ml, $_->[0], $wl, $_->[1], $hl, $_->[2]) } @reports;
+            }
+
+            push @full_reports, "\n";
+        }
+    }
+}
+
+if ( @full_reports ) {
+    diag "\nVersions for all modules listed in $source (including optional ones):\n\n", @full_reports;
+}
+
+if ( @dep_errors ) {
+    diag join("\n",
+        "\n*** WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING ***\n",
+        "The following REQUIRED prerequisites were not satisfied:\n",
+        @dep_errors,
+        "\n"
+    );
+}
+
+pass;
+
+# vim: ts=4 sts=4 sw=4 et:
@@ -0,0 +1,20 @@
+#!perl
+
+BEGIN {
+  unless ($ENV{AUTHOR_TESTING}) {
+    require Test::More;
+    Test::More::plan(skip_all => 'these tests are for testing by the author');
+  }
+}
+
+
+use strict;
+use warnings;
+
+use Test::More;
+use English qw(-no_match_vars);
+
+eval "use Test::Perl::Critic";
+plan skip_all => 'Test::Perl::Critic required to criticise code' if $@;
+Test::Perl::Critic->import( -profile => "perlcritic.rc" ) if -e "perlcritic.rc";
+all_critic_ok();
@@ -0,0 +1,42 @@
+
+BEGIN {
+  unless ($ENV{AUTHOR_TESTING}) {
+    require Test::More;
+    Test::More::plan(skip_all => 'these tests are for testing by the author');
+  }
+}
+
+use strict;
+use warnings;
+
+# this test was generated with Dist::Zilla::Plugin::Test::EOL 0.17
+
+use Test::More 0.88;
+use Test::EOL;
+
+my @files = (
+    'lib/File/chmod.pm',
+    't/00-compile.t',
+    't/00-report-prereqs.dd',
+    't/00-report-prereqs.t',
+    't/author-critic.t',
+    't/author-eol.t',
+    't/executable.t',
+    't/load_chmod.t',
+    't/read.t',
+    't/release-cpan-changes.t',
+    't/release-dist-manifest.t',
+    't/release-meta-json.t',
+    't/release-minimum-version.t',
+    't/release-pod-coverage.t',
+    't/release-pod-syntax.t',
+    't/release-portability.t',
+    't/release-test-version.t',
+    't/release-unused-vars.t',
+    't/remove-write-from-other.t',
+    't/sticky-bit.t',
+    't/write.t'
+);
+
+eol_unix_ok($_, { trailing_whitespace => 1 }) foreach @files;
+done_testing;
@@ -0,0 +1,22 @@
+use strict;
+use warnings;
+use Test::More;
+use English '-no_match_vars';
+use File::Temp ();
+use File::chmod qw( chmod getmod );
+$File::chmod::UMASK = 0;
+
+plan skip_all => "Windows perms work differently" if $OSNAME eq 'MSWin32';
+
+my $tmp = File::Temp->new;
+my $fn  = $tmp->filename;
+
+note sprintf "original state of %s: %o\n", $fn, getmod( $fn );
+
+ok chmod("+x", $fn ), "chmod +x $fn";
+ok -x $fn, "$fn executable";
+
+ok chmod("-x", $fn ), "chmod -x $fn";
+ok ! -x $fn, "$fn not executable";
+
+done_testing;
@@ -0,0 +1,29 @@
+# load_chmod.t
+#
+# Since perl v5.14 (or thereabouts), a warning is issued when the autodie
+# pragma is used and &File::chmod::chmod doesn't match the prototype of (@)
+# that CORE::chmod has.  Adding a prototype to &File::chmod::chmod silences
+# the warning.  This test ensures that the prototype doesn't get lost
+# somewhere in the future.
+
+use strict;
+use warnings;
+use autodie;
+use utf8;
+use Test::More;
+
+my $test_passed;
+BEGIN {
+    $test_passed = 1;
+    $SIG{__WARN__} = sub {
+        my $msg = shift;
+        if ( $msg =~ m/Prototype\s+mismatch:\s+sub\s+main::chmod/i ) {
+            $test_passed = 0;
+        }
+    };
+}
+
+use File::chmod;
+ok( $test_passed, "Load File::chmod without 'Missing prototype' warning" );
+
+done_testing;
@@ -0,0 +1,41 @@
+use strict;
+use warnings;
+use Test::More;
+use English '-no_match_vars';
+use File::Temp ();
+use File::chmod qw( chmod getmod );
+$File::chmod::UMASK = 0;
+
+plan skip_all => "Windows perms work differently" if $OSNAME eq 'MSWin32';
+
+my $tmp = File::Temp->new;
+my $fn  = $tmp->filename;
+
+chmod( 0000, $fn );
+note sprintf "state of %s: %o\n", $fn, getmod( $fn );
+
+ok chmod("+r", $fn ), "chmod +r $fn";
+is sprintf( '%o', getmod( $fn ) ), 444, "$fn is 444";
+
+ok chmod("-r", $fn ), "chmod -r $fn";
+is sprintf( '%o', getmod( $fn ) ), 000, "$fn is 000";
+
+ok chmod("u+r", $fn ), "chmod u+r $fn";
+is sprintf( '%o', getmod( $fn ) ), 400, "$fn is 400";
+
+ok chmod("u-r", $fn ), "chmod u-r $fn";
+is sprintf( '%o', getmod( $fn ) ), 000, "$fn is 000";
+
+ok chmod("ug+r", $fn ), "chmod ug+r $fn";
+is sprintf( '%o', getmod( $fn ) ), 440, "$fn is 440";
+
+ok chmod("ug-r", $fn ), "chmod ug+r $fn";
+is sprintf( '%o', getmod( $fn ) ), 000, "$fn is 000";
+
+ok chmod("ugo+r", $fn ), "chmod ugo+r $fn";
+is sprintf( '%o', getmod( $fn ) ), 444, "$fn is 444";
+
+ok chmod("ugo-r", $fn ), "chmod ugo+r $fn";
+is sprintf( '%o', getmod( $fn ) ), 000, "$fn is 000";
+
+done_testing;
@@ -0,0 +1,19 @@
+#!perl
+
+BEGIN {
+  unless ($ENV{RELEASE_TESTING}) {
+    require Test::More;
+    Test::More::plan(skip_all => 'these tests are for release candidate testing');
+  }
+}
+
+
+use strict;
+use warnings;
+
+use Test::More 0.96 tests => 2;
+use_ok('Test::CPAN::Changes');
+subtest 'changes_ok' => sub {
+    changes_file_ok('Changes');
+};
+done_testing();
@@ -0,0 +1,16 @@
+#!perl
+
+BEGIN {
+  unless ($ENV{RELEASE_TESTING}) {
+    require Test::More;
+    Test::More::plan(skip_all => 'these tests are for release candidate testing');
+  }
+}
+
+
+use Test::More;
+
+eval "use Test::DistManifest";
+plan skip_all => "Test::DistManifest required for testing the manifest"
+  if $@;
+manifest_ok();
@@ -0,0 +1,14 @@
+#!perl
+
+BEGIN {
+  unless ($ENV{RELEASE_TESTING}) {
+    require Test::More;
+    Test::More::plan(skip_all => 'these tests are for release candidate testing');
+  }
+}
+
+
+use Test::More;
+eval 'use Test::CPAN::Meta::JSON';
+plan skip_all => 'Test::CPAN::Meta::JSON required for testing META.json' if $@;
+meta_json_ok();
@@ -0,0 +1,16 @@
+#!perl
+
+BEGIN {
+  unless ($ENV{RELEASE_TESTING}) {
+    require Test::More;
+    Test::More::plan(skip_all => 'these tests are for release candidate testing');
+  }
+}
+
+
+use Test::More;
+
+eval "use Test::MinimumVersion";
+plan skip_all => "Test::MinimumVersion required for testing minimum versions"
+  if $@;
+all_minimum_version_from_metayml_ok();
@@ -0,0 +1,15 @@
+#!perl
+
+BEGIN {
+  unless ($ENV{RELEASE_TESTING}) {
+    require Test::More;
+    Test::More::plan(skip_all => 'these tests are for release candidate testing');
+  }
+}
+
+# This file was automatically generated by Dist::Zilla::Plugin::PodCoverageTests.
+
+use Test::Pod::Coverage 1.08;
+use Pod::Coverage::TrustPod;
+
+all_pod_coverage_ok({ coverage_class => 'Pod::Coverage::TrustPod' });
@@ -0,0 +1,14 @@
+#!perl
+
+BEGIN {
+  unless ($ENV{RELEASE_TESTING}) {
+    require Test::More;
+    Test::More::plan(skip_all => 'these tests are for release candidate testing');
+  }
+}
+
+# This file was automatically generated by Dist::Zilla::Plugin::PodSyntaxTests.
+use Test::More;
+use Test::Pod 1.41;
+
+all_pod_files_ok();
@@ -0,0 +1,20 @@
+#!perl
+
+BEGIN {
+  unless ($ENV{RELEASE_TESTING}) {
+    require Test::More;
+    Test::More::plan(skip_all => 'these tests are for release candidate testing');
+  }
+}
+
+
+use strict;
+use warnings;
+
+use Test::More;
+
+eval 'use Test::Portability::Files';
+plan skip_all => 'Test::Portability::Files required for testing portability'
+    if $@;
+
+run_tests();
@@ -0,0 +1,30 @@
+
+BEGIN {
+  unless ($ENV{RELEASE_TESTING}) {
+    require Test::More;
+    Test::More::plan(skip_all => 'these tests are for release candidate testing');
+  }
+}
+
+use strict;
+use warnings;
+use Test::More;
+
+# generated by Dist::Zilla::Plugin::Test::Version 0.003001
+use Test::Version;
+
+my @imports = ( 'version_all_ok' );
+
+my $params = {
+    is_strict   => 0,
+    has_version => 1,
+};
+
+push @imports, $params
+    if version->parse( $Test::Version::VERSION ) >= version->parse('1.002');
+
+
+Test::Version->import(@imports);
+
+version_all_ok;
+done_testing;
@@ -0,0 +1,22 @@
+#!perl
+
+BEGIN {
+  unless ($ENV{RELEASE_TESTING}) {
+    require Test::More;
+    Test::More::plan(skip_all => 'these tests are for release candidate testing');
+  }
+}
+
+
+use Test::More 0.96 tests => 1;
+eval { require Test::Vars };
+
+SKIP: {
+    skip 1 => 'Test::Vars required for testing for unused vars'
+        if $@;
+    Test::Vars->import;
+
+    subtest 'unused vars' => sub {
+all_vars_ok();
+    };
+};
@@ -0,0 +1,20 @@
+use strict;
+use warnings;
+use Test::More;
+use English '-no_match_vars';
+use File::Temp ();
+use File::chmod qw( chmod getmod );
+$File::chmod::UMASK = 0;
+
+plan skip_all => "Windows perms work differently" if $OSNAME eq 'MSWin32';
+
+my $tmp = File::Temp->new;
+my $fn  = $tmp->filename;
+
+chmod( 0777, $fn );
+note sprintf "state of %s: %o\n", $fn, getmod( $fn );
+
+ok chmod("o-w", $fn ), "chmod -w $fn";
+is sprintf( '%o', getmod( $fn ) ), 775, "$fn is 775";
+
+done_testing;
@@ -0,0 +1,39 @@
+use strict;
+use warnings;
+use Test::More;
+use English '-no_match_vars';
+use File::Temp ();
+use File::chmod qw( chmod getmod );
+$File::chmod::UMASK = 0;
+
+plan skip_all => "Windows perms work differently" if $OSNAME eq 'MSWin32';
+plan skip_all => "old File::Temp without newdir" if !File::Temp->can('newdir');
+
+my $tmp = File::Temp->newdir;
+my $fn  = $tmp->dirname;
+note sprintf "original state of %s: %o\n", $fn, getmod( $fn );
+
+
+ok chmod("+t", $fn ), "chmod +t $fn";
+ok -k $fn, "$fn sticky"
+	or diag sprintf "state of %s: %o\n", $fn, getmod( $fn );
+
+ok chmod("-t", $fn ), "chmod -t $fn";
+ok ! -k $fn, "$fn not sticky"
+	or diag sprintf "state of %s: %o\n", $fn, getmod( $fn );
+
+
+ok chmod("o+t", $fn ), "chmod o+t $fn";
+ok -k $fn, "$fn sticky"
+	or diag sprintf "state of %s: %o\n", $fn, getmod( $fn );
+
+ok chmod("o-t", $fn ), "chmod o-t $fn";
+ok ! -k $fn, "$fn not sticky"
+	or diag sprintf "state of %s: %o\n", $fn, getmod( $fn );
+
+
+ok chmod("u+t", $fn ), "chmod u+t $fn";
+ok ! -k $fn, "$fn sticky"
+	or diag sprintf "state of %s: %o\n", $fn, getmod( $fn );
+
+done_testing;
@@ -0,0 +1,23 @@
+use strict;
+use warnings;
+use Test::More;
+use English '-no_match_vars';
+use File::Temp ();
+use File::chmod qw( chmod getmod );
+$File::chmod::UMASK = 0;
+
+plan skip_all => "Windows perms work differently" if $OSNAME eq 'MSWin32';
+
+my $tmp = File::Temp->new;
+my $fn  = $tmp->filename;
+
+chmod( 0000, $fn );
+note sprintf "state of %s: %o\n", $fn, getmod( $fn );
+
+ok chmod("+w", $fn ), "chmod +w $fn";
+is sprintf( '%o', getmod( $fn ) ), 222, "$fn is 222";
+
+ok chmod("-w", $fn ), "chmod -w $fn";
+is sprintf( '%o', getmod( $fn ) ), 000, "$fn is 000";
+
+done_testing;
@@ -1,29 +0,0 @@
-# Before `make install' is performed this script should be runnable with
-# `make test'. After `make install' it should work as `perl test.pl'
-
-######################### We start with some black magic to print on failure.
-
-# Change 1..1 below to 1..last_test_to_print .
-# (It may become useful if the test is moved to ./t subdirectory.)
-
-BEGIN { $| = 1; print "1..1\n"; }
-END {print "not ok 1\n" unless $loaded;}
-use File::chmod qw( chmod getmod );
-$loaded = 1;
-print "ok 1\n";
-
-######################### End of black magic.
-
-# Insert your test code below (better if it prints "ok 13"
-# (correspondingly "not ok 13") depending on the success of chunk 13
-# of the test code):
-
-printf "original state of chmod.pm: %05o\n", getmod("chmod.pm");
-
-print "calling: chmod('+x', 'chmod.pm')... ";
-chmod("+x","chmod.pm") or warn "couldn't chmod +x chmod.pm: $!";
-printf "chmod.pm: %05o\n", getmod("chmod.pm");
-
-print "calling: chmod('-x', 'chmod.pm')... ";
-chmod("-x","chmod.pm") or warn "couldn't chmod -x chmod.pm: $!";
-printf "chmod.pm: %05o\n", getmod("chmod.pm");