linuxbingc(IO)系统调用文件接口重定向静态库&动态库软硬链接简单文件系统
Posted 月屯
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了linuxbingc(IO)系统调用文件接口重定向静态库&动态库软硬链接简单文件系统相关的知识,希望对你有一定的参考价值。
目录
系统调用文件接口
open
#include <stdio.h>
#include<iostream>
#include <fcntl.h>
using namespace std;
int main()
int p= open("1.txt",O_RDWR|O_CREAT,0664);
if(p<0)
perror("failed");
return 0;
cout<<"success"<<p;
return 0;
write read lseek close
#include <stdio.h>
#include<iostream>
#include <fcntl.h>
#include <unistd.h>
using namespace std;
int main()
int p= open("1.txt",O_RDWR|O_CREAT,0664);
if(p<0)
perror("failed");
return 0;
cout<<"success"<<p<<endl;
//写
char*r="write success";
cout<<write(p,r,14)<<endl;
//重置指针
lseek(p,0,SEEK_SET);
//读
char r2[15];
cout<<read(p,r2,14)<<endl;
cout<<r2;
return 0;
close(p);
文件描述符
内核理解文件描符
扩展:一个进程可以打开多少个文件描述符
使用 ulimit -a 查看
这个值是可以改变的,通过 ulimit -n 数字改变
文件描述符和文件流指针的区别
源码
文件流指针
grep "struct" . -R//搜索内容指令
1.查看 /usr/include/中的文件,vim stdio.h中的文件
FILE本质是上面的结构体
2.进入 /usr/include/中搜索
grep "struct _IO_FILE" . -R
3.该结构体存在于/usr/include/libio.h中
解释
1.运行代码
#include <stdio.h>
#include <unistd.h>
#include <string.h>
int main()
struct _IO_FILE* fp = fopen("1.txt", "w+");
if(fp == NULL)
perror("fopen");
return 0;
const char* lp = "hello";
fwrite(lp, 1, strlen(lp), fp);
printf("fopen success\\n");
// printf("_fileno : %d\\n", fp->_fileno);
while(1)
sleep(1);
return 0;
相应代码的文件描述符信息
两者联系
struct _IO_FILE…这个结构体是C标准库当中的结构体,而该结构体当中维护的读写缓冲区,就是exit函数会刷新缓冲区的那个缓冲区。
文件流指针对应的结构体 struct _IO_FILE这个结构体内部的成员变量int _fileno(1是标准输出,2标准输入,3错误输出)保存了对应的文件描述符的数值。
重定向
原理
每个文件描述符都是一个内核中文件描述信息数组的下标,对应有一个文件的描述信息用于操作文件,而重定向就是在不改变所操作的文件描述符的情况下,通过改变描述符对应的文件描述信息进而实现改变所操作的文件
重定向的符号
//清空重定向
echo "hello" > 1.txt
//追加重定向
echo "hello" >> 1.txt
重定向接口
int dup2(int oldfd,int newfd)
作用:将newfd的值重定向为oldfd,划newfd拷贝oldfd 参数:oldfd/newfd均是文件描述符
成功:
1.关闭newfd;
2.让newfd指向oldfd对应的struct file*结构体
失败:
1.如果oldfd是一个非法/无效的文件描述符,则重定向失败;newfd没有变化
2.如果oldfd和newfd的值相等,则什么事情都不干
#include <stdio.h>
#include<iostream>
#include <fcntl.h>
#include <unistd.h>
using namespace std;
int main()
int p= open("1.txt",O_RDWR|O_CREAT,0664);
if(p<0)
perror("failed");
return 0;
//重定向
dup2(p,1);
cout<<"123";
close(p);
结果:123输入到1.txt中
内核角度理解重定向
静态库&动态库
库:程序代码的集合(二进制文件)
动态库
特征:
win:没有前缀,后缀为dll
linux:前缀为lib,后缀为.so
生成:
使用gcc/g++编译器,(增加两个命令行参数)
-fPIC
-shared
(生成动态库的代码当中不需要包含main函数(程序入口函数)
//print.h
#pragma once
#include <stdio.h>
void Print();
//print.c
#include "print.h"
void Print()
printf("i am so test\\n");
gcc -fPIC -shared print.c -o libPrint.so
补充: vim的命令模式下 :vs …/print.h 进入其他文件
使用
编译可执行程序的时候,依赖动态库-L [path] :指定动态库所在的路径
-l[动态库的名称(去掉前缴和后纱之后的名称)〕﹔指定编译可执行程序时,依赖的动态库是那个。
- 依赖程序
//刚才写的print.h地址
//main.c
#include "../print.h"
int main()
Print();
2.编译可执行程序
gcc main.c -L .. -lPrint -o print
3.但是此时可执行程序找不到动态库
方案:
1.将动态库放到可执行程序的路径下〔不推荐)
2.配置LD_LIBRARY_ PATH
动态库的环境变量LD_LIBRARY__PATH
推荐大家的方式,公司当中产品在客户机器部署的时候,常用的手段
是修改过程文件生效
3.放到系统库的路径下:/lib64《极力不推荐)
直接 cd/lib64进进去
- 执行可执行程序print
静态库
特征:
win:没有前缀。后缀为.lib
linux :前缀为lib。后缀为.a
生成
使用之前的print.h和print.c
1.第一阶段:使用gcc/g++将源代码编译成目标程序(.o)
gcc -c print.c -o print.o
2.第二阶段:使用ar -rc命令编译目标标程序成为静态库
ar -rc静态库文件名称][目标程序]
ar -rc libPrint.a print.o
3.查看静态库中的目录列表
4.生成可执行程序
//依赖程序main.c
#include "../print.h"
int main()
Print();
gcc main.c -L .. -lPrint -o static
5.运行 ./static程序
注意:如果直接用源代码编译是不行的
如果在编译可执行程序的时候,使用到了静态库,则该静态库会被编译到可执行程序当中。并没有可执行程序依赖动态库动态库的问题(即可执行程序放到哪里都行)
软硬链接
软连接:目标文件的快捷方式
生成:
ln -s 源文件 软连接文件
注意事项:
1.修改软连接文件,源文件也会被修改
2.源文件如果被删除,软连接文件还在的,修改软连接文件、会重新建立源文件,重新建立链接关系(这种要慎重)
一定在删除源文件的时候,将软链接文件也删除掉〈以防后患)
硬链接:目标文件的替身
ln 源文件 硬连接文件
简单文件系统
ext2文件系统
1.超级块(Super Block)︰存放文件系统本身的结构信息。记录的信息主要有: bolck和inode的总量,未使用的block和inode的数量,一个block和inode的大小,最近一次挂载的时同,最近一次写入数据的时间,最近一次检验磁盘的时间等其他文件系统的相关信息。Super Block的信息被破坏,可以说整个文件系统结构就被破坏了
2.GDT,Group Descriptor Table:块组描述符,描述块组属性信息
3.块位图(Block Bitmap) : Block Bitmap中记录着Data Bilock中哪个数据块已经被占用,哪个数据块没有被占用
4.Data blocks存储文件内容的
3和4的关系
5.inode位图(inode Bitmap):每个bit表示一个inode是否空闲可用。
6.i节点表:存放文件属性如文件大小,所有者,最近修改时间等。(软连接和文件的i节点表相同;对于硬链接多个文件引用同一个inode节点的时候,里面的引用计数会++,当文件删除的时候,在目录中对应的记录删除,引用计数会减减,直到引用计数减为0,才会释放inode节点。)
5和6的关系类型3和4
例子
以上是关于linuxbingc(IO)系统调用文件接口重定向静态库&动态库软硬链接简单文件系统的主要内容,如果未能解决你的问题,请参考以下文章
将 NodeJS 服务器端口重定向到子域或文件夹(amazon ec2)
Android 逆向Android 逆向通用工具开发 ( adb forward 网络端口重定向命令 | PC 端逆向程序主函数分析 )