From 9ae79930461a9024d01a878bdf63bfc4cd143c0d Mon Sep 17 00:00:00 2001 From: Michael Paquier Date: Wed, 24 Jun 2015 11:26:02 +0900 Subject: [PATCH 2/5] Add new column islink in pg_stat_file This allows to detect if the file path evaluated is a symlink or not. pg_stat_file is switched to use as well lstat to enable soft link detection. --- doc/src/sgml/func.sgml | 5 +++-- src/backend/utils/adt/genfile.c | 15 +++++++++++---- src/include/catalog/pg_proc.h | 5 ++--- 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml index 8b28e29..67e1626 100644 --- a/doc/src/sgml/func.sgml +++ b/doc/src/sgml/func.sgml @@ -17905,8 +17905,9 @@ SELECT convert_from(pg_read_binary_file('file_in_utf8.txt'), 'UTF8'); pg_stat_file returns a record containing the file size, last accessed time stamp, last modified time stamp, last file status change time stamp (Unix platforms only), - file creation time stamp (Windows only), and a boolean - indicating if it is a directory. Typical usages include: + file creation time stamp (Windows only), a boolean + indicating if it is a directory, and a boolean + indicating if it is a symbolic link. Typical usages include: SELECT * FROM pg_stat_file('filename'); SELECT (pg_stat_file('filename')).modification; diff --git a/src/backend/utils/adt/genfile.c b/src/backend/utils/adt/genfile.c index c4eb10d..df8ae88 100644 --- a/src/backend/utils/adt/genfile.c +++ b/src/backend/utils/adt/genfile.c @@ -306,8 +306,8 @@ pg_stat_file(PG_FUNCTION_ARGS) text *filename_t = PG_GETARG_TEXT_P(0); char *filename; struct stat fst; - Datum values[6]; - bool isnull[6]; + Datum values[7]; + bool isnull[7]; HeapTuple tuple; TupleDesc tupdesc; bool missing_ok = false; @@ -323,7 +323,7 @@ pg_stat_file(PG_FUNCTION_ARGS) filename = convert_and_check_filename(filename_t); - if (stat(filename, &fst) < 0) + if (lstat(filename, &fst) < 0) { if (missing_ok && errno == ENOENT) PG_RETURN_NULL(); @@ -337,7 +337,7 @@ pg_stat_file(PG_FUNCTION_ARGS) * This record type had better match the output parameters declared for me * in pg_proc.h. */ - tupdesc = CreateTemplateTupleDesc(6, false); + tupdesc = CreateTemplateTupleDesc(7, false); TupleDescInitEntry(tupdesc, (AttrNumber) 1, "size", INT8OID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 2, @@ -350,6 +350,8 @@ pg_stat_file(PG_FUNCTION_ARGS) "creation", TIMESTAMPTZOID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 6, "isdir", BOOLOID, -1, 0); + TupleDescInitEntry(tupdesc, (AttrNumber) 7, + "islink", BOOLOID, -1, 0); BlessTupleDesc(tupdesc); memset(isnull, false, sizeof(isnull)); @@ -366,6 +368,11 @@ pg_stat_file(PG_FUNCTION_ARGS) values[4] = TimestampTzGetDatum(time_t_to_timestamptz(fst.st_ctime)); #endif values[5] = BoolGetDatum(S_ISDIR(fst.st_mode)); +#ifndef WIN32 + values[6] = BoolGetDatum(S_ISLNK(fst.st_mode)); +#else + values[6] = BoolGetDatum(pgwin32_is_junction(filename)); +#endif tuple = heap_form_tuple(tupdesc, values, isnull); diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h index be3a8fb..f6abd74 100644 --- a/src/include/catalog/pg_proc.h +++ b/src/include/catalog/pg_proc.h @@ -3180,10 +3180,9 @@ DATA(insert OID = 2621 ( pg_reload_conf PGNSP PGUID 12 1 0 0 0 f f f f t f v 0 DESCR("reload configuration files"); DATA(insert OID = 2622 ( pg_rotate_logfile PGNSP PGUID 12 1 0 0 0 f f f f t f v 0 0 16 "" _null_ _null_ _null_ _null_ _null_ pg_rotate_logfile _null_ _null_ _null_ )); DESCR("rotate log file"); - -DATA(insert OID = 2623 ( pg_stat_file PGNSP PGUID 12 1 0 0 0 f f f f t f v 1 0 2249 "25" "{25,20,1184,1184,1184,1184,16}" "{i,o,o,o,o,o,o}" "{filename,size,access,modification,change,creation,isdir}" _null_ _null_ pg_stat_file_1arg _null_ _null_ _null_ )); +DATA(insert OID = 2623 ( pg_stat_file PGNSP PGUID 12 1 0 0 0 f f f f t f v 1 0 2249 "25" "{25,20,1184,1184,1184,1184,16,16}" "{i,o,o,o,o,o,o,o}" "{filename,size,access,modification,change,creation,isdir,islink}" _null_ _null_ pg_stat_file_1arg _null_ _null_ _null_ )); DESCR("get information about file"); -DATA(insert OID = 3307 ( pg_stat_file PGNSP PGUID 12 1 0 0 0 f f f f t f v 2 0 2249 "25 16" "{25,16,20,1184,1184,1184,1184,16}" "{i,i,o,o,o,o,o,o}" "{filename,missing_ok,size,access,modification,change,creation,isdir}" _null_ _null_ pg_stat_file _null_ _null_ _null_ )); +DATA(insert OID = 3307 ( pg_stat_file PGNSP PGUID 12 1 0 0 0 f f f f t f v 2 0 2249 "25 16" "{25,16,20,1184,1184,1184,1184,16,16}" "{i,i,o,o,o,o,o,o,o}" "{filename,missing_ok,size,access,modification,change,creation,isdir,islink}" _null_ _null_ pg_stat_file _null_ _null_ _null_ )); DESCR("get information about file"); DATA(insert OID = 2624 ( pg_read_file PGNSP PGUID 12 1 0 0 0 f f f f t f v 3 0 25 "25 20 20" _null_ _null_ _null_ _null_ _null_ pg_read_file_off_len _null_ _null_ _null_ )); DESCR("read text from a file"); -- 2.4.5