设为首页 收藏本站
查看: 1514|回复: 0

[经验分享] Linux 系统函数open、close、read、write、fcntl 简单应用

[复制链接]

尚未签到

发表于 2019-1-27 07:54:35 | 显示全部楼层 |阅读模式
系统调用
  系统调用是操作系统提供给用户的一组“特殊接口”。系统调用并非直接和程序员或系统管理员直接打交道,而是通过软中断的方式向内核提交请求,从而获取内核函数的服务入口(系统调用表)。系统调用让系统从用户空间进入内核空间内运行,运行后将结果返回给应用程序(内核态->用户空间)。



系统调用和系统API等区别
  
系统API
主要是通过C库libc来实现,程序员多采用这种方式与内核交互,这些API通过系统调用来实现

系统命令
系统管理员采用系统命令与内核交互,是一个可执行文件,通过系统API及系统调用来实现

外壳程序
一系列系统命令和SHELL脚本共同组合成的程序。


函数库调用 与 系统调用



文件描述符
  
-每个进程PCB结构中有文件描述符指针,指向files_struct的文件描述符表,记录每个进程打开的文件列表
-系统内核不允许应用程序访问进程的文件描述符表,只返回这些结构的索引即文件描述符ID(File Description)给应用程序
-Linux系统中,应用程序通过这些文件描述符来实现让内核对文件的访问
-每个进程能够访问的文件描述符是有限制的,通过#ulimit –n可以查看


特殊文件描述符
  标准输入STDIN_FILENO
标准输出STDOUT_FILENO
标准错误STDERR_FILENO

每个进程被加载后,默认打开0,1,2这三个文件描述符
  

open
  
-函数原型
int open(const char *path, int flags,mode_t mode);
-参数
path :文件的名称,可以包含(绝对和相对)路径
flags:文件打开模式
mode:  用来规定对该文件的所有者,文件的用户组及系统中其他用户的访问权限,则文件权限为:mode&(~umask)
-返回值
打开成功,返回文件描述符;
打开失败,返回-1
  

打开方式


访问权限


O_CREATE会产生特殊权限,需要设置访问权限:
S_IRWXU等价于 S_IRUSR|S_IWUSR|S_IXUSR (文件所有者)
S_IRWXG 等价于 S_IRGRP|S_IWGRP|S_IXGRP (文件用户组)
S_IRWXO 等价于 S_IROTH|S_IWOTH|S_IXOTH (文件其他用户)


close
  关闭文件close(将进程中fd对应的文件描述表结构释放):
函数原型:int close(int fd); //如果出现错误,返回-1;调用成功返回0


read
  -函数原型:
int read(int fd, void *buf, size_t nbytes);
-参数
fd :想要读的文件的文件描述符
buf:  指向内存块的指针,从文件中读取来的字节放到这个内存块中
nbytes: 从该文件复制到buf中的字节个数
-返回值
如果出现错误,返回-1;
返回从该文件复制到规定的缓冲区中的字节数!


write
  -函数原型:int write(int fd,void *buf,size_t nbytes);
-函数参数:
fd :要写入的文件的文件描述符
buf:  指向内存块的指针,从这个内存块中读取数据写入          到文件中
nbytes: 要写入文件的字节个数
-返回值
如果出现错误,返回-1
如果写入成功,则返回写入到文件中的字节个数

练习:采用文件系统调用的方式,完成串口通讯配置文件的读写

配置文件serial.cfg如下:


要求:1、程序运行命令格式:
serialchat [-options];
[options]:
p-输出打印serial.cfg各个配置项信息,格式:参数-----参数值;
s-进行菜单(有保存和退出)让用户设置;
f-指定配配置项设置,输出各选项置文件名,并输出各配置项信息   
其他选项提示该程序用法帮助。
2、不支持serialchat运行两次
3、如果无法找到配置文件,则提示运行失败,原因:配置文件无法找到

代码如下:

#include   < stdio.h>
#include   < string.h>
#include   < sys/types.h>
#include   < sys/stat.h>
#include   < unistd.h>
#include    < fcntl.h>
int icount = 0;
//去空格 '\0'
void rm_space(char *pStr)
{
char *pos = pStr;
pos = strchr(pStr,' ');
while(pos != NULL)
{
strcpy(pos,pos+1);
pos = strchr(pos,' ');
}
}
//去注释 '#' '\n#'和中文,留下\n ... \r之间的数据
void rm_annotation(char *pStr)
{
icount++;
char *pos = pStr;
char *end = NULL;
if(icount == 1) //第一行有可能顶格
{
pos = strchr(pStr,'#');
}
else
{
pos = strstr(pStr,"\n#");
}
while(pos != NULL)
{
end = strchr(pos+1,'\n');
strcpy(pos,end);
pos = strstr(pStr,"\n#");
}   
}
//输出配置项信息
void printMsg(char *buf)
{
char key[20] = " ";
char value[20] = " ";
char line[50] = " ";
char *pos = buf;
char *end = NULL;
int flag = 0;
printf("配置项信息如下:\n");
pos = strchr(buf,'\n');
end = strchr(pos,'=');
while(end != NULL)
{
memset(key,0,sizeof(key));
memset(value,0,sizeof(value));
memcpy(key,pos+1,end - (pos + 1));
pos = end;
end = strchr(pos,'\r');
if(end == NULL) //if the final data
{
flag = 1;
break;
}
memcpy(value,pos+1,end - (pos + 1));
sprintf(line,"%s-----%s",key,value);
printf("%s\n",line);
pos = end + 1;
end = strchr(pos,'=');  
}
if(flag)   
{
end = strchr(pos,'\0');
memcpy(value,pos+1,end - (pos + 1));
sprintf(line,"%s-----%s",key,value);
printf("%s\n",line);
}
}
//修改配置文件 (传入的buf是未经处理的)
void updateFile(int fd,char *buf)
{
char *pos = buf;
char *end = NULL;
char key[20] = "";
char newvalue[20] = "";
int lse;
int count;
printf("请输入配置参数: ");
scanf("%s",key);
printf("请输入配置参数的值: ");
scanf("%s",newvalue);
strcat(key,"=");
pos = strstr(buf,key);
if(pos == NULL)
{
printf("输入参数不存在!");
return;
}
pos = pos + strlen(key);
while(*pos == ' ')  //处理'='后面有空格的情况
{
pos = pos + 1;
}
end = strchr(pos,'\r');
if(end == NULL) //if the final data
{
end = strchr(pos,'\0');
}
//修改文件
lse = lseek(fd,pos-buf,SEEK_SET);
write(fd,newvalue,end-pos); //注意新旧值的长度
printf("修改成功!\n");
}
/*--------------------主函数---------------------*/
int main(int argc,char *argv[])
{
int fd;
int readByte = 0;
char buf[512] = "";
char option[3] = "";
char filename[20] = "";
int  index;
int s_flag = 0;
int f_flag = 0;
struct flock lock = {0};
//判断参数个数
if(argc !=2 && argc != 3)
{
printf("输入格式有误!\n");
return 1;
}
//打开配置文件
strcpy(option,argv[1]);
if(strcmp(option,"-f") == 0)    //打开指定文件
{
if(argc != 3)
{
printf("输入格式有误!\n");
return 1;
}
f_flag = 1;
strcpy(filename,argv[2]);
fd = open(filename,O_RDWR,S_IRWXU|S_IRGRP);
}
else
{
fd = open("serial.cfg",O_RDWR,S_IRWXU|S_IRGRP);
}
if(fd == -1)
{
printf("运行失败,无法找到配置文件!\n");
return 1;
}
//读取配置文件
readByte = read(fd,buf,512);
if(readByte

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-668025-1-1.html 上篇帖子: 【symfoware OPEN】数据库基本操作 下篇帖子: ITAA
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表