Linux C/C++源码实现常见命令mkdir

Linux系统是由文件和目录组成的。当我们使用Linux系统时,经常会从中创建目录来保存文件等等,这时会使用Linux自带 mkdir 的命令,用于在操作系统中创建目录或文件夹。在本文中,我们将讨论如何使用带有各种命令行选项的 mkdir 命令以及代码实现。

mkdir命令代码实现

在 Linux 中,虽然 rm 命令允许您删除目录,但首先是 mkdir 命令允许您创建目录。下面我们实现mkdir命令:

#include <stdio.h>
#include <sys/types.h> /*umask、stat*/
#include <sys/stat.h> /*chmod*/
#include <unistd.h>
#include <err.h>
#include <errno.h>
#include <libgen.h> /*dirname*/
#include <stdlib.h>
#include <string.h>

/*
	int mkdir(const char *pathname, mode_t mode);
	mode方式:
	S_IRWXU 	00700权限,代表该文件所有者拥有读,写和执行操作的权限
	S_IRUSR(S_IREAD) 	00400权限,代表该文件所有者拥有可读的权限
	S_IWUSR(S_IWRITE) 	00200权限,代表该文件所有者拥有可写的权限
	S_IXUSR(S_IEXEC) 	00100权限,代表该文件所有者拥有执行的权限
	S_IRWXG 	00070权限,代表该文件用户组拥有读,写和执行操作的权限
	S_IRGRP 	00040权限,代表该文件用户组拥有可读的权限
	S_IWGRP 	00020权限,代表该文件用户组拥有可写的权限
	S_IXGRP 	00010权限,代表该文件用户组拥有执行的权限
	S_IRWXO 	00007权限,代表其他用户拥有读,写和执行操作的权限
	S_IROTH 	00004权限,代表其他用户拥有可读的权限
	S_IWOTH 	00002权限,代表其他用户拥有可写的权限
	S_IXOTH 	00001权限,代表其他用户拥有执行的权限

*/

/*
	参数 mode 有下列数种组合:
	S_ISUID 04000 文件的 (set user-id on execution)位
	S_ISGID 02000 文件的 (set group-id on execution)位
	S_ISVTX 01000 文件的sticky 位
	S_IRUSR (S_IREAD) 00400 文件所有者具可读取权限
	S_IWUSR (S_IWRITE)00200 文件所有者具可写入权限
	S_IXUSR (S_IEXEC) 00100 文件所有者具可执行权限
	S_IRGRP 00040 用户组具可读取权限
	S_IWGRP 00020 用户组具可写入权限
	S_IXGRP 00010 用户组具可执行权限
	S_IROTH 00004 其他用户具可读取权限
	S_IWOTH 00002 其他用户具可写入权限
	S_IXOTH 00001 其他用户具可执行权限
	
*/


static int	vflag;

static void usage(void)
{
	(void)fprintf(stderr,"usage: mkdir [-pv] [-m mode] directory_name ...\n");
}


/*
 *对于一个a/b/c这样的一个多级目录,要想实现父目录的创建方法,
 可以进行字符串处理分出一级一级目录.
 * 成功完成后,mkdir() 应返回 0。否则,应返回 -1,不应创建目录,并应设置 errno 以指示错误。 
 */

static int create_directory(char *path, mode_t omode)
{
	struct stat sb;
	mode_t numask, oumask;
	int first, last, retval;
	char *p;
	/*检查我们是否需要对中间目录做任何事情*/
	p = path;
	oumask = 0;
	retval = 1;
	if (p[0] == '/')		/* Skip  '/'. */
		++p;
	for (first = 1, last = 0; !last ; ++p) {
		if (p[0] == '\0')
			last = 1;
		else if (p[0] != '/')
			continue;
		*p = '\0';
		if (!last && p[1] == '\0')
			last = 1;
		if (first) {
			oumask = umask(0);
			numask = oumask & ~(S_IWUSR | S_IXUSR);
			(void)umask(numask);
			first = 0;
		}
		if (last)
			(void)umask(oumask);
		if (mkdir(path, last ? omode : S_IRWXU | S_IRWXG | S_IRWXO) < 0) {
			if (errno == EEXIST || errno == EISDIR) {
				/*
					判断该文件或目录是否否存在 ;得到st_mode,然后判断是不是目录文件。
					成功判断返回的st_mode是否是一个文件夹。
				*/
				if (stat(path, &sb) < 0) {
					warn("%s", path);
					retval = 0;
					break;
				} else if (!S_ISDIR(sb.st_mode)) {
					if (last)
						errno = EEXIST;
					else
						errno = ENOTDIR;
					warn("%s", path);
					retval = 0;
					break;
				}
				if (last)
					retval = 2;
			} else {
				warn("%s", path);
				retval = 0;
				break;
			}
		} else if (vflag)
			printf("%s\n", path);
		if (!last)
		    *p = '/';
	}
	if (!first && !last)
		(void)umask(oumask);
	return (retval);
}



int main(int argc, char *argv[])
{
	int ch, exitval, success, pflag;
	mode_t omode;
	void *set = NULL;
	char *mode;

	omode = pflag = 0;
	mode = NULL;
	while ((ch = getopt(argc, argv, "m:pv")) != -1)
		switch(ch) {
		case 'm':
			mode = optarg;
			break;
		case 'p':
			pflag = 1;
			break;
		case 'v':
			vflag = 1;
			break;
		case '?':
		default:
			usage();
		}

	argc -= optind;
	argv += optind;
	if (argv[0] == NULL)
		usage();

	if (mode == NULL) {
		omode = S_IRWXU | S_IRWXG | S_IRWXO;
	}

	for (exitval = 0; *argv != NULL; ++argv) {
		if (pflag) {
			success = create_directory(*argv, omode);
		} else if (mkdir(*argv, omode) < 0) {
			if (errno == ENOTDIR || errno == ENOENT)
				warn("%s", dirname(*argv));
			else
				warn("%s", *argv);
			success = 0;
		} else {
			success = 1;
			if (vflag)
				(void)printf("%s\n", *argv);
		}
		if (!success)
			exitval = 1;
		/*
		 chmod()会依参数mode 权限来更改参数path 指定文件的权限。
		 */
		if (success == 1 && mode != NULL && chmod(*argv, omode) == -1) {
			warn("%s", *argv);
			exitval = 1;
		}
	}
	return (exitval);
}

编译运行:

在这里插入图片描述my_mkdir将创建一个名为 path 的新目录。 新目录的文件权限位应从模式初始化。 mode 参数的这些文件权限位应由进程的文件创建掩码修改。

mkdir代码时候很简单, 主要用于在我们的 Linux 操作系统中创建目录。居然代码实现能创建目录,我们接下来使用选项看看效果。

创建多目录

当我们需要创建多目录时,只需要命名我们要创建的目录。这里需要注意一下,我们需要给目录名称加上空格以创建多个目录。 可以使用以下命令:

./my_mkdir aaa bbb ccc

在这里插入图片描述

创建父目录

./my_mkdir a/b

上面的命令将在目录 a 中创建名为 b 的目录。 如果目录 a 不存在,则会显示错误消息。

在这里插入图片描述

如果父目录不存在,则使用 –p 选项将创建它。

在这里插入图片描述

如果目录a不存在,mkdir命令将创建目录a,并在目录a内创建一个名为b的目录。

如何在详细模式下创建目录?

我们可以使用 –v 选项以详细模式创建新目录。 当您使用此选项创建新目录时,它将在屏幕中生成以下详细输出。 在这里插入图片描述

总结

以代码实现mkdir命令,然后将 mkdir 与各种命令行选项结合使用。本篇可以看到 mkdir 是一个非常简单的命令,可以很好的理解和使用。

欢迎关注微信公众号【程序猿编码】,欢迎添加本人微信号(17865354792)交流学习。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值