2

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);

}

fileName はテキストで、この関数は char を受け取るため、問題は「stat」関数の最初の引数にあると思います。

Cコードを書くのはこれが初めてなので、すべてが間違っているかもしれません。

4

2 に答える 2

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これは、 segfaultsが好きでない限り、C文字列として扱いたくないことを示しています。textに渡すことができるヌル文字で終了するC文字列に変換する方法が必要statです。そのための関数があります:text_to_cstring

text_to_cstring私が見つけることができる唯一のドキュメントは、ソースのこのコメントです

/*
 * 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);
于 2012-10-13T00:13:46.453 に答える