(errcode_for_file_access(),
errmsg("could not create file \"%s\": %m",
BACKUP_LABEL_FILE)));
- fwrite(labelfbuf.data, labelfbuf.len, 1, fp);
- if (fflush(fp) || ferror(fp) || FreeFile(fp))
+ if (fwrite(labelfbuf.data, labelfbuf.len, 1, fp) != 1 ||
+ fflush(fp) != 0 ||
+ ferror(fp) ||
+ FreeFile(fp))
ereport(ERROR,
(errcode_for_file_access(),
errmsg("could not write file \"%s\": %m",
#endif
}
- (void) fwrite(fe_msgbuf->data, fe_msgbuf->len,
- 1, cstate->copy_file);
- if (ferror(cstate->copy_file))
+ if (fwrite(fe_msgbuf->data, fe_msgbuf->len, 1,
+ cstate->copy_file) != 1 ||
+ ferror(cstate->copy_file))
ereport(ERROR,
(errcode_for_file_access(),
errmsg("could not write to COPY file: %m")));
int32 format_id;
const char *tmpfile = permanent ? PGSTAT_STAT_PERMANENT_TMPFILE : pgstat_stat_tmpname;
const char *statfile = permanent ? PGSTAT_STAT_PERMANENT_FILENAME : pgstat_stat_filename;
+ int rc;
/*
* Open the statistics temp file to write out the current values.
* Write the file header --- currently just a format ID.
*/
format_id = PGSTAT_FILE_FORMAT_ID;
- fwrite(&format_id, sizeof(format_id), 1, fpout);
+ rc = fwrite(&format_id, sizeof(format_id), 1, fpout);
+ (void) rc; /* we'll check for error with ferror */
/*
* Write global stats struct
*/
- fwrite(&globalStats, sizeof(globalStats), 1, fpout);
+ rc = fwrite(&globalStats, sizeof(globalStats), 1, fpout);
+ (void) rc; /* we'll check for error with ferror */
/*
* Walk through the database table.
* use to any other process.
*/
fputc('D', fpout);
- fwrite(dbentry, offsetof(PgStat_StatDBEntry, tables), 1, fpout);
+ rc = fwrite(dbentry, offsetof(PgStat_StatDBEntry, tables), 1, fpout);
+ (void) rc; /* we'll check for error with ferror */
/*
* Walk through the database's access stats per table.
while ((tabentry = (PgStat_StatTabEntry *) hash_seq_search(&tstat)) != NULL)
{
fputc('T', fpout);
- fwrite(tabentry, sizeof(PgStat_StatTabEntry), 1, fpout);
+ rc = fwrite(tabentry, sizeof(PgStat_StatTabEntry), 1, fpout);
+ (void) rc; /* we'll check for error with ferror */
}
/*
while ((funcentry = (PgStat_StatFuncEntry *) hash_seq_search(&fstat)) != NULL)
{
fputc('F', fpout);
- fwrite(funcentry, sizeof(PgStat_StatFuncEntry), 1, fpout);
+ rc = fwrite(funcentry, sizeof(PgStat_StatFuncEntry), 1, fpout);
+ (void) rc; /* we'll check for error with ferror */
}
/*
static void
write_console(const char *line, int len)
{
+ int rc;
+
#ifdef WIN32
/*
- * WriteConsoleW() will fail of stdout is redirected, so just fall through
+ * WriteConsoleW() will fail if stdout is redirected, so just fall through
* to writing unconverted to the logfile in this case.
*
* Since we palloc the structure required for conversion, also fall
#else
/*
- * Conversion on non-win32 platform is not implemented yet. It requires
+ * Conversion on non-win32 platforms is not implemented yet. It requires
* non-throw version of pg_do_encoding_conversion(), that converts
* unconvertable characters to '?' without errors.
*/
#endif
- write(fileno(stderr), line, len);
+ /*
+ * We ignore any error from write() here. We have no useful way to report
+ * it ... certainly whining on stderr isn't likely to be productive.
+ */
+ rc = write(fileno(stderr), line, len);
+ (void) rc;
}
/*
/*
* Send data to the syslogger using the chunked protocol
+ *
+ * Note: when there are multiple backends writing into the syslogger pipe,
+ * it's critical that each write go into the pipe indivisibly, and not
+ * get interleaved with data from other processes. Fortunately, the POSIX
+ * spec requires that writes to pipes be atomic so long as they are not
+ * more than PIPE_BUF bytes long. So we divide long messages into chunks
+ * that are no more than that length, and send one chunk per write() call.
+ * The collector process knows how to reassemble the chunks.
+ *
+ * Because of the atomic write requirement, there are only two possible
+ * results from write() here: -1 for failure, or the requested number of
+ * bytes. There is not really anything we can do about a failure; retry would
+ * probably be an infinite loop, and we can't even report the error usefully.
+ * (There is noplace else we could send it!) So we might as well just ignore
+ * the result from write(). However, on some platforms you get a compiler
+ * warning from ignoring write()'s result, so do a little dance with casting
+ * rc to void to shut up the compiler.
*/
static void
write_pipe_chunks(char *data, int len, int dest)
{
PipeProtoChunk p;
-
int fd = fileno(stderr);
+ int rc;
Assert(len > 0);
p.proto.is_last = (dest == LOG_DESTINATION_CSVLOG ? 'F' : 'f');
p.proto.len = PIPE_MAX_PAYLOAD;
memcpy(p.proto.data, data, PIPE_MAX_PAYLOAD);
- write(fd, &p, PIPE_HEADER_SIZE + PIPE_MAX_PAYLOAD);
+ rc = write(fd, &p, PIPE_HEADER_SIZE + PIPE_MAX_PAYLOAD);
+ (void) rc;
data += PIPE_MAX_PAYLOAD;
len -= PIPE_MAX_PAYLOAD;
}
p.proto.is_last = (dest == LOG_DESTINATION_CSVLOG ? 'T' : 't');
p.proto.len = len;
memcpy(p.proto.data, data, len);
- write(fd, &p, PIPE_HEADER_SIZE + len);
+ rc = write(fd, &p, PIPE_HEADER_SIZE + len);
+ (void) rc;
}
handle_sigint(SIGNAL_ARGS)
{
int save_errno = errno;
+ int rc;
char errbuf[256];
/* if we are waiting for input, longjmp out of it */
if (cancelConn != NULL)
{
if (PQcancel(cancelConn, errbuf, sizeof(errbuf)))
- write_stderr("Cancel request sent\n");
+ {
+ rc = write_stderr("Cancel request sent\n");
+ (void) rc; /* ignore errors, nothing we can do here */
+ }
else
{
- write_stderr("Could not send cancel request: ");
- write_stderr(errbuf);
+ rc = write_stderr("Could not send cancel request: ");
+ (void) rc; /* ignore errors, nothing we can do here */
+ rc = write_stderr(errbuf);
+ (void) rc; /* ignore errors, nothing we can do here */
}
}