[Win32utils-devel] FFI and errno on Windows

Daniel Berger djberg96 at gmail.com
Mon Apr 16 15:06:59 UTC 2012


On Sun, Apr 15, 2012 at 10:29 AM, Heesob Park <phasis at gmail.com> wrote:
> Hi,
>
> 2012/4/12 Daniel Berger <djberg96 at gmail.com>
>>
>> I'm a bit confused by error handling for posixy functions on Windows.
>> Consider the following code where I'm intentionally passing a bad
>> template to _mktemp. The docs say it should return EINVAL. My first
>> problem is not knowing exactly what the docs mean when they talk about
>> EINVAL on Windows. My second problem is that _get_errno returns a
>> different value that FFI.errno, and FFI.errno seems to return the same
>> value as GetLastError().
>>
>> require 'ffi'
>> class Windows
>>  extend FFI::Library
>>  ffi_lib FFI::Library::LIBC
>>
>>  attach_function :_mktemp, [:pointer], :string
>>  attach_function :_get_errno, [:pointer], :int
>>
>>  ffi_lib :kernel32
>>
>>  attach_function :GetLastError, [], :int
>>
>>  def self.temp(template)
>>    result = _mktemp(template)
>>
>>    err = get_err_num # 22
>>    #err = FFI.errno # 158
>>    #err = GetLastError() # 158
>>
>>    if result.nil?
>>      raise SystemCallError, err, '_mktemp'
>>    end
>>
>>    result
>>  end
>>
>>  def self.get_err_num
>>    ptr = FFI::MemoryPointer.new(:int)
>>
>>    if _get_errno(ptr) != 0
>>      raise SystemCallError, FFI.errno, '_get_errno'
>>    end
>>
>>    ptr.read_int
>>  end
>> end
>>
>> Windows.temp('xx')
>>
>> Any insight on the subject of GetLastError vs _get_errno would be
>> greatly appreciated. My google skills seem to be failing.
>>
>
> As you know, _mktemp is a function of C Runtime Library and provides
> compatibility with mktemp of Linux.
> According to the Linux manual page
> (http://www.kernel.org/doc/man-pages/online/pages/man3/mktemp.3.html):
>
>  EINVAL means that the last six characters of template were not XXXXXX.
>
>
> FFI.errno is same to GetLastError() on Windows by the following lines of
> LastError.c
>
> void
> rbffi_save_errno(void)
> {
>     int error = 0;
>
> #ifdef _WIN32
>     error = GetLastError();
> #else
>     error = errno;
> #endif
>
>     thread_data_get()->td_errno = error;
> }
>
> I think errno and GetLastError must be separated Windows.
>
> The doc of mktemp mentioned only errno value. Thus GetLastError() value is
> undetermined in this case.

I didn't quite understand you. Do you mean the current code for
FFI.errno is wrong? Should it be replaced with _get_errno?

Or is it simply up to library authors to know which one to use?

Regards,

Dan


More information about the win32utils-devel mailing list