PostgreSQL Source Code  git master
file_ops.c File Reference
#include "postgres_fe.h"
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include "common/file_perm.h"
#include "file_ops.h"
#include "filemap.h"
#include "logging.h"
#include "pg_rewind.h"
Include dependency graph for file_ops.c:

Go to the source code of this file.

Functions

static void create_target_dir (const char *path)
 
static void remove_target_dir (const char *path)
 
static void create_target_symlink (const char *path, const char *link)
 
static void remove_target_symlink (const char *path)
 
void open_target_file (const char *path, bool trunc)
 
void close_target_file (void)
 
void write_target_range (char *buf, off_t begin, size_t size)
 
void remove_target (file_entry_t *entry)
 
void create_target (file_entry_t *entry)
 
void remove_target_file (const char *path, bool missing_ok)
 
void truncate_target_file (const char *path, off_t newsize)
 
char * slurpFile (const char *datadir, const char *path, size_t *filesize)
 

Variables

static int dstfd = -1
 
static char dstpath [MAXPGPATH] = ""
 

Function Documentation

◆ close_target_file()

void close_target_file ( void  )

Definition at line 71 of file file_ops.c.

References close, dstfd, dstpath, pg_fatal(), and strerror().

Referenced by copy_executeFileMap(), createBackupLabel(), open_target_file(), and updateControlFile().

72 {
73  if (dstfd == -1)
74  return;
75 
76  if (close(dstfd) != 0)
77  pg_fatal("could not close target file \"%s\": %s\n",
78  dstpath, strerror(errno));
79 
80  dstfd = -1;
81 }
static int dstfd
Definition: file_ops.c:30
void pg_fatal(const char *fmt,...)
Definition: logging.c:83
static char dstpath[MAXPGPATH]
Definition: file_ops.c:31
const char * strerror(int errnum)
Definition: strerror.c:19
#define close(a)
Definition: win32.h:12

◆ create_target()

void create_target ( file_entry_t entry)

Definition at line 147 of file file_ops.c.

References file_entry_t::action, Assert, create_target_dir(), create_target_symlink(), FILE_ACTION_CREATE, FILE_TYPE_DIRECTORY, FILE_TYPE_REGULAR, FILE_TYPE_SYMLINK, file_entry_t::link_target, file_entry_t::path, pg_fatal(), and file_entry_t::type.

Referenced by copy_executeFileMap(), and libpq_executeFileMap().

148 {
149  Assert(entry->action == FILE_ACTION_CREATE);
150 
151  switch (entry->type)
152  {
153  case FILE_TYPE_DIRECTORY:
154  create_target_dir(entry->path);
155  break;
156 
157  case FILE_TYPE_SYMLINK:
158  create_target_symlink(entry->path, entry->link_target);
159  break;
160 
161  case FILE_TYPE_REGULAR:
162  /* can't happen. Regular files are created with open_target_file. */
163  pg_fatal("invalid action (CREATE) for regular file\n");
164  break;
165  }
166 }
void pg_fatal(const char *fmt,...)
Definition: logging.c:83
file_type_t type
Definition: filemap.h:45
static void create_target_symlink(const char *path, const char *link)
Definition: file_ops.c:243
file_action_t action
Definition: filemap.h:47
char * link_target
Definition: filemap.h:57
static void create_target_dir(const char *path)
Definition: file_ops.c:215
#define Assert(condition)
Definition: c.h:699
char * path
Definition: filemap.h:44

◆ create_target_dir()

static void create_target_dir ( const char *  path)
static

Definition at line 215 of file file_ops.c.

References datadir_target, dry_run, dstpath, MAXPGPATH, mkdir, pg_dir_create_mode, pg_fatal(), snprintf(), and strerror().

Referenced by create_target().

216 {
217  char dstpath[MAXPGPATH];
218 
219  if (dry_run)
220  return;
221 
222  snprintf(dstpath, sizeof(dstpath), "%s/%s", datadir_target, path);
223  if (mkdir(dstpath, pg_dir_create_mode) != 0)
224  pg_fatal("could not create directory \"%s\": %s\n",
225  dstpath, strerror(errno));
226 }
char * datadir_target
Definition: pg_rewind.c:51
bool dry_run
Definition: pg_rewind.c:57
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
void pg_fatal(const char *fmt,...)
Definition: logging.c:83
#define MAXPGPATH
static char dstpath[MAXPGPATH]
Definition: file_ops.c:31
int pg_dir_create_mode
Definition: file_perm.c:19
const char * strerror(int errnum)
Definition: strerror.c:19
#define mkdir(a, b)
Definition: win32_port.h:58

◆ create_target_symlink()

static void create_target_symlink ( const char *  path,
const char *  link 
)
static

Definition at line 243 of file file_ops.c.

References datadir_target, dry_run, dstpath, MAXPGPATH, pg_fatal(), snprintf(), strerror(), and symlink.

Referenced by create_target().

244 {
245  char dstpath[MAXPGPATH];
246 
247  if (dry_run)
248  return;
249 
250  snprintf(dstpath, sizeof(dstpath), "%s/%s", datadir_target, path);
251  if (symlink(link, dstpath) != 0)
252  pg_fatal("could not create symbolic link at \"%s\": %s\n",
253  dstpath, strerror(errno));
254 }
char * datadir_target
Definition: pg_rewind.c:51
bool dry_run
Definition: pg_rewind.c:57
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
void pg_fatal(const char *fmt,...)
Definition: logging.c:83
#define MAXPGPATH
#define symlink(oldpath, newpath)
Definition: win32_port.h:232
static char dstpath[MAXPGPATH]
Definition: file_ops.c:31
const char * strerror(int errnum)
Definition: strerror.c:19

◆ open_target_file()

void open_target_file ( const char *  path,
bool  trunc 
)

Definition at line 43 of file file_ops.c.

References close_target_file(), datadir_target, dry_run, dstfd, dstpath, PG_BINARY, pg_fatal(), pg_file_create_mode, snprintf(), and strerror().

Referenced by createBackupLabel(), libpq_executeFileMap(), receiveFileChunks(), rewind_copy_file_range(), and updateControlFile().

44 {
45  int mode;
46 
47  if (dry_run)
48  return;
49 
50  if (dstfd != -1 && !trunc &&
51  strcmp(path, &dstpath[strlen(datadir_target) + 1]) == 0)
52  return; /* already open */
53 
55 
56  snprintf(dstpath, sizeof(dstpath), "%s/%s", datadir_target, path);
57 
58  mode = O_WRONLY | O_CREAT | PG_BINARY;
59  if (trunc)
60  mode |= O_TRUNC;
61  dstfd = open(dstpath, mode, pg_file_create_mode);
62  if (dstfd < 0)
63  pg_fatal("could not open target file \"%s\": %s\n",
64  dstpath, strerror(errno));
65 }
char * datadir_target
Definition: pg_rewind.c:51
static int dstfd
Definition: file_ops.c:30
int pg_file_create_mode
Definition: file_perm.c:20
bool dry_run
Definition: pg_rewind.c:57
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
void pg_fatal(const char *fmt,...)
Definition: logging.c:83
#define PG_BINARY
Definition: c.h:1080
static char dstpath[MAXPGPATH]
Definition: file_ops.c:31
void close_target_file(void)
Definition: file_ops.c:71
const char * strerror(int errnum)
Definition: strerror.c:19

◆ remove_target()

void remove_target ( file_entry_t entry)

Definition at line 126 of file file_ops.c.

References file_entry_t::action, Assert, FILE_ACTION_REMOVE, FILE_TYPE_DIRECTORY, FILE_TYPE_REGULAR, FILE_TYPE_SYMLINK, file_entry_t::path, remove_target_dir(), remove_target_file(), remove_target_symlink(), and file_entry_t::type.

Referenced by copy_executeFileMap(), and libpq_executeFileMap().

127 {
128  Assert(entry->action == FILE_ACTION_REMOVE);
129 
130  switch (entry->type)
131  {
132  case FILE_TYPE_DIRECTORY:
133  remove_target_dir(entry->path);
134  break;
135 
136  case FILE_TYPE_REGULAR:
137  remove_target_file(entry->path, false);
138  break;
139 
140  case FILE_TYPE_SYMLINK:
141  remove_target_symlink(entry->path);
142  break;
143  }
144 }
void remove_target_file(const char *path, bool missing_ok)
Definition: file_ops.c:173
file_type_t type
Definition: filemap.h:45
file_action_t action
Definition: filemap.h:47
static void remove_target_symlink(const char *path)
Definition: file_ops.c:257
static void remove_target_dir(const char *path)
Definition: file_ops.c:229
#define Assert(condition)
Definition: c.h:699
char * path
Definition: filemap.h:44

◆ remove_target_dir()

static void remove_target_dir ( const char *  path)
static

Definition at line 229 of file file_ops.c.

References datadir_target, dry_run, dstpath, MAXPGPATH, pg_fatal(), snprintf(), and strerror().

Referenced by remove_target().

230 {
231  char dstpath[MAXPGPATH];
232 
233  if (dry_run)
234  return;
235 
236  snprintf(dstpath, sizeof(dstpath), "%s/%s", datadir_target, path);
237  if (rmdir(dstpath) != 0)
238  pg_fatal("could not remove directory \"%s\": %s\n",
239  dstpath, strerror(errno));
240 }
char * datadir_target
Definition: pg_rewind.c:51
bool dry_run
Definition: pg_rewind.c:57
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
void pg_fatal(const char *fmt,...)
Definition: logging.c:83
#define MAXPGPATH
static char dstpath[MAXPGPATH]
Definition: file_ops.c:31
const char * strerror(int errnum)
Definition: strerror.c:19

◆ remove_target_file()

void remove_target_file ( const char *  path,
bool  missing_ok 
)

Definition at line 173 of file file_ops.c.

References datadir_target, dry_run, dstpath, MAXPGPATH, pg_fatal(), snprintf(), and strerror().

Referenced by receiveFileChunks(), and remove_target().

174 {
175  char dstpath[MAXPGPATH];
176 
177  if (dry_run)
178  return;
179 
180  snprintf(dstpath, sizeof(dstpath), "%s/%s", datadir_target, path);
181  if (unlink(dstpath) != 0)
182  {
183  if (errno == ENOENT && missing_ok)
184  return;
185 
186  pg_fatal("could not remove file \"%s\": %s\n",
187  dstpath, strerror(errno));
188  }
189 }
char * datadir_target
Definition: pg_rewind.c:51
bool dry_run
Definition: pg_rewind.c:57
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
void pg_fatal(const char *fmt,...)
Definition: logging.c:83
#define MAXPGPATH
static char dstpath[MAXPGPATH]
Definition: file_ops.c:31
const char * strerror(int errnum)
Definition: strerror.c:19

◆ remove_target_symlink()

static void remove_target_symlink ( const char *  path)
static

Definition at line 257 of file file_ops.c.

References datadir_target, dry_run, dstpath, MAXPGPATH, pg_fatal(), snprintf(), and strerror().

Referenced by remove_target().

258 {
259  char dstpath[MAXPGPATH];
260 
261  if (dry_run)
262  return;
263 
264  snprintf(dstpath, sizeof(dstpath), "%s/%s", datadir_target, path);
265  if (unlink(dstpath) != 0)
266  pg_fatal("could not remove symbolic link \"%s\": %s\n",
267  dstpath, strerror(errno));
268 }
char * datadir_target
Definition: pg_rewind.c:51
bool dry_run
Definition: pg_rewind.c:57
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
void pg_fatal(const char *fmt,...)
Definition: logging.c:83
#define MAXPGPATH
static char dstpath[MAXPGPATH]
Definition: file_ops.c:31
const char * strerror(int errnum)
Definition: strerror.c:19

◆ slurpFile()

char* slurpFile ( const char *  datadir,
const char *  path,
size_t *  filesize 
)

Definition at line 285 of file file_ops.c.

References buffer, close, fd(), MAXPGPATH, PG_BINARY, pg_fatal(), pg_malloc(), read, snprintf(), stat, and strerror().

Referenced by fetchFile(), getTimelineHistory(), and main().

286 {
287  int fd;
288  char *buffer;
289  struct stat statbuf;
290  char fullpath[MAXPGPATH];
291  int len;
292 
293  snprintf(fullpath, sizeof(fullpath), "%s/%s", datadir, path);
294 
295  if ((fd = open(fullpath, O_RDONLY | PG_BINARY, 0)) == -1)
296  pg_fatal("could not open file \"%s\" for reading: %s\n",
297  fullpath, strerror(errno));
298 
299  if (fstat(fd, &statbuf) < 0)
300  pg_fatal("could not open file \"%s\" for reading: %s\n",
301  fullpath, strerror(errno));
302 
303  len = statbuf.st_size;
304 
305  buffer = pg_malloc(len + 1);
306 
307  if (read(fd, buffer, len) != len)
308  pg_fatal("could not read file \"%s\": %s\n",
309  fullpath, strerror(errno));
310  close(fd);
311 
312  /* Zero-terminate the buffer. */
313  buffer[len] = '\0';
314 
315  if (filesize)
316  *filesize = len;
317  return buffer;
318 }
void * pg_malloc(size_t size)
Definition: fe_memutils.c:47
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
void pg_fatal(const char *fmt,...)
Definition: logging.c:83
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define PG_BINARY
Definition: c.h:1080
#define MAXPGPATH
char * datadir
#define stat(a, b)
Definition: win32_port.h:266
WalTimeSample buffer[LAG_TRACKER_BUFFER_SIZE]
Definition: walsender.c:215
const char * strerror(int errnum)
Definition: strerror.c:19
#define close(a)
Definition: win32.h:12
#define read(a, b, c)
Definition: win32.h:13

◆ truncate_target_file()

void truncate_target_file ( const char *  path,
off_t  newsize 
)

Definition at line 192 of file file_ops.c.

References close, datadir_target, dry_run, dstpath, fd(), ftruncate, MAXPGPATH, pg_fatal(), pg_file_create_mode, snprintf(), and strerror().

Referenced by copy_executeFileMap(), and libpq_executeFileMap().

193 {
194  char dstpath[MAXPGPATH];
195  int fd;
196 
197  if (dry_run)
198  return;
199 
200  snprintf(dstpath, sizeof(dstpath), "%s/%s", datadir_target, path);
201 
202  fd = open(dstpath, O_WRONLY, pg_file_create_mode);
203  if (fd < 0)
204  pg_fatal("could not open file \"%s\" for truncation: %s\n",
205  dstpath, strerror(errno));
206 
207  if (ftruncate(fd, newsize) != 0)
208  pg_fatal("could not truncate file \"%s\" to %u: %s\n",
209  dstpath, (unsigned int) newsize, strerror(errno));
210 
211  close(fd);
212 }
char * datadir_target
Definition: pg_rewind.c:51
int pg_file_create_mode
Definition: file_perm.c:20
bool dry_run
Definition: pg_rewind.c:57
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
void pg_fatal(const char *fmt,...)
Definition: logging.c:83
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define MAXPGPATH
static char dstpath[MAXPGPATH]
Definition: file_ops.c:31
const char * strerror(int errnum)
Definition: strerror.c:19
#define close(a)
Definition: win32.h:12
#define ftruncate(a, b)
Definition: win32_port.h:60

◆ write_target_range()

void write_target_range ( char *  buf,
off_t  begin,
size_t  size 
)

Definition at line 84 of file file_ops.c.

References buf, dry_run, dstfd, dstpath, fetch_done, pg_fatal(), progress_report(), strerror(), and write.

Referenced by createBackupLabel(), receiveFileChunks(), rewind_copy_file_range(), and updateControlFile().

85 {
86  int writeleft;
87  char *p;
88 
89  /* update progress report */
90  fetch_done += size;
91  progress_report(false);
92 
93  if (dry_run)
94  return;
95 
96  if (lseek(dstfd, begin, SEEK_SET) == -1)
97  pg_fatal("could not seek in target file \"%s\": %s\n",
98  dstpath, strerror(errno));
99 
100  writeleft = size;
101  p = buf;
102  while (writeleft > 0)
103  {
104  int writelen;
105 
106  errno = 0;
107  writelen = write(dstfd, p, writeleft);
108  if (writelen < 0)
109  {
110  /* if write didn't set errno, assume problem is no disk space */
111  if (errno == 0)
112  errno = ENOSPC;
113  pg_fatal("could not write file \"%s\": %s\n",
114  dstpath, strerror(errno));
115  }
116 
117  p += writelen;
118  writeleft -= writelen;
119  }
120 
121  /* keep the file open, in case we need to copy more blocks in it */
122 }
static int dstfd
Definition: file_ops.c:30
uint64 fetch_done
Definition: logging.c:22
#define write(a, b, c)
Definition: win32.h:14
bool dry_run
Definition: pg_rewind.c:57
void pg_fatal(const char *fmt,...)
Definition: logging.c:83
static char * buf
Definition: pg_test_fsync.c:67
static void progress_report(int tablespacenum, const char *filename, bool force)
static char dstpath[MAXPGPATH]
Definition: file_ops.c:31
const char * strerror(int errnum)
Definition: strerror.c:19

Variable Documentation

◆ dstfd

int dstfd = -1
static

Definition at line 30 of file file_ops.c.

Referenced by close_target_file(), copy_file(), open_target_file(), and write_target_range().

◆ dstpath