]> git.proxmox.com Git - ceph.git/blob - ceph/src/seastar/include/seastar/util/print_safe.hh
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / seastar / include / seastar / util / print_safe.hh
1 /*
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.
6 *
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
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
16 * under the License.
17 */
18 /*
19 * Copyright 2016 ScyllaDB
20 */
21
22 #pragma once
23
24 #include <seastar/util/concepts.hh>
25 #include <cassert>
26 #include <cstring>
27 #if __cplusplus > 201703L
28 #include <concepts>
29 #endif
30 #include <stdio.h>
31 #include <unistd.h>
32
33 namespace seastar {
34
35 //
36 // Collection of async-signal safe printing functions.
37 //
38
39 // Outputs string to stderr.
40 // Async-signal safe.
41 inline
42 void print_safe(const char *str, size_t len) noexcept {
43 while (len) {
44 auto result = write(STDERR_FILENO, str, len);
45 if (result > 0) {
46 len -= result;
47 str += result;
48 } else if (result == 0) {
49 break;
50 } else {
51 if (errno == EINTR) {
52 // retry
53 } else {
54 break; // what can we do?
55 }
56 }
57 }
58 }
59
60 // Outputs string to stderr.
61 // Async-signal safe.
62 inline
63 void print_safe(const char *str) noexcept {
64 print_safe(str, strlen(str));
65 }
66
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;
76 do {
77 assert(p > buf);
78 *--p = digits[n & 0xf];
79 n >>= 4;
80 } while (n);
81 return p;
82 }
83
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);
90 }
91
92 // Prints zero-padded hexadecimal representation of an integer to stderr.
93 // For example, print_zero_padded_hex_safe(uint16_t(12)) prints "000c".
94 // Async-signal safe.
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));
101 }
102
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];
110 unsigned i = bufsz;
111 do {
112 assert(i > 0);
113 tmp[--i] = '0' + n % 10;
114 n /= 10;
115 } while (n);
116 memcpy(buf, tmp + i, sizeof(tmp) - i);
117 return sizeof(tmp) - i;
118 }
119
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);
129 }
130
131 }