我需要创建一个函数来测试文件是否存在postgres。我是用C语言做的,但我遇到了问题。代码是:
#include "postgres.h"
#include <string.h>
#include "fmgr.h"
#include <stdio.h>
#include<sys/stat.h>
#ifdef PG_MODULE_MAGIC
PG_MODULE_MAGIC;
#endif
/* by value */
PG_FUNCTION_INFO_V1(file_exists);
Datum
file_exists (PG_FUNCTION_ARGS)
{
text *fileName= PG_GETARG_TEXT_P(0);
struct stat buf;
int i = stat(fileName, &buf);
/* File found */
if ( i == 0 )
{
PG_RETURN_INT32(1);
}
PG_RETURN_INT32(0);
}
我认为问题在于“stat”函数中的第一个参数,因为fileName是一个文本而且这个函数接收一个char。
这是我第一次编写C代码,所以可能一切都都错了。
答案 0 :(得分:5)
如果您仔细阅读标题,可以在server/c.h
中找到:
/* ----------------
* Variable-length datatypes all share the 'struct varlena' header.
*...
*/
struct varlena
{
char vl_len_[4]; /* Do not touch this field directly! */
char vl_dat[1];
};
#define VARHDRSZ ((int32) sizeof(int32))
/*
* These widely-used datatypes are just a varlena header and the data bytes.
* There is no terminating null or anything like that --- the data length is
* always VARSIZE(ptr) - VARHDRSZ.
*/
typedef struct varlena bytea;
typedef struct varlena text;
所以你有text
数据类型的定义。请注意这个评论中相当重要的部分:
没有终止null或类似的东西
这表明您绝对不希望将fileName->data
视为C字符串,除非您喜欢segfaults。您需要一种方法将text
转换为以Nul结尾的C字符串,您可以将其转交给stat
;有一个功能:text_to_cstring
。
我可以找到的text_to_cstring
唯一的文档是this comment in the source:
/*
* text_to_cstring
*
* Create a palloc'd, null-terminated C string from a text value.
*
* We support being passed a compressed or toasted text value.
* This is a bit bogus since such values shouldn't really be referred to as
* "text *", but it seems useful for robustness. If we didn't handle that
* case here, we'd need another routine that did, anyway.
*/
char *command;
/*...*/
/* Convert given text object to a C string */
command = text_to_cstring(sql);
/*...*/
pfree(command);
你应该可以这样做:
struct stat buf;
char *fileName = text_to_cstring(PG_GETARG_TEXT_P(0));
int i = stat(fileName, &buf);
pfree(fileName);
答案 1 :(得分:1)
我有同样的问题。 text_to_cstring对我不起作用,然后我意识到问题是我没有包含text_to_cstring func的头文件。这有多愚蠢。所以我不得不在/ usr / include / postgresql / your_version / server / utils /文件夹中搜索,直到我最终找到它然后一切运行良好。尝试
char *filename = text_to_cstring(PG_GETARG_TEXT_PP(0));
但不要忘记包含第一个builtins.h
#include "utils/builtins.h"