目录
1.目录操作
1.打开目录 ---opendir()
#include <sys/types.h>
#include <dirent.h>DIR *opendir(const char *name);
参数:
name:要打开的目录名("."表示当前目录)
返回值:成功返回目录流指针,失败返回NULL
2.读取目录 --readdir()
readdir一次只能随机读取1个目录项(文件)
隐藏文件也读出
#include <dirent.h>
struct dirent *readdir(DIR *dirp);
参数:目录流指针
返回值:成功返回结构体指针,失败返回NULL
struct dirent {
ino_t d_ino; /* Inode number */
off_t d_off; /* Not an offset; see below */
unsigned short d_reclen; /* Len gth of this record */
unsigned char d_type; /* Type of file; not supported by all filesystem types */
char d_name[256]; /* Null-terminated filename */
};
实现ls的功能
/*===============================================
* 文件名称:ls.c
* 创 建 者:
* 创建日期:2022年08月06日
* 描 述:
================================================*/
#include <stdio.h>
#include <dirent.h>
#include <unistd.h>
#include <string.h>
int main(int argc, char *argv[])
{
struct dirent *dir;
DIR *dp=opendir(".");
if(dp==NULL)
{
perror(opendir);
return -1;
}
while((dir=readdir(dp))!=NULL)
{
if(dir->d_name[0]!='.')
{
//printf("%s\n",dir->d_name);
//write(1,dir->d_name,strlen(dir->d_name));
fputs(dir->d_name,stdout);
printf(" ");
}
}
printf("\n--------------------------\n");
closedir(dp);
return 0;
}
3.关闭目录 --closedir()
#include <sys/types.h>
#include <dirent.h>int closedir(DIR *dirp);
参数:
dirp:要关闭的目录流指针
返回值:成功返回0,失败返回-1
4.获取文件属性 --lstat
lstat可以获取链接文件的信息,stat只能查取本身文件的信息。fsts,通过文件描述符访问文件信息,lstat通过文件名访问
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>int stat(const char *pathname, struct stat *statbuf);
int fstat(int fd, struct stat *statbuf);
int lstat(const char *pathname, struct stat *statbuf);
参数:pathname:文件名
statbuf:
一级指针,传同类型变量的地址(类似返回值)返回值:成功返回0,失败返回-1
struct stat {
dev_t st_dev; /* ID of device containing file */
ino_t st_ino; /* Inode number */
mode_t st_mode; /* File type and mode */
nlink_t st_nlink; /* Number of hard links */
uid_t st_uid; /* User ID of owner */
gid_t st_gid; /* Group ID of owner */
dev_t st_rdev; /* Device ID (if special file) */
off_t st_size; /* Total size, in bytes */
blksize_t st_blksize; /* Block size for filesystem I/O */
blkcnt_t st_blocks; /* Number of 512B blocks allocated *//* Since Linux 2.6, the kernel supports nanosecond
precision for the following timestamp fields.
For the details before Linux 2.6, see NOTES. */struct timespec st_atim; /* Time of last access */
struct timespec st_mtim; /* Time of last modification */
struct timespec st_ctim; /* Time of last status change */#define st_atime st_atim.tv_sec /* Backward compatibility */
#define st_mtime st_mtim.tv_sec //最后一次修改的秒数
#define st_ctime st_ctim.tv_sec
};
实现ls -l
打印时,不知道数据类型,在编译时一个一个调试
#include <sys/types.h>
#include <grp.h>
#include <sys/types.h>
#include <pwd.h>
getgrgid --得到用户组名的函数
getpwuid --得到用户名的函数
localtime --时间的格式
mode_t st_mode
查找inode(7)
获取文件类型:
S_IFMT 0170000 bit mask for the file type bit fieldS_IFSOCK 0140000 socket
S_IFLNK 0120000 symbolic link
S_IFREG 0100000 regular file
S_IFBLK 0060000 block device
S_IFDIR 0040000 directory
S_IFCHR 0020000 character device
S_IFIFO 0010000 FIFO
如果st_mode & S_IFMT 等于对应文件类型宏,则文件类型宏对应类型就位文件类型
查找文件权限
st_mode & 对应权限宏 ==宏本身 表示具有该权限
S_IRUSR 00400 owner has read permission
S_IWUSR 00200 owner has write permission
S_IXUSR 00100 owner has execute permission
S_IRGRP 00040 group has read permission
S_IWGRP 00020 group has write permission
S_IXGRP 00010 group has execute permission
S_IROTH 00004 others have read permission
S_IWOTH 00002 others have write permission
S_IXOTH 00001 others have execute permission
九个权限,
100 000 000
010 000 000
001 000 000
......
利用1,左移,先打印左移九位的,最后打印左移1位的
2.库的制作
库的本质: 二进制文件
库的类型: 静态库和动态库(共享库)
静态库与动态库的区别在于加载程序的时机不同,编译,运行
库文件一般在/lib /usr/lib
1.静态库
在程序编译阶段(链接阶段),将库中的代码,以复制拷贝的方式加载到源程序中。静态库一般不放入默认文件夹,用-L指明路径
特点:
1.运行时,不需要静态库存在
2.方便移植,可移植性强
3.占资源空间,编译之后可执行文件大
4.优化升级麻烦,需要重新编译源文件
静态库制作流程:
1.先预留接口函数
2.实现所有函数功能
3.生成所有的.c文件的目标文件(以.o结尾的文件)
gcc -c hello.c -o hello.o
4.编译生成静态库。(ar crs 生成静态库)
ar crs libhello.a hello.o
功能函数,头文件,主程序(头文件用"")(1.2)
gcc -c hello.c -o hello.o (3)
ar crs libhello.a hello.o(4)
ar crs 库文件名 *.o 多个.o时
静态库文件的命名规范:
以lib开头,以.a结尾,中间为库名
链接时,链接的是库名
libhello.a --->库文件名
hello --->库名
链接静态库 gcc main.c -lhello (默认去/lib /usr/lib下找)
链接静态库 gcc main.c -L. -lhello (去-L之后的路径找)
2.动态库
在程序编译阶段(),只是将需要用到的函数做一个记录(函数名),最后在程序运行阶段再加载函数代码。动态库一般放入默认文件夹。
特点:
1.运行时,需要动态库存在
2.可移植性差
3.不占资源空间,编译之后可执行文件小
4.优化升级方便,不需要重新编译源文件
动态库的制作流程:
1.先预留接口函数
2.实现所有函数功能
3.将所有的.c文件生成对应的目标文件
gcc -c -fPIC hello.c -o hello.o
-fPIC表示生产位置无关代码
4.编译生成动态库
gcc -shared -o libhello.so hello.o
动态库文件的命名规范:
以lib开头,以.so结尾,中间为库名
libhello.so --->库文件名
hello --->库名
链接动态库
1.把动态库复制到/lib或/usr/lib下
gcc main.c -lhello (默认去/lib /usr/lib下找)
2.在LD_LIBRARY_PATH 环境变量中加上库所在路径 (临时,只对当前shell有效)
3.添加 /etc/ld.so.conf.d/my.conf文件,把库所在的路径添加到文件末尾,并执行ldconfig刷新。这样,加入的目录下的所有库文件都可见
3、进程
程序:静态的,是有序数据指令的集合
进程:正在执行的程序
系统分配资源的最小单位,总称。进程是程序执行的一次完整过程(创建、调用、执行、消亡)
程序的组成:
正文段,用户数据段
1.进程的组成:
PCB:
进程ID:
用户名、用户组名
进程的状态,优先级
文件描述符表
pc(程序寄存器):
记录程序下一条指令的地址
保存现场情况,以便继续运行
堆栈(栈):
2.进程的类型:
1.交互进程
与终端相关(终端关了,进程无法运行),可以在前台运行,也可以在后台运行
可执行文件 &(后台程序运行)
kill -9 pid号 结束进程
2.批处理进程
与终端无关,可以将指定的进程放在一个工作队列中按顺序执行,一般由系统管理员操作
3.守护进程
与终端无关,在后台一直循环执行任务
3.进程的状态
+前台进程 > < 优先级
R --运行态(就绪态):正在运行或者准备运行的进程
等待态:两种等待态,区别在于是否能被信号打断。
S --(sleep)睡眠态/可中断等待态:等待某种资源,资源来了继续执行
D --(deep sleep)不可中断等待态
T --暂停态:暂停运行,知道有信号唤醒为止
Z --僵尸态:进程结束之后没有进行资源回收,该进程状态变成僵尸态,占资源,不回应