[Win32utils-devel] file-temp failure
Daniel Berger
djberg96 at gmail.com
Sat Apr 12 10:42:59 EDT 2008
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;
> }
>
More information about the win32utils-devel
mailing list