2 * This file is open source software, licensed to you under the terms
3 * of the Apache License, Version 2.0 (the "License"). See the NOTICE file
4 * distributed with this work for additional information regarding copyright
5 * ownership. You may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing,
12 * software distributed under the License is distributed on an
13 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 * KIND, either express or implied. See the License for the
15 * specific language governing permissions and limitations
19 * Copyright 2016 ScyllaDB
24 #include <seastar/util/concepts.hh>
27 #if __cplusplus > 201703L
36 // Collection of async-signal safe printing functions.
39 // Outputs string to stderr.
42 void print_safe(const char *str, size_t len) noexcept {
44 auto result = write(STDERR_FILENO, str, len);
48 } else if (result == 0) {
54 break; // what can we do?
60 // Outputs string to stderr.
63 void print_safe(const char *str) noexcept {
64 print_safe(str, strlen(str));
67 // Fills a buffer with a hexadecimal representation of an integer
68 // and returns a pointer to the first character.
69 // For example, convert_hex_safe(buf, 4, uint16_t(12)) fills the buffer with " c".
70 template<typename Integral, char Padding = ' '>
71 SEASTAR_CONCEPT( requires std::integral<Integral> )
72 char* convert_hex_safe(char *buf, size_t bufsz, Integral n) noexcept {
73 const char *digits = "0123456789abcdef";
74 memset(buf, Padding, bufsz);
75 auto* p = buf + bufsz;
78 *--p = digits[n & 0xf];
84 // Fills a buffer with a zero-padded hexadecimal representation of an integer.
85 // For example, convert_zero_padded_hex_safe(buf, 4, uint16_t(12)) fills the buffer with "000c".
86 template<typename Integral>
87 SEASTAR_CONCEPT( requires std::integral<Integral> )
88 void convert_zero_padded_hex_safe(char *buf, size_t bufsz, Integral n) noexcept {
89 convert_hex_safe<'0'>(buf, bufsz, n);
92 // Prints zero-padded hexadecimal representation of an integer to stderr.
93 // For example, print_zero_padded_hex_safe(uint16_t(12)) prints "000c".
95 template<typename Integral>
96 SEASTAR_CONCEPT ( requires std::signed_integral<Integral> )
97 void print_zero_padded_hex_safe(Integral n) noexcept {
98 char buf[sizeof(n) * 2];
99 convert_zero_padded_hex_safe(buf, sizeof(buf), n);
100 print_safe(buf, sizeof(buf));
103 // Fills a buffer with a decimal representation of an integer.
104 // The argument bufsz is the maximum size of the buffer.
105 // For example, print_decimal_safe(buf, 16, 12) prints "12".
106 template<typename Integral>
107 SEASTAR_CONCEPT( requires std::unsigned_integral<Integral> )
108 size_t convert_decimal_safe(char *buf, size_t bufsz, Integral n) noexcept {
109 char tmp[sizeof(n) * 3];
113 tmp[--i] = '0' + n % 10;
116 memcpy(buf, tmp + i, sizeof(tmp) - i);
117 return sizeof(tmp) - i;
120 // Prints decimal representation of an integer to stderr.
121 // For example, print_decimal_safe(12) prints "12".
122 // Async-signal safe.
123 template<typename Integral>
124 void print_decimal_safe(Integral n) noexcept {
125 char buf[sizeof(n) * 3];
126 unsigned i = sizeof(buf);
127 auto len = convert_decimal_safe(buf, i, n);
128 print_safe(buf, len);