[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