[Win32utils-devel] file-temp failure

Daniel Berger djberg96 at gmail.com
Sat Apr 12 10:49:42 EDT 2008


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;
>  >  }
>  >
>


More information about the win32utils-devel mailing list