aboutsummaryrefslogtreecommitdiff
path: root/toys/mkdir.c
blob: 4c9f54516b17f50907914ee4affef6faafb2b390 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
/* vi: set sw=4 ts=4:
 *
 * mkdir.c - Make directories
 *
 * Copyright 2012 Georgi Chorbadzhiyski <georgi@unixsol.org>
 *
 * See http://pubs.opengroup.org/onlinepubs/009695399/utilities/mkdir.html
 *
 * TODO: Add -m

USE_MKDIR(NEWTOY(mkdir, "<1p", TOYFLAG_BIN))

config MKDIR
	bool "mkdir"
	default y
	help
	  usage: mkdir [-p] [dirname...]
	  Create one or more directories.

	  -p	make parent directories as needed.
*/

#include "toys.h"


static int create_dir(const char *dir, mode_t mode) {
	int ret = 0;
	unsigned int i;

	// Shortcut
	if (strchr(dir, '/') == NULL || !toys.optflags)
		return mkdir(dir, mode);

	char *d = strdup(dir);
	if (!d)
		return -1;
	unsigned int dlen = strlen(dir);

	// Skip first char (it can be /)
	for (i = 1; i < dlen; i++) {
		if (d[i] != '/')
			continue;
		d[i] = '\0';
		ret = mkdir(d, mode);
		d[i] = '/';
		if (ret < 0 && errno != EEXIST)
			goto OUT;
	}
	ret = mkdir(d, mode);
OUT:
	free(d);
	return ret;
}

void mkdir_main(void)
{
	char **s;
	mode_t umask_val = umask(0);
	mode_t dir_mode = (0777 & ~umask_val) | (S_IWUSR | S_IXUSR);
	umask(umask_val);

	for (s=toys.optargs; *s; s++) {
		if (create_dir(*s, dir_mode) != 0) {
			fprintf(stderr, "mkdir: cannot create directory '%s': %s\n", *s, strerror(errno));
			toys.exitval = 1;
		}
	}
}