ril进程源码阅读札记

时间:2022-12-28 08:41:03

1、access函数

头文件:io.h  功 能: 确定文件或文件夹的访问权限。即,检查某个文件的存取方式,比如说是只读方式、只写方式等。如果指定的存取方式有效,则函数返回0,否则函数返回-1。  用 法: int access(const char *filenpath, int mode); 或者int _access( const char *path, int mode );  参数说明:  filenpath  文件或文件夹的路径,当前目录直接使用文件或文件夹名  备注:当该参数为文件的时候,access函数能使用mode参数所有的值,当该参数为文件夹的时候,access函数值能判断文件夹是否存在。在WIN NT 中,所有的文件夹都有读和写权限  mode  要判断的模式  在头文件unistd.h中的预定义如下:  #define R_OK 4 /* Test for read permission. */  #define W_OK 2 /* Test for write permission. */  #define X_OK 1 /* Test for execute permission. */  #define F_OK 0 /* Test for existence. */  具体含义如下:  R_OK 只判断是否有读权限  W_OK 只判断是否有写权限  X_OK 判断是否有执行权限  F_OK 只判断是否存在  access函数程序范例(C语言中)  #include <stdio.h>  #include <io.h>  int file_exists(char *filename);  int main(void)  {  printf("Does NOTEXIST.FIL exist: %s\n",  file_exists("NOTEXISTS.FIL") ? "YES" : "NO");  return 0;  }  int file_exists(char *filename)  {  return (access(filename, 0) == 0);  }

2、opendir函数

头文件:#include <sys/types.h>   #include <dirent.h>

定义函数:DIR * opendir(const char * name);

函数说明:opendir()用来打开参数name 指定的目录, 并返回DIR*形态的目录流, 和open()类似, 接下来对目录的读取和搜索都要使用此返回值.

返回值:成功则返回DIR* 型态的目录流, 打开失败则返回NULL.

错误代码:
1、EACCESS 权限不足。
2、EMFILE 已达到进程可同时打开的文件数上限。
3、ENFILE 已达到系统可同时打开的文件数上限。
4、ENOTDIR 参数name 非真正的目录。
5、ENOENT 参数name 指定的目录不存在, 或是参数name 为一空字符串。
6、ENOMEM 核心内存不足。


3、readdir函数

头文件:#include <sys/types.h>   #include <dirent.h>

定义函数:struct dirent * readdir(DIR * dir);

函数说明:readdir()返回参数dir 目录流的下个目录进入点。结构dirent 定义如下:
struct dirent
{
    ino_t d_ino; //d_ino 此目录进入点的inode
    ff_t d_off; //d_off 目录文件开头至此目录进入点的位移
    signed short int d_reclen; //d_reclen _name 的长度, 不包含NULL 字符
    unsigned char d_type; //d_type d_name 所指的文件类型 d_name 文件名
    har d_name[256];
};

返回值:成功则返回下个目录进入点. 有错误发生或读取到目录文件尾则返回NULL.

附加说明:EBADF 参数dir 为无效的目录流。

范例
#include <sys/types.h>
#include <dirent.h>
#include <unistd.h>
main()
{
    DIR * dir;
    struct dirent * ptr;
    int i;
    dir = opendir("/etc/rc.d");
    while((ptr = readdir(dir)) != NULL)
    {
        printf("d_name : %s\n", ptr->d_name);
    }
    closedir(dir);
}
执行:
d_name : .
d_name : ..
d_name : init.d
d_name : rc0.d
d_name : rc1.d
d_name : rc2.d
d_name : rc3.d
d_name : rc4.d
d_name : rc5.d
d_name : rc6.d
d_name : rc
d_name : rc.local
d_name : rc.sysinit

4、chdir函数

int chdir(const char *path );

 

说明:chdir函数用于改变当前工作目录。调用参数是指向目录的指针,调用进程需要有搜索整个目录的权限。每个进程都具有一个当前工作目录。在解析相对目录引用时,该目录是搜索路径的开始之处。如果调用进程更改了目录,则它只对该进程有效,而不能影响调用它的那个进程。在退出程序时,shell还会返回开始时的那个工作目录。

(1)内核解析参数中的路径名,并确保这个路径名有效。为了做到这一点,就路径名解析而言,内核使用相同的算法。如果路径名无效,它输出错误消息并退出。

(2)如果路径名有效,内核定位该目录的索引节点,并检查它的文件类型和权限位,确保目标文件是目录以及进程的所有者可以访问该目录(否则改变到新目录就没有用)。

(3) 内核用新目标目录的路径名和/或索引节点替换u区中当前目录路径名和/或它的索引节点号。

 

错误信息:

EFAULT: path 指向了非法地址

ENAMETOOLNG:路径过长

ENOENT:文件不存在

ENOMEM:内核内存不足

ENOTDIR:给出路径不是目录

EACCES:无访问路径中某个目录的权限

ELOOP:解析路径中太多的符号链接

EIO:发生I/O错误

 

实例1:

#include <unistd.h>

#include <iostream>

int main(void)

{

     long cur_path_len;

     char* cur_work_dir;

   if((cur_path_len= pathconf(".",_PC_PATH_MAX)) == -1)

     {

           perror("Couldn`t get currentworking path length");

           return 1;

     }

     std::cout<<"Current path lengthis"<<cur_path_len<<std::endl;

   if((cur_work_dir= (char*)malloc(cur_path_len)) == NULL)

     {

           perror("Couldn't allocate memoryfor the pathname");

           return 1;

     }

    if(getcwd(cur_work_dir,cur_path_len)==NULL)

{

            perror("Couldn`t get currentworking directory!");

     }

     else

{

           std::cout<< "Currentworking directoryis"<<cur_work_dir<<std::endl;

     }

 

if(chdir("..") == -1)

     {

           perror("Couldn`t  change current workingdiretory!");

           return 1;

     }

   if((getcwd(cur_work_dir,cur_path_len)) == NULL)

     {

           perror("Couldn`t get currentworking directory!");

           return 1;

     }

     std::cout<<"Afterchangedirectory,Currentworking directoryis"<<cur_work_dir<<std::endl;

     free(cur_work_dir);

     return 0;

}

5、stat,fstat和lstat函数使用(转)

我们使用函数stat,fstat和lstat来检查文件的属性。这些函数使用struct stat对象来返回属性信息。所有这三个函数声明在头文件‘sys/stat.h’中。

Int   stat(const char *filename, struct stat *buf)                              函数

Stat函数返回buf指向的结构体中filename项中保存的文件名的文件的属性信息。如果filename项是一个符号链接,你得到的是链接指向的文件的属性信息。如果链接指向一个不存在的文件,则stat函数会报告一个文件不存在的失败消息。

如果操作成功的话,该函数返回值为0,失败则返回-1。除了通常的文件名错误外,还定义有如下的errno出错条件。

ENOENT              filename命名的文件不存在

如果使用_FILE_OFFSET_BITS==64来编译时,该函数实际上是stat64,因此使用大型文件支持的接口代替普通的实现。

Int   stat64(const char *filename, struct stat64 *buf)                                     函数

此函数与函数stat类似,区别在于它能够在32位系统上处理大小大于231的文件。为了达到效果,结果保存在一个struct stat64类型的变量中,就是buf指针指向的变量。当源代码中使用_FILE_OFFSET_BITS==64来编译时,该函数在使用stat为函数名时也有效,当然在32位机器代替小文件的接口。

Int   fstat(int filedes,struct stat *buf)                                函数

Fstat函数与stat函数类似,只是在打开一个文件时使用文件描述符代替文件名做为参数。详情查看Chapter 13【低级输入输出】。像stat函数一样,fstat函数调用成功返回值为0,失败则返回-1。下述errno错误情况针对fstat定义的:

EBADF          filedes参数是一个无效的文件描述符。

如果使用_FILE_OFFSET_BITS==64来编译时,该函数实际上是stat64,因此使用大型文件支持的接口代替普通的实现。

Int   fstat64(int filedes, struct stat64 *buf)                        函数

此函数与函数fstat类似,区别在于它能够在32位系统上处理大小大于231的文件。因为大型文件的文件描述符一般通过open64或者creat64来获得。Buf指针指向的变量类型是struct stat64,用于代表大型文件。当源代码中使用_FILE_OFFSET_BITS==64来编译时,该函数在使用stat为函数名时也有效,当然在32位机器代替小文件的接口。

Int   lstat(const char *filename, struct stat *buf)                函数

Lstat函数与stat函数类似,区别在于lstat函数不对符号链接进行追踪。如果参数filename是一个符号链接名,lstat函数仅仅返回链接本身的信息。详情查看Section 14.5【符号链接】,否则lstat函数与stat函数作用相同。

如果使用_FILE_OFFSET_BITS==64来编译时,该函数实际上是stat64,因此使用大型文件支持的接口代替普通的实现。

Int   lstat64(const char *filename, struct stat64 *buf)         函数

此函数与函数stat类似,区别在于它能够在32位系统上处理大小大于231的文件。为了达到效果,结果保存在一个struct stat64类型的变量中,就是buf指针指向的变量。当源代码中使用_FILE_OFFSET_BITS==64来编译时,该函数在使用stat为函数名时也有效,当然在32位机器代替小文件的接口。

6、S_ISLNK(st_mode):是否是一个连接.
S_ISREG(st_mode):是否是一个常规文件.
S_ISDIR(st_mode):是否是一个目录
S_ISCHR(st_mode):是否是一个字符设备.
S_ISBLK(st_mode):是否是一个块设备
S_ISFIFO(st_mode):是否 是一个FIFO文件.
S_ISSOCK(st_mode):是否是一个SOCKET文件 


man 2 stat 可以查到stat数据结构,其中的st_mode就是上面几个宏的输入参数
struct stat {
dev_t st_dev;
ino_t st_ino;
mode_t st_mode;
nlink_t st_nlink;
uid_t st_uid;
gid_t st_gid;
dev_t st_rdev;
off_t st_size;
blksize_t st_blksize;
blkcnt_t st_blocks;
time_t st_mtime;
time_t st_ctime;
};

7、strtol函数

表头文件: #include <stdlib.h>
定义函数: long int strtol(const char *nptr, char **endptr, int base)
函数说明: strtol()会将参数nptr字符串根据参数base来转换成长整型数。参数


base范围从2至36,或0。参数base代表采用的进制方式,如base值为10则采用10


进制(字符串以10进制表示),若base值为16则采用16进制(字符串以16进制表示)


。当base值为0时则是采用10进制做转换,但遇到如''0x''前置字符则会使用16进


制做转换。一开始strtol()会扫描参数nptr字符串,跳过前面的空格字符,直到


遇上数字或正负符号才开始做转换,再遇到非数字或字符串结束时(''\0'')结束


转换,并将结果返回。若参数endptr不为NULL,则会将遇到不合条件而终止的


nptr中的字符指针由endptr返回。
返回值:    返回转换后的长整型数,否则返回ERANGE并将错误代码存入errno中



附加说明: ERANGE指定的转换字符串超出合法范围。




将字符串a, b, c 分别采用10, 2, 16进制转换成数字
------------------------------------------------
#include <stdlib.h>
#include <stdio.h>
main()
{
     char a[] = "100";
     char b[] = "100";
     char c[] = "ffff";
     printf("a = %d\n", strtol(a, NULL, 10)); //100
     printf("b = %d\n", strtol(b, NULL, 2));    //4
     printf("c = %d\n", strtol(c, NULL, 16)); //65535
}


"100" ---> 100 (Dec) ---> 100 (Dec)
"100" ---> 100 (BIN) ---> 4    (Dec)
"ffff"---> ffff(Hex) ---> 65535(Dec)