alive.chmod(Time.now.to_i) raises Errno::EINVAL on OpenBSD

Jeremy Evans jeremyevans0 at gmail.com
Thu Oct 8 19:57:38 EDT 2009


On OpenBSD:

$ ruby -e "File.new('TODO').chmod(Time.now.to_i)"
-e:1:in `chmod': Invalid argument - TODO (Errno::EINVAL)
        from -e:1

This is explained in the man page:

     int
     fchmod(int fd, mode_t mode);

    ...

     [EINVAL]      mode contains bits other than the file type and those de-
                   scribed above.

I think 04777 is the highest allowed mode on OpenBSD.  Time.now.to_i
is obviously higher than that.

Here's a diff that should fix the problem.  At the very least it
allows the workers to start without crashing:

diff --git a/lib/unicorn.rb b/lib/unicorn.rb
index ddec8e9..092f500 100644
--- a/lib/unicorn.rb
+++ b/lib/unicorn.rb
@@ -579,13 +579,13 @@ module Unicorn
         # changes with chmod doesn't update ctime on all filesystems; so
         # we change our counter each and every time (after process_client
         # and before IO.select).
-        t == (ti = Time.now.to_i) or alive.chmod(t = ti)
+        t == (ti = Time.now.to_i) or (t = ti;
alive.chmod(alive.stat.mode ^ 0100))

         ready.each do |sock|
           begin
             process_client(sock.accept_nonblock)
             nr += 1
-            t == (ti = Time.now.to_i) or alive.chmod(t = ti)
+            t == (ti = Time.now.to_i) or (t = ti;
alive.chmod(alive.stat.mode ^ 0100))
           rescue Errno::EAGAIN, Errno::ECONNABORTED
           end
           break if nr < 0

There are definitely other ways that will work, as long as the mode is
kept between 0 and 04777.

Jeremy


More information about the mongrel-unicorn mailing list