PostgreSQL Source Code  git master
genfile.c
Go to the documentation of this file.
1 /*-------------------------------------------------------------------------
2  *
3  * genfile.c
4  * Functions for direct access to files
5  *
6  *
7  * Copyright (c) 2004-2020, PostgreSQL Global Development Group
8  *
9  * Author: Andreas Pflug <pgadmin@pse-consulting.de>
10  *
11  * IDENTIFICATION
12  * src/backend/utils/adt/genfile.c
13  *
14  *-------------------------------------------------------------------------
15  */
16 #include "postgres.h"
17 
18 #include <sys/file.h>
19 #include <sys/stat.h>
20 #include <unistd.h>
21 #include <dirent.h>
22 
23 #include "access/htup_details.h"
24 #include "access/xlog_internal.h"
25 #include "catalog/pg_authid.h"
26 #include "catalog/pg_tablespace_d.h"
27 #include "catalog/pg_type.h"
28 #include "funcapi.h"
29 #include "mb/pg_wchar.h"
30 #include "miscadmin.h"
31 #include "postmaster/syslogger.h"
32 #include "storage/fd.h"
33 #include "utils/acl.h"
34 #include "utils/builtins.h"
35 #include "utils/memutils.h"
36 #include "utils/syscache.h"
37 #include "utils/timestamp.h"
38 
39 
40 /*
41  * Convert a "text" filename argument to C string, and check it's allowable.
42  *
43  * Filename may be absolute or relative to the DataDir, but we only allow
44  * absolute paths that match DataDir or Log_directory.
45  *
46  * This does a privilege check against the 'pg_read_server_files' role, so
47  * this function is really only appropriate for callers who are only checking
48  * 'read' access. Do not use this function if you are looking for a check
49  * for 'write' or 'program' access without updating it to access the type
50  * of check as an argument and checking the appropriate role membership.
51  */
52 static char *
54 {
55  char *filename;
56 
57  filename = text_to_cstring(arg);
58  canonicalize_path(filename); /* filename can change length here */
59 
60  /*
61  * Members of the 'pg_read_server_files' role are allowed to access any
62  * files on the server as the PG user, so no need to do any further checks
63  * here.
64  */
65  if (is_member_of_role(GetUserId(), DEFAULT_ROLE_READ_SERVER_FILES))
66  return filename;
67 
68  /* User isn't a member of the default role, so check if it's allowable */
69  if (is_absolute_path(filename))
70  {
71  /* Disallow '/a/b/data/..' */
72  if (path_contains_parent_reference(filename))
73  ereport(ERROR,
74  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
75  errmsg("reference to parent directory (\"..\") not allowed")));
76 
77  /*
78  * Allow absolute paths if within DataDir or Log_directory, even
79  * though Log_directory might be outside DataDir.
80  */
81  if (!path_is_prefix_of_path(DataDir, filename) &&
84  ereport(ERROR,
85  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
86  errmsg("absolute path not allowed")));
87  }
88  else if (!path_is_relative_and_below_cwd(filename))
89  ereport(ERROR,
90  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
91  errmsg("path must be in or below the current directory")));
92 
93  return filename;
94 }
95 
96 
97 /*
98  * Read a section of a file, returning it as bytea
99  *
100  * Caller is responsible for all permissions checking.
101  *
102  * We read the whole of the file when bytes_to_read is negative.
103  */
104 static bytea *
105 read_binary_file(const char *filename, int64 seek_offset, int64 bytes_to_read,
106  bool missing_ok)
107 {
108  bytea *buf;
109  size_t nbytes;
110  FILE *file;
111 
112  if (bytes_to_read < 0)
113  {
114  if (seek_offset < 0)
115  bytes_to_read = -seek_offset;
116  else
117  {
118  struct stat fst;
119 
120  if (stat(filename, &fst) < 0)
121  {
122  if (missing_ok && errno == ENOENT)
123  return NULL;
124  else
125  ereport(ERROR,
127  errmsg("could not stat file \"%s\": %m", filename)));
128  }
129 
130  bytes_to_read = fst.st_size - seek_offset;
131  }
132  }
133 
134  /* not sure why anyone thought that int64 length was a good idea */
135  if (bytes_to_read > (MaxAllocSize - VARHDRSZ))
136  ereport(ERROR,
137  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
138  errmsg("requested length too large")));
139 
140  if ((file = AllocateFile(filename, PG_BINARY_R)) == NULL)
141  {
142  if (missing_ok && errno == ENOENT)
143  return NULL;
144  else
145  ereport(ERROR,
147  errmsg("could not open file \"%s\" for reading: %m",
148  filename)));
149  }
150 
151  if (fseeko(file, (off_t) seek_offset,
152  (seek_offset >= 0) ? SEEK_SET : SEEK_END) != 0)
153  ereport(ERROR,
155  errmsg("could not seek in file \"%s\": %m", filename)));
156 
157  buf = (bytea *) palloc((Size) bytes_to_read + VARHDRSZ);
158 
159  nbytes = fread(VARDATA(buf), 1, (size_t) bytes_to_read, file);
160 
161  if (ferror(file))
162  ereport(ERROR,
164  errmsg("could not read file \"%s\": %m", filename)));
165 
166  SET_VARSIZE(buf, nbytes + VARHDRSZ);
167 
168  FreeFile(file);
169 
170  return buf;
171 }
172 
173 /*
174  * Similar to read_binary_file, but we verify that the contents are valid
175  * in the database encoding.
176  */
177 static text *
178 read_text_file(const char *filename, int64 seek_offset, int64 bytes_to_read,
179  bool missing_ok)
180 {
181  bytea *buf;
182 
183  buf = read_binary_file(filename, seek_offset, bytes_to_read, missing_ok);
184 
185  if (buf != NULL)
186  {
187  /* Make sure the input is valid */
188  pg_verifymbstr(VARDATA(buf), VARSIZE(buf) - VARHDRSZ, false);
189 
190  /* OK, we can cast it to text safely */
191  return (text *) buf;
192  }
193  else
194  return NULL;
195 }
196 
197 /*
198  * Read a section of a file, returning it as text
199  *
200  * This function is kept to support adminpack 1.0.
201  */
202 Datum
204 {
205  text *filename_t = PG_GETARG_TEXT_PP(0);
206  int64 seek_offset = 0;
207  int64 bytes_to_read = -1;
208  bool missing_ok = false;
209  char *filename;
210  text *result;
211 
212  if (!superuser())
213  ereport(ERROR,
214  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
215  errmsg("must be superuser to read files with adminpack 1.0"),
216  /* translator: %s is a SQL function name */
217  errhint("Consider using %s, which is part of core, instead.",
218  "pg_file_read()")));
219 
220  /* handle optional arguments */
221  if (PG_NARGS() >= 3)
222  {
223  seek_offset = PG_GETARG_INT64(1);
224  bytes_to_read = PG_GETARG_INT64(2);
225 
226  if (bytes_to_read < 0)
227  ereport(ERROR,
228  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
229  errmsg("requested length cannot be negative")));
230  }
231  if (PG_NARGS() >= 4)
232  missing_ok = PG_GETARG_BOOL(3);
233 
234  filename = convert_and_check_filename(filename_t);
235 
236  result = read_text_file(filename, seek_offset, bytes_to_read, missing_ok);
237  if (result)
238  PG_RETURN_TEXT_P(result);
239  else
240  PG_RETURN_NULL();
241 }
242 
243 /*
244  * Read a section of a file, returning it as text
245  *
246  * No superuser check done here- instead privileges are handled by the
247  * GRANT system.
248  */
249 Datum
251 {
252  text *filename_t = PG_GETARG_TEXT_PP(0);
253  int64 seek_offset = 0;
254  int64 bytes_to_read = -1;
255  bool missing_ok = false;
256  char *filename;
257  text *result;
258 
259  /* handle optional arguments */
260  if (PG_NARGS() >= 3)
261  {
262  seek_offset = PG_GETARG_INT64(1);
263  bytes_to_read = PG_GETARG_INT64(2);
264 
265  if (bytes_to_read < 0)
266  ereport(ERROR,
267  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
268  errmsg("requested length cannot be negative")));
269  }
270  if (PG_NARGS() >= 4)
271  missing_ok = PG_GETARG_BOOL(3);
272 
273  filename = convert_and_check_filename(filename_t);
274 
275  result = read_text_file(filename, seek_offset, bytes_to_read, missing_ok);
276  if (result)
277  PG_RETURN_TEXT_P(result);
278  else
279  PG_RETURN_NULL();
280 }
281 
282 /*
283  * Read a section of a file, returning it as bytea
284  */
285 Datum
287 {
288  text *filename_t = PG_GETARG_TEXT_PP(0);
289  int64 seek_offset = 0;
290  int64 bytes_to_read = -1;
291  bool missing_ok = false;
292  char *filename;
293  bytea *result;
294 
295  /* handle optional arguments */
296  if (PG_NARGS() >= 3)
297  {
298  seek_offset = PG_GETARG_INT64(1);
299  bytes_to_read = PG_GETARG_INT64(2);
300 
301  if (bytes_to_read < 0)
302  ereport(ERROR,
303  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
304  errmsg("requested length cannot be negative")));
305  }
306  if (PG_NARGS() >= 4)
307  missing_ok = PG_GETARG_BOOL(3);
308 
309  filename = convert_and_check_filename(filename_t);
310 
311  result = read_binary_file(filename, seek_offset,
312  bytes_to_read, missing_ok);
313  if (result)
314  PG_RETURN_BYTEA_P(result);
315  else
316  PG_RETURN_NULL();
317 }
318 
319 
320 /*
321  * Wrapper functions for the 1 and 3 argument variants of pg_read_file_v2()
322  * and pg_read_binary_file().
323  *
324  * These are necessary to pass the sanity check in opr_sanity, which checks
325  * that all built-in functions that share the implementing C function take
326  * the same number of arguments.
327  */
328 Datum
330 {
331  return pg_read_file_v2(fcinfo);
332 }
333 
334 Datum
336 {
337  return pg_read_file_v2(fcinfo);
338 }
339 
340 Datum
342 {
343  return pg_read_binary_file(fcinfo);
344 }
345 
346 Datum
348 {
349  return pg_read_binary_file(fcinfo);
350 }
351 
352 /*
353  * stat a file
354  */
355 Datum
357 {
358  text *filename_t = PG_GETARG_TEXT_PP(0);
359  char *filename;
360  struct stat fst;
361  Datum values[6];
362  bool isnull[6];
363  HeapTuple tuple;
364  TupleDesc tupdesc;
365  bool missing_ok = false;
366 
367  /* check the optional argument */
368  if (PG_NARGS() == 2)
369  missing_ok = PG_GETARG_BOOL(1);
370 
371  filename = convert_and_check_filename(filename_t);
372 
373  if (stat(filename, &fst) < 0)
374  {
375  if (missing_ok && errno == ENOENT)
376  PG_RETURN_NULL();
377  else
378  ereport(ERROR,
380  errmsg("could not stat file \"%s\": %m", filename)));
381  }
382 
383  /*
384  * This record type had better match the output parameters declared for me
385  * in pg_proc.h.
386  */
387  tupdesc = CreateTemplateTupleDesc(6);
388  TupleDescInitEntry(tupdesc, (AttrNumber) 1,
389  "size", INT8OID, -1, 0);
390  TupleDescInitEntry(tupdesc, (AttrNumber) 2,
391  "access", TIMESTAMPTZOID, -1, 0);
392  TupleDescInitEntry(tupdesc, (AttrNumber) 3,
393  "modification", TIMESTAMPTZOID, -1, 0);
394  TupleDescInitEntry(tupdesc, (AttrNumber) 4,
395  "change", TIMESTAMPTZOID, -1, 0);
396  TupleDescInitEntry(tupdesc, (AttrNumber) 5,
397  "creation", TIMESTAMPTZOID, -1, 0);
398  TupleDescInitEntry(tupdesc, (AttrNumber) 6,
399  "isdir", BOOLOID, -1, 0);
400  BlessTupleDesc(tupdesc);
401 
402  memset(isnull, false, sizeof(isnull));
403 
404  values[0] = Int64GetDatum((int64) fst.st_size);
405  values[1] = TimestampTzGetDatum(time_t_to_timestamptz(fst.st_atime));
406  values[2] = TimestampTzGetDatum(time_t_to_timestamptz(fst.st_mtime));
407  /* Unix has file status change time, while Win32 has creation time */
408 #if !defined(WIN32) && !defined(__CYGWIN__)
409  values[3] = TimestampTzGetDatum(time_t_to_timestamptz(fst.st_ctime));
410  isnull[4] = true;
411 #else
412  isnull[3] = true;
413  values[4] = TimestampTzGetDatum(time_t_to_timestamptz(fst.st_ctime));
414 #endif
415  values[5] = BoolGetDatum(S_ISDIR(fst.st_mode));
416 
417  tuple = heap_form_tuple(tupdesc, values, isnull);
418 
419  pfree(filename);
420 
422 }
423 
424 /*
425  * stat a file (1 argument version)
426  *
427  * note: this wrapper is necessary to pass the sanity check in opr_sanity,
428  * which checks that all built-in functions that share the implementing C
429  * function take the same number of arguments
430  */
431 Datum
433 {
434  return pg_stat_file(fcinfo);
435 }
436 
437 /*
438  * List a directory (returns the filenames only)
439  */
440 Datum
442 {
443  ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
444  char *location;
445  bool missing_ok = false;
446  bool include_dot_dirs = false;
447  bool randomAccess;
448  TupleDesc tupdesc;
449  Tuplestorestate *tupstore;
450  DIR *dirdesc;
451  struct dirent *de;
452  MemoryContext oldcontext;
453 
455 
456  /* check the optional arguments */
457  if (PG_NARGS() == 3)
458  {
459  if (!PG_ARGISNULL(1))
460  missing_ok = PG_GETARG_BOOL(1);
461  if (!PG_ARGISNULL(2))
462  include_dot_dirs = PG_GETARG_BOOL(2);
463  }
464 
465  /* check to see if caller supports us returning a tuplestore */
466  if (rsinfo == NULL || !IsA(rsinfo, ReturnSetInfo))
467  ereport(ERROR,
468  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
469  errmsg("set-valued function called in context that cannot accept a set")));
470  if (!(rsinfo->allowedModes & SFRM_Materialize))
471  ereport(ERROR,
472  (errcode(ERRCODE_SYNTAX_ERROR),
473  errmsg("materialize mode required, but it is not allowed in this context")));
474 
475  /* The tupdesc and tuplestore must be created in ecxt_per_query_memory */
477 
478  tupdesc = CreateTemplateTupleDesc(1);
479  TupleDescInitEntry(tupdesc, (AttrNumber) 1, "pg_ls_dir", TEXTOID, -1, 0);
480 
481  randomAccess = (rsinfo->allowedModes & SFRM_Materialize_Random) != 0;
482  tupstore = tuplestore_begin_heap(randomAccess, false, work_mem);
483  rsinfo->returnMode = SFRM_Materialize;
484  rsinfo->setResult = tupstore;
485  rsinfo->setDesc = tupdesc;
486 
487  MemoryContextSwitchTo(oldcontext);
488 
489  dirdesc = AllocateDir(location);
490  if (!dirdesc)
491  {
492  /* Return empty tuplestore if appropriate */
493  if (missing_ok && errno == ENOENT)
494  return (Datum) 0;
495  /* Otherwise, we can let ReadDir() throw the error */
496  }
497 
498  while ((de = ReadDir(dirdesc, location)) != NULL)
499  {
500  Datum values[1];
501  bool nulls[1];
502 
503  if (!include_dot_dirs &&
504  (strcmp(de->d_name, ".") == 0 ||
505  strcmp(de->d_name, "..") == 0))
506  continue;
507 
508  values[0] = CStringGetTextDatum(de->d_name);
509  nulls[0] = false;
510 
511  tuplestore_putvalues(tupstore, tupdesc, values, nulls);
512  }
513 
514  FreeDir(dirdesc);
515  return (Datum) 0;
516 }
517 
518 /*
519  * List a directory (1 argument version)
520  *
521  * note: this wrapper is necessary to pass the sanity check in opr_sanity,
522  * which checks that all built-in functions that share the implementing C
523  * function take the same number of arguments.
524  */
525 Datum
527 {
528  return pg_ls_dir(fcinfo);
529 }
530 
531 /*
532  * Generic function to return a directory listing of files.
533  *
534  * If the directory isn't there, silently return an empty set if missing_ok.
535  * Other unreadable-directory cases throw an error.
536  */
537 static Datum
538 pg_ls_dir_files(FunctionCallInfo fcinfo, const char *dir, bool missing_ok)
539 {
540  ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
541  bool randomAccess;
542  TupleDesc tupdesc;
543  Tuplestorestate *tupstore;
544  DIR *dirdesc;
545  struct dirent *de;
546  MemoryContext oldcontext;
547 
548  /* check to see if caller supports us returning a tuplestore */
549  if (rsinfo == NULL || !IsA(rsinfo, ReturnSetInfo))
550  ereport(ERROR,
551  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
552  errmsg("set-valued function called in context that cannot accept a set")));
553  if (!(rsinfo->allowedModes & SFRM_Materialize))
554  ereport(ERROR,
555  (errcode(ERRCODE_SYNTAX_ERROR),
556  errmsg("materialize mode required, but it is not allowed in this context")));
557 
558  /* The tupdesc and tuplestore must be created in ecxt_per_query_memory */
560 
561  if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
562  elog(ERROR, "return type must be a row type");
563 
564  randomAccess = (rsinfo->allowedModes & SFRM_Materialize_Random) != 0;
565  tupstore = tuplestore_begin_heap(randomAccess, false, work_mem);
566  rsinfo->returnMode = SFRM_Materialize;
567  rsinfo->setResult = tupstore;
568  rsinfo->setDesc = tupdesc;
569 
570  MemoryContextSwitchTo(oldcontext);
571 
572  /*
573  * Now walk the directory. Note that we must do this within a single SRF
574  * call, not leave the directory open across multiple calls, since we
575  * can't count on the SRF being run to completion.
576  */
577  dirdesc = AllocateDir(dir);
578  if (!dirdesc)
579  {
580  /* Return empty tuplestore if appropriate */
581  if (missing_ok && errno == ENOENT)
582  return (Datum) 0;
583  /* Otherwise, we can let ReadDir() throw the error */
584  }
585 
586  while ((de = ReadDir(dirdesc, dir)) != NULL)
587  {
588  Datum values[3];
589  bool nulls[3];
590  char path[MAXPGPATH * 2];
591  struct stat attrib;
592 
593  /* Skip hidden files */
594  if (de->d_name[0] == '.')
595  continue;
596 
597  /* Get the file info */
598  snprintf(path, sizeof(path), "%s/%s", dir, de->d_name);
599  if (stat(path, &attrib) < 0)
600  ereport(ERROR,
602  errmsg("could not stat file \"%s\": %m", path)));
603 
604  /* Ignore anything but regular files */
605  if (!S_ISREG(attrib.st_mode))
606  continue;
607 
608  values[0] = CStringGetTextDatum(de->d_name);
609  values[1] = Int64GetDatum((int64) attrib.st_size);
610  values[2] = TimestampTzGetDatum(time_t_to_timestamptz(attrib.st_mtime));
611  memset(nulls, 0, sizeof(nulls));
612 
613  tuplestore_putvalues(tupstore, tupdesc, values, nulls);
614  }
615 
616  FreeDir(dirdesc);
617  return (Datum) 0;
618 }
619 
620 /* Function to return the list of files in the log directory */
621 Datum
623 {
624  return pg_ls_dir_files(fcinfo, Log_directory, false);
625 }
626 
627 /* Function to return the list of files in the WAL directory */
628 Datum
630 {
631  return pg_ls_dir_files(fcinfo, XLOGDIR, false);
632 }
633 
634 /*
635  * Generic function to return the list of files in pgsql_tmp
636  */
637 static Datum
639 {
640  char path[MAXPGPATH];
641 
643  ereport(ERROR,
644  (errcode(ERRCODE_UNDEFINED_OBJECT),
645  errmsg("tablespace with OID %u does not exist",
646  tblspc)));
647 
648  TempTablespacePath(path, tblspc);
649  return pg_ls_dir_files(fcinfo, path, true);
650 }
651 
652 /*
653  * Function to return the list of temporary files in the pg_default tablespace's
654  * pgsql_tmp directory
655  */
656 Datum
658 {
659  return pg_ls_tmpdir(fcinfo, DEFAULTTABLESPACE_OID);
660 }
661 
662 /*
663  * Function to return the list of temporary files in the specified tablespace's
664  * pgsql_tmp directory
665  */
666 Datum
668 {
669  return pg_ls_tmpdir(fcinfo, PG_GETARG_OID(0));
670 }
671 
672 /*
673  * Function to return the list of files in the WAL archive status directory.
674  */
675 Datum
677 {
678  return pg_ls_dir_files(fcinfo, XLOGDIR "/archive_status", true);
679 }
void tuplestore_putvalues(Tuplestorestate *state, TupleDesc tdesc, Datum *values, bool *isnull)
Definition: tuplestore.c:750
Datum pg_ls_logdir(PG_FUNCTION_ARGS)
Definition: genfile.c:622
static char * convert_and_check_filename(text *arg)
Definition: genfile.c:53
#define IsA(nodeptr, _type_)
Definition: nodes.h:577
TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo, Oid *resultTypeId, TupleDesc *resultTupleDesc)
Definition: funcapi.c:205
int errhint(const char *fmt,...)
Definition: elog.c:1071
Datum pg_ls_tmpdir_noargs(PG_FUNCTION_ARGS)
Definition: genfile.c:657
#define VARDATA(PTR)
Definition: postgres.h:302
char * Log_directory
Definition: syslogger.c:72
TupleDesc CreateTemplateTupleDesc(int natts)
Definition: tupdesc.c:44
Oid GetUserId(void)
Definition: miscinit.c:439
#define VARSIZE(PTR)
Definition: postgres.h:303
bool path_is_prefix_of_path(const char *path1, const char *path2)
Definition: path.c:438
#define VARHDRSZ
Definition: c.h:561
Datum pg_read_file_all(PG_FUNCTION_ARGS)
Definition: genfile.c:335
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
void canonicalize_path(char *path)
Definition: path.c:254
int errcode(int sqlerrcode)
Definition: elog.c:610
bool superuser(void)
Definition: superuser.c:46
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, Datum *values, bool *isnull)
Definition: heaptuple.c:1020
#define PG_GETARG_BOOL(n)
Definition: fmgr.h:269
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:360
void TempTablespacePath(char *path, Oid tablespace)
Definition: fd.c:1628
unsigned int Oid
Definition: postgres_ext.h:31
Definition: dirent.h:9
#define PG_BINARY_R
Definition: c.h:1236
bool path_contains_parent_reference(const char *path)
Definition: path.c:376
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:303
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:183
void pfree(void *pointer)
Definition: mcxt.c:1056
Datum pg_read_binary_file_off_len(PG_FUNCTION_ARGS)
Definition: genfile.c:341
static Datum pg_ls_tmpdir(FunctionCallInfo fcinfo, Oid tblspc)
Definition: genfile.c:638
Datum pg_stat_file(PG_FUNCTION_ARGS)
Definition: genfile.c:356
Definition: dirent.c:25
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
fmNodePtr resultinfo
Definition: fmgr.h:89
Datum pg_read_file_off_len(PG_FUNCTION_ARGS)
Definition: genfile.c:329
#define TimestampTzGetDatum(X)
Definition: timestamp.h:32
#define MAXPGPATH
TupleDesc BlessTupleDesc(TupleDesc tupdesc)
Definition: execTuples.c:2052
static bytea * read_binary_file(const char *filename, int64 seek_offset, int64 bytes_to_read, bool missing_ok)
Definition: genfile.c:105
static char * buf
Definition: pg_test_fsync.c:67
#define PG_GETARG_OID(n)
Definition: fmgr.h:270
int errcode_for_file_access(void)
Definition: elog.c:633
#define is_absolute_path(filename)
Definition: port.h:86
bool path_is_relative_and_below_cwd(const char *path)
Definition: path.c:405
FILE * AllocateFile(const char *name, const char *mode)
Definition: fd.c:2320
DIR * AllocateDir(const char *dirname)
Definition: fd.c:2581
Datum Int64GetDatum(int64 X)
Definition: fmgr.c:1699
void TupleDescInitEntry(TupleDesc desc, AttrNumber attributeNumber, const char *attributeName, Oid oidtypeid, int32 typmod, int attdim)
Definition: tupdesc.c:603
Datum pg_read_binary_file(PG_FUNCTION_ARGS)
Definition: genfile.c:286
#define S_ISREG(m)
Definition: win32_port.h:299
Datum pg_ls_dir_1arg(PG_FUNCTION_ARGS)
Definition: genfile.c:526
#define MaxAllocSize
Definition: memutils.h:40
static Datum pg_ls_dir_files(FunctionCallInfo fcinfo, const char *dir, bool missing_ok)
Definition: genfile.c:538
#define stat(a, b)
Definition: win32_port.h:255
Tuplestorestate * tuplestore_begin_heap(bool randomAccess, bool interXact, int maxKBytes)
Definition: tuplestore.c:318
Datum pg_ls_archive_statusdir(PG_FUNCTION_ARGS)
Definition: genfile.c:676
Datum pg_ls_dir(PG_FUNCTION_ARGS)
Definition: genfile.c:441
#define XLOGDIR
uintptr_t Datum
Definition: postgres.h:367
#define PG_RETURN_DATUM(x)
Definition: fmgr.h:343
int work_mem
Definition: globals.c:121
TimestampTz time_t_to_timestamptz(pg_time_t tm)
Definition: timestamp.c:1703
#define fseeko(stream, offset, origin)
Definition: win32_port.h:201
#define BoolGetDatum(X)
Definition: postgres.h:402
bool pg_verifymbstr(const char *mbstr, int len, bool noError)
Definition: mbutils.c:1446
#define ereport(elevel,...)
Definition: elog.h:144
int allowedModes
Definition: execnodes.h:303
Datum pg_read_file_v2(PG_FUNCTION_ARGS)
Definition: genfile.c:250
bool is_member_of_role(Oid member, Oid role)
Definition: acl.c:4924
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:361
SetFunctionReturnMode returnMode
Definition: execnodes.h:305
Datum pg_read_file(PG_FUNCTION_ARGS)
Definition: genfile.c:203
#define PG_ARGISNULL(n)
Definition: fmgr.h:204
Datum pg_read_binary_file_all(PG_FUNCTION_ARGS)
Definition: genfile.c:347
struct dirent * ReadDir(DIR *dir, const char *dirname)
Definition: fd.c:2647
size_t Size
Definition: c.h:466
Datum pg_stat_file_1arg(PG_FUNCTION_ARGS)
Definition: genfile.c:432
#define PG_NARGS()
Definition: fmgr.h:198
#define HeapTupleGetDatum(tuple)
Definition: funcapi.h:220
MemoryContext ecxt_per_query_memory
Definition: execnodes.h:231
#define S_ISDIR(m)
Definition: win32_port.h:296
Tuplestorestate * setResult
Definition: execnodes.h:308
int FreeFile(FILE *file)
Definition: fd.c:2519
static Datum values[MAXATTR]
Definition: bootstrap.c:167
char * text_to_cstring(const text *t)
Definition: varlena.c:204
ExprContext * econtext
Definition: execnodes.h:301
static char * filename
Definition: pg_dumpall.c:90
TupleDesc setDesc
Definition: execnodes.h:309
void * palloc(Size size)
Definition: mcxt.c:949
int errmsg(const char *fmt,...)
Definition: elog.c:824
Datum pg_ls_tmpdir_1arg(PG_FUNCTION_ARGS)
Definition: genfile.c:667
#define elog(elevel,...)
Definition: elog.h:214
#define CStringGetTextDatum(s)
Definition: builtins.h:87
void * arg
char * DataDir
Definition: globals.c:62
Definition: c.h:555
#define PG_FUNCTION_ARGS
Definition: fmgr.h:188
#define SET_VARSIZE(PTR, len)
Definition: postgres.h:329
static text * read_text_file(const char *filename, int64 seek_offset, int64 bytes_to_read, bool missing_ok)
Definition: genfile.c:178
#define PG_GETARG_INT64(n)
Definition: fmgr.h:277
#define snprintf
Definition: port.h:192
int16 AttrNumber
Definition: attnum.h:21
#define PG_RETURN_NULL()
Definition: fmgr.h:335
int FreeDir(DIR *dir)
Definition: fd.c:2699
Datum pg_ls_waldir(PG_FUNCTION_ARGS)
Definition: genfile.c:629