/* * log_proto_file_writer_post: * @msg: formatted log message to send (this might be consumed by this function) * @msg_len: length of @msg * @consumed: pointer to a gboolean that gets set if the message was consumed by this function * @error: error information, if any * * This function posts a message to the log transport, performing buffering * of partially sent data if needed. The return value indicates whether we * successfully sent this message, or if it should be resent by the caller. **/ static LogProtoStatus log_proto_file_writer_post(LogProtoClient *s, guchar *msg, gsize msg_len, gboolean *consumed) { LogProtoFileWriter *self = (LogProtoFileWriter *)s; LogProtoStatus result; *consumed = FALSE; if (self->buf_count >= self->buf_size || self->partial) { result = log_proto_file_writer_flush(s); if (result != LPS_SUCCESS || self->buf_count >= self->buf_size || self->partial) { /* don't consume a new message if flush failed OR if we couldn't * progress in flush() to empty the outgoing buffer (either * buffers or partial) */ return result; } } /* register the new message */ self->buffer[self->buf_count].iov_base = (void *) msg; self->buffer[self->buf_count].iov_len = msg_len; ++self->buf_count; self->sum_len += msg_len; if (self->buf_count == self->buf_size) { /* we have reached the max buffer size -> we need to write the messages */ result = log_proto_file_writer_flush(s); if (result != LPS_SUCCESS) return result; } *consumed = TRUE; log_proto_client_msg_ack(&self->super, 1); return LPS_SUCCESS; }
/* * log_proto_file_writer_post: * @msg: formatted log message to send (this might be consumed by this function) * @msg_len: length of @msg * @consumed: pointer to a gboolean that gets set if the message was consumed by this function * @error: error information, if any * * This function posts a message to the log transport, performing buffering * of partially sent data if needed. The return value indicates whether we * successfully sent this message, or if it should be resent by the caller. **/ static LogProtoStatus log_proto_file_writer_post(LogProtoClient *s, guchar *msg, gsize msg_len, gboolean *consumed) { LogProtoFileWriter *self = (LogProtoFileWriter *)s; gint rc; if (self->buf_count >= self->buf_size) { rc = log_proto_file_writer_flush(s); if (rc != LPS_SUCCESS || self->buf_count >= self->buf_size) { /* don't consume a new message if flush failed, or even after the flush we don't have any free slots */ return rc; } } *consumed = FALSE; if (self->partial) { /* there is still some data from the previous file writing process */ gint len = self->partial_len - self->partial_pos; rc = write(self->fd, self->partial + self->partial_pos, len); if (rc > 0 && self->fsync) fsync(self->fd); if (rc < 0) { goto write_error; } else if (rc != len) { self->partial_pos += rc; return LPS_SUCCESS; } else { g_free(self->partial); self->partial = NULL; /* NOTE: we return here to give a chance to the framed protocol to send the frame header. */ return LPS_SUCCESS; } } /* register the new message */ self->buffer[self->buf_count].iov_base = (void *) msg; self->buffer[self->buf_count].iov_len = msg_len; ++self->buf_count; self->sum_len += msg_len; *consumed = TRUE; if (self->buf_count == self->buf_size) { /* we have reached the max buffer size -> we need to write the messages */ return log_proto_file_writer_flush(s); } return LPS_SUCCESS; write_error: if (errno != EAGAIN && errno != EINTR) { msg_error("I/O error occurred while writing", evt_tag_int("fd", self->super.transport->fd), evt_tag_errno(EVT_TAG_OSERROR, errno), NULL); return LPS_ERROR; } return LPS_SUCCESS; }