Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: jruby/jruby
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 0ca3184e2f4e
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: f8da225571eb
Choose a head ref
  • 2 commits
  • 3 files changed
  • 1 contributor

Commits on Sep 20, 2016

  1. Copy the full SHA
    f5ad9e4 View commit details
  2. Copy the full SHA
    f8da225 View commit details
Showing with 77 additions and 0 deletions.
  1. +6 −0 core/src/main/java/org/jruby/RubyFile.java
  2. +3 −0 core/src/main/java/org/jruby/platform/Platform.java
  3. +68 −0 core/src/main/ruby/jruby/kernel/file.rb
6 changes: 6 additions & 0 deletions core/src/main/java/org/jruby/RubyFile.java
Original file line number Diff line number Diff line change
@@ -298,6 +298,12 @@ protected IRubyObject rbIoClose(Ruby runtime) {

@JRubyMethod(required = 1)
public IRubyObject flock(ThreadContext context, IRubyObject operation) {

// Solaris uses a ruby-ffi version defined in jruby/kernel/file.rb, so re-dispatch
if (org.jruby.platform.Platform.IS_SOLARIS) {
return callMethod(context, "flock", operation);
}

Ruby runtime = context.runtime;
OpenFile fptr;
// int[] op = {0,0};
3 changes: 3 additions & 0 deletions core/src/main/java/org/jruby/platform/Platform.java
Original file line number Diff line number Diff line change
@@ -82,6 +82,9 @@ private static String initOperatingSystem() {
if (osname.startsWith("windows")) {
return WINDOWS;
}
if (osname.startsWith("sunos")) {
return SOLARIS;
}
return osname;
}
private static String initArchitecture() {
68 changes: 68 additions & 0 deletions core/src/main/ruby/jruby/kernel/file.rb
Original file line number Diff line number Diff line change
@@ -172,3 +172,71 @@ def wincode
end
end
end

# flock support for Solaris
if org.jruby.platform.Platform::IS_SOLARIS
begin
require 'ffi'
rescue LoadError
# Gracefully bail if FFI is not available
end

if defined?(::FFI)

require 'ffi/platform/x86_64-solaris/fcntl'
module Fcntl
extend FFI::Library
ffi_lib 'c'
attach_function :fcntl, [:short, :short, :varargs], :int
class Flock < FFI::Struct
self.size = 44
layout :l_type, :short, 0,
:l_whence, :short, 2,
:l_start, :off_t, 4,
:l_len, :off_t, 12,
:l_sysid, :int, 20,
:l_pid, :int, 24,
:l_pad, :int, 28
end
end

class File
# Adapted from MRI's missing/flock.c
def flock(operation)
type = case (operation & ~LOCK_NB)
when LOCK_SH
Fcntl::F_RDLCK
when LOCK_EX
Fcntl::F_WRLCK
when LOCK_UN
Fcntl::F_UNLCK
else
raise Errno::EINVAL
end

flock = Fcntl::Flock.new
flock[:l_type] = type
flock[:l_whence] = File::SEEK_SET
flock[:l_start] = flock[:l_len] = 0

while Fcntl.fcntl(fileno, (operation & LOCK_NB) != 0 ? Fcntl::F_SETLK : Fcntl::F_SETLKW, :pointer, flock) != 0
errno = FFI.errno
case errno
when Errno::EAGAIN::Errno, Errno::EWOULDBLOCK::Errno, Errno::EACCES::Errno
return false if operation & LOCK_NB != 0

sleep 0.1
next
when Errno::EINTR::Errno
# try again
next
else
raise SystemCallError.new('fcntl', FFI.errno)
end
end

return 0
end
end
end
end