Line data Source code
1 : /**
2 : * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 : * SPDX-License-Identifier: Apache-2.0.
4 : */
5 :
6 : #include <aws/common/log_writer.h>
7 :
8 : #include <aws/common/string.h>
9 :
10 : #include <errno.h>
11 : #include <stdio.h>
12 :
13 : #ifdef _MSC_VER
14 : # pragma warning(disable : 4996) /* Disable warnings about fopen() being insecure */
15 : #endif /* _MSC_VER */
16 :
17 : /*
18 : * Basic log writer implementations - stdout, stderr, arbitrary file
19 : */
20 :
21 : struct aws_file_writer;
22 :
23 : struct aws_file_writer {
24 : FILE *log_file;
25 : bool close_file_on_cleanup;
26 : };
27 :
28 0 : static int s_aws_file_writer_write(struct aws_log_writer *writer, const struct aws_string *output) {
29 0 : struct aws_file_writer *impl = (struct aws_file_writer *)writer->impl;
30 0 :
31 0 : size_t length = output->len;
32 0 : if (fwrite(output->bytes, 1, length, impl->log_file) < length) {
33 0 : return aws_translate_and_raise_io_error(errno);
34 0 : }
35 0 :
36 0 : return AWS_OP_SUCCESS;
37 0 : }
38 :
39 0 : static void s_aws_file_writer_clean_up(struct aws_log_writer *writer) {
40 0 : struct aws_file_writer *impl = (struct aws_file_writer *)writer->impl;
41 0 :
42 0 : if (impl->close_file_on_cleanup) {
43 0 : fclose(impl->log_file);
44 0 : }
45 0 :
46 0 : aws_mem_release(writer->allocator, impl);
47 0 : }
48 :
49 : static struct aws_log_writer_vtable s_aws_file_writer_vtable = {
50 : .write = s_aws_file_writer_write,
51 : .clean_up = s_aws_file_writer_clean_up,
52 : };
53 :
54 : /*
55 : * Shared internal init implementation
56 : */
57 : static int s_aws_file_writer_init_internal(
58 : struct aws_log_writer *writer,
59 : struct aws_allocator *allocator,
60 : const char *file_name_to_open,
61 0 : FILE *currently_open_file) {
62 0 :
63 0 : /* One or the other should be set */
64 0 : if (!((file_name_to_open != NULL) ^ (currently_open_file != NULL))) {
65 0 : return aws_raise_error(AWS_ERROR_INVALID_ARGUMENT);
66 0 : }
67 0 :
68 0 : /* Allocate and initialize the file writer */
69 0 : struct aws_file_writer *impl = aws_mem_calloc(allocator, 1, sizeof(struct aws_file_writer));
70 0 : if (impl == NULL) {
71 0 : return AWS_OP_ERR;
72 0 : }
73 0 :
74 0 : impl->log_file = NULL;
75 0 : impl->close_file_on_cleanup = false;
76 0 :
77 0 : /* Open file if name passed in */
78 0 : if (file_name_to_open != NULL) {
79 0 : impl->log_file = fopen(file_name_to_open, "a+");
80 0 : if (impl->log_file == NULL) {
81 0 : aws_mem_release(allocator, impl);
82 0 : return aws_translate_and_raise_io_error(errno);
83 0 : }
84 0 : impl->close_file_on_cleanup = true;
85 0 : } else {
86 0 : impl->log_file = currently_open_file;
87 0 : }
88 0 :
89 0 : writer->vtable = &s_aws_file_writer_vtable;
90 0 : writer->allocator = allocator;
91 0 : writer->impl = impl;
92 0 :
93 0 : return AWS_OP_SUCCESS;
94 0 : }
95 :
96 : /*
97 : * Public initialization interface
98 : */
99 0 : int aws_log_writer_init_stdout(struct aws_log_writer *writer, struct aws_allocator *allocator) {
100 0 : return s_aws_file_writer_init_internal(writer, allocator, NULL, stdout);
101 0 : }
102 :
103 0 : int aws_log_writer_init_stderr(struct aws_log_writer *writer, struct aws_allocator *allocator) {
104 0 : return s_aws_file_writer_init_internal(writer, allocator, NULL, stderr);
105 0 : }
106 :
107 : int aws_log_writer_init_file(
108 : struct aws_log_writer *writer,
109 : struct aws_allocator *allocator,
110 0 : struct aws_log_writer_file_options *options) {
111 0 : return s_aws_file_writer_init_internal(writer, allocator, options->filename, options->file);
112 0 : }
113 :
114 0 : void aws_log_writer_clean_up(struct aws_log_writer *writer) {
115 0 : AWS_ASSERT(writer->vtable->clean_up);
116 0 : (writer->vtable->clean_up)(writer);
117 0 : }
|