]> git.proxmox.com Git - ceph.git/blame - ceph/src/jaegertracing/thrift/lib/cpp/src/thrift/TOutput.cpp
update source to Ceph Pacific 16.2.2
[ceph.git] / ceph / src / jaegertracing / thrift / lib / cpp / src / thrift / TOutput.cpp
CommitLineData
f67539c2
TL
1/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19
20#include <thrift/Thrift.h>
21#include <thrift/TToString.h>
22#include <cstring>
23#include <cstdlib>
24#include <stdarg.h>
25#include <stdio.h>
26
27namespace apache {
28namespace thrift {
29
30THRIFT_EXPORT TOutput GlobalOutput;
31
32TOutput::TOutput() : f_(&errorTimeWrapper) {}
33
34void TOutput::printf(const char* message, ...) {
35#ifndef THRIFT_SQUELCH_CONSOLE_OUTPUT
36 // Try to reduce heap usage, even if printf is called rarely.
37 static const int STACK_BUF_SIZE = 256;
38 char stack_buf[STACK_BUF_SIZE];
39 va_list ap;
40
41#ifdef _MSC_VER
42 va_start(ap, message);
43 int need = _vscprintf(message, ap);
44 va_end(ap);
45
46 if (need < STACK_BUF_SIZE) {
47 va_start(ap, message);
48 vsnprintf_s(stack_buf, STACK_BUF_SIZE, _TRUNCATE, message, ap);
49 va_end(ap);
50 f_(stack_buf);
51 return;
52 }
53#else
54 va_start(ap, message);
55 int need = vsnprintf(stack_buf, STACK_BUF_SIZE, message, ap);
56 va_end(ap);
57
58 if (need < STACK_BUF_SIZE) {
59 f_(stack_buf);
60 return;
61 }
62#endif
63
64 char* heap_buf = (char*)malloc((need + 1) * sizeof(char));
65 if (heap_buf == nullptr) {
66#ifdef _MSC_VER
67 va_start(ap, message);
68 vsnprintf_s(stack_buf, STACK_BUF_SIZE, _TRUNCATE, message, ap);
69 va_end(ap);
70#endif
71 // Malloc failed. We might as well print the stack buffer.
72 f_(stack_buf);
73 return;
74 }
75
76 va_start(ap, message);
77 int rval = vsnprintf(heap_buf, need + 1, message, ap);
78 va_end(ap);
79 // TODO(shigin): inform user
80 if (rval != -1) {
81 f_(heap_buf);
82 }
83 free(heap_buf);
84#endif
85}
86
87void TOutput::errorTimeWrapper(const char* msg) {
88#ifndef THRIFT_SQUELCH_CONSOLE_OUTPUT
89 time_t now;
90 char dbgtime[26];
91 time(&now);
92 THRIFT_CTIME_R(&now, dbgtime);
93 dbgtime[24] = 0;
94 fprintf(stderr, "Thrift: %s %s\n", dbgtime, msg);
95#endif
96}
97
98void TOutput::perror(const char* message, int errno_copy) {
99 std::string out = message + std::string(": ") + strerror_s(errno_copy);
100 f_(out.c_str());
101}
102
103std::string TOutput::strerror_s(int errno_copy) {
104#ifndef HAVE_STRERROR_R
105 return "errno = " + to_string(errno_copy);
106#else // HAVE_STRERROR_R
107
108 char b_errbuf[1024] = {'\0'};
109#ifdef STRERROR_R_CHAR_P
110 char* b_error = strerror_r(errno_copy, b_errbuf, sizeof(b_errbuf));
111#else
112 char* b_error = b_errbuf;
113 int rv = strerror_r(errno_copy, b_errbuf, sizeof(b_errbuf));
114 if (rv == -1) {
115 // strerror_r failed. omgwtfbbq.
116 return "XSI-compliant strerror_r() failed with errno = "
117 + to_string(errno_copy);
118 }
119#endif
120 // Can anyone prove that explicit cast is probably not necessary
121 // to ensure that the string object is constructed before
122 // b_error becomes invalid?
123 return std::string(b_error);
124
125#endif // HAVE_STRERROR_R
126}
127}
128} // apache::thrift