这是linux下的C编程 将系统调用改为函数调用 希望可以学习一些细节和方法 麻烦各位高手了

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>

#define BUF_SIZE 1024
#define READ_LEN 10
/**************************************************************
name:test_lseek
description:This function is use to test lseek function
par:fd/
offset/
where/
read_len/
return:
***************************************************************/
void test_lseek(int fd,off_t offset,int where,int read_len)
{
off_t result;
char temp[20],len;
result = lseek(fd,offset,where);
printf("lseek function options is SEEK_SET and return value is %d\n",result);
if (result != -1)
{
memset(temp,'\n',sizeof(temp));
if ((len=read(fd,temp,read_len))>0)
{
write(1,temp,(len+1));
}
}
else
{
perror("lseek function seek error occured:");
}
}

int main(int argc,char *argv[])
{
char buf[BUF_SIZE];
int in,out,len;

in = open("./main.c",O_RDONLY);
if (in == -1)
{
perror("Error occured when open file main.c:");
exit(1);
}

test_lseek(in,5,SEEK_SET,10);//Call test_lseek to test lseek function
test_lseek(in,5,SEEK_CUR,10);
test_lseek(in,-10,SEEK_END,10);

out = open("./mainnew.c",O_WRONLY | O_CREAT | O_EXCL,S_IRUSR | S_IWUSR | S_IRGRP);
if (out == -1)
{
out = open("./mainnew.c",O_WRONLY | O_TRUNC);
if (out == -1)
{
close(in);
perror("Error occured when open and create file mainnew.c:");
exit(1);
}
}

lseek(in,0,SEEK_SET) ;
while((len=read(in,buf,READ_LEN))!=0)
{
write(out,buf,len);
}
if ((close(in)==-1) || (close(out)==-1))
{
perror("Error occured when close file:");
exit(1);
}
exit(0);
}

不知道你想要知道什么,我给你逐句解释下吧:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h> //头文件不用解释

#define BUF_SIZE 1024 //两个宏定义
#define READ_LEN 10
/**************************************************************
name:test_lseek
description:This function is use to test lseek function
par:fd/
offset/
where/
read_len/
return:
***************************************************************/
void test_lseek(int fd,off_t offset,int where,int read_len) //你自己写的函数,此函数调用系统函
//数lseek
{
off_t result; //局部变量,存储结果,这个off_t相当于int,是个格式,具体是什么你
//查查书
char temp[20],len; //定义一个数组和一个char型变量
result = lseek(fd,offset,where); //调用系统函数lseek,结果存在result中,函数具体作
//用你查查书,应该是移动指针,把指针放在文件要读写的某个地方
printf("lseek function options is SEEK_SET and return value is %d\n",result);
if (result != -1)//如果lseek成功,做以下动作
{
memset(temp,'\n',sizeof(temp)); //将temp中全部赋值为\n
if ((len=read(fd,temp,read_len))>0)//从当前lseek之后的指针位置开始读取
//read_len长度的字节放入temp中,读取的实际长度为返回值len
{
write(1,temp,(len+1)); 将temp中的数据写到标准输出上,也就是
//屏幕上,长度为len+1
}
}
else //如果失败,执行以下动作
{
perror("lseek function seek error occured:");
}
}

int main(int argc,char *argv[]) //主函数
{
char buf[BUF_SIZE];
int in,out,len;

in = open("./main.c",O_RDONLY); //打开要读取的文件,只读方式
if (in == -1) //如果打开失败,执行以下动作
{
perror("Error occured when open file main.c:");
exit(1);
}

test_lseek(in,5,SEEK_SET,10);//Call test_lseek to test lseek function
test_lseek(in,5,SEEK_CUR,10); //调用上面你自己定义的函数
test_lseek(in,-10,SEEK_END,10);

out = open("./mainnew.c",O_WRONLY | O_CREAT | O_EXCL,S_IRUSR | S_IWUSR | S_IRGRP); //以只写的方式打开文件,后面的O_CREAT什么意思,自己找书
if (out == -1) //打开失败
{
out = open("./mainnew.c",O_WRONLY | O_TRUNC);//如果打开失败再次换
//种方式打开,具体为什么你找书看看O_TRUNC什么意思就可以推测下了
if (out == -1)//这次是真的失败了
{
close(in);
perror("Error occured when open and create file mainnew.c:");
exit(1);
}
}

lseek(in,0,SEEK_SET);//直接调用系统函数,将指针放在文件开头
while((len=read(in,buf,READ_LEN))!=0) //将文件里的东西全部输出来
{
write(out,buf,len);
}
if ((close(in)==-1) || (close(out)==-1)) //关闭文件
{
perror("Error occured when close file:");
exit(1);
}
exit(0);
}
好了,就说这么多了,还有不明白的可以给我留言
温馨提示:答案为网友推荐,仅供参考
第1个回答  2011-07-28
看了几次你的标题才明白你要干吗...

你是说希望对于类似lseek和close这样的系统调用,你希望看到实现细节实现是吗?

大部分的系统调用,是因为涉及到太多底层的操作(和硬件相关或者需要修改内核数据),而又大量使用到,才封装成系统调用的。这些系统调用的实现细节在glibc中,而glibc是一个用户空间运行的库,它会初步检查参数的合法性,然后通过sysenter或者int $80(这两个是汇编语言的命令)这样的系统调,并且给出特定的系统调用号和参数,使得执行程序进入内核态执行系统调用号指定的函数,然后才能修改内核数据或者接触到实际硬件。所以,很多调用你即使去阅读glibc源码,也可能无法看到你最想看到的那部分实现代码。

例如,一次read调用,先是根据#include <stdio.h>,找到glibc里面的对应的函数,然后可能做一些检查参数之类的前期工作,然后就使用了sysenter这类指令使得进程跳到内核态,然后开始根据系统调用号,将参数传递给sys_read并执行,它又会调用到vfs(虚拟文件系统)的函数,继而调用到特定于文件系统的打开函数,然后才是设备相关的驱动程序。最后再逐层返回。(我上面的描述不是精确的描述,但是基本是这么个一层一层的调用并返回的过程)。
又比如,printf函数,这样一个简答的函数,你需要通过系统调用,系统调用将数据准备好,然后又调用中断,此时中断服务程序将数据送给设备,设备才将printf的内容最终显示在显示器上。

所以,你希望看细节的话,当然是没问题,只是往往不够直接,你需要去看更多操作系统底层实现,会比较繁琐,如果有兴趣你可以去参考《understanding linux kernel》,其中专门有一章解释系统调用,还有文件系统那部分,也有一章会专门以用户空间的一次open(记不清了,也可能是read或者write)调用,到底经过哪些细节过程,最后返回。
第2个回答  2011-07-28
- -
相似回答