Linux系统编程(1)

父子进程通过两个管道进行通信。

 

伪代码
#include <unistd.h>
void client(int, int), server(int, int);int main(int argc, char** argv) {int pipe1[2], pipe2[2];pid_t childpid;Pipe(pipe1);Pipe(pipe2);if ((childpid == Fork()) == 0) {// childClose(pipe1[1]);Close(pipe2[0]);server(pipe1[0], pipe2[1]);exit(0);}// parentClose(pipe1[0]);Close(pipe2[1]);client(pipe2[0], pipe1[1]);Waitpid(childpid, NULL, 0);exit(0);
}

open()函数

int fd;
fd = open("test.txt", O_RDONLY);
if (fd == -1) {//错误
}==========================================
int fd;
//如果文件存在,则截断文件,文件不存在,则创建,并且后面指定了文件的权限
fd = open(file, O_WRONLY | O_CREAT | O_TRUNC, S_IWUSR | S_IRUSR | S_IWGRP | S_IRGRP | S_IROTH);

creat()函数

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>int fd;
fd = creat(file, 0644);
if (fd == -1) 和
fd = open(file, O_RWONLY | O_CREAT | O_TRUNC, 0644);
是一样的效果。

read()函数

#include <unistd.h>
ssize_t read(int fd, void* buf, size_t len);从文件描述符fd对应当前的位置读取len字节到buf中,执行成功返回读取的字节数,失败返回-1并设置errno,ssize_t ret;
while(len != 0 && (ret = read(fd, buf, len)) != 0) {if (ret == -1) {if (errno == EINTR) continue;perror("read");break;}len -= ret;buf += ret;
}

 lseek()查找文件位置

#include <sys/types.h>
#include <unistd.h>off_t lseek (int fd, off_t pos, int origin);

origin参数主要有一下值:

SEEK_CUR:fd的当前文件位置被设置为当前值+pos(其值可是负数,0,正数),pos为零时,返回当前位置。

SEEK_END:fd的当前位置被设定为文件的当前长度+pos(其值可是负数,0,正数),pos为零时,当前位置为文件的末端。

SEEK_SET:fd的当前位置被设置为pos,pos为零时,偏移值为文件的开头。

此调用执行成功时,返回新的文件位置,执行错误时,返回-1,并且将errno设置为适当值。

//将文件fd的位置设置为1825
ret = lseek(fd, (off_t)1825, SEEK_SET);
if (ret == (off_t)-1)//将文件的位置设置为文件的末端
ret = lseek(fd, 0, SEEK_END);//找到文件当前的位置
ret = lseek(fd, 0, SEEK_CUR);

pread()和pwrite()函数

#define _XOPEN_SOURCE 500
#include <unistd.h>
ssize_t pread(int fd, void* buf, size_t count, off_t pos);此调用会从文件fd的pos位置读取count字节放入到buf中ssize_t pwrite(int fd, const void*buf, size_t count, off_t pos);将count字节从buf中写入到fd的文件pos位置以上两个调用不会改变文件的位置

截短文件ftruncate(int fd, off_t len)和truncate(const char* path, off_t len);

#include <unistd.h>
#include <sys/types.h>
int ftruncate(int fd, off_t len);int truncate(const char* path, off_t len);

 这两个系统调用会将指定的文件截短成len所指定的长度,不改变文件当前位置。

 select()  

#include <stdio.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>#define TIMEOUT 5    //select的等待时间,秒为单位
#define BUF_LEN 1024  //读取缓冲区,字节为单位
//编译:    gcc -o select_test select_test.cpp
int main(void) {struct timeval tv;fd_set readfds;int ret;// 等候stdin的输入数据FD_ZERO(&readfds);FD_SET(STDIN_FILENO, &readfds);// 等候5秒的时间tv.tv_sec = TIMEOUT;tv.tv_usec = 0;ret = select(STDIN_FILENO+1, &readfds, NULL, NULL, &tv);if (ret == -1) {perror("select");return 1;} else if(!ret) {printf("%d seconds elapsed.\n", TIMEOUT);return 0;}// 是否可读if (FD_ISSET(STDIN_FILENO, &readfds)) {char buf[BUF_LEN+1];int len;// 保证不会遭到阻挡len = read(STDIN_FILENO, buf, BUF_LEN);if (len == -1) {perror("read");return 1;}if (len) {buf[len] = '\0';printf("read: %s\n", buf);}return 0;}fprintf(stderr, "This should not happen!\n");return 1;
}

poll()函数

#include <stdio.h>
#include <sys/poll.h>
#include <unistd.h>#define TIMEOUT 5   //poll的等待时间
/*
使用poll()同时检查由读取stdin以及写入stdout是否会受到阻挡
*/int main() {struct pollfd fds[2];int ret;// 查看stdin输入fds[0].fd = STDIN_FILENO;fds[0].events = POLLIN;// 查看stdout是否可供写入fds[1].fd = STDOUT_FILENO;fds[1].events = POLLOUT;ret = poll(fds, 2, TIMEOUT*1000);if (ret == -1) {perror("poll");return 1;} if (!ret) {printf("%d seconds elapsed.\n", TIMEOUT);return 0;}if (fds[0].revents & POLLIN) {printf("stdin is readable\n");}if (fds[1].revents & POLLOUT) {printf("stdout is writable\n");}return 0;
}

运行上述程序

./poll

输出stdout is writable

添加一个输入,运行

./poll < xxxx.txt

stdin is readable

stdout is writable

fdopen()将一个已打开的文件描述符fd转成流

#include <stdio.h>
FILE * fdopen(int fd, const char* mode);

关闭流

fclose()关闭流

#include <stdio.h>
int fclose(FILE* stream);

关闭所有流

#define _GNU_SOURCE
#include <stdio.h>
int fcloseall(void);

一次读取一个字符

#include <stdio.h>
//返回类型需是int类型
int fgetc(FILE* stream);

将字符放回

#include <stdio.h>
int ungetc(int c, FILE* stream);

读取一整行

#include <stdio.h>
char* fgets(char* str, int size, FILE* stream);
char* s;
int c;
s = str;
while(--n>0 && (c = fgetc(stream)) != EOF) {*s++ = c;
}
*s = '\0';

遇到d时停止读取

char* s;
int c = 0;
s = str;
while(--n>0 && (c = fgetc(stream)) != EOF && (*s++ = c) != d);
if (c == d)*--s = '\0';
else*s = '\0';

读取二进制数据

#include <stdio.h>
size_t fread(void* buf, size_t size, size_t nr, FILE* stream);

写入一个字符

#include <stdio.h>
int fputc(int c, FILE* stream);

写入一个字符串

#include <stdio.h>
int fputs(const char* str, FILE* stream)

fputs()会把str所指向的以null分割的字符串全部写入到stream流中,执行成功返回一个非负值,执行失败,返回EOF。

写入二进制数据

#include <stdio.h>
size_t fwrite(void* buf, size_t size, size_t nr, FILE* stream);
执行成功返回写入的元素数目,而不是字节数,执行失败,返回一个小于nr的值,指发生了错误。

 

#include <stdio.h>int main() {FILE* in, *out;struct pirate {char             name[100];   //姓名unsigned long    booty;       unsigned int     beard_len;} p, blackbeard = {"Edward Teach", 950, 48};// 将blackbear写入一个流中,再读出来out = fopen("data", "w");if (!out) {perror("fopen");return 1;}if (!fwrite(&blackbeard, sizeof(struct pirate), 1, out)) {perror("fwrite");return 1;}if (fclose(out)) {perror("fclose");return 1;}in = fopen("data", "r");if (!in) {perror("fopen");return 1;}if (!fread(&p, sizeof(struct pirate), 1, in)) {perror("fread");return 1;}if (fclose(in)) {perror("fclose");return 1;}printf("name=\"%s\" booty=%lu beard_len = %u\n", p.name, p.booty, p.beard_len);return 0;
}

查找流fseek()

#include <stdio.h>
int fseek(FILE* stream, long offset, int whence);

 如果whence的值被设置为SEEK_SET,则文件位置会被设置为offset,如果whence的值被设置为SEEK_CUR,则文件位置会被设置为当前位置加上offset,如果whence的值被设置为SEEK_END,则文件的位置会被设置为文件末端加上offset。

执行成功时返回0,清除EOF的指示器并取消ungetc()所造成的影响(如果有的话),发生错误返回-1,并将errno设置为适当值,

 fsetpos()

#include <stdio.h>
int fsetpos(FILE* stream, fpos_t *pos);

将流重新设置为开头

#include <stdio.h>
void rewind(FILE* stream);//调用如下
rewind(stream)
和下面的功能相同
fseek(stream,0, SEEK_SET);

注意:rewind没有返回值,因此无法传达错误信息,如果要确认错误信息,需要调用之前先清除errno的值,在事后检查。

errno = 0;
rewind(stream);
if (errno)//错误

获取当前位置

lseek()函数调用结束会返回当前位置,fseek()函数不会,要获得当前位置使用ftell()函数

#include <stdio.h>
long ftell(TILE* stream);

发生错误返回-1,并且将errno设置为合适的值。

fgetpos()

#include <stdio.h>
int fgetpos(FILE* stream, fpos_t *pos);

成功返回0,并且将位置保存在pos中。

 刷新一个流

#include <stdio.h>
int fflush(FILE* stream);

将流中的数据刷新至内核,如果stream为NULL,则进程中所有的流都会被刷新。

 检查错误ferror()

#include <stdio.h>
int ferror(FILE* stream);

 用于检查流上是否有错误。

feof()用于检测stream上是否设置了EOF指示器。

#include <stdio.h>
int feof(FILE* stream);

 clearerr()用于清除stream之上的错误和EOF指示器。

#include <stdio.h.
void clearerr(FILE* stream);

获得相应的文件描述符

#include <stdio.h>
int fileno(FILE* stream);

设置缓冲模式
 

#include <stdio.h>
int setvbuf(FILE* stream, char* buf, int mod, size_t size);

setvbuf()函数会将stream的缓冲区设置为mode类型,_IONBF:未经缓冲,_IOLBF:行缓冲,_IOFBF:经块缓冲。_IONBF(在此情况下会忽略buf和size)除外,buf会指向一个大小为size字节的缓冲区,而标准IO将以此为特定流的缓冲区,如果buf的值为NULL,则glibc会自动分配一个缓冲区。

打开流之后,必须setvbuf函数,而且必须在对流执行任何操作之前进行.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/120901.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

上网Tips: Linux截取动态效果图工具_byzanz

链接1 链接2 安装&#xff1a; sudo apt-get install byzanz 查看指令 说明 byzanz-record --help日常操作 xwininfo点击 待录制窗口 左上角 byzanz-record -x 72 -y 64 -w 1848 -h 893 -d 10 --delay5 -c /home/xixi/myGIF/test.gif小工具 获取鼠标坐标 xdotool getm…

python使用mitmproxy和mitmdump抓包之拦截和修改包(四)

我认为mitmproxy最强大的地方&#xff0c;就是mitmdump可以结合python代码&#xff0c;灵活拦截和处理数据包。 首先&#xff0c;mitmdump的路径如下&#xff1a;&#xff08;使用pip3 install mitmproxy安装的情况&#xff0c;参考我的文章python使用mitmproxy和mitmdump抓包…

Django(21):使用Celery任务框架

目录 Celery介绍Celery安装Celery使用项目文件和配置启动Celery编写任务调用异步任务查看任务执行状态及结果 设置定时和周期性任务配置文件添加任务Django Admin添加周期性任务启动任务调度器beat Flower监控任务执行状态Celery高级用法与注意事项给任务设置最大重试次数不同任…

【Orange Pi】Orange Pi5 Plus 安装记录

官网&#xff1a;Orange Pi - Orangepi 主控芯片&#xff1a;Rockchip RK3588(8nm LP制程&#xff09;NPU&#xff1a;内嵌的 NPU 支持INT4/INT8/INT16/FP16混合运算&#xff0c;算力高达 6Top支持的操作系统&#xff1a; Orangepi OS&#xff08;Droid&#xff09;Orangepi O…

lwIP 开发指南(下)

目录 NETCONN 编程接口简介netbuf 数据缓冲区netconn 连接结构netconn 编程API 函数 NETCONN 编程接口UDP 实验NETCONN 实现UDPNETCONN 接口的UDP 实验硬件设计软件设计下载验证 NETCONN 接口编程TCP 客户端实验NETCONN 实现TCP 客户端连接步骤NETCONN 接口的TCPClient 实验硬件…

华为智能企业远程办公安全解决方案(1)

华为智能企业远程办公安全解决方案&#xff08;1&#xff09; 课程地址方案背景需求分析企业远程办公业务概述企业远程办公安全风险分析企业远程办公环境搭建需求分析 方案设计组网架构设备选型方案亮点 课程地址 本方案相关课程资源已在华为O3社区发布&#xff0c;可按照以下…

Vue组件通信方式

1.props通信 1.1在 Vue 2 中使用 props 通信 注意:props传递的数据是只读的,子组件修改,不会影响父组件 1.1.1.定义 props 在子组件中使用 props 选项来定义要接收的属性 // 子组件 <script> export default {props: {message: String} } </script>1.1.2.传递…

预编译(1)

目录 预定义符号&#xff1a; 使用&#xff1a; 结果&#xff1a; 预编译前后对比&#xff1a; #define定义常量&#xff1a; 基本语法&#xff1a; 举例1&#xff1a; 结果&#xff1a; 预编译前后对比&#xff1a; 举例2&#xff1a; 预编译前后对比&#xff1a; 注…

Lua表公共操作

--表的公共操作 t1 {{age 1,name "123"},{age 2,name "456"}} t2 {name "Holens" , sex true} --插入 print(#t1) table.insert(t1,t2) print(#t1) print(t1[3].sex) print("*************************************")--删除 -…

wordpress插件-免费的wordpress全套插件

在当今数字化时代&#xff0c;网站和博客已经成为信息传递、观点分享和商业交流的重要平台。在这个背景下&#xff0c;WordPress作为最受欢迎的内容管理系统之一&#xff0c;无疑扮演着至关重要的角色。然而&#xff0c;要保持一个成功的WordPress网站&#xff0c;不仅需要出色…

关于操作系统与内核科普

关于操作系统与内核科普 一.什么是操作系统 操作系统是管理计算机硬件与软件资源的计算机程序。它为计算机硬件和软件提供了一种中间层。 操作系统是一种软件&#xff0c;主要目的有三种&#xff1a; 一.管理计算机资源&#xff0c;这些资源包括CPU&#xff0c;内存&#xff0…

【算法分析与设计】动态规划(下)

目录 一、最长公共子序列1.1 最长公共子序列的结构1.2 子问题的递归结构1.3 计算最优值1.4 举例说明1.5 算法的改进 二、最大子段和2.1 代码2.2 最大子段和问题的分治算法2.3 代码2.4 分治算法的时间复杂度2.5 最大子段和问题的动态规划算法 三、凸多边形最优三角剖分3.1 三角剖…