From djberg96 at gmail.com Sat Apr 12 10:22:59 2008 From: djberg96 at gmail.com (Daniel Berger) Date: Sat, 12 Apr 2008 08:22:59 -0600 Subject: [Win32utils-devel] file-temp failure Message-ID: <4800C5C3.9020604@gmail.com> Hi all, Anyone know why this code would work with VC++ 6, but fail with VC++ 8? Attached is the source. The sample code I tried is: require 'file/temp' fh = FileTemp.new fh.puts "hello" fh.close But it chokes with an Errno::EBADF error in the call to FileTemp.new. I tried removing the call to tmpfile_s() and just using tmpfile(), but that didn't seem to matter. Thanks, Dan -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: test.rb Url: http://rubyforge.org/pipermail/win32utils-devel/attachments/20080412/c0e1e4f3/attachment.pl -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: extconf.rb Url: http://rubyforge.org/pipermail/win32utils-devel/attachments/20080412/c0e1e4f3/attachment-0001.pl -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: temp.c Url: http://rubyforge.org/pipermail/win32utils-devel/attachments/20080412/c0e1e4f3/attachment.c -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: temp.h Url: http://rubyforge.org/pipermail/win32utils-devel/attachments/20080412/c0e1e4f3/attachment.h From djberg96 at gmail.com Sat Apr 12 10:42:59 2008 From: djberg96 at gmail.com (Daniel Berger) Date: Sat, 12 Apr 2008 08:42:59 -0600 Subject: [Win32utils-devel] file-temp failure In-Reply-To: <4800C5C3.9020604@gmail.com> References: <4800C5C3.9020604@gmail.com> Message-ID: <6037b70c0804120742n1de9d96fwd9a08265f7a536f1@mail.gmail.com> It's actually "wb+", but that doesn't help. On Sat, Apr 12, 2008 at 8:22 AM, Daniel Berger wrote: > Hi all, > > Anyone know why this code would work with VC++ 6, but fail with VC++ 8? > Attached is the source. > > The sample code I tried is: > > require 'file/temp' > fh = FileTemp.new > fh.puts "hello" > fh.close > > But it chokes with an Errno::EBADF error in the call to FileTemp.new. > > I tried removing the call to tmpfile_s() and just using tmpfile(), but that > didn't seem to matter. > > Thanks, > > Dan > > > $:.unshift Dir.pwd > > require 'temp' > > fh = FileTemp.new > fh.puts "hello" > fh.close > > require 'mkmf' > dir_config('tmpfile') > > have_func('tmpfile_s') > have_func('_sopen_s') > > unless have_func('tmpfile') > raise 'This library is not supported on your platform. Aborting' > end > > have_func('mkstemp') > > create_makefile('file/temp') > > #include > #include > > #ifdef HAVE__SOPEN_S > #include > #endif > > #ifndef HAVE_MKSTEMP > #include > #include > #endif > > #ifndef P_tmpdir > #define P_tmpdir "/tmp" > #endif > > #define VERSION "0.1.3" > > VALUE cFileTemp; > > /* call-seq: > * FileTemp.new(delete = true, template = 'rb_file_temp_XXXXXX') => file > * > * Creates a new, anonymous temporary file in your FileTemp::TMPDIR > directory, > * or /tmp if that cannot be accessed. If your $TMPDIR environment variable > is > * set, it will be used instead. If $TMPDIR is not writable by the process, > it > * will resort back to FileTemp::TMPDIR or /tmp. > * > * If the +delete+ option is set to true (the default) then the temporary > file > * will be deleted automatically as soon as all references to it are > closed. > * Otherwise, the file will live on in your $TMPDIR. > * > * If the +delete+ option is set to false, then the file is *not* deleted. > In > * addition, you can supply a string +template+ that the system replaces > with > * a unique filename. This template should end with 3 to 6 'X' characters. > * The default template is 'rb_file_temp_XXXXXX'. In this case the > temporary > * file lives in the directory where it was created. > * > * The +template+ argument is ignored if the +delete+ argument is true. > */ > static VALUE tempfile_init(int argc, VALUE* argv, VALUE self){ > VALUE v_args[2]; > VALUE v_delete; > VALUE v_template; > > rb_scan_args(argc, argv, "02", &v_delete, &v_template); > > if(NIL_P(v_delete)) > v_delete = Qtrue; > > if(RTEST(v_delete)){ > /* > #ifdef HAVE_TMPFILE_S > FILE* fptr; > > if(tmpfile_s(&fptr)) > rb_sys_fail("tmpfile_s()"); > #else > */ > FILE* fptr = tmpfile(); > if(!fptr) > rb_sys_fail("tmpfile()"); > //#endif > v_args[0] = INT2FIX(fileno(fptr)); > } > else{ > int fd; > > if(NIL_P(v_template)) > v_template = rb_str_new2("rb_file_temp_XXXXXX"); > > fd = mkstemp(StringValuePtr(v_template)); > > if(fd < 0) > rb_sys_fail("mkstemp()"); > > v_args[0] = INT2FIX(fd); > } > > // This bit of explicitness is necessary for MS Windows > v_args[1] = rb_str_new2("wb"); > > return rb_call_super(2, v_args); > } > > /* > * Generates a unique file name, prefixed with the value of > FileTemp::TMPDIR. > * Note that a file is not actually generated on the filesystem. > */ > static VALUE tempfile_tmpnam(VALUE klass){ > char buf[L_tmpnam]; > return rb_str_new2(tmpnam(buf)); > } > > void Init_temp(){ > > /* The FileTemp class creates managed temporary files. Unlike Ruby's > * Tempfile class from this standard library, this is a subclass of File. > * In addition, the temporary file is automatically deleted when all > * references to it are closed (instead of waiting until the Ruby process > * is complete). > */ > cFileTemp = rb_define_class("FileTemp", rb_cFile); > > /* Instance Methods */ > rb_define_method(cFileTemp, "initialize", tempfile_init, -1); > > /* Singleton Methods */ > rb_define_singleton_method(cFileTemp, "temp_name", tempfile_tmpnam, 0); > > /* Constants */ > > /* ENV['P_tmpdir']: Your system's tmpdir */ > rb_define_const(cFileTemp, "TMPDIR", rb_str_new2(P_tmpdir)); > > /* 0.1.3: The version of this library */ > rb_define_const(cFileTemp, "VERSION", rb_str_new2(VERSION)); > } > > /* This is a custom definition of the mkstemp() function for those > * platforms that don't support it natively. > */ > int mkstemp(char* mtemplate){ > int fd; > > #ifdef HAVE__SOPEN_S > if(_sopen_s( > &fd, > mtemplate, > O_RDWR | O_BINARY | O_CREAT | O_EXCL | _O_SHORT_LIVED, > _SH_DENYNO, > _S_IREAD |_S_IWRITE > )) > rb_sys_fail("_sopen_s()"); > #else > fd = _open( > mtemplate, > O_RDWR | O_BINARY | O_CREAT | O_EXCL | _O_SHORT_LIVED, > _S_IREAD |_S_IWRITE > ); > > if(fd < 0) > rb_sys_fail("open()"); > #endif > return fd; > } > From djberg96 at gmail.com Sat Apr 12 10:49:42 2008 From: djberg96 at gmail.com (Daniel Berger) Date: Sat, 12 Apr 2008 08:49:42 -0600 Subject: [Win32utils-devel] file-temp failure In-Reply-To: <6037b70c0804120742n1de9d96fwd9a08265f7a536f1@mail.gmail.com> References: <4800C5C3.9020604@gmail.com> <6037b70c0804120742n1de9d96fwd9a08265f7a536f1@mail.gmail.com> Message-ID: <6037b70c0804120749o207f675ardbeca36f7b339de7@mail.gmail.com> Upon further review, it seems I had a botched Ruby build. It works with p114 anyway. Sorry for the noise. Dan On Sat, Apr 12, 2008 at 8:42 AM, Daniel Berger wrote: > It's actually "wb+", but that doesn't help. > > > > On Sat, Apr 12, 2008 at 8:22 AM, Daniel Berger wrote: > > Hi all, > > > > Anyone know why this code would work with VC++ 6, but fail with VC++ 8? > > Attached is the source. > > > > The sample code I tried is: > > > > require 'file/temp' > > fh = FileTemp.new > > fh.puts "hello" > > fh.close > > > > But it chokes with an Errno::EBADF error in the call to FileTemp.new. > > > > I tried removing the call to tmpfile_s() and just using tmpfile(), but that > > didn't seem to matter. > > > > Thanks, > > > > Dan > > > > > > $:.unshift Dir.pwd > > > > require 'temp' > > > > > fh = FileTemp.new > > fh.puts "hello" > > fh.close > > > > require 'mkmf' > > dir_config('tmpfile') > > > > have_func('tmpfile_s') > > have_func('_sopen_s') > > > > unless have_func('tmpfile') > > raise 'This library is not supported on your platform. Aborting' > > end > > > > have_func('mkstemp') > > > > create_makefile('file/temp') > > > > #include > > #include > > > > #ifdef HAVE__SOPEN_S > > #include > > #endif > > > > #ifndef HAVE_MKSTEMP > > #include > > #include > > #endif > > > > #ifndef P_tmpdir > > #define P_tmpdir "/tmp" > > #endif > > > > #define VERSION "0.1.3" > > > > VALUE cFileTemp; > > > > /* call-seq: > > * FileTemp.new(delete = true, template = 'rb_file_temp_XXXXXX') => file > > * > > * Creates a new, anonymous temporary file in your FileTemp::TMPDIR > > directory, > > * or /tmp if that cannot be accessed. If your $TMPDIR environment variable > > is > > * set, it will be used instead. If $TMPDIR is not writable by the process, > > it > > * will resort back to FileTemp::TMPDIR or /tmp. > > * > > * If the +delete+ option is set to true (the default) then the temporary > > file > > * will be deleted automatically as soon as all references to it are > > closed. > > * Otherwise, the file will live on in your $TMPDIR. > > * > > * If the +delete+ option is set to false, then the file is *not* deleted. > > In > > * addition, you can supply a string +template+ that the system replaces > > with > > * a unique filename. This template should end with 3 to 6 'X' characters. > > * The default template is 'rb_file_temp_XXXXXX'. In this case the > > temporary > > * file lives in the directory where it was created. > > * > > * The +template+ argument is ignored if the +delete+ argument is true. > > */ > > static VALUE tempfile_init(int argc, VALUE* argv, VALUE self){ > > VALUE v_args[2]; > > VALUE v_delete; > > VALUE v_template; > > > > rb_scan_args(argc, argv, "02", &v_delete, &v_template); > > > > if(NIL_P(v_delete)) > > v_delete = Qtrue; > > > > if(RTEST(v_delete)){ > > /* > > #ifdef HAVE_TMPFILE_S > > FILE* fptr; > > > > if(tmpfile_s(&fptr)) > > rb_sys_fail("tmpfile_s()"); > > #else > > */ > > FILE* fptr = tmpfile(); > > if(!fptr) > > rb_sys_fail("tmpfile()"); > > //#endif > > v_args[0] = INT2FIX(fileno(fptr)); > > } > > else{ > > int fd; > > > > if(NIL_P(v_template)) > > v_template = rb_str_new2("rb_file_temp_XXXXXX"); > > > > fd = mkstemp(StringValuePtr(v_template)); > > > > if(fd < 0) > > rb_sys_fail("mkstemp()"); > > > > v_args[0] = INT2FIX(fd); > > } > > > > // This bit of explicitness is necessary for MS Windows > > v_args[1] = rb_str_new2("wb"); > > > > return rb_call_super(2, v_args); > > } > > > > /* > > * Generates a unique file name, prefixed with the value of > > FileTemp::TMPDIR. > > * Note that a file is not actually generated on the filesystem. > > */ > > static VALUE tempfile_tmpnam(VALUE klass){ > > char buf[L_tmpnam]; > > return rb_str_new2(tmpnam(buf)); > > } > > > > void Init_temp(){ > > > > /* The FileTemp class creates managed temporary files. Unlike Ruby's > > * Tempfile class from this standard library, this is a subclass of File. > > * In addition, the temporary file is automatically deleted when all > > * references to it are closed (instead of waiting until the Ruby process > > * is complete). > > */ > > cFileTemp = rb_define_class("FileTemp", rb_cFile); > > > > /* Instance Methods */ > > rb_define_method(cFileTemp, "initialize", tempfile_init, -1); > > > > /* Singleton Methods */ > > rb_define_singleton_method(cFileTemp, "temp_name", tempfile_tmpnam, 0); > > > > /* Constants */ > > > > /* ENV['P_tmpdir']: Your system's tmpdir */ > > rb_define_const(cFileTemp, "TMPDIR", rb_str_new2(P_tmpdir)); > > > > /* 0.1.3: The version of this library */ > > rb_define_const(cFileTemp, "VERSION", rb_str_new2(VERSION)); > > } > > > > /* This is a custom definition of the mkstemp() function for those > > * platforms that don't support it natively. > > */ > > int mkstemp(char* mtemplate){ > > int fd; > > > > #ifdef HAVE__SOPEN_S > > if(_sopen_s( > > &fd, > > mtemplate, > > O_RDWR | O_BINARY | O_CREAT | O_EXCL | _O_SHORT_LIVED, > > _SH_DENYNO, > > _S_IREAD |_S_IWRITE > > )) > > rb_sys_fail("_sopen_s()"); > > #else > > fd = _open( > > mtemplate, > > O_RDWR | O_BINARY | O_CREAT | O_EXCL | _O_SHORT_LIVED, > > _S_IREAD |_S_IWRITE > > ); > > > > if(fd < 0) > > rb_sys_fail("open()"); > > #endif > > return fd; > > } > > > From djberg96 at gmail.com Wed Apr 16 00:16:09 2008 From: djberg96 at gmail.com (Daniel Berger) Date: Tue, 15 Apr 2008 22:16:09 -0600 Subject: [Win32utils-devel] Rethinking stat Message-ID: <48057D89.6030901@gmail.com> Here's an interesting link on stat'ing a file on Windows: http://www.mail-archive.com/factor-talk at lists.sourceforge.net/msg00816.html Regards, Dan From djberg96 at gmail.com Thu Apr 17 19:18:38 2008 From: djberg96 at gmail.com (Daniel Berger) Date: Thu, 17 Apr 2008 17:18:38 -0600 Subject: [Win32utils-devel] Process.create patch - please review Message-ID: <4807DACE.9060002@gmail.com> Hi all, There's a patch on the tracker I'd like some feedback on. It's for Process.create to handle command_line and app_name separately. In practice this only seems to affect how command line parameters are seen by something like GetCommandLine(). Please take a look at the command-line.patch at: http://rubyforge.org/tracker/index.php?func=detail&aid=18280&group_id=85&atid=411 And let me know if you think it's reasonable. Thanks, Dan From gthiesfeld at gmail.com Thu Apr 17 19:45:11 2008 From: gthiesfeld at gmail.com (Gordon Thiesfeld) Date: Thu, 17 Apr 2008 18:45:11 -0500 Subject: [Win32utils-devel] win32-api (1.0.5) on Ruby 1.8.6 Mingw Message-ID: When trying to compile the win32-api gem on ruby 1.8.6 (2008-03-03 patchlevel 114) [i386-mingw32], I get the following error: gcc -shared -s -o api.so api.o -L"." -L"C:/ruby/ruby_mingw/lib" -L. -Wl,--enable-auto-image-base,--enable-auto-import,--export-all -lmsvcrt-ruby18 -lws2_32 api.o: In function `api_init': C:/ruby/ruby_mingw/lib/ruby/gems/1.8/gems/win32-api-1.0.5/ext/win32/api.c:201: undefined reference to `_tcscmp' collect2: ld returned 1 exit status make: *** [api.so] Error 1 Here's the relevant code from api.c (lines 200 - 204) /* The order of 'A' and 'W' is reversed if $KCODE is set to 'UTF8'. */ if(!_tcscmp(rb_get_kcode(), "UTF8")){ first = "W"; second = "A"; } Any ideas? Thanks, Gordon From djberg96 at gmail.com Thu Apr 17 20:05:20 2008 From: djberg96 at gmail.com (Daniel Berger) Date: Thu, 17 Apr 2008 18:05:20 -0600 Subject: [Win32utils-devel] win32-api (1.0.5) on Ruby 1.8.6 Mingw In-Reply-To: References: Message-ID: <4807E5C0.3080107@gmail.com> Gordon Thiesfeld wrote: > When trying to compile the win32-api gem on ruby 1.8.6 (2008-03-03 > patchlevel 114) [i386-mingw32], I get the following error: > > gcc -shared -s -o api.so api.o -L"." -L"C:/ruby/ruby_mingw/lib" -L. > -Wl,--enable-auto-image-base,--enable-auto-import,--export-all > -lmsvcrt-ruby18 -lws2_32 > api.o: In function `api_init': > C:/ruby/ruby_mingw/lib/ruby/gems/1.8/gems/win32-api-1.0.5/ext/win32/api.c:201: > undefined reference to `_tcscmp' > collect2: ld returned 1 exit status > make: *** [api.so] Error 1 > > Here's the relevant code from api.c (lines 200 - 204) > > /* The order of 'A' and 'W' is reversed if $KCODE is set to 'UTF8'. */ > if(!_tcscmp(rb_get_kcode(), "UTF8")){ > first = "W"; > second = "A"; > } > > Any ideas? Yeah, I got a little overzealous with the TCHAR stuff there. Just change "_tcscmp" to "strcmp" and rebuild. I think I've already made this change in CVS, since we know $KCODE is always ASCII. Regards, Dan From djberg96 at gmail.com Fri Apr 18 07:16:59 2008 From: djberg96 at gmail.com (Daniel Berger) Date: Fri, 18 Apr 2008 05:16:59 -0600 Subject: [Win32utils-devel] win32-api segfault Message-ID: <4808832B.1030103@gmail.com> It looks like win32-api, both 1.0.5 and the latest in CVS, are segfaulting when I build with VC++ 8 or later. Both work fine with VC++ 6, though. Thinking it might be strncpy_s, I removed that, but it didn't help. I installed a fresh Ruby built with VC++ 8 as well, but that didn't help either. Loaded suite C:/rubyvc8/lib/ruby/site_ruby/1.8/rake/rake_test_loader Started ............/test/tc_win32_api_callback.rb:45: [BUG] Segmentation fault ruby 1.8.6 (2008-03-03) [i386-mswin32_80] Any ideas? Thanks, Dan From phasis at gmail.com Fri Apr 18 08:39:59 2008 From: phasis at gmail.com (Heesob Park) Date: Fri, 18 Apr 2008 21:39:59 +0900 Subject: [Win32utils-devel] win32-api segfault In-Reply-To: <4808832B.1030103@gmail.com> References: <4808832B.1030103@gmail.com> Message-ID: Hi, 2008/4/18, Daniel Berger : > It looks like win32-api, both 1.0.5 and the latest in CVS, are > segfaulting when I build with VC++ 8 or later. Both work fine with VC++ > 6, though. > > Thinking it might be strncpy_s, I removed that, but it didn't help. I > installed a fresh Ruby built with VC++ 8 as well, but that didn't help > either. > > Loaded suite C:/rubyvc8/lib/ruby/site_ruby/1.8/rake/rake_test_loader > Started > ............/test/tc_win32_api_callback.rb:45: [BUG] Segmentation fault > ruby 1.8.6 (2008-03-03) [i386-mswin32_80] > > Any ideas? I have no idea. In my test with ruby 1.8.6 (2007-09-24 patchlevel 111) [i386-mswin32_90] the latest in CVS works fine. BTW, why not use Visual C++ 2008 Express Edition(VC++ 9.0) ? It is free also. http://www.microsoft.com/express/vc/ Regards, Park Heesob -------------- next part -------------- An HTML attachment was scrubbed... URL: http://rubyforge.org/pipermail/win32utils-devel/attachments/20080418/764dfcb1/attachment.html From gthiesfeld at gmail.com Fri Apr 18 10:46:25 2008 From: gthiesfeld at gmail.com (Gordon Thiesfeld) Date: Fri, 18 Apr 2008 09:46:25 -0500 Subject: [Win32utils-devel] win32-api (1.0.5) on Ruby 1.8.6 Mingw In-Reply-To: <4807E5C0.3080107@gmail.com> References: <4807E5C0.3080107@gmail.com> Message-ID: On Thu, Apr 17, 2008 at 7:05 PM, Daniel Berger wrote: > Yeah, I got a little overzealous with the TCHAR stuff there. Just change > "_tcscmp" to "strcmp" and rebuild. I think I've already made this change > in CVS, since we know $KCODE is always ASCII. That did the trick. Thanks. From djberg96 at gmail.com Sat Apr 19 13:42:49 2008 From: djberg96 at gmail.com (Daniel Berger) Date: Sat, 19 Apr 2008 11:42:49 -0600 Subject: [Win32utils-devel] [Fwd: win32-service-0.6.1 using a Rails Model] Message-ID: <480A2F19.5040607@gmail.com> Any ideas here? Line 911-921 indicates a failure in OpenService: handle_scs = OpenService( handle_scm, service, SERVICE_QUERY_STATUS ) if handle_scs == 0 error = get_last_error CloseServiceHandle(handle_scm) raise Error, error end Something to do with WEBrick perhaps? Regards, Dan -------------- next part -------------- An embedded message was scrubbed... From: david Subject: win32-service-0.6.1 using a Rails Model Date: Sun, 20 Apr 2008 01:30:07 +0900 Size: 10165 Url: http://rubyforge.org/pipermail/win32utils-devel/attachments/20080419/bd238074/attachment-0001.eml From noreply at rubyforge.org Sun Apr 20 16:05:47 2008 From: noreply at rubyforge.org (noreply at rubyforge.org) Date: Sun, 20 Apr 2008 16:05:47 -0400 (EDT) Subject: [Win32utils-devel] [ win32utils-Feature Requests-19668 ] play 2 tones ones on sometime Message-ID: <20080420200547.1501618585DE@rubyforge.org> Feature Requests item #19668, was opened at 2008-04-20 20:05 You can respond by visiting: http://rubyforge.org/tracker/?func=detail&atid=414&aid=19668&group_id=85 Category: win32-sound Group: Code Status: Open Resolution: None Priority: 3 Submitted By: Christof Spies (wingfire) Assigned to: Nobody (None) Summary: play 2 tones ones on sometime Initial Comment: Hi, i need to play a dualtone. Instead of playing behind Sound.beep(100, 1000) Sound.beep(200, 1000) Play both frequences on the same time Sound.beep([100, 200], 1000) Christof ---------------------------------------------------------------------- You can respond by visiting: http://rubyforge.org/tracker/?func=detail&atid=414&aid=19668&group_id=85 From djberg96 at gmail.com Mon Apr 21 23:16:21 2008 From: djberg96 at gmail.com (Daniel Berger) Date: Mon, 21 Apr 2008 21:16:21 -0600 Subject: [Win32utils-devel] Global substitution with win32-mmap Message-ID: <480D5885.9090600@gmail.com> Hi all, I'm trying to figure out how to do an inline file substitute/replace using the address. In short, I'm trying to replace "assert_raises" with "assert_raise" throughout a file. I tried this: require 'win32/mmap' require 'windows/msvcrt/string' require 'windows/msvcrt/buffer' include Win32 include Windows::MSVCRT::String include Windows::MSVCRT::Buffer StrlenL = API.new('strlen', 'L', 'L', 'msvcrt') MMap.new(:file => 'test.rb') do |addr| old_str = 'assert_raises' old_len = old_str.length new_str = 'assert_raise' new_len = new_str.length ptr1 = ptr2 = ptr3 = [strstr(addr,old_str)].pack('p*').unpack('l')[0] while ptr1 && ptr1 != 0 ptr2 += new_len ptr3 += old_len memmove(ptr2, ptr3, 1 + StrlenL.call(ptr3)) memcpy(ptr1, new_str, new_len) ptr1 = ptr2 = ptr3 = [strstr(ptr2, old_str)].pack('p*').unpack('l')[0] end end I based it off of this thread: http://tinyurl.com/5qvbnw But, that doesn't seem to be working. Any ideas? Thanks, Dan # test.rb class Foo < Test::Unit::TestCase def setup @foo = Foo.new end def test_bar_expected_errors assert_raises(ArgumentError){ 1 == 2 } assert_raise(StandardError){ 2 == 1 } end def test_foo_expected_errors assert_raises(ArgumentError){ 1 == 2 } assert_raise(StandardError){ 2 == 1 } end def teardown @foo = nil end en From phasis at gmail.com Tue Apr 22 01:51:44 2008 From: phasis at gmail.com (Heesob Park) Date: Tue, 22 Apr 2008 14:51:44 +0900 Subject: [Win32utils-devel] Global substitution with win32-mmap In-Reply-To: <480D5885.9090600@gmail.com> References: <480D5885.9090600@gmail.com> Message-ID: Hi, 2008/4/22, Daniel Berger : > > Hi all, > > I'm trying to figure out how to do an inline file substitute/replace > using the address. In short, I'm trying to replace "assert_raises" with > "assert_raise" throughout a file. > > I tried this: > > require 'win32/mmap' > require 'windows/msvcrt/string' > require 'windows/msvcrt/buffer' > include Win32 > include Windows::MSVCRT::String > include Windows::MSVCRT::Buffer > > StrlenL = API.new('strlen', 'L', 'L', 'msvcrt') > > MMap.new(:file => 'test.rb') do |addr| > old_str = 'assert_raises' > old_len = old_str.length > new_str = 'assert_raise' > new_len = new_str.length > > ptr1 = ptr2 = ptr3 = [strstr(addr,old_str)].pack('p*').unpack('l')[0] > > while ptr1 && ptr1 != 0 > ptr2 += new_len > ptr3 += old_len > memmove(ptr2, ptr3, 1 + StrlenL.call(ptr3)) > memcpy(ptr1, new_str, new_len) > ptr1 = ptr2 = ptr3 = [strstr(ptr2, > old_str)].pack('p*').unpack('l')[0] > end > end > > I based it off of this thread: > > http://tinyurl.com/5qvbnw > > But, that doesn't seem to be working. Any ideas? You must define strstr like this: Strstr = API.new('strstr', 'LP', 'L', 'msvcrt') and try this: StrlenL = API.new('strlen', 'L', 'L', 'msvcrt') MMap.new(:file => 'test.rb') do |addr| old_str = 'assert_raises' old_len = old_str.length new_str = 'assert_raise' new_len = new_str.length ptr1 = ptr2 = ptr3 = strstr(addr,old_str) while ptr1 && ptr1 != 0 ptr2 += new_len ptr3 += old_len memmove(ptr2, ptr3, 1 + StrlenL.call(ptr3)) memcpy(ptr1, new_str, new_len) ptr1 = ptr2 = ptr3 = strstr(ptr2,old_str) end end Regads, Park Heesob -------------- next part -------------- An HTML attachment was scrubbed... URL: http://rubyforge.org/pipermail/win32utils-devel/attachments/20080422/f9b876bb/attachment.html From Daniel.Berger at qwest.com Thu Apr 24 10:13:37 2008 From: Daniel.Berger at qwest.com (Berger, Daniel) Date: Thu, 24 Apr 2008 09:13:37 -0500 Subject: [Win32utils-devel] A generalized struct implementation for windows-api Message-ID: <7524A45A1A5B264FA4809E2156496CFB023D31F4@ITOMAE2KM01.AD.QINTRA.COM> Hi, After yet another win32-process bug, I've decided that we need some form of generalized struct handling for use with the windows-api library instead of packing and unpacking data structures manually. We currently do stuff like this: proc_info = 0.chr * 16 # sizeof(PROCESS_INFORMATION) Process.create(... proc_info ...) CloseHandle(proc_info[0,4]) I would like a way to generalize the creation of these structures. Something like this: require 'win32/struct' Win32::Struct.new( 'PROCESS_INFORMATION', :hProcess => HANDLE, :hThread => HANDLE, :dwProcessId => DWORD, :dwThreadId => DWORD ) And, with that in place, we could then write: proc_info = PROCESS_INFORMATION.new Process.create(... proc_info ...) CloseHandle(proc_info.hProcess) The struct would automatically handle the packing/unpacking behind the scenes based on the data type that was declared in the constructor. It's easier to read and easier to maintain, IMO. And, we could predefine a bunch of the most common structures in advance so that users wouldn't have to do this themselves. They would be immediately available. This could probably be an addon to the windows-api library already out there. What do you think? Thanks, Dan This communication is the property of Qwest and may contain confidential or privileged information. Unauthorized use of this communication is strictly prohibited and may be unlawful. If you have received this communication in error, please immediately notify the sender by reply e-mail and destroy all copies of the communication and any attachments. From Daniel.Berger at qwest.com Fri Apr 25 11:30:30 2008 From: Daniel.Berger at qwest.com (Berger, Daniel) Date: Fri, 25 Apr 2008 10:30:30 -0500 Subject: [Win32utils-devel] win32-mmap test failures Message-ID: <7524A45A1A5B264FA4809E2156496CFB023D31FF@ITOMAE2KM01.AD.QINTRA.COM> Hi all, This is odd. It looks to me like we have all 4 variations of memcpy set in Windows::MSVCRT::Buffer but somehow this one creeps up. I actually noticed it in a few cases with that earlier mmap sub/replace example, but I wasn't sure what was happening. Note that windows-api 0.2.3 and windows-pr-0.8.3 are the latest versions in CVS, but this happens with windows-api-0.2.2 and windows-pr-0.8.2 as well. Any ideas? Thanks, Dan C:\Documents and Settings\djberge\workspace\win32-mmap>rake test (in C:/Documents and Settings/djberge/workspace/win32-mmap) c:/ruby/bin/ruby -w -Ilib;test "c:/ruby/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake/rake_test_loader.rb" "test/ tc_mmap.rb" Loaded suite c:/ruby/lib/ruby/gems/1.8/gems/rake-0.8.1/lib/rake/rake_test_loader Started ....FFFF....... Finished in 0.031 seconds. 1) Failure: test_dynamic_array_value(TC_Mmap) [./test/tc_mmap.rb:42]: Exception raised: Class: Message: <"can't convert String into Integer"> ---Backtrace--- c:/ruby/lib/ruby/gems/1.8/gems/windows-api-0.2.3/lib/windows/api.rb:479: in `call' c:/ruby/lib/ruby/gems/1.8/gems/windows-api-0.2.3/lib/windows/api.rb:479: in `call' c:/ruby/lib/ruby/gems/1.8/gems/windows-pr-0.8.3/lib/windows/msvcrt/buffe r.rb:34:in `memcpy' ./lib/win32/mmap.rb:321:in `method_missing' ./test/tc_mmap.rb:42:in `test_dynamic_array_value' ./test/tc_mmap.rb:42:in `test_dynamic_array_value' --------------- 2) Failure: test_dynamic_hash_value(TC_Mmap) [./test/tc_mmap.rb:35]: Exception raised: Class: Message: <"can't convert String into Integer"> ---Backtrace--- c:/ruby/lib/ruby/gems/1.8/gems/windows-api-0.2.3/lib/windows/api.rb:479: in `call' c:/ruby/lib/ruby/gems/1.8/gems/windows-api-0.2.3/lib/windows/api.rb:479: in `call' c:/ruby/lib/ruby/gems/1.8/gems/windows-pr-0.8.3/lib/windows/msvcrt/buffe r.rb:34:in `memcpy' ./lib/win32/mmap.rb:321:in `method_missing' ./test/tc_mmap.rb:35:in `test_dynamic_hash_value' ./test/tc_mmap.rb:35:in `test_dynamic_hash_value' --------------- 3) Failure: test_dynamic_integer_value(TC_Mmap) [./test/tc_mmap.rb:28]: Exception raised: Class: Message: <"can't convert String into Integer"> ---Backtrace--- c:/ruby/lib/ruby/gems/1.8/gems/windows-api-0.2.3/lib/windows/api.rb:479: in `call' c:/ruby/lib/ruby/gems/1.8/gems/windows-api-0.2.3/lib/windows/api.rb:479: in `call' c:/ruby/lib/ruby/gems/1.8/gems/windows-pr-0.8.3/lib/windows/msvcrt/buffe r.rb:34:in `memcpy' ./lib/win32/mmap.rb:321:in `method_missing' ./test/tc_mmap.rb:28:in `test_dynamic_integer_value' ./test/tc_mmap.rb:28:in `test_dynamic_integer_value' --------------- 4) Failure: test_dynamic_string_value(TC_Mmap) [./test/tc_mmap.rb:21]: Exception raised: Class: Message: <"can't convert String into Integer"> ---Backtrace--- c:/ruby/lib/ruby/gems/1.8/gems/windows-api-0.2.3/lib/windows/api.rb:479: in `call' c:/ruby/lib/ruby/gems/1.8/gems/windows-api-0.2.3/lib/windows/api.rb:479: in `call' c:/ruby/lib/ruby/gems/1.8/gems/windows-pr-0.8.3/lib/windows/msvcrt/buffe r.rb:34:in `memcpy' ./lib/win32/mmap.rb:321:in `method_missing' ./test/tc_mmap.rb:21:in `test_dynamic_string_value' ./test/tc_mmap.rb:21:in `test_dynamic_string_value' --------------- 15 tests, 31 assertions, 4 failures, 0 errors rake aborted! Command failed with status (1): [c:/ruby/bin/ruby -w -Ilib;test "c:/ruby/li...] (See full trace by running task with --trace) This communication is the property of Qwest and may contain confidential or privileged information. Unauthorized use of this communication is strictly prohibited and may be unlawful. If you have received this communication in error, please immediately notify the sender by reply e-mail and destroy all copies of the communication and any attachments. From Daniel.Berger at qwest.com Fri Apr 25 12:05:45 2008 From: Daniel.Berger at qwest.com (Berger, Daniel) Date: Fri, 25 Apr 2008 11:05:45 -0500 Subject: [Win32utils-devel] win32-mmap test failures In-Reply-To: <7524A45A1A5B264FA4809E2156496CFB023D31FF@ITOMAE2KM01.AD.QINTRA.COM> References: <7524A45A1A5B264FA4809E2156496CFB023D31FF@ITOMAE2KM01.AD.QINTRA.COM> Message-ID: <7524A45A1A5B264FA4809E2156496CFB023D3201@ITOMAE2KM01.AD.QINTRA.COM> > -----Original Message----- > From: win32utils-devel-bounces at rubyforge.org > [mailto:win32utils-devel-bounces at rubyforge.org] On Behalf Of > Berger, Daniel > Sent: Friday, April 25, 2008 9:31 AM > To: Development and ideas for win32utils projects > Subject: [Win32utils-devel] win32-mmap test failures > > Hi all, > > This is odd. It looks to me like we have all 4 variations of > memcpy set in Windows::MSVCRT::Buffer but somehow this one > creeps up. I actually noticed it in a few cases with that > earlier mmap sub/replace example, but I wasn't sure what was > happening. This is baffling. Somehow it's failing the src.is_a?(String) check on the marshalled source on line 31 of buffer.rb, even though it definitely _is_ a String. I cannot duplicate this in a standalone script. Ideas? Thanks, Dan This communication is the property of Qwest and may contain confidential or privileged information. Unauthorized use of this communication is strictly prohibited and may be unlawful. If you have received this communication in error, please immediately notify the sender by reply e-mail and destroy all copies of the communication and any attachments. From phasis at gmail.com Fri Apr 25 12:20:20 2008 From: phasis at gmail.com (Heesob Park) Date: Sat, 26 Apr 2008 01:20:20 +0900 Subject: [Win32utils-devel] win32-mmap test failures In-Reply-To: <7524A45A1A5B264FA4809E2156496CFB023D3201@ITOMAE2KM01.AD.QINTRA.COM> References: <7524A45A1A5B264FA4809E2156496CFB023D31FF@ITOMAE2KM01.AD.QINTRA.COM> <7524A45A1A5B264FA4809E2156496CFB023D3201@ITOMAE2KM01.AD.QINTRA.COM> Message-ID: Hi, 2008/4/26, Berger, Daniel : > > > > -----Original Message----- > > From: win32utils-devel-bounces at rubyforge.org > > [mailto:win32utils-devel-bounces at rubyforge.org] On Behalf Of > > Berger, Daniel > > Sent: Friday, April 25, 2008 9:31 AM > > To: Development and ideas for win32utils projects > > Subject: [Win32utils-devel] win32-mmap test failures > > > > Hi all, > > > > This is odd. It looks to me like we have all 4 variations of > > memcpy set in Windows::MSVCRT::Buffer but somehow this one > > creeps up. I actually noticed it in a few cases with that > > earlier mmap sub/replace example, but I wasn't sure what was > > happening. > > > > This is baffling. Somehow it's failing the src.is_a?(String) check on > the marshalled source on line 31 of buffer.rb, even though it definitely > _is_ a String. I cannot duplicate this in a standalone script. > > Ideas? > > Thanks, > > Dan If you modify src.is_a?(String) to src.class.to_s=="String", it will work. But I don't know what it means. Regards, Park Heesob -------------- next part -------------- An HTML attachment was scrubbed... URL: From Daniel.Berger at qwest.com Fri Apr 25 12:36:51 2008 From: Daniel.Berger at qwest.com (Berger, Daniel) Date: Fri, 25 Apr 2008 11:36:51 -0500 Subject: [Win32utils-devel] win32-mmap test failures In-Reply-To: References: <7524A45A1A5B264FA4809E2156496CFB023D31FF@ITOMAE2KM01.AD.QINTRA.COM><7524A45A1A5B264FA4809E2156496CFB023D3201@ITOMAE2KM01.AD.QINTRA.COM> Message-ID: <7524A45A1A5B264FA4809E2156496CFB023D3202@ITOMAE2KM01.AD.QINTRA.COM> Thanks. The only thing I can figure is that it's some sort of name collision with Windows::MSVCRT::String, but I can't see how right off the bat. Dan ________________________________ From: win32utils-devel-bounces at rubyforge.org [mailto:win32utils-devel-bounces at rubyforge.org] On Behalf Of Heesob Park Sent: Friday, April 25, 2008 10:20 AM To: Development and ideas for win32utils projects Subject: Re: [Win32utils-devel] win32-mmap test failures Hi, 2008/4/26, Berger, Daniel : > -----Original Message----- > From: win32utils-devel-bounces at rubyforge.org > [mailto:win32utils-devel-bounces at rubyforge.org] On Behalf Of > Berger, Daniel > Sent: Friday, April 25, 2008 9:31 AM > To: Development and ideas for win32utils projects > Subject: [Win32utils-devel] win32-mmap test failures > > Hi all, > > This is odd. It looks to me like we have all 4 variations of > memcpy set in Windows::MSVCRT::Buffer but somehow this one > creeps up. I actually noticed it in a few cases with that > earlier mmap sub/replace example, but I wasn't sure what was > happening. This is baffling. Somehow it's failing the src.is_a?(String) check on the marshalled source on line 31 of buffer.rb, even though it definitely _is_ a String. I cannot duplicate this in a standalone script. Ideas? Thanks, Dan If you modify src.is_a?(String) to src.class.to_s=="String", it will work. But I don't know what it means. Regards, Park Heesob This communication is the property of Qwest and may contain confidential or privileged information. Unauthorized use of this communication is strictly prohibited and may be unlawful. If you have received this communication in error, please immediately notify the sender by reply e-mail and destroy all copies of the communication and any attachments. -------------- next part -------------- An HTML attachment was scrubbed... URL: From Daniel.Berger at qwest.com Fri Apr 25 13:04:13 2008 From: Daniel.Berger at qwest.com (Berger, Daniel) Date: Fri, 25 Apr 2008 12:04:13 -0500 Subject: [Win32utils-devel] win32-mmap test failures In-Reply-To: <7524A45A1A5B264FA4809E2156496CFB023D3202@ITOMAE2KM01.AD.QINTRA.COM> References: <7524A45A1A5B264FA4809E2156496CFB023D31FF@ITOMAE2KM01.AD.QINTRA.COM><7524A45A1A5B264FA4809E2156496CFB023D3201@ITOMAE2KM01.AD.QINTRA.COM> <7524A45A1A5B264FA4809E2156496CFB023D3202@ITOMAE2KM01.AD.QINTRA.COM> Message-ID: <7524A45A1A5B264FA4809E2156496CFB023D3203@ITOMAE2KM01.AD.QINTRA.COM> Yeah, it's a scope resolution bug of some sort. Using "::String" works. I'll fix that in the next windows-pr release. Dan PS - Sorry for the top posting (Outlook is being a pain) ________________________________ From: win32utils-devel-bounces at rubyforge.org [mailto:win32utils-devel-bounces at rubyforge.org] On Behalf Of Berger, Daniel Sent: Friday, April 25, 2008 10:37 AM To: Development and ideas for win32utils projects Subject: Re: [Win32utils-devel] win32-mmap test failures Thanks. The only thing I can figure is that it's some sort of name collision with Windows::MSVCRT::String, but I can't see how right off the bat. Dan ________________________________ From: win32utils-devel-bounces at rubyforge.org [mailto:win32utils-devel-bounces at rubyforge.org] On Behalf Of Heesob Park Sent: Friday, April 25, 2008 10:20 AM To: Development and ideas for win32utils projects Subject: Re: [Win32utils-devel] win32-mmap test failures Hi, 2008/4/26, Berger, Daniel : > -----Original Message----- > From: win32utils-devel-bounces at rubyforge.org > [mailto:win32utils-devel-bounces at rubyforge.org] On Behalf Of > Berger, Daniel > Sent: Friday, April 25, 2008 9:31 AM > To: Development and ideas for win32utils projects > Subject: [Win32utils-devel] win32-mmap test failures > > Hi all, > > This is odd. It looks to me like we have all 4 variations of > memcpy set in Windows::MSVCRT::Buffer but somehow this one > creeps up. I actually noticed it in a few cases with that > earlier mmap sub/replace example, but I wasn't sure what was > happening. This is baffling. Somehow it's failing the src.is_a?(String) check on the marshalled source on line 31 of buffer.rb, even though it definitely _is_ a String. I cannot duplicate this in a standalone script. Ideas? Thanks, Dan If you modify src.is_a?(String) to src.class.to_s=="String", it will work. But I don't know what it means. Regards, Park Heesob This communication is the property of Qwest and may contain confidential or privileged information. Unauthorized use of this communication is strictly prohibited and may be unlawful. If you have received this communication in error, please immediately notify the sender by reply e-mail and destroy all copies of the communication and any attachments. -------------- next part -------------- An HTML attachment was scrubbed... URL: From phasis at gmail.com Mon Apr 28 06:53:26 2008 From: phasis at gmail.com (Heesob Park) Date: Mon, 28 Apr 2008 19:53:26 +0900 Subject: [Win32utils-devel] rb_w32_select function patch Message-ID: Hi, all As you know, rb_w32_select don't work well with standard input. Here is test code: t = Thread.new { while true puts "printing a line" sleep 2 end } gets t.exit puts "exiting" Following is the first version of patch code of rb_w32_select function in win32.c It is inspired by cygwin select implementation code and adopted some code from it. The basic idea is creating thread for each file descriptor and wait events. What's your thought about it? Regards, Park Heesob /*========================================================================================*/ static HANDLE main_select_event=NULL; static HANDLE *select_thread_list=NULL; static struct { int vk; int val[4]; } keytable[] = { /* N S C A */ {VK_LEFT, {1,1,1,1}}, {VK_RIGHT, {1,1,1,1}}, {VK_UP, {1,1,1,1}}, {VK_DOWN, {1,1,1,1}}, {VK_PRIOR, {1,1,1,1}}, {VK_NEXT, {1,1,1,1}}, {VK_HOME, {1,1,1,1}}, {VK_END, {1,1,1,1}}, {VK_INSERT, {1,1,1,1}}, {VK_DELETE, {1,1,1,1}}, {VK_F1, {1,1,0,0}}, {VK_F2, {1,1,0,0}}, {VK_F3, {1,1,0,0}}, {VK_F4, {1,1,0,0}}, {VK_F5, {1,1,0,0}}, {VK_F6, {1,1,1,0}}, {VK_F7, {1,1,0,0}}, {VK_F8, {1,1,0,0}}, {VK_F9, {1,1,0,0}}, {VK_F10, {1,1,0,0}}, {VK_F11, {1,0,0,0}}, {VK_F12, {1,0,0,0}}, {VK_NUMPAD5, {1,0,0,0}}, {VK_CLEAR, {1,0,0,0}}, {'6', {0,0,1,0}}, {0, {0,0,0,0}} }; static int is_non_ascii_key(INPUT_RECORD* irec) { #define NORMAL 0 #define SHIFT 1 #define CONTROL 2 #define ALT 3 int modifier_index = NORMAL; int i; if (irec->Event.KeyEvent.dwControlKeyState & SHIFT_PRESSED) modifier_index = SHIFT; else if (irec->Event.KeyEvent.dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) modifier_index = CONTROL; else if (irec->Event.KeyEvent.dwControlKeyState & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED)) modifier_index = ALT; for (i = 0; keytable[i].vk; i++) if (irec->Event.KeyEvent.wVirtualKeyCode == keytable[i].vk) return keytable[i].val[modifier_index]; if (irec->Event.KeyEvent.uChar.AsciiChar) { return 1; } return 0; } static DWORD WINAPI select_read_thread(PVOID argp) { HANDLE fd_handle = (HANDLE)argp; DWORD ret = 1; DWORD mode = 0; mode = 0; GetConsoleMode(fd_handle,&mode); if(mode!=0) { // RealConsole Input INPUT_RECORD irec; DWORD events_read=0; for(;;) { ret = WaitForSingleObject(main_select_event,0); if(ret!=WAIT_TIMEOUT) break; if(!PeekConsoleInput(fd_handle,&irec,1,&events_read)) break; if (irec.EventType == KEY_EVENT && irec.Event.KeyEvent.bKeyDown && (irec.Event.KeyEvent.uChar.AsciiChar || is_non_ascii_key(&irec))) { return ret; } if(events_read>0) ReadConsoleInput(fd_handle, &irec, 1, &events_read); } return ret; } return ret; } static DWORD WINAPI select_write_thread(PVOID argp) { HANDLE fd_handle = (HANDLE)argp; DWORD ret = 1; DWORD mode = 0; GetConsoleMode(fd_handle,&mode); if(mode!=0) { // RealConsole Output return ret; } return ret; } long rb_w32_select (int nfds, fd_set *rd, fd_set *wr, fd_set *ex, struct timeval *timeout) { long r; fd_set file_rd; fd_set file_wr; #ifdef USE_INTERRUPT_WINSOCK fd_set trap; #endif /* USE_INTERRUPT_WINSOCK */ int file_nfds; DWORD val; int fd; int i; if (!NtSocketsInitialized) { StartSockets(); } r = 0; if (rd && rd->fd_count > r) r = rd->fd_count; if (wr && wr->fd_count > r) r = wr->fd_count; if (ex && ex->fd_count > r) r = ex->fd_count; if (nfds > r) nfds = r; if (nfds == 0 && timeout) { Sleep(timeout->tv_sec * 1000 + timeout->tv_usec / 1000); return 0; } file_nfds = extract_file_fd(rd, &file_rd); file_nfds += extract_file_fd(wr, &file_wr); if (file_nfds) { main_select_event = CreateEvent(NULL,TRUE,FALSE,"main_select_event"); if(main_select_event == NULL) { printf("CreateEvent failed (%d)\n", GetLastError()); return -1; } select_thread_list = ALLOCA_N(HANDLE, file_nfds+1); for(i=0; itv_sec * 1000 + timeout->tv_usec / 1000); if (!SetEvent(main_select_event) ) { printf("SetEvent failed (%d)\n", GetLastError()); return -1; } CloseHandle(main_select_event); if(r==WAIT_TIMEOUT) return 0; // assume normal files are always readable/writable // fake read/write fd_set and return value if (rd) *rd = file_rd; if (wr) *wr = file_wr; return file_nfds; } #if USE_INTERRUPT_WINSOCK if (ex) trap = *ex; else trap.fd_count = 0; if (trap.fd_count < FD_SETSIZE) trap.fd_array[trap.fd_count++] = (SOCKET)interrupted_event; // else unable to catch interrupt. ex = &trap; #endif /* USE_INTERRUPT_WINSOCK */ RUBY_CRITICAL({ r = select(nfds, rd, wr, ex, timeout); if (r == SOCKET_ERROR) { errno = map_errno(WSAGetLastError()); } }); return r; } -------------- next part -------------- An HTML attachment was scrubbed... URL: From luislavena at gmail.com Mon Apr 28 06:56:22 2008 From: luislavena at gmail.com (Luis Lavena) Date: Mon, 28 Apr 2008 07:56:22 -0300 Subject: [Win32utils-devel] rb_w32_select function patch In-Reply-To: References: Message-ID: <71166b3b0804280356k1d34d337x162b8e04944e8725@mail.gmail.com> On Mon, Apr 28, 2008 at 7:53 AM, Heesob Park wrote: > Hi, all > > As you know, rb_w32_select don't work well with standard input. > Here is test code: > > t = Thread.new { > while true > puts "printing a line" > sleep 2 > end > } > > gets > t.exit > puts "exiting" > > > Following is the first version of patch code of rb_w32_select function in > win32.c > It is inspired by cygwin select implementation code and adopted some code > from it. > The basic idea is creating thread for each file descriptor and wait events. > > What's your thought about it? > Park, This replacement is compatible with ruby_1_8 branch or just for Sapphire? I'll love get this included in 1.8 to solve issues regarding One-Click Installer for the time being. > > Regards, > > Park Heesob > Thank you for your work, tried to apply your older patch about this and failed due changes introduced by years in ruby code. Regards, -- Luis Lavena Multimedia systems - Human beings, who are almost unique in having the ability to learn from the experience of others, are also remarkable for their apparent disinclination to do so. Douglas Adams From phasis at gmail.com Mon Apr 28 08:45:23 2008 From: phasis at gmail.com (Park Heesob) Date: Mon, 28 Apr 2008 21:45:23 +0900 Subject: [Win32utils-devel] rb_w32_select function patch References: <71166b3b0804280356k1d34d337x162b8e04944e8725@mail.gmail.com> Message-ID: <000d01c8a92d$bb37d500$9a7ba8c0@mycomputer> Hi, ----- Original Message ----- From: "Luis Lavena" To: "Development and ideas for win32utils projects" Sent: Monday, April 28, 2008 7:56 PM Subject: Re: [Win32utils-devel] rb_w32_select function patch > On Mon, Apr 28, 2008 at 7:53 AM, Heesob Park wrote: >> Hi, all >> >> As you know, rb_w32_select don't work well with standard input. >> Here is test code: >> >> t = Thread.new { >> while true >> puts "printing a line" >> sleep 2 >> end >> } >> >> gets >> t.exit >> puts "exiting" >> >> >> Following is the first version of patch code of rb_w32_select function in >> win32.c >> It is inspired by cygwin select implementation code and adopted some code >> from it. >> The basic idea is creating thread for each file descriptor and wait events. >> >> What's your thought about it? >> > > Park, > > This replacement is compatible with ruby_1_8 branch or just for > Sapphire? I'll love get this included in 1.8 to solve issues regarding > One-Click Installer for the time being. > I tested code with ruby 1.8.6 p-114 compiled with VC++6.0 and VC++9.0. Regards, Park Heesob From luislavena at gmail.com Mon Apr 28 11:30:51 2008 From: luislavena at gmail.com (Luis Lavena) Date: Mon, 28 Apr 2008 12:30:51 -0300 Subject: [Win32utils-devel] rb_w32_select function patch In-Reply-To: <000d01c8a92d$bb37d500$9a7ba8c0@mycomputer> References: <71166b3b0804280356k1d34d337x162b8e04944e8725@mail.gmail.com> <000d01c8a92d$bb37d500$9a7ba8c0@mycomputer> Message-ID: <71166b3b0804280830x38ddc02cxeb3a55e62f596dc4@mail.gmail.com> On Mon, Apr 28, 2008 at 9:45 AM, Park Heesob wrote: > Hi, > > > ----- Original Message ----- > From: "Luis Lavena" > To: "Development and ideas for win32utils projects" > Sent: Monday, April 28, 2008 7:56 PM > Subject: Re: [Win32utils-devel] rb_w32_select function patch > > > > > Park, > > > > This replacement is compatible with ruby_1_8 branch or just for > > Sapphire? I'll love get this included in 1.8 to solve issues regarding > > One-Click Installer for the time being. > > > I tested code with ruby 1.8.6 p-114 compiled with VC++6.0 and VC++9.0. > Good thing to know. I'll check with GCC build of One-Click. > Regards, > Thank you again, -- Luis Lavena Multimedia systems - Human beings, who are almost unique in having the ability to learn from the experience of others, are also remarkable for their apparent disinclination to do so. Douglas Adams From djberg96 at gmail.com Mon Apr 28 21:29:47 2008 From: djberg96 at gmail.com (Daniel Berger) Date: Mon, 28 Apr 2008 19:29:47 -0600 Subject: [Win32utils-devel] rb_w32_select function patch In-Reply-To: References: Message-ID: <48167A0B.2060608@gmail.com> Heesob Park wrote: > Hi, all > > As you know, rb_w32_select don't work well with standard input. > Here is test code: > > t = Thread.new { > while true > puts "printing a line" > sleep 2 > end > } > > gets > t.exit > puts "exiting" > > Following is the first version of patch code of rb_w32_select function > in win32.c > It is inspired by cygwin select implementation code and adopted some > code from it. > The basic idea is creating thread for each file descriptor and wait events. > > What's your thought about it? I applied the patch and then tried to run the thread tests in my ruby_test test suite against Ruby 1.8.6 p114 on Windows XP, built with VC++ 8. C:\Documents and Settings\djberge\workspace\ruby_test>ruby test_thread.rb Loaded suite test_thread Started ......................................................C:/rubyVC8/lib/ruby/1.8/test/unit/ui/console/testrunner. rb:113: [BUG] Segmentation fault ruby 1.8.6 (2008-03-03) [i386-mswin32_80] This application has requested the Runtime to terminate it in an unusual way. Please contact the application's support team for more information. Where "test_thread.rb" is just: # test_thread.rb $LOAD_PATH.unshift File.join(Dir.pwd, 'lib') Dir['test/core/thread/**/*.rb'].each{ |f| begin require f rescue LoadError next end } Or you can just run 'rake test_thread' if you have Rake installed. You can grab "ruby_test" out of the "shards" CVS repo. cvs -d :pserver:anonymous at rubyforge.org:/var/cvs/shards login cvs -d :pserver:anonymous at rubyforge.org:/var/cvs/shards checkout ruby_test Is it possible I applied the patch wrong? Do you happen to have a unified diff, i.e. "diff -u" output? Regards, Dan From djberg96 at gmail.com Mon Apr 28 21:43:56 2008 From: djberg96 at gmail.com (Daniel Berger) Date: Mon, 28 Apr 2008 19:43:56 -0600 Subject: [Win32utils-devel] win32-changejournal for the one-click Message-ID: <48167D5C.3030907@gmail.com> Hi, Anyone remember how we got win32-changejournal built so that the one-click installer could use it? When I build the latest version with VC++ 8 and try to use the shared object with the one-click installer, it dies with with a DLL. Yet the 0.3.1 shared object works ok. I don't remember how we pulled that off now, because I can't build the source for win32-changejournal with VC++ 6. Thanks, Dan From phasis at gmail.com Tue Apr 29 01:53:07 2008 From: phasis at gmail.com (Heesob Park) Date: Tue, 29 Apr 2008 14:53:07 +0900 Subject: [Win32utils-devel] rb_w32_select function patch In-Reply-To: <48167A0B.2060608@gmail.com> References: <48167A0B.2060608@gmail.com> Message-ID: Hi, 2008/4/29 Daniel Berger : > Heesob Park wrote: > > Hi, all > > As you know, rb_w32_select don't work well with standard input. > > Here is test code: > > > > t = Thread.new { > > while true > > puts "printing a line" > > sleep 2 > > end > > } > > > > gets > > t.exit > > puts "exiting" > > Following is the first version of patch code of rb_w32_select function > in win32.c > > It is inspired by cygwin select implementation code and adopted some code > from it. > > The basic idea is creating thread for each file descriptor and wait > events. > > What's your thought about it? > > > > I applied the patch and then tried to run the thread tests in my ruby_test > test suite against Ruby 1.8.6 p114 on Windows XP, built with VC++ 8. > > C:\Documents and Settings\djberge\workspace\ruby_test>ruby test_thread.rb > Loaded suite test_thread > Started > ......................................................C:/rubyVC8/lib/ruby/1.8/test/unit/ui/console/testrunner. > rb:113: [BUG] Segmentation fault > ruby 1.8.6 (2008-03-03) [i386-mswin32_80] > > > This application has requested the Runtime to terminate it in an unusual > way. > Please contact the application's support team for more information. > I missed timeval NULL check for sleep without argument. > > Is it possible I applied the patch wrong? Do you happen to have a unified > diff, i.e. "diff -u" output? > I added some safe check code. Here is diff -u output: --- win32.c.org 2008-04-29 14:44:41.000000000 +0900 +++ win32.c 2008-04-29 14:32:59.000000000 +0900 @@ -2046,6 +2046,117 @@ return fileset->fd_count; } +static HANDLE main_select_event=NULL; +static HANDLE *select_thread_list=NULL; + +static struct { + int vk; + int val[4]; +} keytable[] = { + /* N S C A */ + {VK_LEFT, {1,1,1,1}}, + {VK_RIGHT, {1,1,1,1}}, + {VK_UP, {1,1,1,1}}, + {VK_DOWN, {1,1,1,1}}, + {VK_PRIOR, {1,1,1,1}}, + {VK_NEXT, {1,1,1,1}}, + {VK_HOME, {1,1,1,1}}, + {VK_END, {1,1,1,1}}, + {VK_INSERT, {1,1,1,1}}, + {VK_DELETE, {1,1,1,1}}, + {VK_F1, {1,1,0,0}}, + {VK_F2, {1,1,0,0}}, + {VK_F3, {1,1,0,0}}, + {VK_F4, {1,1,0,0}}, + {VK_F5, {1,1,0,0}}, + {VK_F6, {1,1,1,0}}, + {VK_F7, {1,1,0,0}}, + {VK_F8, {1,1,0,0}}, + {VK_F9, {1,1,0,0}}, + {VK_F10, {1,1,0,0}}, + {VK_F11, {1,0,0,0}}, + {VK_F12, {1,0,0,0}}, + {VK_NUMPAD5, {1,0,0,0}}, + {VK_CLEAR, {1,0,0,0}}, + {'6', {0,0,1,0}}, + {0, {0,0,0,0}} +}; + +static int +is_non_ascii_key(INPUT_RECORD* irec) +{ +#define NORMAL 0 +#define SHIFT 1 +#define CONTROL 2 +#define ALT 3 + int modifier_index = NORMAL; + int i; + + if (irec->Event.KeyEvent.dwControlKeyState & SHIFT_PRESSED) + modifier_index = SHIFT; + else if (irec->Event.KeyEvent.dwControlKeyState & + (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) + modifier_index = CONTROL; + else if (irec->Event.KeyEvent.dwControlKeyState & + (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED)) + modifier_index = ALT; + + for (i = 0; keytable[i].vk; i++) + if (irec->Event.KeyEvent.wVirtualKeyCode == keytable[i].vk) + return keytable[i].val[modifier_index]; + + if (irec->Event.KeyEvent.uChar.AsciiChar) { + return 1; + } + return 0; +} + +static DWORD WINAPI +select_read_thread(PVOID argp) +{ + HANDLE fd_handle = (HANDLE)argp; + DWORD ret = 1; + DWORD mode = 0; + + mode = 0; + GetConsoleMode(fd_handle,&mode); + if(mode!=0) { + // RealConsole Input + INPUT_RECORD irec; + DWORD events_read=0; + + for(;;) { + ret = WaitForSingleObject(main_select_event,0); + if(ret!=WAIT_TIMEOUT) break; + if(!PeekConsoleInput(fd_handle,&irec,1,&events_read)) + break; + if (irec.EventType == KEY_EVENT && irec.Event.KeyEvent.bKeyDown && + (irec.Event.KeyEvent.uChar.AsciiChar || is_non_ascii_key(&irec))) { + return ret; + } + if(events_read>0) + ReadConsoleInput(fd_handle, &irec, 1, &events_read); + } + return ret; + } + return ret; +} + +static DWORD WINAPI +select_write_thread(PVOID argp) +{ + HANDLE fd_handle = (HANDLE)argp; + DWORD ret = 1; + DWORD mode = 0; + + GetConsoleMode(fd_handle,&mode); + if(mode!=0) { + // RealConsole Output + return ret; + } + return ret; +} + long rb_w32_select (int nfds, fd_set *rd, fd_set *wr, fd_set *ex, struct timeval *timeout) @@ -2057,6 +2168,10 @@ fd_set trap; #endif /* USE_INTERRUPT_WINSOCK */ int file_nfds; + DWORD val; + int fd; + int i; + DWORD exit_code; if (!NtSocketsInitialized) { StartSockets(); @@ -2074,6 +2189,55 @@ file_nfds += extract_file_fd(wr, &file_wr); if (file_nfds) { + main_select_event = CreateEvent(NULL,TRUE,FALSE,"main_select_event"); + if(main_select_event == NULL) + { + fprintf(stderr,"CreateEvent failed (%d)\n", GetLastError()); + return -1; + } + select_thread_list = malloc(sizeof(HANDLE)*(file_nfds+1)); + + for(i=0; itv_sec * 1000 + timeout->tv_usec / 1000); + else + r = WaitForMultipleObjects(file_nfds+1,select_thread_list,FALSE,INFINITE); + if (!SetEvent(main_select_event) ) + { + printf("SetEvent failed (%d)\n", GetLastError()); + return -1; + } + for(i=0;i References: <48167A0B.2060608@gmail.com> Message-ID: <71166b3b0804282355n1f105392h8defbafd83c9152f@mail.gmail.com> On Tue, Apr 29, 2008 at 2:53 AM, Heesob Park wrote: > Hi, > > [snip] > I added some safe check code. > Here is diff -u output: > Hello Park, I just tested your patch for rb_w32_select and found, even gets() is no longer blocking other threads from being executed, everything stops when you start typing something... Compared to other other platforms, the behavior differs, so maybe is not the best solution... I thought your previous patch (2005, 2006 maybe?) workaround that issue. But don't remember quite right. In any case, this looks good, one step closer :-) (btw, platform i386-mingw32) -- Luis Lavena Multimedia systems - Human beings, who are almost unique in having the ability to learn from the experience of others, are also remarkable for their apparent disinclination to do so. Douglas Adams From phasis at gmail.com Tue Apr 29 03:07:39 2008 From: phasis at gmail.com (Heesob Park) Date: Tue, 29 Apr 2008 16:07:39 +0900 Subject: [Win32utils-devel] win32-changejournal for the one-click In-Reply-To: <48167D5C.3030907@gmail.com> References: <48167D5C.3030907@gmail.com> Message-ID: Hi, 2008/4/29 Daniel Berger : > Hi, > > Anyone remember how we got win32-changejournal built so that the one-click > installer could use it? When I build the latest version with VC++ 8 and try > to use the shared object with the one-click installer, it dies with with a > DLL. > > Yet the 0.3.1 shared object works ok. I don't remember how we pulled that > off now, because I can't build the source for win32-changejournal with VC++ > 6. > > Thanks, > > Dan I guess you installed Platform SDK. Regards, Park Heesob From phasis at gmail.com Tue Apr 29 05:32:48 2008 From: phasis at gmail.com (Heesob Park) Date: Tue, 29 Apr 2008 18:32:48 +0900 Subject: [Win32utils-devel] rb_w32_select function patch In-Reply-To: <71166b3b0804282355n1f105392h8defbafd83c9152f@mail.gmail.com> References: <48167A0B.2060608@gmail.com> <71166b3b0804282355n1f105392h8defbafd83c9152f@mail.gmail.com> Message-ID: Hi, 2008/4/29 Luis Lavena : > On Tue, Apr 29, 2008 at 2:53 AM, Heesob Park wrote: > > Hi, > > > > [snip] > > > I added some safe check code. > > Here is diff -u output: > > > > Hello Park, > > I just tested your patch for rb_w32_select and found, even gets() is > no longer blocking other threads from being executed, everything stops > when you start typing something... > > Compared to other other platforms, the behavior differs, so maybe is > not the best solution... > > I thought your previous patch (2005, 2006 maybe?) workaround that > issue. But don't remember quite right. > That patch is not working well as you expected. > In any case, this looks good, one step closer :-) > > (btw, platform i386-mingw32) > Here is a modified version for two step closer :) --- win32.c.org 2008-04-29 14:44:41.000000000 +0900 +++ win32.c 2008-04-29 18:25:26.000000000 +0900 @@ -2046,6 +2046,65 @@ return fileset->fd_count; } +static HANDLE main_select_event=NULL; +static HANDLE *select_thread_list=NULL; + +static DWORD WINAPI +select_read_thread(PVOID argp) +{ + HANDLE fd_handle = (HANDLE)argp; + DWORD ret = 1; + DWORD mode = 0; + + GetConsoleMode(fd_handle,&mode); + if(mode!=0) { + // RealConsole Input + DWORD num_events,num_events_read,pre_num=0; + INPUT_RECORD *input_record; + int i; + + while(1) { + if(WaitForSingleObject(main_select_event,0)!=WAIT_TIMEOUT) break; + GetNumberOfConsoleInputEvents(fd_handle, &num_events); + if(pre_num != num_events) { + input_record = (INPUT_RECORD *)malloc(sizeof(INPUT_RECORD)*num_events); + PeekConsoleInput(fd_handle, input_record, num_events, &num_events_read); + for(i=0;itv_sec * 1000 + timeout->tv_usec / 1000); + else + r = WaitForMultipleObjects(file_nfds+1,select_thread_list,FALSE,INFINITE); + if (!SetEvent(main_select_event) ) + { + printf("SetEvent failed (%d)\n", GetLastError()); + return -1; + } + for(i=0;i References: <48167A0B.2060608@gmail.com> <71166b3b0804282355n1f105392h8defbafd83c9152f@mail.gmail.com> Message-ID: <48171385.1030304@gmail.com> Heesob Park wrote: > Hi, > > 2008/4/29 Luis Lavena : >> On Tue, Apr 29, 2008 at 2:53 AM, Heesob Park wrote: >>> Hi, >>> >>> [snip] >>> I added some safe check code. >>> Here is diff -u output: >>> >> Hello Park, >> >> I just tested your patch for rb_w32_select and found, even gets() is >> no longer blocking other threads from being executed, everything stops >> when you start typing something... >> >> Compared to other other platforms, the behavior differs, so maybe is >> not the best solution... >> >> I thought your previous patch (2005, 2006 maybe?) workaround that >> issue. But don't remember quite right. >> > That patch is not working well as you expected. > >> In any case, this looks good, one step closer :-) >> >> (btw, platform i386-mingw32) >> > Here is a modified version for two step closer :) That works. Passes my (limited) thread test suite, too. :) Awesome. Many thanks. I'll commit this in the CVS repo for Sapphire. Dan From djberg96 at gmail.com Tue Apr 29 08:29:59 2008 From: djberg96 at gmail.com (Daniel Berger) Date: Tue, 29 Apr 2008 06:29:59 -0600 Subject: [Win32utils-devel] win32-changejournal for the one-click In-Reply-To: References: <48167D5C.3030907@gmail.com> Message-ID: <6037b70c0804290529m31b0a625yb2baff184814cf21@mail.gmail.com> On Tue, Apr 29, 2008 at 1:07 AM, Heesob Park wrote: > Hi, > > 2008/4/29 Daniel Berger : > > > > Hi, > > > > Anyone remember how we got win32-changejournal built so that the one-click > > installer could use it? When I build the latest version with VC++ 8 and try > > to use the shared object with the one-click installer, it dies with with a > > DLL. > > > > Yet the 0.3.1 shared object works ok. I don't remember how we pulled that > > off now, because I can't build the source for win32-changejournal with VC++ > > 6. > > > > Thanks, > > > > Dan > I guess you installed Platform SDK. Got a shared object you can build for me so I can distribute this as a gem that will work with the one-click? Thanks, Dan From phasis at gmail.com Tue Apr 29 09:25:54 2008 From: phasis at gmail.com (Park Heesob) Date: Tue, 29 Apr 2008 22:25:54 +0900 Subject: [Win32utils-devel] win32-changejournal for the one-click References: <48167D5C.3030907@gmail.com> <6037b70c0804290529m31b0a625yb2baff184814cf21@mail.gmail.com> Message-ID: <003e01c8a9fc$9006da00$9a7ba8c0@mycomputer> Hi, ----- Original Message ----- From: "Daniel Berger" To: "Development and ideas for win32utils projects" Sent: Tuesday, April 29, 2008 9:29 PM Subject: Re: [Win32utils-devel] win32-changejournal for the one-click > On Tue, Apr 29, 2008 at 1:07 AM, Heesob Park wrote: >> Hi, >> >> 2008/4/29 Daniel Berger : >> >> >> > Hi, >> > >> > Anyone remember how we got win32-changejournal built so that the one-click >> > installer could use it? When I build the latest version with VC++ 8 and try >> > to use the shared object with the one-click installer, it dies with with a >> > DLL. >> > >> > Yet the 0.3.1 shared object works ok. I don't remember how we pulled that >> > off now, because I can't build the source for win32-changejournal with VC++ >> > 6. >> > >> > Thanks, >> > >> > Dan >> I guess you installed Platform SDK. > > Got a shared object you can build for me so I can distribute this as a > gem that will work with the one-click? > Here is Platform SDK compatible with VC++6.0 http://www.microsoft.com/msdownload/platformsdk/sdkupdate/psdk-full.htm I attached a shared object for one-click. Regards, Park Heesob -------------- next part -------------- A non-text attachment was scrubbed... Name: changejournal.so Type: application/octet-stream Size: 24655 bytes Desc: not available URL: From Daniel.Berger at qwest.com Tue Apr 29 12:14:24 2008 From: Daniel.Berger at qwest.com (Berger, Daniel) Date: Tue, 29 Apr 2008 11:14:24 -0500 Subject: [Win32utils-devel] ZwXX functions Message-ID: <7524A45A1A5B264FA4809E2156496CFB023D3217@ITOMAE2KM01.AD.QINTRA.COM> Hi all, I noticed that some of the Zw functions would be very handy to use. While they're exported by NTDLL, it seems they're part of the Windows Driver Kit, and those headers don't ship with Visual C++ by default. Or do they? I don't have them with Visual C++ 8 anyway. What I'm mainly after is the ZwQueryInformationFile for use with File::Stat, so I can get information more easily from a handle. This would be useful for a custom IO#stat implementation, where I'll have a fileno but not a file name. While it's technically part of the WDK, there's no reason it can't be used for regular file operations as well. Any suggestions? Thanks, Dan This communication is the property of Qwest and may contain confidential or privileged information. Unauthorized use of this communication is strictly prohibited and may be unlawful. If you have received this communication in error, please immediately notify the sender by reply e-mail and destroy all copies of the communication and any attachments. From phasis at gmail.com Tue Apr 29 22:15:04 2008 From: phasis at gmail.com (Heesob Park) Date: Wed, 30 Apr 2008 11:15:04 +0900 Subject: [Win32utils-devel] ZwXX functions In-Reply-To: <7524A45A1A5B264FA4809E2156496CFB023D3217@ITOMAE2KM01.AD.QINTRA.COM> References: <7524A45A1A5B264FA4809E2156496CFB023D3217@ITOMAE2KM01.AD.QINTRA.COM> Message-ID: Hi, 2008/4/30 Berger, Daniel : > Hi all, > > I noticed that some of the Zw functions would be very handy to use. > While they're exported by NTDLL, it seems they're part of the Windows > Driver Kit, and those headers don't ship with Visual C++ by default. Or > do they? I don't have them with Visual C++ 8 anyway. > > What I'm mainly after is the ZwQueryInformationFile for use with > File::Stat, so I can get information more easily from a handle. This > would be useful for a custom IO#stat implementation, where I'll have a > fileno but not a file name. > > While it's technically part of the WDK, there's no reason it can't be > used for regular file operations as well. > > Any suggestions? > You cannot call ZwXX functions directly in application. Instead, there is NtXX functions including NtQueryInformationFile. Refer to http://www.codeguru.com/Cpp/W-P/system/processesmodules/article.php/c2827/ It has sample program and source code availabe. Regards, Park Heesob From phasis at gmail.com Wed Apr 30 04:08:35 2008 From: phasis at gmail.com (Heesob Park) Date: Wed, 30 Apr 2008 17:08:35 +0900 Subject: [Win32utils-devel] rb_w32_select function patch In-Reply-To: <48171385.1030304@gmail.com> References: <48167A0B.2060608@gmail.com> <71166b3b0804282355n1f105392h8defbafd83c9152f@mail.gmail.com> <48171385.1030304@gmail.com> Message-ID: Hi, 2008/4/29 Daniel Berger : > > > > That works. Passes my (limited) thread test suite, too. :) > > Awesome. Many thanks. I'll commit this in the CVS repo for Sapphire. > > Dan > Now, I have made rb_w32_select function to work with pipe . Here is a test code: readPipe, writePipe = IO.pipe t = Thread.new { while true; sleep 1; puts "got #{readPipe.readline}"; end } i = 1 while true i += 1 sleep 1 puts "hello from main" if i>3 writePipe.puts "test #{i}\n" end end t.join Here is patch diff output: --- win32.c.org 2008-04-29 14:44:41.000000000 +0900 +++ win32.c 2008-04-30 16:46:32.000000000 +0900 @@ -2046,6 +2050,91 @@ return fileset->fd_count; } +static HANDLE main_select_event=NULL; +static HANDLE *select_thread_list=NULL; + +static DWORD WINAPI +select_read_thread(PVOID argp) +{ + HANDLE fd_handle = (HANDLE)argp; + DWORD ret = 1; + DWORD mode = 0; + + GetConsoleMode(fd_handle,&mode); + if(mode) { + /* Console Input */ + DWORD num_events,num_events_read,pre_num=0; + INPUT_RECORD *input_record; + int i; + + while(1) { + if(WaitForSingleObject(main_select_event,0)!=WAIT_TIMEOUT) break; + GetNumberOfConsoleInputEvents(fd_handle, &num_events); + if(pre_num != num_events) { + input_record = (INPUT_RECORD *)malloc(sizeof(INPUT_RECORD)*num_events); + PeekConsoleInput(fd_handle, input_record, num_events, &num_events_read); + for(i=0;i0) { + return bytes_avail; + } + } + } + return ret; + } + return ret; +} + +static DWORD WINAPI +select_write_thread(PVOID argp) +{ + HANDLE fd_handle = (HANDLE)argp; + DWORD ret = 1; + DWORD mode = 0; + + GetConsoleMode(fd_handle,&mode); + if(mode) { + /* Console Output */ + return ret; + } else { + DWORD state; + ret = GetNamedPipeHandleState(fd_handle,&state,NULL,NULL,NULL,NULL,0); + if(ret) { + /* Pipe output */ + int bytes_written=0; + ret = WriteFile(fd_handle,NULL,0,&bytes_written,NULL); + if(ret) { + return ret; + } + } + } + return ret; +} + long rb_w32_select (int nfds, fd_set *rd, fd_set *wr, fd_set *ex, struct timeval *timeout) @@ -2074,6 +2163,80 @@ file_nfds += extract_file_fd(wr, &file_wr); if (file_nfds) { + DWORD val,exit_code; + int i; + main_select_event = CreateEvent(NULL,TRUE,FALSE,NULL); + if(main_select_event == NULL) + { + printf("CreateEvent failed (%d)\n", GetLastError()); + return -1; + } + select_thread_list = malloc(sizeof(HANDLE)*(file_nfds+1)); + + for(i=0; itv_sec * 1000 + timeout->tv_usec / 1000); + else + r = WaitForMultipleObjects(file_nfds+1,select_thread_list,FALSE, + INFINITE); + + if (!SetEvent(main_select_event) ) + { + printf("SetEvent failed (%d)\n", GetLastError()); + return -1; + } + /* thread cleanup */ + for(i=0;i References: <48167A0B.2060608@gmail.com><71166b3b0804282355n1f105392h8defbafd83c9152f@mail.gmail.com><48171385.1030304@gmail.com> Message-ID: <7524A45A1A5B264FA4809E2156496CFB023D321B@ITOMAE2KM01.AD.QINTRA.COM> > -----Original Message----- > From: win32utils-devel-bounces at rubyforge.org > [mailto:win32utils-devel-bounces at rubyforge.org] On Behalf Of > Heesob Park > Sent: Wednesday, April 30, 2008 2:09 AM > To: Development and ideas for win32utils projects > Subject: Re: [Win32utils-devel] rb_w32_select function patch > > Hi, > > 2008/4/29 Daniel Berger : > > > > > > > > That works. Passes my (limited) thread test suite, too. :) > > > > Awesome. Many thanks. I'll commit this in the CVS repo for Sapphire. > > > > Dan > > > Now, I have made rb_w32_select function to work with pipe . > Here is a test code: > > readPipe, writePipe = IO.pipe > t = Thread.new { while true; sleep 1; puts "got > #{readPipe.readline}"; end } > > i = 1 > while true > i += 1 > sleep 1 > puts "hello from main" > if i>3 > writePipe.puts "test #{i}\n" > end > end > > t.join Excellent, thanks! With this in place I'm wondering how open3 could be implemented to work on Windows without fork and without resorting to a C extension. Or if IO.popen needs to be reworked. Any thoughts? Thanks, Dan This communication is the property of Qwest and may contain confidential or privileged information. Unauthorized use of this communication is strictly prohibited and may be unlawful. If you have received this communication in error, please immediately notify the sender by reply e-mail and destroy all copies of the communication and any attachments. From Daniel.Berger at qwest.com Wed Apr 30 10:45:04 2008 From: Daniel.Berger at qwest.com (Berger, Daniel) Date: Wed, 30 Apr 2008 09:45:04 -0500 Subject: [Win32utils-devel] rb_w32_select function patch In-Reply-To: References: <48167A0B.2060608@gmail.com><71166b3b0804282355n1f105392h8defbafd83c9152f@mail.gmail.com> Message-ID: <7524A45A1A5B264FA4809E2156496CFB023D321C@ITOMAE2KM01.AD.QINTRA.COM> > -----Original Message----- > From: win32utils-devel-bounces at rubyforge.org > [mailto:win32utils-devel-bounces at rubyforge.org] On Behalf Of > Heesob Park > Sent: Tuesday, April 29, 2008 3:33 AM > To: Development and ideas for win32utils projects > Subject: Re: [Win32utils-devel] rb_w32_select function patch > > Hi, > > 2008/4/29 Luis Lavena : > > On Tue, Apr 29, 2008 at 2:53 AM, Heesob Park > wrote: > > > Hi, > > > > > > [snip] > > > > > I added some safe check code. > > > Here is diff -u output: > > > > > > > Hello Park, > > > > I just tested your patch for rb_w32_select and found, even > gets() is > > no longer blocking other threads from being executed, > everything stops > > when you start typing something... > > > > Compared to other other platforms, the behavior differs, so > maybe is > > not the best solution... > > > > I thought your previous patch (2005, 2006 maybe?) workaround that > > issue. But don't remember quite right. > > > That patch is not working well as you expected. > > > In any case, this looks good, one step closer :-) > > > > (btw, platform i386-mingw32) > > > Here is a modified version for two step closer :) The only difference I see between this and a Unix version is that anything I type on the command line doesn't appear until I hit the Enter key. On Unix (or with Jruby on Windows), I see whatever I type on the console right away. I'm guessing it's a cmd.exe or native thread issue. It's nothing big, but I thought I'd mention it. Regards, Dan This communication is the property of Qwest and may contain confidential or privileged information. Unauthorized use of this communication is strictly prohibited and may be unlawful. If you have received this communication in error, please immediately notify the sender by reply e-mail and destroy all copies of the communication and any attachments. From Daniel.Berger at qwest.com Wed Apr 30 15:13:10 2008 From: Daniel.Berger at qwest.com (Berger, Daniel) Date: Wed, 30 Apr 2008 14:13:10 -0500 Subject: [Win32utils-devel] Playing with NtQueryInformationFile Message-ID: <7524A45A1A5B264FA4809E2156496CFB023D3222@ITOMAE2KM01.AD.QINTRA.COM> Hi all, I'm trying to get the allocation size of a file via a file handle (rather than its name). The example below works for FileNameInformation but I can't get it to work as expected for FileStandardInformation. Here's some sample code: # query_test.rb require 'windows/handle' require 'windows/error' include Windows::Handle include Windows::Error NtQueryInformationFile = API.new('NtQueryInformationFile', 'LPPLL', 'L', 'ntdll') # http://msdn.microsoft.com/en-us/library/cc232064.aspx FileNameInformation = 9 FileStandardInformation = 5 STATUS_SUCCESS = 0 fh = File.open('test.txt', 'w') fh.puts "hello" handle = get_osfhandle(fh.fileno) if handle == INVALID_HANDLE_VALUE puts "ERROR, get_osfhandle() : " + get_last_error fh.close rescue nil File.delete('test.txt') exit end # Excessive but harmless (?) io_status_block = 0.chr * 512 file_information = 0.chr * 512 status = NtQueryInformationFile.call( handle, io_status_block, file_information, file_information.size, # FileStandardInformation # Doesn't work as expected FileNameInformation # But this does ) if status != STATUS_SUCCESS puts "ERROR, NtQueryInformationFile() : #{status}" fh.close File.delete('test.txt') exit end # p file_information[0, 8].unpack('L')[0] # Zero ??? # Use with FileStandardInformation p file_information[0,4].unpack('L')[0] / 2 # Unicode p file_information[4,file_information.length].tr("\000",'').strip fh.close # end query_test.rb The above will print the file name (without the drive letter) as well as the length of the file name, which varies depending on whatever path you created 'test.txt' on. However, if I try to replace "FileNameInformation" with "FileStandardInformation" and inspect the first 8 bytes of file_information (the AllocationSize), it's always zero. The only thing I get out of the buffer at all is the NumberOfLinks, which is always 1. What am I doing wrong? Thanks, Dan This communication is the property of Qwest and may contain confidential or privileged information. Unauthorized use of this communication is strictly prohibited and may be unlawful. If you have received this communication in error, please immediately notify the sender by reply e-mail and destroy all copies of the communication and any attachments. From phasis at gmail.com Wed Apr 30 20:41:42 2008 From: phasis at gmail.com (Heesob Park) Date: Thu, 1 May 2008 09:41:42 +0900 Subject: [Win32utils-devel] Playing with NtQueryInformationFile In-Reply-To: <7524A45A1A5B264FA4809E2156496CFB023D3222@ITOMAE2KM01.AD.QINTRA.COM> References: <7524A45A1A5B264FA4809E2156496CFB023D3222@ITOMAE2KM01.AD.QINTRA.COM> Message-ID: Hi, 2008/5/1 Berger, Daniel : > Hi all, > > I'm trying to get the allocation size of a file via a file handle > (rather than its name). The example below works for FileNameInformation > but I can't get it to work as expected for FileStandardInformation. > > Here's some sample code: > > # query_test.rb > require 'windows/handle' > require 'windows/error' > include Windows::Handle > include Windows::Error > > NtQueryInformationFile = API.new('NtQueryInformationFile', 'LPPLL', 'L', > 'ntdll') > > # http://msdn.microsoft.com/en-us/library/cc232064.aspx > FileNameInformation = 9 > FileStandardInformation = 5 > STATUS_SUCCESS = 0 > > fh = File.open('test.txt', 'w') > fh.puts "hello" > > handle = get_osfhandle(fh.fileno) > > if handle == INVALID_HANDLE_VALUE > puts "ERROR, get_osfhandle() : " + get_last_error > fh.close rescue nil > File.delete('test.txt') > exit > end > > # Excessive but harmless (?) > io_status_block = 0.chr * 512 > file_information = 0.chr * 512 > > status = NtQueryInformationFile.call( > handle, > io_status_block, > file_information, > file_information.size, > # FileStandardInformation # Doesn't work as expected > FileNameInformation # But this does > ) > > if status != STATUS_SUCCESS > puts "ERROR, NtQueryInformationFile() : #{status}" > fh.close > File.delete('test.txt') > exit > end > > # p file_information[0, 8].unpack('L')[0] # Zero ??? # Use with > FileStandardInformation > > p file_information[0,4].unpack('L')[0] / 2 # Unicode > p file_information[4,file_information.length].tr("\000",'').strip > > fh.close > > # end query_test.rb > > The above will print the file name (without the drive letter) as well as > the length of the file name, which varies depending on whatever path you > created 'test.txt' on. > > However, if I try to replace "FileNameInformation" with > "FileStandardInformation" and inspect the first 8 bytes of > file_information (the AllocationSize), it's always zero. The only thing > I get out of the buffer at all is the NumberOfLinks, which is always 1. > > What am I doing wrong? > Insert fh.flush atfer fh.puts "hello" must be required. Following code will work for you: fh = File.open('test.txt', 'w') fh.puts "hello" fh.flush handle = get_osfhandle(fh.fileno) io_status_block = 0.chr * 8 file_information = 0.chr * 0x18 status = NtQueryInformationFile.call( handle, io_status_block, file_information, file_information.size, FileStandardInformation ) For the actual buffer size, Reter to http://undocumented.ntinternals.net/ http://undocumented.ntinternals.net/UserMode/Undocumented%20Functions/NT%20Objects/File/FILE_INFORMATION_CLASS.html Regards, Park Heesob