1.3 creat简介

这篇博客探讨了Unix系统中的creat函数,它用于创建新文件,其实现相当于open函数与O_CREAT|O_WRONLY|O_TRUNC标志的组合。由于历史原因,早期内核中引入了creat,但现在open函数通过指定选项可以实现相同功能,使得creat变得不再必要。内核源码显示creat调用最终转化为open的调用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.3 creat简介

creat函数用于创建一个新文件,其等价于

open(pathname,O_WRONLY|O_CREAT|O_TRUNC,mode)。

APUE介绍了引入creat的原因:

由于历史原因,早期的Unix版本中,open的第二个参数只能是0、1或者2。这样就没有办法打开一个不存在的文件。因此,一个独立系统调用creat被引入,用于创建新文件。现在的open函数,通过使用O_CREAT和O_TRUNC选项,可以实现creat的功能,因此creat已经不是必要的了。

内核creat的实现代码如下所示:


SYSCALL_DEFINE2(creat, const char __user *, pathname, int, mode)
 {
     return sys_open(pathname, O_CREAT | O_WRONLY | O_TRUNC, mode); 
}

 

这样就确定了creat无非是open的一种封装实现。

以下内容,建议使用 Kali Linux 环境完成。各位可以在 Get Kali 页面 中自主选择安装方式,下载相关镜像完成环境配置。个人建议使用 Live Boot 或是 Virtual Machine 方式。其中,如果使用 Virtual Machine 的话,在 Windows 系统中可以使用原生的 Hyper-V 虚拟机。 镜像大小约为 3 − 4G,各位可以考虑局域网互传一下,或者 u 盘互相 拷一下,以节省流量。 Live Boot 如果使用 Live Boot 模式,需要一个 8G 或以上容量的 U 盘,对照 说明文 档,将 镜像 烧制 U 盘制作引导启动盘。而后,则可通过 BIOS/UEFI 设置 引导启动方式为 U 盘优先,接上 U 盘重启后,系统进入 Kali. 值得注意的是,如果需要保存文件,则需要参照 相应文档 为 U 盘添加 一个分区用于文件存储。 Hyper-V 如果使用 Hyper-V 运行 Kali 镜像,可以在 说明文档 中查看相关导入方法。 如果,你的电脑屏幕是 4K 分辨率,则需要启动 高分辨模式。否则会出现 屏幕显示内容过小,无法正常使用的情况。 1 任务 1. 阅读以下程序,推测执行结果。 2. 编译并执行,验证结果是否与推测结果一致。 3. 分析推测执行结果产生的原因。 注意:编译时,common.h 及 common_threads.h 需与所写文件在同一路 径方可正常编译。 1.1 CPU 1.1.1 程序 cpu.c 1 #include <stdio.h> 2 #include <stdlib.h> 3 #include "common.h" 4 5 int main(int argc, char *argv[]) 6 { 7 if (argc !) 2) 8 { 9 fprintf(stderr, "usage: cpu <string>\n"); 10 exit(1); 11 } 12 char *str = argv[1]; 13 14 while (1) 15 { 16 printf("%s\n", str); 17 Spin(1); 18 } 19 return 0; 20 } 1.1.2 编译 1 gcc -o cpu cup.c -Wall -o 定义输出的可执行文件的名字 -Wall 允许编译器发出所有警告信息,利于提前发现程序中的潜在问题 1.1.3 执行 1. ./cpu A 注意: 该程序将无限执行下去,在 shell 中,可使用 ctrl-c 强行中 止。 2. ./cpu A & ./cpu B & ./cpu C & ./cpu D & 注意: & 将使得程序处于后台运行状态。可使用 killall cpu 终结 所有名字为 cpu 的程序。 1.2 内存 1.2.1 程序 mem.c 1 #include <unistd.h> 2 #include <stdio.h> 3 #include <stdlib.h> 4 #include "common.h" 5 6 int main(int argc, char *argv[]) 7 { 8 if (argc !) 2) 9 { 10 fprintf(stderr, "usage: mem <value>\n"); 11 exit(1); 12 } 13 int *p; 14 p = malloc(sizeof(int)); 15 assert(p !) NULL); 16 printf("(%d) addr pointed to by p: %p\n", (int)getpid(), p); 17 *p = atoi(argv[1]); /) assign value to addr stored in p 18 while (1) 19 { 20 Spin(1); 21 *p = *p + 1; 22 printf("(%d) value of p: %d\n", getpid(), *p); 23 } 24 return 0; 25 } 1.2.2 编译 1 gcc -o mem mem.c -Wall 1.2.3 执行 1. ./mem 0 2. ./mem 0 & ./mem 0 & 可以使用 killall mem 终结所有名字为 mem 的程序。 1.3 多线程 1.3.1 程序 threads.c 1 #include <stdio.h> 2 #include <stdlib.h> 3 #include "common.h" 4 #include "common_threads.h" 5 6 volatile int counter = 0; 7 int loops; 8 9 void *worker(void *arg) 10 { 11 int i; 12 for (i = 0; i < loops; i+)) 13 { 14 counter+); 15 } 16 return NULL; 17 } 18 19 int main(int argc, char *argv[]) 20 { 21 if (argc !) 2) 22 { 23 fprintf(stderr, "usage: threads <loops>\n"); 24 exit(1); 25 } 26 loops = atoi(argv[1]); 27 pthread_t p1, p2; 28 printf("Initial value : %d\n", counter); 29 Pthread_create(&p1, NULL, worker, NULL); 30 Pthread_create(&p2, NULL, worker, NULL); 31 Pthread_join(p1, NULL); 32 Pthread_join(p2, NULL); 33 printf("Final value : %d\n", counter); 34 return 0; 35 } 1.3.2 编译 1 gcc -o threads threads.c -Wall -pthread -pthread 告诉 gcc 程序将使用 pthread 创新线程。 1.3.3 执行 1. ./threads 1000 2. ./threads 10000 3. ./threads 100000 1.4 文件 1.4.1 程序 io.c 1 #include <stdio.h> 2 #include <unistd.h> 3 #include <assert.h> 4 #include <fcntl.h> 5 #include <sys/stat.h> 6 #include <sys/types.h> #include <string.h> 8 9 int main(int argc, char *argv[]) 10 { 11 int fd = open("/tmp/file", O_WRONLY | O_CREAT | O_TRUNC, → S_IRUSR | S_IWUSR); 12 assert(fd >= 0); 13 char buffer[20]; 14 sprintf(buffer, "hello world\n"); 15 int rc = write(fd, buffer, strlen(buffer)); 16 assert(rc =) (strlen(buffer))); 17 fsync(fd); 18 close(fd); 19 return 0; 20 } 1.4.2 编译 1 gcc -o io io.c -Wall 1.4.3 执行 ./io 在 shell 中可以使用 cat 来显示文件内容
最新发布
03-09
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值