Seastar
High performance C++ framework for concurrent servers
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Modules Pages
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#ifndef SEASTAR_MODULE
25#include <cassert>
26#include <cerrno>
27#include <concepts>
28#include <cstring>
29#include <stdio.h>
30#include <unistd.h>
31#endif
32
33#include <seastar/util/modules.hh>
34
35namespace seastar {
36
37SEASTAR_MODULE_EXPORT_BEGIN
38//
39// Collection of async-signal safe printing functions.
40//
41
42// Outputs string to stderr.
43// Async-signal safe.
44inline
45void print_safe(const char *str, size_t len) noexcept {
46 while (len) {
47 auto result = write(STDERR_FILENO, str, len);
48 if (result > 0) {
49 len -= result;
50 str += result;
51 } else if (result == 0) {
52 break;
53 } else {
54 if (errno == EINTR) {
55 // retry
56 } else {
57 break; // what can we do?
58 }
59 }
60 }
61}
62
63// Outputs string to stderr.
64// Async-signal safe.
65inline
66void print_safe(const char *str) noexcept {
67 print_safe(str, strlen(str));
68}
69
70// Fills a buffer with a hexadecimal representation of an integer
71// and returns a pointer to the first character.
72// For example, convert_hex_safe(buf, 4, uint16_t(12)) fills the buffer with " c".
73template<typename Integral, char Padding = ' '>
74requires std::integral<Integral>
75char* convert_hex_safe(char *buf, size_t bufsz, Integral n) noexcept {
76 const char *digits = "0123456789abcdef";
77 memset(buf, Padding, bufsz);
78 auto* p = buf + bufsz;
79 do {
80 assert(p > buf);
81 *--p = digits[n & 0xf];
82 n >>= 4;
83 } while (n);
84 return p;
85}
86
87// Fills a buffer with a zero-padded hexadecimal representation of an integer.
88// For example, convert_zero_padded_hex_safe(buf, 4, uint16_t(12)) fills the buffer with "000c".
89template<typename Integral>
90requires std::integral<Integral>
91void convert_zero_padded_hex_safe(char *buf, size_t bufsz, Integral n) noexcept {
92 convert_hex_safe<Integral, '0'>(buf, bufsz, n);
93}
94
95// Prints zero-padded hexadecimal representation of an integer to stderr.
96// For example, print_zero_padded_hex_safe(uint16_t(12)) prints "000c".
97// Async-signal safe.
98template<typename Integral>
99requires std::unsigned_integral<Integral>
100void print_zero_padded_hex_safe(Integral n) noexcept {
101 char buf[sizeof(n) * 2];
102 convert_zero_padded_hex_safe(buf, sizeof(buf), n);
103 print_safe(buf, sizeof(buf));
104}
105
106// Fills a buffer with a decimal representation of an integer.
107// The argument bufsz is the maximum size of the buffer.
108// For example, print_decimal_safe(buf, 16, 12) prints "12".
109template<typename Integral>
110requires std::unsigned_integral<Integral>
111size_t convert_decimal_safe(char *buf, size_t bufsz, Integral n) noexcept {
112 char tmp[sizeof(n) * 3];
113 unsigned i = bufsz;
114 do {
115 assert(i > 0);
116 tmp[--i] = '0' + n % 10;
117 n /= 10;
118 } while (n);
119 memcpy(buf, tmp + i, sizeof(tmp) - i);
120 return sizeof(tmp) - i;
121}
122
123// Prints decimal representation of an integer to stderr.
124// For example, print_decimal_safe(12) prints "12".
125// Async-signal safe.
126template<typename Integral>
127void print_decimal_safe(Integral n) noexcept {
128 char buf[sizeof(n) * 3];
129 unsigned i = sizeof(buf);
130 auto len = convert_decimal_safe(buf, i, n);
131 print_safe(buf, len);
132}
133SEASTAR_MODULE_EXPORT_END
134}
Seastar API namespace.
Definition: abort_on_ebadf.hh:26