迹忆客 专注技术分享

当前位置:主页 > 学无止境 > 编程语言 > C++ >

用 C++ 编写系统调用

作者:迹忆客 最近更新:2023/08/29 浏览次数:

本文将讨论从 C++ 编写的程序中调用写入系统的方法。 首先,我们将快速刷新系统调用,特别是 write 系统调用及其原型。

稍后,我们将讨论从 C++ 程序调用 write 系统调用。


C++ 中的系统调用

每个操作系统都通过系统调用提供一组服务。 它是计算机程序向操作系统请求服务的一种机制。

系统调用提供以下服务:

  1. 流程创建和管理
  2. 主存管理
  3. 文件和文件系统管理
  4. 设备输入/输出
  5. 保护
  6. 联网

程序所需的最频繁的服务是输入/输出。 接下来,我们将讨论 write 系统调用。

程序通过 write 系统调用请求底层操作系统在某些设备上写入。

在进行写入调用之前,了解文件描述符很重要。

文件描述符

在 Unix 和基于 Unix 的操作系统中,文件描述符是唯一标识文件或其他 IO 资源(如套接字或管道)的数字。

通常,文件描述符是一个非负整数值。 程序通过文件描述符访问文件进行IO。

库函数处理 IO 并以文件描述符作为参数。

第一步是按名称打开文件(如果文件不在程序文件夹中,则为绝对/相对路径)以访问文件以进行 IO。

如果 open 函数成功打开一个文件(即,存在同名文件并且用户具有所需的权限),它将返回一个文件描述符。

int fd = open("abc.txt", O_RDONLY | O_CREAT);

open 函数有两个参数。 第一个参数是文件名,第二个参数是读取模式(例如只读模式、只写模式等)。

后续对文件的IO操作都是通过文件描述符进行的。


C++ 中的 write 系统调用

write系统调用是操作系统内核提供的最基本的例程之一。 它将数据从主内存(缓冲区)写入文件(存储在某些硬件设备上)。

write() 系统调用将 buf 指向的内存缓冲区中最多 count 个字节写入文件描述符引用的文件。

它是一个低级函数,只能理解字节。 write 调用不能用于写入记录,例如类。

因此,更高级别的输入输出函数(如 printf())不可避免地要执行复杂的 I/O。

我们首先看一下用于将数据写入文件的 write 系统调用的语法。

ssize_t write(int fd, const void *buf, size_t count);

write函数的三个参数详细信息是:

  1. 文件描述符 fd 是从打开文件的调用中获得的。 它是一个整数值。 还可以分别为标准输入、标准输出和标准错误指定值 0、1 和 2。
  2. 指向内存中缓冲区 buf 的指针,数据存储在主内存中。
  3. count 指定要从缓冲区 buf 写入 fd 指向的文件的字节数。

类型 ssize_t 和 size_t 分别是 stddef.h 中定义的有符号和无符号整数数据类型。

返回值

write 函数返回一个带符号的值。 成功时,它返回成功写入文件的字节数,有时可能小于指定的计数。

总写入字节数小于计数的可能原因可能是输出设备内存已满,或者源写入缓冲区要写入的字符数少于计数中指定的数量。

出错时,write 系统调用返回 -1,并设置 errno 来指示遇到的错误。

在这里,我们有一个完整的程序可以使用 write 系统调用写入文件。

#include<fcntl.h>
#include<errno.h>
#include<iostream>

extern int errno;

using namespace std;

int main() {
    int fd, count;
    fd = open("abc.txt", O_WRONLY | O_CREAT | O_TRUNC, 0644);
    cout << "File descriptor = " << fd << '\n';
    if (fd == -1) {
        // print which type of error have in a code
        printf("Error Number % d\n", errno);
        // print program detail "Success or failure"
        perror("Program");
    }
    char buff[]="This is a test program to check write system call.";
    count = write(fd, buff, 50);
    if (count == -1)
        cout << "Error writing in file";
    else
        cout << "Number of bytes written to the file: " << count << '\n';
    close(fd);
    return 0;
}

第一个头文件 fcntl.h 有一个 write 系统调用。 第二个头文件有错误函数。

在 open 函数调用中,我们以写入模式创建一个新文件名 abc.txt。 该文件之前可能存在,但使用 O_TRUNC 时,之前的内容将被删除,并创建一个新的空文件。

代码0644表示文件权限。 接下来,if 条件检查文件是否成功打开。

如果失败,将显示错误消息。

接下来,我们使用示例文本创建了一个字符数组(用作缓冲区)。 最后,我们写入文件。

第三个参数是 50,表示要从 buff 数组写入的字符数。

计数是从 write() API 调用返回的整数值。 如果失败,该值为-1; 因此,我们检查计数并相应地打印错误消息。

如果写入操作成功,我们将得到一个正值的 count,并且 if 条件将显示成功写入文件的总字节数。

第一个输出值 3 显示文件已成功打开。 第二行50表示50个字节全部写入成功。

接下来,我们修改了 open 语句。

fd = open("abc.txt", O_RDONLY | O_CREAT | O_TRUNC, 0644);

请注意,我们已将 O_WRONLY 替换为 O_RDONLY,结果是,输出为:

File descriptor = -1
Error Number  13
Program: Permission denied
Error writing in file

我们的打开操作失败,因为不可能通过截断内容来以读取模式打开现有文件。

由于失败,您可以看到文件描述符为-1。 另外,写入操作也不成功。

如果我们在 write 系统调用之前关闭文件,结果将是 write 系统调用操作不成功。 在这种情况下,输出应该是这样的:

File descriptor = 3
Error writing in file

这里,文件描述符不为-1,但文件已关闭; 因此,write 系统调用失败。

write系统调用返回的值为-1。 因此,会打印一条错误消息。

转载请发邮件至 1244347461@qq.com 进行申请,经作者同意之后,转载请以链接形式注明出处

本文地址:

相关文章

Arduino 中停止循环

发布时间:2024/03/13 浏览次数:444 分类:C++

可以使用 exit(0),无限循环和 Sleep_n0m1 库在 Arduino 中停止循环。

Arduino 复位

发布时间:2024/03/13 浏览次数:315 分类:C++

可以通过使用复位按钮,Softwarereset 库和 Adafruit SleepyDog 库来复位 Arduino。

Arduino 的字符转换为整型

发布时间:2024/03/13 浏览次数:181 分类:C++

可以使用简单的方法 toInt()函数和 Serial.parseInt()函数将 char 转换为 int。

Arduino 串口打印多个变量

发布时间:2024/03/13 浏览次数:381 分类:C++

可以使用 Serial.print()和 Serial.println()函数在串口监视器上显示变量值。

Arduino if 语句

发布时间:2024/03/13 浏览次数:123 分类:C++

可以使用 if 语句检查 Arduino 中的不同条件。

Arduino ICSP

发布时间:2024/03/13 浏览次数:214 分类:C++

ICSP 引脚用于两个 Arduino 之间的通信以及对 Arduino 引导加载程序进行编程。

使用 C++ 编程 Arduino

发布时间:2024/03/13 浏览次数:127 分类:C++

本教程将讨论使用 Arduino IDE 在 C++ 中对 Arduino 进行编程。

Arduino 中的子程序

发布时间:2024/03/13 浏览次数:168 分类:C++

可以通过在 Arduino 中声明函数来处理子程序。

扫一扫阅读全部技术教程

社交账号
  • https://www.github.com/onmpw
  • qq:1244347461

最新推荐

教程更新

热门标签

扫码一下
查看教程更方便