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
It''s actually "wb+", but that doesn''t help. On Sat, Apr 12, 2008 at 8:22 AM, Daniel Berger <djberg96 at gmail.com> 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 <ruby.h> > #include <stdio.h> > > #ifdef HAVE__SOPEN_S > #include <share.h> > #endif > > #ifndef HAVE_MKSTEMP > #include <fcntl.h> > #include <temp.h> > #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; > } >
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 <djberg96 at gmail.com> wrote:> It''s actually "wb+", but that doesn''t help. > > > > On Sat, Apr 12, 2008 at 8:22 AM, Daniel Berger <djberg96 at gmail.com> 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 <ruby.h> > > #include <stdio.h> > > > > #ifdef HAVE__SOPEN_S > > #include <share.h> > > #endif > > > > #ifndef HAVE_MKSTEMP > > #include <fcntl.h> > > #include <temp.h> > > #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; > > } > > >