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. Regards, Dan
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. Regards, Park Heesob -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://rubyforge.org/pipermail/win32utils-devel/attachments/20120415/6b0e51ac/attachment.html>
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
Hi, 2012/4/17 Daniel Berger <djberg96 at gmail.com>> 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? > > >I think FFI.errno should be errno regardless Linux or Windows and provide another method for GetLastError() something like FFI.get_last_error. Regards, Park Heesob -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://rubyforge.org/pipermail/win32utils-devel/attachments/20120417/aafeb96d/attachment.html>