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