一.系统文件IO
1.open、read、write、lseek、close
int open(const char *pathname, int flags);
ssize_t read(int fd, void *buf, size_t count);
ssize_t write(int fd, const void *buf, size_t count);
off_t lseek(int fd, off_t offset, int whence);
int close(int fd);
2.fd与FILE结构体
int fd:文件描述符:系统调用IO的操作句柄
FILE*:文件流指针:标准库IO接口的操作句柄
库函数与系统调用接口的关系:库函数封装了系统调用接口
文件流指针这个结构体中包含了一个成员变量就是文件描述符
二.支持输入/输出/追加重定向的minishell
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<string.h>
#include<sys/wait.h>
#include<ctype.h>
#include<fcntl.h>
int main()
{
while(1)
{
printf("[liyuchen@localhost]$");
fflush(stdout);
char tmp[1024]={0};
scanf("%[^\n]%*c",tmp);
printf("[%s]\n",tmp);
char *ptr=tmp;
int redirect_flag=0;
char *redirect_file=NULL;
while(*ptr!='\0')
{
if(*ptr=='>')
{
*ptr='\0';
ptr++;
redirect_flag=1;
if(*ptr=='>')
{
*ptr='\0';
ptr++;
redirect_flag=2;
}
while(isspace(*ptr)&&*ptr!='\0')ptr++;
redirect_file=ptr;
while(!isspace(*ptr)&&*ptr!='\0')ptr++;
*ptr='\0';
}
ptr++;
}
ptr=tmp;
int argc=0;
char *argv[32]={NULL};
while(*ptr!='\0')
{
if(!isspace(*ptr))
{
argv[argc]=ptr;
argc++;
while(!isspace(*ptr)&&*ptr!='0')ptr++;
*ptr='\0';
ptr++;
continue;
}
ptr++;
}
argv[argc]=NULL;
if(!strcmp(argv[0],"cd"))
{
chdir(argv[1]);
continue;
}
int pid=fork();
if(pid==0)
{
int fd=1;
if(redirect_flag==1)
{
fd=open(redirect_file,O_CREAT|O_WRONLY|O_TRUNC,0664);
}
else if(redirect_flag==2)
{
fd=open(redirect_file,O_CREAT|O_WRONLY|O_APPEND,0664);
}
dup2(fd,1);
execvp(argv[0],argv);
exit(0);
}
wait(NULL);
}
return 0;
}
三.动态库/静态库
动态库:程序在运行的时候才去链接动态库的代码,多个程序共享使用库的代码
静态库程序在编译链接的时候把库的代码链接到可执行文件中
//add.c
#include <stdio.h>
int add(int a,int b)
{
return a+b;
}
int sub(int a,int b)
{
return a-b;
}
int mul(int a,int b)
{
return a*b;
}
int dev(int a,int b)
{
return a/b;
}
通过gcc -c add.c -o add.o -fPIC指令
动态库生成:gcc --share add.o -o libmyadd.so
静态库生成:ar -cr libmyadd.a add.o
//main.c
#include<stdio.h>
int main()
{
printf("3+3=%d\n",add(3,3));
printf("3-3=%d\n",sub(3,3));
printf("3*3=%d\n",mul(3,3));
printf("3/3=%d\n",dev(3,3));
return 0;
}
库的使用
gcc main.c -o main -L . -lmyadd
1.生成可执行程序时–链接库文件的搜索路径
生成一个可执行程序时,若需要链接一个第三方库,需要将这个第三方库放置到指定路径下
/lib64 /usr/lib64…
也可以使用export LIBRARY_PATH=.环境变量的设置,来设置库的链接搜索路径
gcc的-L选项:指定链接时库的搜索路径
2.运行可执行程序时–动态库的加载搜索路径
程序运行时,若程序是动态链接生成,运行时需要到指定的目录下加载动态库
/lib64 /usr/lib64…
也可以使用export LD_LIBRARY_PATH=.环境变量的设置,来声明程序运行时库的加载路径
LIBRARY_PATH:搜索路径
LD_LIBRARY_PATH:加载搜索路径
结果如图