bool TSFrameReader::SetFile(string filePath) { FreeFile(); _freeFile = true; _pFile = GetFile(filePath, 4 * 1024 * 1024); if (_pFile == NULL) { FATAL("Unable to open file %s", STR(filePath)); return false; } if (!DetermineChunkSize()) { FATAL("Unable to determine chunk size"); FreeFile(); return false; } SetChunkSize(_chunkSize); if (!_pFile->SeekTo(_chunkSizeDetectionCount)) { FATAL("Unable to seek to the beginning of file"); FreeFile(); return false; } _eof = _pFile->IsEOF(); _defaultBlockSize = ((1024 * 1024 * 2) / _chunkSize) * _chunkSize; return true; }
/* Dumps the histogram data into a file (with a md5 hash of the contents at the beginning). */ static void pg_record_shmem_shutdown(int code, Datum arg) { FILE * file; /* do we need to write the queries? */ if (query_buffer->next == 0) { return; } prepare_file(log_file, query_buffer, query_buffer->next); file = AllocateFile(log_file->curr_filename, PG_BINARY_A); if (file == NULL) goto error; /* now write the actual shared segment */ if (fwrite(query_buffer->buffer, query_buffer->next, 1, file) != 1) goto error; FreeFile(file); return; error: ereport(LOG, (errcode_for_file_access(), errmsg("could not write query buffer to the file \"%s\": %m", log_file->curr_filename))); if (file) FreeFile(file); }
/* Dumps the histogram data into a file (with a md5 hash of the contents at the beginning). */ static void buffer_write() { FILE * file; prepare_file(log_file, query_buffer, query_buffer->next); file = AllocateFile(log_file->curr_filename, PG_BINARY_A); if (file == NULL) goto error; /* now write the actual shared segment */ if (fwrite(query_buffer->buffer, query_buffer->next, 1, file) != 1) goto error; FreeFile(file); return; error: ereport(LOG, (errcode_for_file_access(), errmsg("could not write query histogram file \"%s\": %m", log_file->curr_filename))); if (file) FreeFile(file); }
/* * shmem_shutdown hook: Dump statistics into file. * * Note: we don't bother with acquiring lock, because there should be no * other processes running when this is called. */ static void pgss_shmem_shutdown(int code, Datum arg) { FILE *file; HASH_SEQ_STATUS hash_seq; int32 num_entries; pgssEntry *entry; /* Don't try to dump during a crash. */ if (code) return; /* Safety check ... shouldn't get here unless shmem is set up. */ if (!pgss || !pgss_hash) return; /* Don't dump if told not to. */ if (!pgss_save) return; file = AllocateFile(PGSS_DUMP_FILE, PG_BINARY_W); if (file == NULL) goto error; if (fwrite(&PGSS_FILE_HEADER, sizeof(uint32), 1, file) != 1) goto error; num_entries = hash_get_num_entries(pgss_hash); if (fwrite(&num_entries, sizeof(int32), 1, file) != 1) goto error; hash_seq_init(&hash_seq, pgss_hash); while ((entry = hash_seq_search(&hash_seq)) != NULL) { int len = entry->key.query_len; if (fwrite(entry, offsetof(pgssEntry, mutex), 1, file) != 1 || fwrite(entry->query, 1, len, file) != len) goto error; } if (FreeFile(file)) { file = NULL; goto error; } return; error: ereport(LOG, (errcode_for_file_access(), errmsg("could not write pg_stat_statement file \"%s\": %m", PGSS_DUMP_FILE))); if (file) FreeFile(file); unlink(PGSS_DUMP_FILE); }
/* * CREATE FUNCTION utl_file.fcopy( * src_location text, * src_filename text, * dest_location text, * dest_filename text, * start_line integer DEFAULT NULL * end_line integer DEFAULT NULL) */ Datum utl_file_fcopy(PG_FUNCTION_ARGS) { char *srcpath; char *dstpath; int start_line; int end_line; FILE *srcfile; FILE *dstfile; NOT_NULL_ARG(0); NOT_NULL_ARG(1); NOT_NULL_ARG(2); NOT_NULL_ARG(3); srcpath = get_safe_path(PG_GETARG_TEXT_P(0), PG_GETARG_TEXT_P(1)); dstpath = get_safe_path(PG_GETARG_TEXT_P(2), PG_GETARG_TEXT_P(3)); start_line = PG_GETARG_IF_EXISTS(4, INT32, 1); if (start_line <= 0) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("start_line must be positive (%d passed)", start_line))); end_line = PG_GETARG_IF_EXISTS(5, INT32, INT_MAX); if (end_line <= 0) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("end_line must be positive (%d passed)", end_line))); srcfile = AllocateFile(srcpath, "rt"); if (srcfile == NULL) { /* failed to open src file. */ IO_EXCEPTION(); } dstfile = AllocateFile(dstpath, "wt"); if (dstfile == NULL) { /* failed to open dst file. */ fclose(srcfile); IO_EXCEPTION(); } if (copy_text_file(srcfile, dstfile, start_line, end_line)) IO_EXCEPTION(); FreeFile(srcfile); FreeFile(dstfile); PG_RETURN_VOID(); }
/** * @brief clean up Reader structure. */ int64 ReaderClose(Reader *rd, bool onError) { int64 skip = 0; if (rd == NULL) return 0; /* Close and release members. */ if (rd->parser) skip = ParserTerm(rd->parser); CheckerTerm(&rd->checker); if (!onError) { if (rd->parse_fp != NULL && FreeFile(rd->parse_fp) < 0) ereport(WARNING, (errcode_for_file_access(), errmsg("could not close parse bad file \"%s\": %m", rd->parse_badfile))); if (rd->infile != NULL) pfree(rd->infile); if (rd->logfile != NULL) pfree(rd->logfile); if (rd->parse_badfile != NULL) pfree(rd->parse_badfile); pfree(rd); } return skip; }
/* * Close down after reading a file with tsearch_readline() */ void tsearch_readline_end(tsearch_readline_state *stp) { FreeFile(stp->fp); /* Pop the error context stack */ error_context_stack = stp->cb.previous; }
//------------------------------------------------------ int FrameSeq::Load(AnsiString filename) { FreeFile(); try {File=new TFileStream(filename,fmOpenRead|fmShareExclusive);} catch(...) {return 1;} File->Seek(0,soFromBeginning); Header=new __int8[4100]; File->Read(Header,4100); File->Seek(108,soFromBeginning); short int datatype; File->Read(&datatype,2); if(datatype == 0) return 2; //FLOATING POINT intensity format is not supported DatLength=datatype>1?2:4; File->Seek(1446,soFromBeginning); int NFramestemp=0,XDimtemp=0,YDimtemp=0; File->Read(&NFramestemp,4); File->Seek(42,soFromBeginning); File->Read(&XDimtemp,2); File->Seek(656,soFromBeginning); File->Read(&YDimtemp,2); if( (NFramestemp<1)||(NFramestemp>MaxFrames)||(!datatype)||(XDimtemp<1) ||(XDimtemp>MaxDim)||(YDimtemp<1)||(YDimtemp>MaxDim) ) { delete File; File=NULL; return 1; } NFrames=NFramestemp; XDim=XDimtemp; YDim=YDimtemp; CurFrame=new Frame(XDim,YDim); // LoadFrame(1); return 0; };
/* * XLogArchiveNotify * * Create an archive notification file * * The name of the notification file is the message that will be picked up * by the archiver, e.g. we write 0000000100000001000000C6.ready * and the archiver then knows to archive XLOGDIR/0000000100000001000000C6, * then when complete, rename it to 0000000100000001000000C6.done */ void XLogArchiveNotify(const char *xlog) { char archiveStatusPath[MAXPGPATH]; FILE *fd; /* insert an otherwise empty file called <XLOG>.ready */ StatusFilePath(archiveStatusPath, xlog, ".ready"); fd = AllocateFile(archiveStatusPath, "w"); if (fd == NULL) { ereport(LOG, (errcode_for_file_access(), errmsg("could not create archive status file \"%s\": %m", archiveStatusPath))); return; } if (FreeFile(fd)) { ereport(LOG, (errcode_for_file_access(), errmsg("could not write archive status file \"%s\": %m", archiveStatusPath))); return; } /* Notify archiver that it's got something to do */ if (IsUnderPostmaster) SendPostmasterSignal(PMSIGNAL_WAKEN_ARCHIVER); }
/* * FindMyDatabase -- get the critical info needed to locate my database * * Find the named database in pg_database, return its database OID and the * OID of its default tablespace. Return TRUE if found, FALSE if not. * * Since we are not yet up and running as a backend, we cannot look directly * at pg_database (we can't obtain locks nor participate in transactions). * So to get the info we need before starting up, we must look at the "flat * file" copy of pg_database that is helpfully maintained by flatfiles.c. * This is subject to various race conditions, so after we have the * transaction infrastructure started, we have to recheck the information; * see InitPostgres. */ static bool FindMyDatabase(const char *name, Oid *db_id, Oid *db_tablespace) { bool result = false; char *filename; FILE *db_file; char thisname[NAMEDATALEN]; TransactionId db_frozenxid; filename = database_getflatfilename(); db_file = AllocateFile(filename, "r"); if (db_file == NULL) ereport(FATAL, (errcode_for_file_access(), errmsg("could not open file \"%s\": %m", filename))); while (read_pg_database_line(db_file, thisname, db_id, db_tablespace, &db_frozenxid)) { if (strcmp(thisname, name) == 0) { result = true; break; } } FreeFile(db_file); pfree(filename); return result; }
/* * Returns start time of an online exclusive backup. * * When there's no exclusive backup in progress, the function * returns NULL. */ Datum pg_backup_start_time(PG_FUNCTION_ARGS) { Datum xtime; FILE *lfp; char fline[MAXPGPATH]; char backup_start_time[30]; /* * See if label file is present */ lfp = AllocateFile(BACKUP_LABEL_FILE, "r"); if (lfp == NULL) { if (errno != ENOENT) ereport(ERROR, (errcode_for_file_access(), errmsg("could not read file \"%s\": %m", BACKUP_LABEL_FILE))); PG_RETURN_NULL(); } /* * Parse the file to find the START TIME line. */ backup_start_time[0] = '\0'; while (fgets(fline, sizeof(fline), lfp) != NULL) { if (sscanf(fline, "START TIME: %25[^\n]\n", backup_start_time) == 1) break; } /* Check for a read error. */ if (ferror(lfp)) ereport(ERROR, (errcode_for_file_access(), errmsg("could not read file \"%s\": %m", BACKUP_LABEL_FILE))); /* Close the backup label file. */ if (FreeFile(lfp)) ereport(ERROR, (errcode_for_file_access(), errmsg("could not close file \"%s\": %m", BACKUP_LABEL_FILE))); if (strlen(backup_start_time) == 0) ereport(ERROR, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), errmsg("invalid data in file \"%s\"", BACKUP_LABEL_FILE))); /* * Convert the time string read from file to TimestampTz form. */ xtime = DirectFunctionCall3(timestamptz_in, CStringGetDatum(backup_start_time), ObjectIdGetDatum(InvalidOid), Int32GetDatum(-1)); PG_RETURN_DATUM(xtime); }
/* * Read a section of a file, returning it as text */ Datum pg_read_file(PG_FUNCTION_ARGS) { text *filename_t = PG_GETARG_TEXT_P(0); int64 seek_offset = PG_GETARG_INT64(1); int64 bytes_to_read = PG_GETARG_INT64(2); char *buf; size_t nbytes; FILE *file; char *filename; if (!superuser()) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), (errmsg("must be superuser to read files")))); filename = convert_and_check_filename(filename_t); if ((file = AllocateFile(filename, PG_BINARY_R)) == NULL) ereport(ERROR, (errcode_for_file_access(), errmsg("could not open file \"%s\" for reading: %m", filename))); if (fseeko(file, (off_t) seek_offset, (seek_offset >= 0) ? SEEK_SET : SEEK_END) != 0) ereport(ERROR, (errcode_for_file_access(), errmsg("could not seek in file \"%s\": %m", filename))); if (bytes_to_read < 0) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("requested length cannot be negative"))); /* not sure why anyone thought that int64 length was a good idea */ if (bytes_to_read > (MaxAllocSize - VARHDRSZ)) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("requested length too large"))); buf = palloc((Size) bytes_to_read + VARHDRSZ); nbytes = fread(VARDATA(buf), 1, (size_t) bytes_to_read, file); if (ferror(file)) ereport(ERROR, (errcode_for_file_access(), errmsg("could not read file \"%s\": %m", filename))); SET_VARSIZE(buf, nbytes + VARHDRSZ); FreeFile(file); pfree(filename); PG_RETURN_TEXT_P(buf); }
/* * Read a section of a file, returning it as bytea * * Caller is responsible for all permissions checking. * * We read the whole of the file when bytes_to_read is negative. */ bytea * read_binary_file(const char *filename, int64 seek_offset, int64 bytes_to_read) { bytea *buf; size_t nbytes; FILE *file; if (bytes_to_read < 0) { if (seek_offset < 0) bytes_to_read = -seek_offset; else { struct stat fst; if (stat(filename, &fst) < 0) ereport(ERROR, (errcode_for_file_access(), errmsg("could not stat file \"%s\": %m", filename))); bytes_to_read = fst.st_size - seek_offset; } } /* not sure why anyone thought that int64 length was a good idea */ if (bytes_to_read > (MaxAllocSize - VARHDRSZ)) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("requested length too large"))); if ((file = AllocateFile(filename, PG_BINARY_R)) == NULL) ereport(ERROR, (errcode_for_file_access(), errmsg("could not open file \"%s\" for reading: %m", filename))); if (fseeko(file, (off_t) seek_offset, (seek_offset >= 0) ? SEEK_SET : SEEK_END) != 0) ereport(ERROR, (errcode_for_file_access(), errmsg("could not seek in file \"%s\": %m", filename))); buf = (bytea *) palloc((Size) bytes_to_read + VARHDRSZ); nbytes = fread(VARDATA(buf), 1, (size_t) bytes_to_read, file); if (ferror(file)) ereport(ERROR, (errcode_for_file_access(), errmsg("could not read file \"%s\": %m", filename))); SET_VARSIZE(buf, nbytes + VARHDRSZ); FreeFile(file); return buf; }
/* * Load precomputed DH parameters. * * To prevent "downgrade" attacks, we perform a number of checks * to verify that the DBA-generated DH parameters file contains * what we expect it to contain. */ static DH * load_dh_file(char *filename, bool isServerStart) { FILE *fp; DH *dh = NULL; int codes; /* attempt to open file. It's not an error if it doesn't exist. */ if ((fp = AllocateFile(filename, "r")) == NULL) { ereport(isServerStart ? FATAL : LOG, (errcode_for_file_access(), errmsg("could not open DH parameters file \"%s\": %m", filename))); return NULL; } dh = PEM_read_DHparams(fp, NULL, NULL, NULL); FreeFile(fp); if (dh == NULL) { ereport(isServerStart ? FATAL : LOG, (errcode(ERRCODE_CONFIG_FILE_ERROR), errmsg("could not load DH parameters file: %s", SSLerrmessage(ERR_get_error())))); return NULL; } /* make sure the DH parameters are usable */ if (DH_check(dh, &codes) == 0) { ereport(isServerStart ? FATAL : LOG, (errcode(ERRCODE_CONFIG_FILE_ERROR), errmsg("invalid DH parameters: %s", SSLerrmessage(ERR_get_error())))); return NULL; } if (codes & DH_CHECK_P_NOT_PRIME) { ereport(isServerStart ? FATAL : LOG, (errcode(ERRCODE_CONFIG_FILE_ERROR), errmsg("invalid DH parameters: p is not prime"))); return NULL; } if ((codes & DH_NOT_SUITABLE_GENERATOR) && (codes & DH_CHECK_P_NOT_SAFE_PRIME)) { ereport(isServerStart ? FATAL : LOG, (errcode(ERRCODE_CONFIG_FILE_ERROR), errmsg("invalid DH parameters: neither suitable generator or safe prime"))); return NULL; } return dh; }
static void FileSourceClose(FileSource *self) { if (self->fd != NULL && FreeFile(self->fd) < 0) { ereport(WARNING, (errcode_for_file_access(), errmsg("could not close source file: %m"))); } pfree(self); }
/* * write out the PG_VERSION file in the specified directory */ static void set_short_version(const char *path) { char *short_version; bool gotdot = false; int end; char *fullname; FILE *version_file; /* Construct short version string (should match initdb.c) */ short_version = pstrdup(PG_VERSION); for (end = 0; short_version[end] != '\0'; end++) { if (short_version[end] == '.') { Assert(end != 0); if (gotdot) break; else gotdot = true; } else if (short_version[end] < '0' || short_version[end] > '9') { /* gone past digits and dots */ break; } } Assert(end > 0 && short_version[end - 1] != '.' && gotdot); short_version[end] = '\0'; /* Now write the file */ fullname = palloc(strlen(path) + 11 + 1); sprintf(fullname, "%s/PG_VERSION", path); version_file = AllocateFile(fullname, PG_BINARY_W); if (version_file == NULL) ereport(ERROR, (errcode_for_file_access(), errmsg("could not write to file \"%s\": %m", fullname))); fprintf(version_file, "%s\n", short_version); if (FreeFile(version_file)) ereport(ERROR, (errcode_for_file_access(), errmsg("could not write to file \"%s\": %m", fullname))); pfree(fullname); pfree(short_version); }
int DoNames(int state) { int wnum = (int)CurrentWorld; int lnum = (int)CurrentLevel; // Skip the title screen // and only process the code if the State is set to 1 // (the screen has been initialised) if (state == 1 && lnum != STAGE_TITLE) { // grab the CRSIN object Actor *ptr = FindActorByType(CRSIN, 0); // FIX !!!!! if (ptr != 0) { void *worldObj = EmbeddedLayout_FindTextBoxByName((Layout*)((u32)ptr+0xB0), "TXT_WorldName"); void *levelObj = EmbeddedLayout_FindTextBoxByName((Layout*)((u32)ptr+0xB0), "TXT_LevelName"); if (worldObj == 0 || levelObj == 0) return state; /*char *file = RetrieveFileFromArc(ARC_TABLE, "Mario", "newer/names.bin"); char *worldname = file + (wnum * 0x40); char *levelname = file + 0x280 + (wnum * 0xA80) + (lnum * 0x40);*/ FileHandle fh; void *info = LoadFile(&fh, "/NewerRes/LevelInfo.bin"); LevelInfo_Prepare(&fh); LevelInfo_Entry *entry = LevelInfo_SearchSlot(info, wnum, lnum); char *worldname = LevelInfo_GetName(info, entry); char *levelname = ""; void *vtable = *((void**)levelObj); void *funcaddr = *((void**)((u32)vtable+0x7C)); int (*SetString)(void*, unsigned short*, unsigned short); SetString = (int(*)(void*, unsigned short*, unsigned short))funcaddr; unsigned short wbuffer[0x40], lbuffer[0x40]; for (int i = 0; i < 0x40; i++) { wbuffer[i] = (unsigned short)worldname[i]; lbuffer[i] = (unsigned short)levelname[i]; } SetString(worldObj, wbuffer, 0); SetString(levelObj, lbuffer, 0); FreeFile(&fh); } } else { } return state; }
void LoggerClose(void) { if (logger.fp != NULL && FreeFile(logger.fp) < 0) ereport(WARNING, (errcode_for_file_access(), errmsg("could not close loader log file \"%s\": %m", logger.logfile))); if (logger.logfile != NULL) pfree(logger.logfile); memset(&logger, 0, sizeof(logger)); }
/* Dumps the histogram data into a file (with a md5 hash of the contents at the beginning). */ static void query_write(double duration, const char * query, int len, const char * header, int hlen) { FILE * file; /* write the buffer first */ buffer_write(); /* now write the query */ prepare_file(log_file, query_buffer, hlen + len); file = AllocateFile(log_file->curr_filename, PG_BINARY_A); if (file == NULL) goto error; /* now write the actual shared segment */ if (fwrite(header, hlen, 1, file) != 1) goto error; /* now write the actual shared segment */ if (fwrite(query, len, 1, file) != 1) goto error; FreeFile(file); return; error: ereport(LOG, (errcode_for_file_access(), errmsg("could not write query to the file \"%s\": %m", log_file->curr_filename))); if (file) FreeFile(file); }
/* * Write into the error log file. This opens the file every time, * so that we can keep it simple to deal with concurrent write. */ static void ErrorLogWrite(CdbSreh *cdbsreh) { HeapTuple tuple; char filename[MAXPGPATH]; FILE *fp; pg_crc32 crc; Assert(OidIsValid(cdbsreh->relid)); ErrorLogFileName(filename, MyDatabaseId, cdbsreh->relid); tuple = FormErrorTuple(cdbsreh); INIT_CRC32C(crc); COMP_CRC32C(crc, tuple->t_data, tuple->t_len); FIN_CRC32C(crc); LWLockAcquire(ErrorLogLock, LW_EXCLUSIVE); fp = AllocateFile(filename, "a"); if (!fp) { mkdir(ErrorLogDir, S_IRWXU); fp = AllocateFile(filename, "a"); } if (!fp) ereport(ERROR, (errmsg("could not open \"%s\": %m", filename))); /* * format: * 0-4: length * 5-8: crc * 9-n: tuple data */ if (fwrite(&tuple->t_len, 1, sizeof(tuple->t_len), fp) != sizeof(tuple->t_len)) elog(ERROR, "could not write tuple length: %m"); if (fwrite(&crc, 1, sizeof(pg_crc32), fp) != sizeof(pg_crc32)) elog(ERROR, "could not write checksum: %m"); if (fwrite(tuple->t_data, 1, tuple->t_len, fp) != tuple->t_len) elog(ERROR, "could not write tuple data: %m"); FreeFile(fp); LWLockRelease(ErrorLogLock); heap_freetuple(tuple); }
/* * XLogArchiveForceDone * * Emit notification forcibly that an XLOG segment file has been successfully * archived, by creating <XLOG>.done regardless of whether <XLOG>.ready * exists or not. */ void XLogArchiveForceDone(const char *xlog) { char archiveReady[MAXPGPATH]; char archiveDone[MAXPGPATH]; struct stat stat_buf; FILE *fd; /* Exit if already known done */ StatusFilePath(archiveDone, xlog, ".done"); if (stat(archiveDone, &stat_buf) == 0) return; /* If .ready exists, rename it to .done */ StatusFilePath(archiveReady, xlog, ".ready"); if (stat(archiveReady, &stat_buf) == 0) { if (rename(archiveReady, archiveDone) < 0) ereport(WARNING, (errcode_for_file_access(), errmsg("could not rename file \"%s\" to \"%s\": %m", archiveReady, archiveDone))); return; } /* insert an otherwise empty file called <XLOG>.done */ fd = AllocateFile(archiveDone, "w"); if (fd == NULL) { ereport(LOG, (errcode_for_file_access(), errmsg("could not create archive status file \"%s\": %m", archiveDone))); return; } if (FreeFile(fd)) { ereport(LOG, (errcode_for_file_access(), errmsg("could not write archive status file \"%s\": %m", archiveDone))); return; } }
/* * Identify the huge page size to use. * * Some Linux kernel versions have a bug causing mmap() to fail on requests * that are not a multiple of the hugepage size. Versions without that bug * instead silently round the request up to the next hugepage multiple --- * and then munmap() fails when we give it a size different from that. * So we have to round our request up to a multiple of the actual hugepage * size to avoid trouble. * * Doing the round-up ourselves also lets us make use of the extra memory, * rather than just wasting it. Currently, we just increase the available * space recorded in the shmem header, which will make the extra usable for * purposes such as additional locktable entries. Someday, for very large * hugepage sizes, we might want to think about more invasive strategies, * such as increasing shared_buffers to absorb the extra space. * * Returns the (real or assumed) page size into *hugepagesize, * and the hugepage-related mmap flags to use into *mmap_flags. * * Currently *mmap_flags is always just MAP_HUGETLB. Someday, on systems * that support it, we might OR in additional bits to specify a particular * non-default huge page size. */ static void GetHugePageSize(Size *hugepagesize, int *mmap_flags) { /* * If we fail to find out the system's default huge page size, assume it * is 2MB. This will work fine when the actual size is less. If it's * more, we might get mmap() or munmap() failures due to unaligned * requests; but at this writing, there are no reports of any non-Linux * systems being picky about that. */ *hugepagesize = 2 * 1024 * 1024; *mmap_flags = MAP_HUGETLB; /* * System-dependent code to find out the default huge page size. * * On Linux, read /proc/meminfo looking for a line like "Hugepagesize: * nnnn kB". Ignore any failures, falling back to the preset default. */ #ifdef __linux__ { FILE *fp = AllocateFile("/proc/meminfo", "r"); char buf[128]; unsigned int sz; char ch; if (fp) { while (fgets(buf, sizeof(buf), fp)) { if (sscanf(buf, "Hugepagesize: %u %c", &sz, &ch) == 2) { if (ch == 'k') { *hugepagesize = sz * (Size) 1024; break; } /* We could accept other units besides kB, if needed */ } } FreeFile(fp); } } #endif /* __linux__ */ }
void write_nondefault_variables(GucContext context) { int elevel; FILE *fp; int i; Assert(context == PGC_POSTMASTER || context == PGC_SIGHUP); elevel = (context == PGC_SIGHUP) ? LOG : ERROR; /* * Open file */ fp = AllocateFile(CONFIG_EXEC_PARAMS_NEW, "w"); if (!fp) { ereport(elevel, (errcode_for_file_access(), errmsg("could not write to file \"%s\": %m", CONFIG_EXEC_PARAMS_NEW))); return; } for (i = 0; i < num_guc_variables; i++) { write_one_nondefault_variable(fp, guc_variables[i]); } if (FreeFile(fp)) { ereport(elevel, (errcode_for_file_access(), errmsg("could not write to file \"%s\": %m", CONFIG_EXEC_PARAMS_NEW))); return; } /* * Put new file in place. This could delay on Win32, but we don't hold * any exclusive locks. */ rename(CONFIG_EXEC_PARAMS_NEW, CONFIG_EXEC_PARAMS); }
Datum pg_file_write(PG_FUNCTION_ARGS) { FILE *f; char *filename; text *data; int64 count = 0; requireSuperuser(); filename = convert_and_check_filename(PG_GETARG_TEXT_PP(0), false); data = PG_GETARG_TEXT_PP(1); if (!PG_GETARG_BOOL(2)) { struct stat fst; if (stat(filename, &fst) >= 0) ereport(ERROR, (ERRCODE_DUPLICATE_FILE, errmsg("file \"%s\" exists", filename))); f = AllocateFile(filename, "wb"); } else f = AllocateFile(filename, "ab"); if (!f) ereport(ERROR, (errcode_for_file_access(), errmsg("could not open file \"%s\" for writing: %m", filename))); count = fwrite(VARDATA_ANY(data), 1, VARSIZE_ANY_EXHDR(data), f); if (count != VARSIZE_ANY_EXHDR(data) || FreeFile(f)) ereport(ERROR, (errcode_for_file_access(), errmsg("could not write file \"%s\": %m", filename))); PG_RETURN_INT64(count); }
static void AsyncSourceClose(AsyncSource *self) { self->eof = true; pthread_mutex_unlock(&self->lock); pthread_join(self->th, NULL); if (self->fd != NULL && FreeFile(self->fd) < 0) { ereport(WARNING, (errcode_for_file_access(), errmsg("could not close source file: %m"))); } self->fd = NULL; if (self->buffer != NULL) pfree(self->buffer); self->buffer = NULL; pfree(self); }
void SpoolerClose(Spooler *self) { /* Merge indexes */ if (self->spools != NULL) IndexSpoolEnd(self, true); /* Terminate spooler. */ ExecDropSingleTupleTableSlot(self->slot); if (self->estate->es_result_relation_info) ExecCloseIndices(self->estate->es_result_relation_info); FreeExecutorState(self->estate); /* Close and release members. */ if (self->dup_fp != NULL && FreeFile(self->dup_fp) < 0) ereport(WARNING, (errcode_for_file_access(), errmsg("could not close duplicate bad file \"%s\": %m", self->dup_badfile))); if (self->dup_badfile != NULL) pfree(self->dup_badfile); }
/* Flushes, syncs, and closes the given file pointer and checks for errors. */ static void SyncAndCloseFile(FILE *file) { int flushResult = 0; int syncResult = 0; int errorResult = 0; int freeResult = 0; errno = 0; flushResult = fflush(file); if (flushResult != 0) { ereport(ERROR, (errcode_for_file_access(), errmsg("could not flush file: %m"))); } syncResult = pg_fsync(fileno(file)); if (syncResult != 0) { ereport(ERROR, (errcode_for_file_access(), errmsg("could not sync file: %m"))); } errorResult = ferror(file); if (errorResult != 0) { ereport(ERROR, (errcode_for_file_access(), errmsg("error in file: %m"))); } freeResult = FreeFile(file); if (freeResult != 0) { ereport(ERROR, (errcode_for_file_access(), errmsg("could not close file: %m"))); } }
/* * Load rules from the file. * * Parses the pg_limits.conf file and loads all the connection rules that * are defined in it. A syntax error should not result in a failure, * only a WARNING message (and skipping the row). If there are too many * rules in the file (exceeding MAX_RULES), that fails with an ERROR. * * FIXME The current implementation modifies the segment in-place, so * if a config reload fails, the backends will see the result of * the failed reload. That's not really nice. This should use a * local buffer an only copy it in place if everything went OK. * * FIXME The other issue is that we're holding ProcArrayLock while * parsing the file - at the moment this is necessary because of * the in-place reload. Once this is fixed, we can hold the lock * only for the final copy (in case of success). */ static void load_rules() { FILE *file; char line[LINE_MAXLEN]; char dbname[NAMEDATALEN], user[NAMEDATALEN], ip[NAMEDATALEN], mask[NAMEDATALEN]; int limit; int line_number = 0; file = AllocateFile(LIMITS_FILE, "r"); if (file == NULL) { ereport(WARNING, (errcode_for_file_access(), errmsg("could not open configuration file \"%s\": %m", LIMITS_FILE))); return; } /* * Use the same lock as when checking the rules (when opening the * connection) etc. This is probably the right thing to do. */ LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE); /* make sure there are no rules (keep the backend info though) */ memset(rules, 0, RULES_SEGMENT_SIZE); while (fgets(line, LINE_MAXLEN, file) != NULL) { /* remove the comment from the line */ char * comment = strchr(line, '#'); if (comment != NULL) (*comment) = '\0'; /* remove all white-space chars from the end of the line */ comment--; while (isspace(comment) && (comment >= line)) { *comment = '\0'; comment--; } ++line_number; /* database user ip mask limit */ if (sscanf(line, "%s %s %s %s %d", dbname, user, ip, mask, &limit) == 5) load_rule(line_number, dbname, user, ip, mask, limit); /* database user ip/mask limit */ else if (sscanf(line, "%s %s %s %d", dbname, user, ip, &limit) == 4) load_rule(line_number, dbname, user, ip, NULL, limit); /* non-empty line with invalid format */ else if (strlen(line) > 0) elog(WARNING, "invalid rule at line %d", line_number); } FreeFile(file); LWLockRelease(ProcArrayLock); elog(DEBUG1, "loaded %d connection limit rule(s)", rules->n_rules); }
/* * shmem_startup hook: allocate or attach to shared memory, * then load any pre-existing statistics from file. */ static void pgss_shmem_startup(void) { bool found; HASHCTL info; FILE *file; uint32 header; int32 num; int32 i; int query_size; int buffer_size; char *buffer = NULL; if (prev_shmem_startup_hook) prev_shmem_startup_hook(); /* reset in case this is a restart within the postmaster */ pgss = NULL; pgss_hash = NULL; /* * Create or attach to the shared memory state, including hash table */ LWLockAcquire(AddinShmemInitLock, LW_EXCLUSIVE); pgss = ShmemInitStruct("pg_stat_statements", sizeof(pgssSharedState), &found); if (!found) { /* First time through ... */ pgss->lock = LWLockAssign(); pgss->query_size = pgstat_track_activity_query_size; } /* Be sure everyone agrees on the hash table entry size */ query_size = pgss->query_size; memset(&info, 0, sizeof(info)); info.keysize = sizeof(pgssHashKey); info.entrysize = offsetof(pgssEntry, query) +query_size; info.hash = pgss_hash_fn; info.match = pgss_match_fn; pgss_hash = ShmemInitHash("pg_stat_statements hash", pgss_max, pgss_max, &info, HASH_ELEM | HASH_FUNCTION | HASH_COMPARE); LWLockRelease(AddinShmemInitLock); /* * If we're in the postmaster (or a standalone backend...), set up a shmem * exit hook to dump the statistics to disk. */ if (!IsUnderPostmaster) on_shmem_exit(pgss_shmem_shutdown, (Datum) 0); /* * Attempt to load old statistics from the dump file, if this is the first * time through and we weren't told not to. */ if (found || !pgss_save) return; /* * Note: we don't bother with locks here, because there should be no other * processes running when this code is reached. */ file = AllocateFile(PGSS_DUMP_FILE, PG_BINARY_R); if (file == NULL) { if (errno == ENOENT) return; /* ignore not-found error */ goto error; } buffer_size = query_size; buffer = (char *) palloc(buffer_size); if (fread(&header, sizeof(uint32), 1, file) != 1 || header != PGSS_FILE_HEADER || fread(&num, sizeof(int32), 1, file) != 1) goto error; for (i = 0; i < num; i++) { pgssEntry temp; pgssEntry *entry; if (fread(&temp, offsetof(pgssEntry, mutex), 1, file) != 1) goto error; /* Encoding is the only field we can easily sanity-check */ if (!PG_VALID_BE_ENCODING(temp.key.encoding)) goto error; /* Previous incarnation might have had a larger query_size */ if (temp.key.query_len >= buffer_size) { buffer = (char *) repalloc(buffer, temp.key.query_len + 1); buffer_size = temp.key.query_len + 1; } if (fread(buffer, 1, temp.key.query_len, file) != temp.key.query_len) goto error; buffer[temp.key.query_len] = '\0'; /* Clip to available length if needed */ if (temp.key.query_len >= query_size) temp.key.query_len = pg_encoding_mbcliplen(temp.key.encoding, buffer, temp.key.query_len, query_size - 1); temp.key.query_ptr = buffer; /* make the hashtable entry (discards old entries if too many) */ entry = entry_alloc(&temp.key); /* copy in the actual stats */ entry->counters = temp.counters; } pfree(buffer); FreeFile(file); return; error: ereport(LOG, (errcode_for_file_access(), errmsg("could not read pg_stat_statement file \"%s\": %m", PGSS_DUMP_FILE))); if (buffer) pfree(buffer); if (file) FreeFile(file); /* If possible, throw away the bogus file; ignore any error */ unlink(PGSS_DUMP_FILE); }
/* * ImportSnapshot * Import a previously exported snapshot. The argument should be a * filename in SNAPSHOT_EXPORT_DIR. Load the snapshot from that file. * This is called by "SET TRANSACTION SNAPSHOT 'foo'". */ void ImportSnapshot(const char *idstr) { char path[MAXPGPATH]; FILE *f; struct stat stat_buf; char *filebuf; int xcnt; int i; TransactionId src_xid; Oid src_dbid; int src_isolevel; bool src_readonly; SnapshotData snapshot; /* * Must be at top level of a fresh transaction. Note in particular that * we check we haven't acquired an XID --- if we have, it's conceivable * that the snapshot would show it as not running, making for very * screwy behavior. */ if (FirstSnapshotSet || GetTopTransactionIdIfAny() != InvalidTransactionId || IsSubTransaction()) ereport(ERROR, (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION), errmsg("SET TRANSACTION SNAPSHOT must be called before any query"))); /* * If we are in read committed mode then the next query would execute * with a new snapshot thus making this function call quite useless. */ if (!IsolationUsesXactSnapshot()) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("a snapshot-importing transaction must have isolation level SERIALIZABLE or REPEATABLE READ"))); /* * Verify the identifier: only 0-9, A-F and hyphens are allowed. We do * this mainly to prevent reading arbitrary files. */ if (strspn(idstr, "0123456789ABCDEF-") != strlen(idstr)) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("invalid snapshot identifier \"%s\"", idstr))); /* OK, read the file */ snprintf(path, MAXPGPATH, SNAPSHOT_EXPORT_DIR "/%s", idstr); f = AllocateFile(path, PG_BINARY_R); if (!f) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("invalid snapshot identifier \"%s\"", idstr))); /* get the size of the file so that we know how much memory we need */ if (fstat(fileno(f), &stat_buf)) elog(ERROR, "could not stat file \"%s\": %m", path); /* and read the file into a palloc'd string */ filebuf = (char *) palloc(stat_buf.st_size + 1); if (fread(filebuf, stat_buf.st_size, 1, f) != 1) elog(ERROR, "could not read file \"%s\": %m", path); filebuf[stat_buf.st_size] = '\0'; FreeFile(f); /* * Construct a snapshot struct by parsing the file content. */ memset(&snapshot, 0, sizeof(snapshot)); src_xid = parseXidFromText("xid:", &filebuf, path); /* we abuse parseXidFromText a bit here ... */ src_dbid = parseXidFromText("dbid:", &filebuf, path); src_isolevel = parseIntFromText("iso:", &filebuf, path); src_readonly = parseIntFromText("ro:", &filebuf, path); snapshot.xmin = parseXidFromText("xmin:", &filebuf, path); snapshot.xmax = parseXidFromText("xmax:", &filebuf, path); snapshot.xcnt = xcnt = parseIntFromText("xcnt:", &filebuf, path); /* sanity-check the xid count before palloc */ if (xcnt < 0 || xcnt > GetMaxSnapshotXidCount()) ereport(ERROR, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), errmsg("invalid snapshot data in file \"%s\"", path))); snapshot.xip = (TransactionId *) palloc(xcnt * sizeof(TransactionId)); for (i = 0; i < xcnt; i++) snapshot.xip[i] = parseXidFromText("xip:", &filebuf, path); snapshot.suboverflowed = parseIntFromText("sof:", &filebuf, path); if (!snapshot.suboverflowed) { snapshot.subxcnt = xcnt = parseIntFromText("sxcnt:", &filebuf, path); /* sanity-check the xid count before palloc */ if (xcnt < 0 || xcnt > GetMaxSnapshotSubxidCount()) ereport(ERROR, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), errmsg("invalid snapshot data in file \"%s\"", path))); snapshot.subxip = (TransactionId *) palloc(xcnt * sizeof(TransactionId)); for (i = 0; i < xcnt; i++) snapshot.subxip[i] = parseXidFromText("sxp:", &filebuf, path); } else { snapshot.subxcnt = 0; snapshot.subxip = NULL; } snapshot.takenDuringRecovery = parseIntFromText("rec:", &filebuf, path); /* * Do some additional sanity checking, just to protect ourselves. We * don't trouble to check the array elements, just the most critical * fields. */ if (!TransactionIdIsNormal(src_xid) || !OidIsValid(src_dbid) || !TransactionIdIsNormal(snapshot.xmin) || !TransactionIdIsNormal(snapshot.xmax)) ereport(ERROR, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), errmsg("invalid snapshot data in file \"%s\"", path))); /* * If we're serializable, the source transaction must be too, otherwise * predicate.c has problems (SxactGlobalXmin could go backwards). Also, * a non-read-only transaction can't adopt a snapshot from a read-only * transaction, as predicate.c handles the cases very differently. */ if (IsolationIsSerializable()) { if (src_isolevel != XACT_SERIALIZABLE) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("a serializable transaction cannot import a snapshot from a non-serializable transaction"))); if (src_readonly && !XactReadOnly) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("a non-read-only serializable transaction cannot import a snapshot from a read-only transaction"))); } /* * We cannot import a snapshot that was taken in a different database, * because vacuum calculates OldestXmin on a per-database basis; so the * source transaction's xmin doesn't protect us from data loss. This * restriction could be removed if the source transaction were to mark * its xmin as being globally applicable. But that would require some * additional syntax, since that has to be known when the snapshot is * initially taken. (See pgsql-hackers discussion of 2011-10-21.) */ if (src_dbid != MyDatabaseId) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("cannot import a snapshot from a different database"))); /* OK, install the snapshot */ SetTransactionSnapshot(&snapshot, src_xid); }