2012-10-12 4 views
2

파일이 포스트그레스와 함께 존재하는지 테스트 할 함수를 만들어야합니다. 나는 C 언어로하고 있지만 문제가있다. 코드는 다음과 같습니다파일이 Postgres와 함께 존재하는지 테스트하십시오.

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

} 

나는 문제가 "합계"함수의 첫 번째 인수로 생각, 파일 이름 텍스트이며,이 기능은 문자를 수신하기 때문이다.

C 코드를 처음 작성한 것이므로 모든 것이 잘못되었을 수 있습니다. 당신이 헤더를 통해 발굴 경우

+0

방법 '텍스트'가 정의 첫번째 builtins.h을 포함하는 것을 잊지 말아? 'text *'대신'char *'를 사용할 수 없습니까? –

+0

나는 그것이 postgresql.h에 정의되어 있고 다음과 같이되어야한다고 생각한다 : typedef struct { int4 length; 문자 데이터 [1]; } 텍스트; –

+0

분명히 보인다 :'fileName' 대신'fileName-> data' 만 참조하면된다. – netcoder

답변

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 데이터 유형의 당신의 정의가있다. 주석이 오히려 중요한 부분을 참고 :

은 당신이 절대적으로 세그먼테이션 폴트 (segfault)와 같은 당신 않는 한 C 문자열로 fileName->data을 치료하지 않을 것을 나타냅니다 그

같은 더 널 (null) 종료 또는 아무것도 없다. text을 Null 종료 C 문자열로 변환하여 stat으로 넘길 수있는 방법이 필요합니다. 그 기능은 다음과 같습니다 : text_to_cstring.

내가 찾을 수 text_to_cstring에 대한 유일한 문서는 this comment in the source입니다 : 또한 an example that uses it 있습니다

/* 
* 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

나는 동일한 문제가 있었다. text_to_cstring이 작동하지 않는다면 text_to_cstring func의 헤더 파일을 포함시키지 않았다는 것을 깨달았습니다. 얼마나 어리석은가. 그래서 나는/usr/include/postgresql/your_version/server/utils/폴더를 검색해야만 마침내 찾은 다음 잘 작동 할 때까지해야했습니다.

char *filename = text_to_cstring(PG_GETARG_TEXT_PP(0)); 

을 시도하지만

#include "utils/builtins.h" 
관련 문제