]> git.wincent.com - mkdtemp.git/blob - ext/mkdtemp.c
Avoid unnecessary reallocation in mkdtemp function
[mkdtemp.git] / ext / mkdtemp.c
1 /* 
2 Copyright 2007 Wincent Colaiuta
3 This program is free software: you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation, either version 3 of the License, or
6 (at your option) any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program.  If not, see <http://www.gnu.org/licenses/>.
15 */
16
17 #include <ruby.h>
18 #include <errno.h>
19 #include <unistd.h>
20
21 /*
22
23 call-seq:
24     Dir.mkdtemp([string])   -> String or nil
25
26 This method securely creates temporary directories. It is a wrapper for the mkdtemp() function in the standard C library. It takes
27 an optional String parameter as a template describing the desired form of the directory name and overwriting the template in-place;
28 if no template is supplied then "/tmp/temp.XXXXXX" is used as a default.
29
30 */
31 static VALUE walrus_dir_mkdtemp_m(int argc, VALUE *argv, VALUE self)
32 {
33     VALUE template;
34     if (rb_scan_args(argc, argv, "01", &template) == 0  /* check for 0 mandatory arguments, 1 optional argument */
35         template = Qnil;                                /* default to nil if no argument passed */
36     if (NIL_P(template))
37         template = rb_str_new2("/tmp/temp.XXXXXX");     /* fallback to this template if passed nil */
38     SafeStringValue(template);                          /* raises if template is tainted and SAFE level > 0 */
39     VALUE safe  = StringValue(template);                /* duck typing support */
40     char *path  = mkdtemp(RSTRING(safe)->ptr);
41     if (path == NULL)
42         rb_raise(rb_eSystemCallError, "mkdtemp failed (error: %d)", errno);
43     return safe;
44 }
45
46 void Init_mkdtemp()
47 {
48     rb_define_module_function(rb_cDir, "mkdtemp", walrus_dir_mkdtemp_m, -1);
49 }