| 1 | /*------------------------------------------------------------------------- |
| 2 | * |
| 3 | * fd.h |
| 4 | * Virtual file descriptor definitions. |
| 5 | * |
| 6 | * |
| 7 | * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group |
| 8 | * Portions Copyright (c) 1994, Regents of the University of California |
| 9 | * |
| 10 | * src/include/storage/fd.h |
| 11 | * |
| 12 | *------------------------------------------------------------------------- |
| 13 | */ |
| 14 | |
| 15 | /* |
| 16 | * calls: |
| 17 | * |
| 18 | * File {Close, Read, Write, Size, Sync} |
| 19 | * {Path Name Open, Allocate, Free} File |
| 20 | * |
| 21 | * These are NOT JUST RENAMINGS OF THE UNIX ROUTINES. |
| 22 | * Use them for all file activity... |
| 23 | * |
| 24 | * File fd; |
| 25 | * fd = PathNameOpenFile("foo", O_RDONLY); |
| 26 | * |
| 27 | * AllocateFile(); |
| 28 | * FreeFile(); |
| 29 | * |
| 30 | * Use AllocateFile, not fopen, if you need a stdio file (FILE*); then |
| 31 | * use FreeFile, not fclose, to close it. AVOID using stdio for files |
| 32 | * that you intend to hold open for any length of time, since there is |
| 33 | * no way for them to share kernel file descriptors with other files. |
| 34 | * |
| 35 | * Likewise, use AllocateDir/FreeDir, not opendir/closedir, to allocate |
| 36 | * open directories (DIR*), and OpenTransientFile/CloseTransientFile for an |
| 37 | * unbuffered file descriptor. |
| 38 | */ |
| 39 | #ifndef FD_H |
| 40 | #define FD_H |
| 41 | |
| 42 | #include <dirent.h> |
| 43 | |
| 44 | |
| 45 | typedef int File; |
| 46 | |
| 47 | |
| 48 | /* GUC parameter */ |
| 49 | extern PGDLLIMPORT int max_files_per_process; |
| 50 | extern PGDLLIMPORT bool data_sync_retry; |
| 51 | |
| 52 | /* |
| 53 | * This is private to fd.c, but exported for save/restore_backend_variables() |
| 54 | */ |
| 55 | extern int max_safe_fds; |
| 56 | |
| 57 | /* |
| 58 | * On Windows, we have to interpret EACCES as possibly meaning the same as |
| 59 | * ENOENT, because if a file is unlinked-but-not-yet-gone on that platform, |
| 60 | * that's what you get. Ugh. This code is designed so that we don't |
| 61 | * actually believe these cases are okay without further evidence (namely, |
| 62 | * a pending fsync request getting canceled ... see ProcessSyncRequests). |
| 63 | */ |
| 64 | #ifndef WIN32 |
| 65 | #define FILE_POSSIBLY_DELETED(err) ((err) == ENOENT) |
| 66 | #else |
| 67 | #define FILE_POSSIBLY_DELETED(err) ((err) == ENOENT || (err) == EACCES) |
| 68 | #endif |
| 69 | |
| 70 | /* |
| 71 | * prototypes for functions in fd.c |
| 72 | */ |
| 73 | |
| 74 | /* Operations on virtual Files --- equivalent to Unix kernel file ops */ |
| 75 | extern File PathNameOpenFile(const char *fileName, int fileFlags); |
| 76 | extern File PathNameOpenFilePerm(const char *fileName, int fileFlags, mode_t fileMode); |
| 77 | extern File OpenTemporaryFile(bool interXact); |
| 78 | extern void FileClose(File file); |
| 79 | extern int FilePrefetch(File file, off_t offset, int amount, uint32 wait_event_info); |
| 80 | extern int FileRead(File file, char *buffer, int amount, off_t offset, uint32 wait_event_info); |
| 81 | extern int FileWrite(File file, char *buffer, int amount, off_t offset, uint32 wait_event_info); |
| 82 | extern int FileSync(File file, uint32 wait_event_info); |
| 83 | extern off_t FileSize(File file); |
| 84 | extern int FileTruncate(File file, off_t offset, uint32 wait_event_info); |
| 85 | extern void FileWriteback(File file, off_t offset, off_t nbytes, uint32 wait_event_info); |
| 86 | extern char *FilePathName(File file); |
| 87 | extern int FileGetRawDesc(File file); |
| 88 | extern int FileGetRawFlags(File file); |
| 89 | extern mode_t FileGetRawMode(File file); |
| 90 | |
| 91 | /* Operations used for sharing named temporary files */ |
| 92 | extern File PathNameCreateTemporaryFile(const char *name, bool error_on_failure); |
| 93 | extern File PathNameOpenTemporaryFile(const char *name); |
| 94 | extern bool PathNameDeleteTemporaryFile(const char *name, bool error_on_failure); |
| 95 | extern void PathNameCreateTemporaryDir(const char *base, const char *name); |
| 96 | extern void PathNameDeleteTemporaryDir(const char *name); |
| 97 | extern void TempTablespacePath(char *path, Oid tablespace); |
| 98 | |
| 99 | /* Operations that allow use of regular stdio --- USE WITH CAUTION */ |
| 100 | extern FILE *AllocateFile(const char *name, const char *mode); |
| 101 | extern int FreeFile(FILE *file); |
| 102 | |
| 103 | /* Operations that allow use of pipe streams (popen/pclose) */ |
| 104 | extern FILE *OpenPipeStream(const char *command, const char *mode); |
| 105 | extern int ClosePipeStream(FILE *file); |
| 106 | |
| 107 | /* Operations to allow use of the <dirent.h> library routines */ |
| 108 | extern DIR *AllocateDir(const char *dirname); |
| 109 | extern struct dirent *ReadDir(DIR *dir, const char *dirname); |
| 110 | extern struct dirent *ReadDirExtended(DIR *dir, const char *dirname, |
| 111 | int elevel); |
| 112 | extern int FreeDir(DIR *dir); |
| 113 | |
| 114 | /* Operations to allow use of a plain kernel FD, with automatic cleanup */ |
| 115 | extern int OpenTransientFile(const char *fileName, int fileFlags); |
| 116 | extern int OpenTransientFilePerm(const char *fileName, int fileFlags, mode_t fileMode); |
| 117 | extern int CloseTransientFile(int fd); |
| 118 | |
| 119 | /* If you've really really gotta have a plain kernel FD, use this */ |
| 120 | extern int BasicOpenFile(const char *fileName, int fileFlags); |
| 121 | extern int BasicOpenFilePerm(const char *fileName, int fileFlags, mode_t fileMode); |
| 122 | |
| 123 | /* Make a directory with default permissions */ |
| 124 | extern int MakePGDirectory(const char *directoryName); |
| 125 | |
| 126 | /* Miscellaneous support routines */ |
| 127 | extern void InitFileAccess(void); |
| 128 | extern void set_max_safe_fds(void); |
| 129 | extern void closeAllVfds(void); |
| 130 | extern void SetTempTablespaces(Oid *tableSpaces, int numSpaces); |
| 131 | extern bool TempTablespacesAreSet(void); |
| 132 | extern int GetTempTablespaces(Oid *tableSpaces, int numSpaces); |
| 133 | extern Oid GetNextTempTableSpace(void); |
| 134 | extern void AtEOXact_Files(bool isCommit); |
| 135 | extern void AtEOSubXact_Files(bool isCommit, SubTransactionId mySubid, |
| 136 | SubTransactionId parentSubid); |
| 137 | extern void RemovePgTempFiles(void); |
| 138 | extern bool looks_like_temp_rel_name(const char *name); |
| 139 | |
| 140 | extern int pg_fsync(int fd); |
| 141 | extern int pg_fsync_no_writethrough(int fd); |
| 142 | extern int pg_fsync_writethrough(int fd); |
| 143 | extern int pg_fdatasync(int fd); |
| 144 | extern void pg_flush_data(int fd, off_t offset, off_t amount); |
| 145 | extern void fsync_fname(const char *fname, bool isdir); |
| 146 | extern int durable_rename(const char *oldfile, const char *newfile, int loglevel); |
| 147 | extern int durable_unlink(const char *fname, int loglevel); |
| 148 | extern int durable_link_or_rename(const char *oldfile, const char *newfile, int loglevel); |
| 149 | extern void SyncDataDirectory(void); |
| 150 | extern int data_sync_elevel(int elevel); |
| 151 | |
| 152 | /* Filename components */ |
| 153 | #define PG_TEMP_FILES_DIR "pgsql_tmp" |
| 154 | #define PG_TEMP_FILE_PREFIX "pgsql_tmp" |
| 155 | |
| 156 | #endif /* FD_H */ |
| 157 | |