From: Ian Macdonald Date: 2004-01-09T18:02:07+09:00 Subject: [PATCH] File.readable_world? and File.writable_world? --OwLcNYc0lM97+oe1 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Hello, As a system administrator, it's nice to be able to check for world readable and writable files without having to File.stat the file and check the mode for the relevant bits. Whilst that's easy enough to do, the resulting code is too ugly for an elegant language like Ruby, IMHO. The attached patch implements the File.readable_world? and File.writable_world? methods. Please consider its inclusion in Ruby. The diff is against the latest 1.8.1 snapshot. Thanks, Ian -- Ian Macdonald | In this world of sin and sorrow there is System Administrator | always something to be thankful for; as for ian@caliban.org | me, I rejoice that I am not a Republican. http://www.caliban.org | -- H.L. Mencken | --OwLcNYc0lM97+oe1 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="ruby-1.8.1-File.diff" diff -uNr ruby.orig/file.c ruby/file.c --- ruby.orig/file.c 2003-12-24 07:19:09.000000000 -0800 +++ ruby/file.c 2004-01-09 00:42:36.000000000 -0800 @@ -1015,6 +1015,25 @@ return Qtrue; } +/* + * call-seq: + * File.readable_world?(file_name) => true or false + * + * Returns true if the named file is readable by anyone. + */ + +static VALUE +test_rw(obj, fname) + VALUE obj, fname; +{ +#ifdef S_IROTH + struct stat st; + + if (rb_stat(fname, &st) < 0) return Qfalse; + if (st.st_mode & S_IROTH) return Qtrue; +#endif + return Qfalse; +} /* * call-seq: @@ -1052,6 +1071,26 @@ /* * call-seq: + * File.writable_world?(file_name) => true or false + * + * Returns true if the named file is writable by anyone. + */ + +static VALUE +test_ww(obj, fname) + VALUE obj, fname; +{ +#ifdef S_IWOTH + struct stat st; + + if (rb_stat(fname, &st) < 0) return Qfalse; + if (st.st_mode & S_IWOTH) return Qtrue; +#endif + return Qfalse; +} + +/* + * call-seq: * File.executable?(file_name) => true or false * * Returns true if the named file is executable by the effective @@ -4052,8 +4091,10 @@ define_filetest_function("exists?", test_e, 1); /* temporary */ define_filetest_function("readable?", test_r, 1); define_filetest_function("readable_real?", test_R, 1); + define_filetest_function("readable_world?", test_rw, 1); define_filetest_function("writable?", test_w, 1); define_filetest_function("writable_real?", test_W, 1); + define_filetest_function("writable_world?", test_ww, 1); define_filetest_function("executable?", test_x, 1); define_filetest_function("executable_real?", test_X, 1); define_filetest_function("file?", test_f, 1); diff -uNr ruby.orig/lib/pathname.rb ruby/lib/pathname.rb --- ruby.orig/lib/pathname.rb 2003-12-25 23:42:35.000000000 -0800 +++ ruby/lib/pathname.rb 2004-01-09 00:19:55.000000000 -0800 @@ -423,6 +423,7 @@ def owned?() FileTest.owned?(@path) end def readable?() FileTest.readable?(@path) end def readable_real?() FileTest.readable_real?(@path) end + def readable_world?() FileTest.readable_world?(@path) end def setuid?() FileTest.setuid?(@path) end def setgid?() FileTest.setgid?(@path) end def size() FileTest.size(@path) end @@ -431,6 +432,7 @@ def symlink?() FileTest.symlink?(@path) end def writable?() FileTest.writable?(@path) end def writable_real?() FileTest.writable_real?(@path) end + def writable_world?() FileTest.writable_world?(@path) end def zero?() FileTest.zero?(@path) end end --OwLcNYc0lM97+oe1--