Class: Dir

Inherits:
Object
  • Object
show all
Defined in:
lib/mkdtemp/version.rb,
ext/mkdtemp.c

Defined Under Namespace

Modules: Mkdtemp

Class Method Summary collapse

Class Method Details

.mkdtemp(template) { ... } ⇒ String

Note:

Note that the exact implementation of mkdtemp() may vary depending on the target system. For example, on Mac OS X at the time of writing, the man page states that the template may contain “some number” of “Xs” on the end of the string, whereas on Red Hat Enterprise Linux it states that the template suffix “must be XXXXXX”.

Securely create a temporary directory.

This method securely creates temporary directories. It is a wrapper for the mkdtemp() function in the standard C library.

If supplied a block, performs a Dir.chdir into the created directory and yields to the block:

Examples:

# this:            # is a shorthand for:
Dir.mkdtemp do     #   dir = Dir.mkdtemp
  puts Dir.pwd     #   Dir.chdir dir do
end                #     puts Dir.pwd
                   #   end

Parameters:

  • template (String, nil)

    a template describing the desired form of the directory name. If no template is supplied then “/tmp/temp.XXXXXX” is used as a default.

Yields:

  • an optional block to perform operations inside the created directory.

Returns:

  • (String)

    the path to the created directory

Raises:

  • (TypeError)

    if template is not a String or cannot be converted into one

  • (SecurityError)

    if template is tainted and $SAFE is > 0

  • (NoMemoryError)

    if temporary storage for the template could not be allocated

  • (SystemCallError)

    if the call to mkdtemp() fails



79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'ext/mkdtemp.c', line 79

static VALUE dir_mkdtemp_m(int argc, VALUE *argv, VALUE self)
{
    VALUE template, block;
    char *c_template;
    char *path;

    // process arguments
    if (rb_scan_args(argc, argv, "01&", &template, &block) == 0)    // 0 mandatory, 1 optional, 1 block
        template = Qnil;                                            // default to nil if no argument passed
    if (NIL_P(template))
        template = rb_str_new2("/tmp/temp.XXXXXX");                 // fallback to this template if passed nil
    SafeStringValue(template);                                      // raises if template is tainted and SAFE level > 0
    template = StringValue(template);                               // duck typing support

    // create temporary storage
    c_template = malloc(RSTRING_LEN(template) + 1);
    if (!c_template)
        rb_raise(rb_eNoMemError, "failed to allocate %ld bytes of template storage", RSTRING_LEN(template) + 1);
    strncpy(c_template, RSTRING_PTR(template), RSTRING_LEN(template));
    c_template[RSTRING_LEN(template)] = 0;              // NUL-terminate

    // fill out template
    path = mkdtemp(c_template);
    if (path)
        template = rb_str_new2(path);
    free(c_template);
    if (path == NULL)
        rb_raise(rb_eSystemCallError, "mkdtemp failed (error #%d: %s)", errno, strerror(errno));

    // yield to block if given, inside Dir.chdir
    if (rb_block_given_p())
        rb_iterate(call_chdir, template, yield_block, block);
    return template;
}