如何为stat函数编写函数存根?

问题描述

我正在尝试从中为stat()函数编写存根。 我可以使用以下代码为fstat成功完成此操作:

static int fstat_count;
static int fstat_fail_instance;
int my_fstat(const int fd,struct stat * st) {
  fstat_count ++;
  if (fstat_count == fstat_fail_instance) {
    return EINVAL;
  }
  st->st_size = ST_SIZE;
  return EOK;
}
#undef fstat
#define fstat my_fstat

当我尝试使用stat执行此操作时,出现如下错误

mkqfs_file_test.c:28:20: error: storage size of ‘sb’ isn’t kNown
  const struct stat sb;
我相信是因为

#undef stat #define stat my_stat 就像我对fstat所做的一样,它未定义struct stat而不是函数。 知道如何解决这个问题,也就是只能取消定义/重新定义功能吗?

解决方法

[...]我收到如下错误:

mkqfs_file_test.c:28:20: error: storage size of ‘sb’ isn’t known
  const struct stat sb;

我认为这是因为当我像对fstat那样执行#undef stat #define stat my_stat时,它是在定义struct stat而不是 功能。

否,#undef stat不会取消定义任何函数或任何结构类型。它使用该名称未定义预处理器宏的任何先前定义。这样,它可能是不必要的,并且最坏的情况是无害的。但是,万一有这样一个现有的宏定义,这种情况不太可能发生,符合标准的程序确实需要在重新定义它之前先取消定义。

问题在于#define。如果stat宏的定义在您的结构声明出现的地方可见,那么它将在该标识符用作结构标记的地方扩展。结果,这...

  const struct stat sb;

...扩展为...

  const struct my_stat sb;

。在范围内没有可见的类型struct my_struct的定义,该声明是不允许的。正如编译器所说,它既不知道为struct my_stat提供多少空间,也不知道它是否可用,因为编译器也不知道其任何成员。请注意,这不会阻止声明或使用指向struct my_stat的指针,但这有其自身的问题。

任何想法我都可以解决的,即仅取消定义/重新定义 功能?

同样,您并未定义任何功能。由于my_stat()被用于不同命名空间中的相关目的,因此没有完全干净的方法使用宏来将stat()替换为stat。您可以做三件事:

  1. 使用类似函数的宏代替:

    #define stat(p,b) my_stat((p),(b))
    

    在这种情况下,您必须确保没有尝试计算指向stat的指针。这可能是您最好的选择。

  2. 完全省略#undefine#define,并将替换函数命名为stat(),与原始函数相同。这依赖于链接程序来选择库版本而不是库版本,您可能会这样做。但是,那可能会产生意想不到的影响。

  3. #undefine之前,为typedef声明一个struct stat

    typedef struct stat struct_stat;
    #undefine stat
    #define stat my_stat
    

    然后在您的宏定义可见的所有地方使用typedef而不是类型struct stat

    struct_stat sb;