├── .github
└── workflows
│ └── ci.yml
├── .gitignore
├── LICENSE.GPL2
├── LICENSE.LGPL2.1
├── Makefile.am
├── README
├── TODO
├── autogen.sh
├── configure.ac
├── m4
├── .gitignore
├── arch.m4
├── attributes.m4
└── ax_normalize_path.m4
├── man
├── .gitignore
├── bootchart.conf.xml
├── custom-man.xsl
├── standard-conf.xml
├── standard-options.xml
└── systemd-bootchart.xml
├── po
└── .gitignore
├── src
├── Makefile
├── _sd-common.h
├── alloc-util.c
├── alloc-util.h
├── architecture.h
├── attributes.h
├── bootchart.c
├── bootchart.conf
├── bootchart.h
├── build.h
├── cgroup-util.c
├── cgroup-util.h
├── conf-files.c
├── conf-files.h
├── conf-parser.c
├── conf-parser.h
├── def.h
├── dirent-util.c
├── dirent-util.h
├── fd-util.c
├── fd-util.h
├── fileio.c
├── fileio.h
├── formats-util.h
├── fs-util.c
├── fs-util.h
├── hash-funcs.c
├── hash-funcs.h
├── hashmap.c
├── hashmap.h
├── io-util.c
├── io-util.h
├── list.h
├── log.c
├── log.h
├── macro.h
├── mempool.c
├── mempool.h
├── missing.h
├── parse-util.c
├── parse-util.h
├── path-util.c
├── path-util.h
├── process-util.c
├── process-util.h
├── random-util.c
├── random-util.h
├── sd-messages.h
├── set.h
├── siphash24.c
├── siphash24.h
├── stdio-util.h
├── store.c
├── store.h
├── string-util.c
├── string-util.h
├── strv.c
├── strv.h
├── strxcpyx.c
├── strxcpyx.h
├── svg.c
├── svg.h
├── terminal-util.c
├── terminal-util.h
├── time-util.c
├── time-util.h
├── unaligned.h
├── utf8.c
├── utf8.h
├── util.c
└── util.h
├── tests
└── run
└── units
├── .gitignore
└── systemd-bootchart.service.in
/.github/workflows/ci.yml:
--------------------------------------------------------------------------------
1 | name: CI
2 |
3 | on:
4 | push:
5 | branches:
6 | - main
7 | pull_request:
8 | branches:
9 | - main
10 |
11 | jobs:
12 | unit-test:
13 | runs-on: ubuntu-22.04
14 | concurrency:
15 | group: ${{ github.workflow }}-${{ toJSON(matrix.env) }}-${{ github.ref }}
16 | cancel-in-progress: true
17 | strategy:
18 | fail-fast: false
19 | matrix:
20 | env:
21 | - { CC: "gcc", CFLAGS: "-fno-omit-frame-pointer -fsanitize=undefined,address -ggdb3 -Og -fvar-tracking-assignments" }
22 | - { CC: "clang", CFLAGS: "-fno-omit-frame-pointer -fsanitize=undefined,address -ggdb3 -Og" }
23 | env: ${{ matrix.env }}
24 | steps:
25 | - uses: actions/checkout@v3
26 |
27 | - name: Install dependencies
28 | run: |
29 | sudo apt-get update
30 | sudo apt-get install intltool gcc llvm clang
31 |
32 | - name: ${{ format('Build check ({0})', env.CC) }}
33 | run: |
34 | ./autogen.sh
35 | ./configure --without-libsystemd --disable-man || cat config.log
36 | make -j
37 | make -j -k check
38 |
39 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.a
2 | *.cache
3 | *.html
4 | *.la
5 | *.lo
6 | *.log
7 | *.o
8 | *.plist
9 | *.pyc
10 | *.stamp
11 | *.swp
12 | *.trs
13 | *~
14 | .config.args
15 | .deps/
16 | .dirstamp
17 | .libs/
18 | /*.gcda
19 | /*.gcno
20 | /*.tar.bz2
21 | /*.tar.gz
22 | /*.tar.xz
23 | /build-aux
24 | /libtool
25 | /Makefile
26 | /TAGS
27 | /GPATH
28 | /GRTAGS
29 | /GSYMS
30 | /GTAGS
31 | /systemd-bootchart
32 | Makefile.in
33 | aclocal.m4
34 | config.h
35 | config.h.in
36 | config.log
37 | config.status
38 | configure
39 | stamp-*
40 |
--------------------------------------------------------------------------------
/Makefile.am:
--------------------------------------------------------------------------------
1 | # -*- Mode: makefile; indent-tabs-mode: t -*-
2 | #
3 | # This file is part of systemd-bootchart
4 | #
5 | # systemd is free software; you can redistribute it and/or modify it
6 | # under the terms of the GNU Lesser General Public License as published by
7 | # the Free Software Foundation; either version 2.1 of the License, or
8 | # (at your option) any later version.
9 | #
10 | # systemd is distributed in the hope that it will be useful, but
11 | # WITHOUT ANY WARRANTY; without even the implied warranty of
12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 | # Lesser General Public License for more details.
14 | #
15 | # You should have received a copy of the GNU Lesser General Public License
16 | # along with systemd; If not, see .
17 |
18 | ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS}
19 | AM_MAKEFLAGS = --no-print-directory
20 | AUTOMAKE_OPTIONS = color-tests parallel-tests
21 |
22 | GCC_COLORS ?= 'ooh, shiny!'
23 | export GCC_COLORS
24 |
25 | SUBDIRS = .
26 |
27 | # remove targets if the command fails
28 | .DELETE_ON_ERROR:
29 |
30 | # keep intermediate files
31 | .SECONDARY:
32 |
33 | # Keep the test-suite.log
34 | .PRECIOUS: $(TEST_SUITE_LOG) Makefile
35 |
36 | # Dirs of external packages
37 | systemdir=@systemdir@
38 |
39 | # And these are the special ones for /
40 | rootprefix=@rootprefix@
41 | rootbindir=$(rootprefix)/bin
42 | rootlibexecdir=$(rootprefix)/lib/systemd
43 | pkgsysconfdir=$(sysconfdir)/systemd
44 | systemunitdir=$(rootprefix)/lib/systemd/system
45 |
46 | AM_CFLAGS = $(OUR_CFLAGS)
47 | AM_LDFLAGS = $(OUR_LDFLAGS)
48 | AM_CPPFLAGS = \
49 | -include $(top_builddir)/config.h \
50 | -DPKGSYSCONFDIR=\"$(pkgsysconfdir)\" \
51 | -DSYSTEM_CONFIG_UNIT_PATH=\"$(pkgsysconfdir)/system\" \
52 | -DSYSTEM_DATA_UNIT_PATH=\"$(systemunitdir)\" \
53 | -DSYSTEMD_BINARY_PATH=\"$(rootlibexecdir)/systemd\" \
54 | -DROOTPREFIX=\"$(rootprefix)\" \
55 | -DLIBDIR=\"$(libdir)\" \
56 | -DROOTLIBDIR=\"$(rootlibdir)\" \
57 | -DROOTLIBEXECDIR=\"$(rootlibexecdir)\" \
58 | -I $(top_srcdir)/src
59 |
60 | #####################################################
61 |
62 | dist_noinst_DATA = \
63 | LICENSE.LGPL2.1 \
64 | LICENSE.GPL2
65 |
66 | EXTRA_DIST = \
67 | man/bootchart.conf.xml \
68 | man/systemd-bootchart.xml \
69 | man/custom-man.xsl \
70 | man/standard-conf.xml \
71 | man/standard-options.xml \
72 | units/systemd-bootchart.service.in \
73 | tests/run
74 |
75 | MANPAGES = man/bootchart.conf.5 man/systemd-bootchart.1
76 | MANPAGES_ALIAS = man/bootchart.conf.d.5
77 |
78 | if COND_man
79 | MAYBE_MANPAGES = $(MANPAGES) $(MANPAGES_ALIAS)
80 | endif
81 | man_MANS = $(MAYBE_MANPAGES)
82 |
83 | man/bootchart.conf.d.5: man/bootchart.conf.5
84 |
85 | XSLTPROC_FLAGS = \
86 | --nonet \
87 | --xinclude \
88 | --stringparam man.output.quietly 1 \
89 | --stringparam funcsynopsis.style ansi \
90 | --stringparam man.authors.section.enabled 0 \
91 | --stringparam man.copyright.section.enabled 0 \
92 | --stringparam systemd.version $(VERSION) \
93 | --path '$(builddir)/man:$(srcdir)/man'
94 |
95 | XSLT = $(if $(XSLTPROC), $(XSLTPROC), xsltproc)
96 | XSLTPROC_PROCESS_MAN = \
97 | $(AM_V_XSLT)$(XSLT) -o $@ $(XSLTPROC_FLAGS) $(srcdir)/man/custom-man.xsl $<
98 |
99 | man/%.1: man/%.xml man/custom-man.xsl
100 | $(XSLTPROC_PROCESS_MAN)
101 |
102 | man/%.5: man/%.xml man/custom-man.xsl
103 | $(XSLTPROC_PROCESS_MAN)
104 |
105 | #####################################################
106 |
107 | libutils_la_SOURCES = \
108 | src/alloc-util.c \
109 | src/alloc-util.h \
110 | src/architecture.h \
111 | src/attributes.h \
112 | src/build.h \
113 | src/cgroup-util.c \
114 | src/cgroup-util.h \
115 | src/conf-files.c \
116 | src/conf-files.h \
117 | src/conf-parser.c \
118 | src/conf-parser.h \
119 | src/def.h \
120 | src/dirent-util.c \
121 | src/dirent-util.h \
122 | src/fd-util.c \
123 | src/fd-util.h \
124 | src/fileio.c \
125 | src/fileio.h \
126 | src/formats-util.h \
127 | src/fs-util.c \
128 | src/fs-util.h \
129 | src/hash-funcs.c \
130 | src/hash-funcs.h \
131 | src/hashmap.c \
132 | src/hashmap.h \
133 | src/io-util.c \
134 | src/io-util.h \
135 | src/list.h \
136 | src/log.c \
137 | src/log.h \
138 | src/macro.h \
139 | src/mempool.c \
140 | src/mempool.h \
141 | src/missing.h \
142 | src/parse-util.c \
143 | src/parse-util.h \
144 | src/path-util.c \
145 | src/path-util.h \
146 | src/process-util.c \
147 | src/process-util.h \
148 | src/random-util.c \
149 | src/random-util.h \
150 | src/_sd-common.h \
151 | src/sd-messages.h \
152 | src/set.h \
153 | src/siphash24.c \
154 | src/siphash24.h \
155 | src/stdio-util.h \
156 | src/string-util.c \
157 | src/string-util.h \
158 | src/strv.c \
159 | src/strv.h \
160 | src/strxcpyx.c \
161 | src/strxcpyx.h \
162 | src/terminal-util.c \
163 | src/terminal-util.h \
164 | src/time-util.c \
165 | src/time-util.h \
166 | src/unaligned.h \
167 | src/utf8.c \
168 | src/utf8.h \
169 | src/util.c \
170 | src/util.h
171 |
172 | libutils_la_CFLAGS = \
173 | $(AM_CFLAGS) \
174 | $(LIBSYSTEMD_CFLAGS)
175 |
176 | libutils_la_LIBADD = \
177 | $(LIBSYSTEMD_LIBS)
178 |
179 | noinst_LTLIBRARIES = libutils.la
180 |
181 | #####################################################
182 |
183 | systemd_bootchart_SOURCES = \
184 | src/bootchart.c \
185 | src/bootchart.h \
186 | src/store.c \
187 | src/store.h \
188 | src/svg.c \
189 | src/svg.h
190 |
191 | systemd_bootchart_LDADD = \
192 | libutils.la
193 |
194 | #####################################################
195 |
196 | TESTS = tests/run
197 |
198 | substitutions = \
199 | '|rootlibexecdir=$(rootlibexecdir)|'
200 |
201 | SED_PROCESS = \
202 | $(AM_V_GEN)$(MKDIR_P) $(dir $@) && \
203 | $(SED) $(subst '|,-e 's|@,$(subst =,\@|,$(subst |',|g',$(substitutions)))) \
204 | < $< > $@
205 |
206 | units/%: units/%.in
207 | $(SED_PROCESS)
208 |
209 | man/%: man/%.in
210 | $(SED_PROCESS)
211 |
212 | rootlibexec_PROGRAMS = systemd-bootchart
213 | dist_pkgsysconf_DATA = src/bootchart.conf
214 | nodist_systemunit_DATA = units/systemd-bootchart.service
215 |
216 | in_files = $(filter %.in,$(EXTRA_DIST))
217 |
218 | CLEANFILES = \
219 | $(MANPAGES) $(MANPAGES_ALIAS) \
220 | $(pkgconfigdata_DATA) \
221 | $(pkgconfiglib_DATA) \
222 | $(in_files:.in=)
223 |
224 | install-exec-hook: $(INSTALL_EXEC_HOOKS)
225 |
226 | uninstall-hook: $(UNINSTALL_DATA_HOOKS) $(UNINSTALL_EXEC_HOOKS)
227 |
228 | install-data-hook: $(INSTALL_DATA_HOOKS)
229 |
230 | .PHONY: git-tag
231 | git-tag:
232 | git tag -s "v$(VERSION)" -m "systemd $(VERSION)"
233 |
234 | .PHONY: git-tar
235 | git-tar:
236 | git archive --format=tar --prefix=systemd-$(VERSION)/ HEAD | xz > systemd-$(VERSION).tar.xz
237 |
--------------------------------------------------------------------------------
/README:
--------------------------------------------------------------------------------
1 | For systemd-bootchart, several proc debug interfaces are required in the kernel config:
2 | CONFIG_SCHEDSTATS
3 | below is optional, for additional info:
4 | CONFIG_SCHED_DEBUG
5 |
--------------------------------------------------------------------------------
/TODO:
--------------------------------------------------------------------------------
1 | - plot per-process IO utilization
2 | - group processes based on service association (cgroups)
3 | - document initcall_debug
4 | - kernel cmdline "bootchart" option for simplicity?
5 |
--------------------------------------------------------------------------------
/autogen.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | # This file is part of systemd-journal-remote.
4 | #
5 | # systemd is free software; you can redistribute it and/or modify it
6 | # under the terms of the GNU Lesser General Public License as published by
7 | # the Free Software Foundation; either version 2.1 of the License, or
8 | # (at your option) any later version.
9 | #
10 | # systemd is distributed in the hope that it will be useful, but
11 | # WITHOUT ANY WARRANTY; without even the implied warranty of
12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 | # Lesser General Public License for more details.
14 | #
15 | # You should have received a copy of the GNU Lesser General Public License
16 | # along with systemd; If not, see .
17 |
18 | set -e
19 |
20 | oldpwd=$(pwd)
21 | topdir=$(dirname $0)
22 | cd $topdir
23 |
24 | if [ -f .git/hooks/pre-commit.sample ] && [ ! -f .git/hooks/pre-commit ]; then
25 | # This part is allowed to fail
26 | cp -p .git/hooks/pre-commit.sample .git/hooks/pre-commit && \
27 | chmod +x .git/hooks/pre-commit && \
28 | echo "Activated pre-commit hook." || :
29 | fi
30 |
31 | intltoolize --force --automake
32 | autoreconf --force --install --symlink
33 |
34 | libdir() {
35 | echo $(cd "$1/$(gcc -print-multi-os-directory)"; pwd)
36 | }
37 |
38 | args="\
39 | --sysconfdir=/etc \
40 | --localstatedir=/var \
41 | --libdir=$(libdir /usr/lib) \
42 | "
43 |
44 | if [ -f "$topdir/.config.args" ]; then
45 | args="$args $(cat $topdir/.config.args)"
46 | fi
47 |
48 | if [ ! -L /bin ]; then
49 | args="$args \
50 | --with-rootprefix=/ \
51 | --with-rootlibdir=$(libdir /lib) \
52 | "
53 | fi
54 |
55 | cd $oldpwd
56 |
57 | if [ "x$1" = "xc" ]; then
58 | $topdir/configure CFLAGS='-g -O0 -ftrapv' $args
59 | make clean
60 | else
61 | echo
62 | echo "----------------------------------------------------------------"
63 | echo "Initialized build system. For a common configuration please run:"
64 | echo "----------------------------------------------------------------"
65 | echo
66 | echo "$topdir/configure CFLAGS='-g -O0 -ftrapv' $args"
67 | echo
68 | fi
69 |
--------------------------------------------------------------------------------
/configure.ac:
--------------------------------------------------------------------------------
1 | #
2 | # This file is part of systemd-bootchart.
3 | #
4 | # systemd is free software; you can redistribute it and/or modify it
5 | # under the terms of the GNU Lesser General Public License as published by
6 | # the Free Software Foundation; either version 2.1 of the License, or
7 | # (at your option) any later version.
8 | #
9 | # systemd is distributed in the hope that it will be useful, but
10 | # WITHOUT ANY WARRANTY; without even the implied warranty of
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 | # Lesser General Public License for more details.
13 | #
14 | # You should have received a copy of the GNU Lesser General Public License
15 | # along with systemd; If not, see .
16 |
17 | AC_PREREQ([2.64])
18 |
19 | AC_INIT([systemd-bootchart],
20 | [235],
21 | [https://github.com/systemd/systemd-bootchart/issues],
22 | [systemd-bootchart],
23 | [https://github.com/systemd/systemd-bootchart/])
24 |
25 | AC_CONFIG_SRCDIR([src/bootchart.c])
26 | AC_CONFIG_MACRO_DIR([m4])
27 | AC_CONFIG_HEADERS([config.h])
28 | AC_CONFIG_AUX_DIR([build-aux])
29 |
30 | AC_USE_SYSTEM_EXTENSIONS
31 | AC_SYS_LARGEFILE
32 | AC_PREFIX_DEFAULT([/usr])
33 | AM_MAINTAINER_MODE([enable])
34 | AM_INIT_AUTOMAKE([foreign 1.11 -Wall -Wno-portability silent-rules tar-pax no-dist-gzip dist-xz subdir-objects parallel-tests])
35 | AM_SILENT_RULES([yes])
36 | AC_CANONICAL_HOST
37 | AC_DEFINE_UNQUOTED([CANONICAL_HOST], "$host", [Canonical host string.])
38 | LT_PREREQ(2.2)
39 | LT_INIT([disable-static])
40 |
41 | AC_PROG_CC_C99
42 |
43 | SET_ARCH(X86_64, x86_64*)
44 | SET_ARCH(IA32, i*86*)
45 | SET_ARCH(MIPS, mips*)
46 | SET_ARCH(AARCH64, aarch64*)
47 | SET_ARCH(RISCV64, riscv64*)
48 | SET_ARCH(RISCV32, riscv32*)
49 |
50 | AC_CHECK_SIZEOF(pid_t)
51 | AC_CHECK_SIZEOF(uid_t)
52 | AC_CHECK_SIZEOF(gid_t)
53 | AC_CHECK_SIZEOF(time_t)
54 | AC_CHECK_SIZEOF(dev_t)
55 | AC_CHECK_SIZEOF(rlim_t,,[
56 | #include
57 | #include
58 | ])
59 |
60 | AC_CHECK_DECLS([gettid, getrandom], [], [], [[
61 | #include
62 | #include
63 | #include
64 | #include
65 | ]])
66 |
67 | AC_ARG_WITH(libsystemd,
68 | AS_HELP_STRING([--without-libsystemd], [Disable use of libsystemd for journal output]),
69 | [], [with_libsystemd=yes])
70 |
71 | AS_IF([test "x$with_libsystemd" != xno],
72 | [PKG_CHECK_MODULES(LIBSYSTEMD, [libsystemd >= 221],
73 | [AC_DEFINE([HAVE_LIBSYSTEMD],[1],[Define if you have libsystemd])],
74 | [AC_MSG_ERROR([*** libsystemd library not found])]
75 | )]
76 | )
77 |
78 | CC_CHECK_FLAGS_APPEND([with_cflags], [CFLAGS], [\
79 | -pipe \
80 | -Wall \
81 | -Wextra \
82 | -Wundef \
83 | "-Wformat=2 -Wformat-security -Wformat-nonliteral" \
84 | -Wlogical-op \
85 | -Wmissing-include-dirs \
86 | -Wold-style-definition \
87 | -Wpointer-arith \
88 | -Winit-self \
89 | -Wdeclaration-after-statement \
90 | -Wfloat-equal \
91 | -Wsuggest-attribute=noreturn \
92 | -Werror=missing-prototypes \
93 | -Werror=implicit-function-declaration \
94 | -Werror=missing-declarations \
95 | -Werror=return-type \
96 | -Werror=shadow \
97 | -Wstrict-prototypes \
98 | -Wredundant-decls \
99 | -Wmissing-noreturn \
100 | -Wshadow \
101 | -Wendif-labels \
102 | -Wstrict-aliasing=2 \
103 | -Wwrite-strings \
104 | -Wno-unused-parameter \
105 | -Wno-missing-field-initializers \
106 | -Wno-unused-result \
107 | -Wno-format-signedness \
108 | -Werror=overflow \
109 | -Wdate-time \
110 | -Wnested-externs \
111 | -ffast-math \
112 | -fno-common \
113 | -fdiagnostics-show-option \
114 | -fno-strict-aliasing \
115 | -fvisibility=hidden \
116 | -fstack-protector \
117 | -fstack-protector-strong \
118 | -fPIE \
119 | --param=ssp-buffer-size=4])
120 |
121 | AS_CASE([$CC], [*clang*],
122 | [CC_CHECK_FLAGS_APPEND([with_cppflags], [CPPFLAGS], [\
123 | -Wno-typedef-redefinition \
124 | -Wno-gnu-variable-sized-type-not-at-end \
125 | ])])
126 |
127 | AS_CASE([$CFLAGS], [*-O[[12345sz\ ]]*],
128 | [CC_CHECK_FLAGS_APPEND([with_cflags], [CFLAGS], [\
129 | -flto -ffat-lto-objects])],
130 | [AC_MSG_RESULT([skipping -flto, optimization not enabled])])
131 | AC_SUBST([OUR_CFLAGS], "$with_cflags $sanitizer_cflags")
132 |
133 | AS_CASE([$CFLAGS], [*-O[[12345sz\ ]]*],
134 | [CC_CHECK_FLAGS_APPEND([with_cppflags], [CPPFLAGS], [\
135 | -Wp,-D_FORTIFY_SOURCE=2])],
136 | [AC_MSG_RESULT([skipping -D_FORTIFY_SOURCE, optimization not enabled])])
137 | AC_SUBST([OUR_CPPFLAGS], "$with_cppflags $sanitizer_cppflags")
138 |
139 | AS_CASE([$CFLAGS], [*-O[[12345sz\ ]]*],
140 | [CC_CHECK_FLAGS_APPEND([with_ldflags], [LDFLAGS], [\
141 | -Wl,--gc-sections])],
142 | [AC_MSG_RESULT([skipping --gc-sections, optimization not enabled])])
143 | AC_SUBST([OUR_CFLAGS], "$with_ldflags $sanitizer_cflags")
144 |
145 | AS_CASE([$CFLAGS], [*-O[[12345sz\ ]]*],
146 | [CC_CHECK_FLAGS_APPEND([with_cflags], [CFLAGS], [\
147 | -ffunction-sections -fdata-sections])],
148 | [AC_MSG_RESULT([skipping -ffunction/data-section, optimization not enabled])])
149 | AC_SUBST([OUR_CFLAGS], "$with_cflags $sanitizer_cflags")
150 |
151 | CC_CHECK_FLAGS_APPEND([with_ldflags], [LDFLAGS], [\
152 | -Wl,--as-needed \
153 | -Wl,--no-undefined \
154 | -Wl,-z,relro \
155 | -Wl,-z,now \
156 | -pie])
157 | AC_SUBST([OUR_LDFLAGS], "$with_ldflags $sanitizer_ldflags")
158 |
159 | AC_ARG_WITH([rootprefix],
160 | AS_HELP_STRING([--with-rootprefix=DIR], [rootfs directory prefix for config files and binaries necessary for boot]),
161 | [], [with_rootprefix=${ac_default_prefix}])
162 | # --with-rootprefix= (empty) should default to "/" but AX_NORMALIZE_PATH
163 | # defaults those to ".", solve that here for now until we can find a suitable
164 | # fix for AX_NORMALIZE_PATH upstream at autoconf-archive.
165 | # See: https://github.com/systemd/systemd/issues/54
166 | if test "x${with_rootprefix}" = "x"; then
167 | with_rootprefix="/"
168 | fi
169 | AX_NORMALIZE_PATH([with_rootprefix])
170 |
171 | AC_ARG_WITH([rootlibdir],
172 | AS_HELP_STRING([--with-rootlibdir=DIR], [Root directory for libraries necessary for boot]),
173 | [],
174 | [with_rootlibdir=${libdir}])
175 |
176 | AC_SUBST([rootprefix], [$with_rootprefix])
177 | AC_SUBST([rootlibdir], [$with_rootlibdir])
178 |
179 | AC_ARG_ENABLE([man],
180 | AS_HELP_STRING([--disable-man],[Build the man pages (default: yes)]),
181 | [build_man=$enableval],
182 | [build_man=yes])
183 |
184 | AC_PATH_PROG([XSLTPROC], [xsltproc])
185 | AS_IF([test -z "$XSLTPROC" -a "$build_man" = "yes"],
186 | [AC_MSG_ERROR([*** xsltproc is required for man pages])])
187 |
188 | AM_CONDITIONAL([COND_man],[test "$build_man" = "yes"])
189 |
190 | AC_CONFIG_FILES([
191 | Makefile
192 | ])
193 |
194 | AC_OUTPUT
195 | AC_MSG_RESULT([
196 | $PACKAGE_NAME $VERSION
197 |
198 | prefix: ${prefix}
199 | sysconf dir: ${sysconfdir}
200 | datarootdir: ${datarootdir}
201 | includedir: ${includedir}
202 | lib dir: ${libdir}
203 | rootlib dir: ${with_rootlibdir}
204 |
205 | CFLAGS: ${OUR_CFLAGS} ${CFLAGS}
206 | CPPFLAGS: ${OUR_CPPFLAGS} ${CPPFLAGS}
207 | LDFLAGS: ${OUR_LDFLAGS} ${LDFLAGS}
208 | ])
209 |
--------------------------------------------------------------------------------
/m4/.gitignore:
--------------------------------------------------------------------------------
1 | intltool.m4
2 | libtool.m4
3 | ltoptions.m4
4 | ltsugar.m4
5 | ltversion.m4
6 | lt~obsolete.m4
7 |
--------------------------------------------------------------------------------
/m4/arch.m4:
--------------------------------------------------------------------------------
1 |
2 | dnl SET_ARCH(ARCHNAME, PATTERN)
3 | dnl
4 | dnl Define ARCH_ condition if the pattern match with the current
5 | dnl architecture
6 | dnl
7 | AC_DEFUN([SET_ARCH], [
8 | cpu_$1=false
9 | case "$host" in
10 | $2) cpu_$1=true ;;
11 | esac
12 | AM_CONDITIONAL(AS_TR_CPP(ARCH_$1), [test "x$cpu_$1" = xtrue])
13 | ])
14 |
--------------------------------------------------------------------------------
/m4/ax_normalize_path.m4:
--------------------------------------------------------------------------------
1 | # ===========================================================================
2 | # http://www.gnu.org/software/autoconf-archive/ax_normalize_path.html
3 | # ===========================================================================
4 | #
5 | # SYNOPSIS
6 | #
7 | # AX_NORMALIZE_PATH(VARNAME, [REFERENCE_STRING])
8 | #
9 | # DESCRIPTION
10 | #
11 | # Perform some cleanups on the value of $VARNAME (interpreted as a path):
12 | #
13 | # - empty paths are changed to '.'
14 | # - trailing slashes are removed
15 | # - repeated slashes are squeezed except a leading doubled slash '//'
16 | # (which might indicate a networked disk on some OS).
17 | #
18 | # REFERENCE_STRING is used to turn '/' into '\' and vice-versa: if
19 | # REFERENCE_STRING contains some backslashes, all slashes and backslashes
20 | # are turned into backslashes, otherwise they are all turned into slashes.
21 | #
22 | # This makes processing of DOS filenames quite easier, because you can
23 | # turn a filename to the Unix notation, make your processing, and turn it
24 | # back to original notation.
25 | #
26 | # filename='A:\FOO\\BAR\'
27 | # old_filename="$filename"
28 | # # Switch to the unix notation
29 | # AX_NORMALIZE_PATH([filename], ["/"])
30 | # # now we have $filename = 'A:/FOO/BAR' and we can process it as if
31 | # # it was a Unix path. For instance let's say that you want
32 | # # to append '/subpath':
33 | # filename="$filename/subpath"
34 | # # finally switch back to the original notation
35 | # AX_NORMALIZE_PATH([filename], ["$old_filename"])
36 | # # now $filename equals to 'A:\FOO\BAR\subpath'
37 | #
38 | # One good reason to make all path processing with the unix convention is
39 | # that backslashes have a special meaning in many cases. For instance
40 | #
41 | # expr 'A:\FOO' : 'A:\Foo'
42 | #
43 | # will return 0 because the second argument is a regex in which
44 | # backslashes have to be backslashed. In other words, to have the two
45 | # strings to match you should write this instead:
46 | #
47 | # expr 'A:\Foo' : 'A:\\Foo'
48 | #
49 | # Such behavior makes DOS filenames extremely unpleasant to work with. So
50 | # temporary turn your paths to the Unix notation, and revert them to the
51 | # original notation after the processing. See the macro
52 | # AX_COMPUTE_RELATIVE_PATHS for a concrete example of this.
53 | #
54 | # REFERENCE_STRING defaults to $VARIABLE, this means that slashes will be
55 | # converted to backslashes if $VARIABLE already contains some backslashes
56 | # (see $thirddir below).
57 | #
58 | # firstdir='/usr/local//share'
59 | # seconddir='C:\Program Files\\'
60 | # thirddir='C:\home/usr/'
61 | # AX_NORMALIZE_PATH([firstdir])
62 | # AX_NORMALIZE_PATH([seconddir])
63 | # AX_NORMALIZE_PATH([thirddir])
64 | # # $firstdir = '/usr/local/share'
65 | # # $seconddir = 'C:\Program Files'
66 | # # $thirddir = 'C:\home\usr'
67 | #
68 | # LICENSE
69 | #
70 | # Copyright (c) 2008 Alexandre Duret-Lutz
71 | #
72 | # This program is free software; you can redistribute it and/or modify it
73 | # under the terms of the GNU General Public License as published by the
74 | # Free Software Foundation; either version 2 of the License, or (at your
75 | # option) any later version.
76 | #
77 | # This program is distributed in the hope that it will be useful, but
78 | # WITHOUT ANY WARRANTY; without even the implied warranty of
79 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
80 | # Public License for more details.
81 | #
82 | # You should have received a copy of the GNU General Public License along
83 | # with this program. If not, see .
84 | #
85 | # As a special exception, the respective Autoconf Macro's copyright owner
86 | # gives unlimited permission to copy, distribute and modify the configure
87 | # scripts that are the output of Autoconf when processing the Macro. You
88 | # need not follow the terms of the GNU General Public License when using
89 | # or distributing such scripts, even though portions of the text of the
90 | # Macro appear in them. The GNU General Public License (GPL) does govern
91 | # all other use of the material that constitutes the Autoconf Macro.
92 | #
93 | # This special exception to the GPL applies to versions of the Autoconf
94 | # Macro released by the Autoconf Archive. When you make and distribute a
95 | # modified version of the Autoconf Macro, you may extend this special
96 | # exception to the GPL to apply to your modified version as well.
97 |
98 | #serial 5
99 |
100 | AU_ALIAS([ADL_NORMALIZE_PATH], [AX_NORMALIZE_PATH])
101 | AC_DEFUN([AX_NORMALIZE_PATH],
102 | [case ":[$]$1:" in
103 | # change empty paths to '.'
104 | ::) $1='.' ;;
105 | # strip trailing slashes
106 | :*[[\\/]]:) $1=`echo "[$]$1" | sed 's,[[\\/]]*[$],,'` ;;
107 | :*:) ;;
108 | esac
109 | # squeze repeated slashes
110 | case ifelse($2,,"[$]$1",$2) in
111 | # if the path contains any backslashes, turn slashes into backslashes
112 | *\\*) $1=`echo "[$]$1" | sed 's,\(.\)[[\\/]][[\\/]]*,\1\\\\,g'` ;;
113 | # if the path contains slashes, also turn backslashes into slashes
114 | *) $1=`echo "[$]$1" | sed 's,\(.\)[[\\/]][[\\/]]*,\1/,g'` ;;
115 | esac])
116 |
--------------------------------------------------------------------------------
/man/.gitignore:
--------------------------------------------------------------------------------
1 | /systemd.directives.xml
2 | /systemd.index.xml
3 | /*.[13578]
4 | /*.html
5 | /custom-entities.ent
6 |
--------------------------------------------------------------------------------
/man/bootchart.conf.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
26 |
27 |
29 |
30 | bootchart.conf
31 | systemd
32 |
33 |
34 |
35 | Developer
36 | Auke
37 | Kok
38 | auke-jan.h.kok@intel.com
39 |
40 |
41 |
42 |
43 |
44 | bootchart.conf
45 | 5
46 |
47 |
48 |
49 | bootchart.conf
50 | bootchart.conf.d
51 | Boot performance analysis graphing tool configuration files
52 |
53 |
54 |
55 | /etc/systemd/bootchart.conf
56 | /etc/systemd/bootchart.conf.d/*.conf
57 | /run/systemd/bootchart.conf.d/*.conf
58 | /usr/lib/systemd/bootchart.conf.d/*.conf
59 |
60 |
61 |
62 | Description
63 |
64 | When starting, systemd-bootchart will read the configuration
65 | file /etc/systemd/bootchart.conf, followed by
66 | the files in the bootchart.conf.d
67 | directories. These configuration files determine logging
68 | parameters and graph output.
69 |
70 |
71 |
72 |
73 |
74 | Options
75 |
76 |
77 |
78 |
79 | Samples=500
80 | Configure the amount of samples to record in
81 | total before bootchart exits. Each sample will record at
82 | intervals defined by Frequency=.
83 |
84 |
85 |
86 | Frequency=25
87 | Configure the sample log frequency. This can
88 | be a fractional number, but must be larger than 0.0. Most
89 | systems can cope with values under 25-50 without impacting
90 | boot time severely.
91 |
92 |
93 |
94 | Relative=no
95 | Configures whether the left axis of the output
96 | graph equals time=0.0 (CLOCK_MONOTONIC
97 | start). This is useful for using bootchart at post-boot time
98 | to profile an already booted system, otherwise the graph would
99 | become extremely large. If set to yes, the horizontal axis
100 | starts at the first recorded sample instead of time=0.0.
101 |
102 |
103 |
104 |
105 | Filter=no
106 | Configures whether the resulting graph should
107 | omit tasks that did not contribute significantly to the boot.
108 | Processes that are too short-lived (only seen in one sample)
109 | or that do not consume any significant CPU time (less than
110 | 0.001sec) will not be displayed in the output
111 | graph.
112 |
113 |
114 |
115 | Output=[path]
116 | Configures the output directory for writing
117 | the graphs. By default, bootchart writes the graphs to
118 | /run/log.
119 |
120 |
121 |
122 | Init=[path]
123 | Configures bootchart to run a non-standard
124 | binary instead of
125 | /usr/lib/systemd/systemd. This option is
126 | only relevant if bootchart was invoked from the kernel command
127 | line with
128 | init=/usr/lib/systemd/systemd-bootchart.
129 |
130 |
131 |
132 | PlotMemoryUsage=no
133 | If set to yes, enables logging and graphing of
134 | processes' PSS memory consumption.
135 |
136 |
137 |
138 | PlotEntropyGraph=no
139 | If set to yes, enables logging and graphing of
140 | the kernel random entropy pool size.
141 |
142 |
143 |
144 | ScaleX=100
145 | Horizontal scaling factor for all variable
146 | graph components.
147 |
148 |
149 |
150 | ScaleY=20
151 | Vertical scaling factor for all variable graph
152 | components.
153 |
154 |
155 |
156 | ControlGroup=no
157 | Display process control group.
158 |
159 |
160 |
161 |
162 | Cmdline=no
163 | Display the full command line of each process.
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 | See Also
172 |
173 | systemd-bootchart1,
174 | systemd.directives7
175 |
176 |
177 |
178 |
179 |
--------------------------------------------------------------------------------
/man/custom-man.xsl:
--------------------------------------------------------------------------------
1 |
2 |
3 |
21 |
22 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 | .TH "
40 |
41 |
42 |
43 |
44 |
45 | " "
46 |
47 | " "" "systemd
48 |
49 | " "
50 |
51 | "
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 | "
60 |
61 | "
62 |
63 |
64 |
65 |
--------------------------------------------------------------------------------
/man/standard-conf.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 | Configuration Directories and Precedence
8 |
9 | Configuration files are read from directories in
10 | /etc/, /run/, and
11 | /usr/lib/, in order of precedence.
12 | Each configuration file in these configuration directories shall be named in
13 | the style of filename.conf.
14 | Files in /etc/ override files with the same name in
15 | /run/ and /usr/lib/. Files in
16 | /run/ override files with the same name in
17 | /usr/lib/.
18 |
19 | Packages should install their configuration files in
20 | /usr/lib/. Files in /etc/ are
21 | reserved for the local administrator, who may use this logic to override the
22 | configuration files installed by vendor packages. All configuration files
23 | are sorted by their filename in lexicographic order, regardless of which of
24 | the directories they reside in. If multiple files specify the same option,
25 | the entry in the file with the lexicographically latest name will take
26 | precedence. It is recommended to prefix all filenames with a two-digit number
27 | and a dash, to simplify the ordering of the files.
28 |
29 | If the administrator wants to disable a configuration file supplied by
30 | the vendor, the recommended way is to place a symlink to
31 | /dev/null in the configuration directory in
32 | /etc/, with the same filename as the vendor
33 | configuration file. If the vendor configuration file is included in
34 | the initrd image, the image has to be regenerated.
35 |
36 |
37 |
38 |
39 | Configuration Directories and Precedence
40 |
41 | The default configuration is defined during compilation, so a
42 | configuration file is only needed when it is necessary to deviate
43 | from those defaults. By default, the configuration file in
44 | /etc/systemd/ contains commented out entries
45 | showing the defaults as a guide to the administrator. This file
46 | can be edited to create local overrides.
47 |
48 |
49 | When packages need to customize the configuration, they can
50 | install configuration snippets in
51 | /usr/lib/systemd/*.conf.d/. Files in
52 | /etc/ are reserved for the local
53 | administrator, who may use this logic to override the
54 | configuration files installed by vendor packages. The main
55 | configuration file is read before any of the configuration
56 | directories, and has the lowest precedence; entries in a file in
57 | any configuration directory override entries in the single
58 | configuration file. Files in the
59 | *.conf.d/ configuration subdirectories
60 | are sorted by their filename in lexicographic order, regardless of
61 | which of the subdirectories they reside in. If multiple files
62 | specify the same option, the entry in the file with the
63 | lexicographically latest name takes precedence. It is recommended
64 | to prefix all filenames in those subdirectories with a two-digit
65 | number and a dash, to simplify the ordering of the files.
66 |
67 | To disable a configuration file supplied by the vendor, the
68 | recommended way is to place a symlink to
69 | /dev/null in the configuration directory in
70 | /etc/, with the same filename as the vendor
71 | configuration file.
72 |
73 |
74 |
--------------------------------------------------------------------------------
/man/standard-options.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 | Print a short help text and exit.
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 | Print a short version string and exit.
20 |
21 |
22 |
23 |
30 |
31 |
32 |
33 |
34 |
35 | Do not print the legend, i.e. column headers and the
36 | footer with hints.
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/po/.gitignore:
--------------------------------------------------------------------------------
1 | POTFILES
2 | Makefile.in.in
3 | .intltool-merge-cache
4 | Makefile
5 | systemd.pot
6 | /*.gmo
7 |
--------------------------------------------------------------------------------
/src/Makefile:
--------------------------------------------------------------------------------
1 | # This file is part of systemd.
2 | #
3 | # Copyright 2010 Lennart Poettering
4 | #
5 | # systemd is free software; you can redistribute it and/or modify it
6 | # under the terms of the GNU Lesser General Public License as published by
7 | # the Free Software Foundation; either version 2.1 of the License, or
8 | # (at your option) any later version.
9 | #
10 | # systemd is distributed in the hope that it will be useful, but
11 | # WITHOUT ANY WARRANTY; without even the implied warranty of
12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 | # Lesser General Public License for more details.
14 | #
15 | # You should have received a copy of the GNU Lesser General Public License
16 | # along with systemd; If not, see .
17 |
18 | # This file is a dirty trick to simplify compilation from within
19 | # emacs. This file is not intended to be distributed. So, don't touch
20 | # it, even better ignore it!
21 |
22 | all:
23 | $(MAKE) -C ..
24 |
25 | clean:
26 | $(MAKE) -C .. clean
27 |
28 | .PHONY: all clean
29 |
--------------------------------------------------------------------------------
/src/_sd-common.h:
--------------------------------------------------------------------------------
1 | #ifndef foosdcommonhfoo
2 | #define foosdcommonhfoo
3 |
4 | /***
5 | This file is part of systemd.
6 |
7 | Copyright 2013 Lennart Poettering
8 |
9 | systemd is free software; you can redistribute it and/or modify it
10 | under the terms of the GNU Lesser General Public License as published by
11 | the Free Software Foundation; either version 2.1 of the License, or
12 | (at your option) any later version.
13 |
14 | systemd is distributed in the hope that it will be useful, but
15 | WITHOUT ANY WARRANTY; without even the implied warranty of
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | Lesser General Public License for more details.
18 |
19 | You should have received a copy of the GNU Lesser General Public License
20 | along with systemd; If not, see .
21 | ***/
22 |
23 | /* This is a private header; never even think of including this directly! */
24 |
25 | #if __INCLUDE_LEVEL__ <= 1
26 | #error "Do not include _sd-common.h directly; it is a private header."
27 | #endif
28 |
29 | #ifndef _sd_printf_
30 | # if __GNUC__ >= 4
31 | # define _sd_printf_(a,b) __attribute__ ((format (printf, a, b)))
32 | # else
33 | # define _sd_printf_(a,b)
34 | # endif
35 | #endif
36 |
37 | #ifndef _sd_sentinel_
38 | # define _sd_sentinel_ __attribute__((sentinel))
39 | #endif
40 |
41 | #ifndef _sd_packed_
42 | # define _sd_packed_ __attribute__((packed))
43 | #endif
44 |
45 | #ifndef _sd_pure_
46 | # define _sd_pure_ __attribute__((pure))
47 | #endif
48 |
49 | #ifndef _SD_STRINGIFY
50 | # define _SD_XSTRINGIFY(x) #x
51 | # define _SD_STRINGIFY(x) _SD_XSTRINGIFY(x)
52 | #endif
53 |
54 | #ifndef _SD_BEGIN_DECLARATIONS
55 | # ifdef __cplusplus
56 | # define _SD_BEGIN_DECLARATIONS \
57 | extern "C" { \
58 | struct _sd_useless_struct_to_allow_trailing_semicolon_
59 | # else
60 | # define _SD_BEGIN_DECLARATIONS \
61 | struct _sd_useless_struct_to_allow_trailing_semicolon_
62 | # endif
63 | #endif
64 |
65 | #ifndef _SD_END_DECLARATIONS
66 | # ifdef __cplusplus
67 | # define _SD_END_DECLARATIONS \
68 | } \
69 | struct _sd_useless_cpp_struct_to_allow_trailing_semicolon_
70 | # else
71 | # define _SD_END_DECLARATIONS \
72 | struct _sd_useless_struct_to_allow_trailing_semicolon_
73 | # endif
74 | #endif
75 |
76 | #define _SD_DEFINE_POINTER_CLEANUP_FUNC(type, func) \
77 | static inline void func##p(type **p) { \
78 | if (*p) \
79 | func(*p); \
80 | } \
81 | struct _sd_useless_struct_to_allow_trailing_semicolon_
82 |
83 | #endif
84 |
--------------------------------------------------------------------------------
/src/alloc-util.c:
--------------------------------------------------------------------------------
1 | /***
2 | This file is part of systemd.
3 |
4 | Copyright 2010 Lennart Poettering
5 |
6 | systemd is free software; you can redistribute it and/or modify it
7 | under the terms of the GNU Lesser General Public License as published by
8 | the Free Software Foundation; either version 2.1 of the License, or
9 | (at your option) any later version.
10 |
11 | systemd is distributed in the hope that it will be useful, but
12 | WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | Lesser General Public License for more details.
15 |
16 | You should have received a copy of the GNU Lesser General Public License
17 | along with systemd; If not, see .
18 | ***/
19 |
20 | #include
21 |
22 | #include "alloc-util.h"
23 | #include "macro.h"
24 |
25 | void* memdup(const void *p, size_t l) {
26 | void *r;
27 |
28 | assert(p);
29 |
30 | r = malloc(l);
31 | if (!r)
32 | return NULL;
33 |
34 | memcpy(r, p, l);
35 | return r;
36 | }
37 |
38 | void* greedy_realloc(void **p, size_t *allocated, size_t need, size_t size) {
39 | size_t a, newalloc;
40 | void *q;
41 |
42 | assert(p);
43 | assert(allocated);
44 |
45 | if (*allocated >= need)
46 | return *p;
47 |
48 | newalloc = MAX(need * 2, 64u / size);
49 | a = newalloc * size;
50 |
51 | /* check for overflows */
52 | if (a < size * need)
53 | return NULL;
54 |
55 | q = realloc(*p, a);
56 | if (!q)
57 | return NULL;
58 |
59 | *p = q;
60 | *allocated = newalloc;
61 | return q;
62 | }
63 |
--------------------------------------------------------------------------------
/src/alloc-util.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | /***
4 | This file is part of systemd.
5 |
6 | Copyright 2010 Lennart Poettering
7 |
8 | systemd is free software; you can redistribute it and/or modify it
9 | under the terms of the GNU Lesser General Public License as published by
10 | the Free Software Foundation; either version 2.1 of the License, or
11 | (at your option) any later version.
12 |
13 | systemd is distributed in the hope that it will be useful, but
14 | WITHOUT ANY WARRANTY; without even the implied warranty of
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | Lesser General Public License for more details.
17 |
18 | You should have received a copy of the GNU Lesser General Public License
19 | along with systemd; If not, see .
20 | ***/
21 |
22 | #include
23 | #include
24 | #include
25 |
26 | #include "attributes.h"
27 |
28 | #define new(t, n) ((t*) malloc_multiply(sizeof(t), (n)))
29 |
30 | #define new0(t, n) ((t*) calloc((n), sizeof(t)))
31 |
32 | #define newa(t, n) ((t*) alloca(sizeof(t)*(n)))
33 |
34 | #define newa0(t, n) ((t*) alloca0(sizeof(t)*(n)))
35 |
36 | #define newdup(t, p, n) ((t*) memdup_multiply(p, sizeof(t), (n)))
37 |
38 | #define malloc0(n) (calloc(1, (n)))
39 |
40 | static inline void *mfree(void *memory) {
41 | free(memory);
42 | return NULL;
43 | }
44 |
45 | void* memdup(const void *p, size_t l) _alloc_(2);
46 |
47 | static inline void freep(void *p) {
48 | free(*(void**) p);
49 | }
50 |
51 | #define _cleanup_free_ _cleanup_(freep)
52 |
53 | _malloc_ _alloc_(1, 2) static inline void *malloc_multiply(size_t a, size_t b) {
54 | if (_unlikely_(b != 0 && a > ((size_t) -1) / b))
55 | return NULL;
56 |
57 | return malloc(a * b);
58 | }
59 |
60 | _alloc_(2, 3) static inline void *realloc_multiply(void *p, size_t a, size_t b) {
61 | if (_unlikely_(b != 0 && a > ((size_t) -1) / b))
62 | return NULL;
63 |
64 | return realloc(p, a * b);
65 | }
66 |
67 | _alloc_(2, 3) static inline void *memdup_multiply(const void *p, size_t a, size_t b) {
68 | if (_unlikely_(b != 0 && a > ((size_t) -1) / b))
69 | return NULL;
70 |
71 | return memdup(p, a * b);
72 | }
73 |
74 | void* greedy_realloc(void **p, size_t *allocated, size_t need, size_t size);
75 |
76 | #define GREEDY_REALLOC(array, allocated, need) \
77 | greedy_realloc((void**) &(array), &(allocated), (need), sizeof((array)[0]))
78 |
79 | #define alloca0(n) \
80 | ({ \
81 | char *_new_; \
82 | size_t _len_ = n; \
83 | _new_ = alloca(_len_); \
84 | (void *) memset(_new_, 0, _len_); \
85 | })
86 |
87 | /* It's not clear what alignment glibc/gcc alloca() guarantee, hence provide a guaranteed safe version */
88 | #define alloca_align(size, align) \
89 | ({ \
90 | void *_ptr_; \
91 | size_t _mask_ = (align) - 1; \
92 | _ptr_ = alloca((size) + _mask_); \
93 | (void*)(((uintptr_t)_ptr_ + _mask_) & ~_mask_); \
94 | })
95 |
96 | #define alloca0_align(size, align) \
97 | ({ \
98 | void *_new_; \
99 | size_t _size_ = (size); \
100 | _new_ = alloca_align(_size_, (align)); \
101 | (void*)memset(_new_, 0, _size_); \
102 | })
103 |
--------------------------------------------------------------------------------
/src/architecture.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | /***
4 | This file is part of systemd.
5 |
6 | Copyright 2014 Lennart Poettering
7 |
8 | systemd is free software; you can redistribute it and/or modify it
9 | under the terms of the GNU Lesser General Public License as published by
10 | the Free Software Foundation; either version 2.1 of the License, or
11 | (at your option) any later version.
12 |
13 | systemd is distributed in the hope that it will be useful, but
14 | WITHOUT ANY WARRANTY; without even the implied warranty of
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | Lesser General Public License for more details.
17 |
18 | You should have received a copy of the GNU Lesser General Public License
19 | along with systemd; If not, see .
20 | ***/
21 |
22 | #include
23 |
24 | #include "macro.h"
25 | #include "util.h"
26 |
27 | /* A cleaned up architecture definition. We don't want to get lost in
28 | * processor features, models, generations or even ABIs. Hence we
29 | * focus on general family, and distinguish word width and
30 | * endianness. */
31 |
32 | enum {
33 | ARCHITECTURE_X86 = 0,
34 | ARCHITECTURE_X86_64,
35 | ARCHITECTURE_PPC,
36 | ARCHITECTURE_PPC_LE,
37 | ARCHITECTURE_PPC64,
38 | ARCHITECTURE_PPC64_LE,
39 | ARCHITECTURE_IA64,
40 | ARCHITECTURE_PARISC,
41 | ARCHITECTURE_PARISC64,
42 | ARCHITECTURE_S390,
43 | ARCHITECTURE_S390X,
44 | ARCHITECTURE_SPARC,
45 | ARCHITECTURE_SPARC64,
46 | ARCHITECTURE_MIPS,
47 | ARCHITECTURE_MIPS_LE,
48 | ARCHITECTURE_MIPS64,
49 | ARCHITECTURE_MIPS64_LE,
50 | ARCHITECTURE_ALPHA,
51 | ARCHITECTURE_ARM,
52 | ARCHITECTURE_ARM_BE,
53 | ARCHITECTURE_ARM64,
54 | ARCHITECTURE_ARM64_BE,
55 | ARCHITECTURE_SH,
56 | ARCHITECTURE_SH64,
57 | ARCHITECTURE_M68K,
58 | ARCHITECTURE_TILEGX,
59 | ARCHITECTURE_CRIS,
60 | ARCHITECTURE_RISCV64,
61 | ARCHITECTURE_RISCV32,
62 | ARCHITECTURE_LOONGARCH,
63 | _ARCHITECTURE_MAX,
64 | _ARCHITECTURE_INVALID = -1
65 | };
66 |
67 | int uname_architecture(void);
68 |
69 | /*
70 | * LIB_ARCH_TUPLE should resolve to the local library path
71 | * architecture tuple systemd is built for, according to the Debian
72 | * tuple list:
73 | *
74 | * https://wiki.debian.org/Multiarch/Tuples
75 | *
76 | * This is used in library search paths that should understand
77 | * Debian's paths on all distributions.
78 | */
79 |
80 | #if defined(__x86_64__)
81 | # define native_architecture() ARCHITECTURE_X86_64
82 | # define LIB_ARCH_TUPLE "x86_64-linux-gnu"
83 | # define PROC_CPUINFO_MODEL "model name"
84 | #elif defined(__i386__)
85 | # define native_architecture() ARCHITECTURE_X86
86 | # define LIB_ARCH_TUPLE "i386-linux-gnu"
87 | # define PROC_CPUINFO_MODEL "model name"
88 | #elif defined(__powerpc64__)
89 | # if __BYTE_ORDER == __BIG_ENDIAN
90 | # define native_architecture() ARCHITECTURE_PPC64
91 | # define LIB_ARCH_TUPLE "ppc64-linux-gnu"
92 | # else
93 | # define native_architecture() ARCHITECTURE_PPC64_LE
94 | # define LIB_ARCH_TUPLE "powerpc64le-linux-gnu"
95 | # endif
96 | # define PROC_CPUINFO_MODEL "cpu"
97 | #elif defined(__powerpc__)
98 | # if __BYTE_ORDER == __BIG_ENDIAN
99 | # define native_architecture() ARCHITECTURE_PPC
100 | # define LIB_ARCH_TUPLE "powerpc-linux-gnu"
101 | # else
102 | # define native_architecture() ARCHITECTURE_PPC_LE
103 | # error "Missing LIB_ARCH_TUPLE for PPCLE"
104 | # endif
105 | # define PROC_CPUINFO_MODEL "cpu"
106 | #elif defined(__ia64__)
107 | # define native_architecture() ARCHITECTURE_IA64
108 | # define LIB_ARCH_TUPLE "ia64-linux-gnu"
109 | #elif defined(__hppa64__)
110 | # define native_architecture() ARCHITECTURE_PARISC64
111 | # error "Missing LIB_ARCH_TUPLE for HPPA64"
112 | # define PROC_CPUINFO_MODEL "cpu"
113 | #elif defined(__hppa__)
114 | # define native_architecture() ARCHITECTURE_PARISC
115 | # define LIB_ARCH_TUPLE "hppa‑linux‑gnu"
116 | # define PROC_CPUINFO_MODEL "cpu"
117 | #elif defined(__s390x__)
118 | # define native_architecture() ARCHITECTURE_S390X
119 | # define LIB_ARCH_TUPLE "s390x-linux-gnu"
120 | #elif defined(__s390__)
121 | # define native_architecture() ARCHITECTURE_S390
122 | # define LIB_ARCH_TUPLE "s390-linux-gnu"
123 | #elif defined(__sparc64__)
124 | # define native_architecture() ARCHITECTURE_SPARC64
125 | # define LIB_ARCH_TUPLE "sparc64-linux-gnu"
126 | # define PROC_CPUINFO_MODEL "cpu"
127 | #elif defined(__sparc__)
128 | # define native_architecture() ARCHITECTURE_SPARC
129 | # define LIB_ARCH_TUPLE "sparc-linux-gnu"
130 | # define PROC_CPUINFO_MODEL "cpu"
131 | #elif defined(__mips64__)
132 | # if __BYTE_ORDER == __BIG_ENDIAN
133 | # define native_architecture() ARCHITECTURE_MIPS64
134 | # error "Missing LIB_ARCH_TUPLE for MIPS64"
135 | # else
136 | # define native_architecture() ARCHITECTURE_MIPS64_LE
137 | # error "Missing LIB_ARCH_TUPLE for MIPS64_LE"
138 | # endif
139 | # define PROC_CPUINFO_MODEL "cpu model"
140 | #elif defined(__mips__)
141 | # if __BYTE_ORDER == __BIG_ENDIAN
142 | # define native_architecture() ARCHITECTURE_MIPS
143 | # define LIB_ARCH_TUPLE "mips-linux-gnu"
144 | # else
145 | # define native_architecture() ARCHITECTURE_MIPS_LE
146 | # define LIB_ARCH_TUPLE "mipsel-linux-gnu"
147 | # endif
148 | # define PROC_CPUINFO_MODEL "cpu model"
149 | #elif defined(__alpha__)
150 | # define native_architecture() ARCHITECTURE_ALPHA
151 | # define LIB_ARCH_TUPLE "alpha-linux-gnu"
152 | #elif defined(__riscv) && __riscv_xlen == 64
153 | # define native_architecture() ARCHITECTURE_RISCV64
154 | # define define LIB_ARCH_TUPLE "riscv64-linux-gnu"
155 | #elif defined(__riscv) && __riscv_xlen == 32
156 | # define native_architecture() ARCHITECTURE_RISCV32
157 | # define define LIB_ARCH_TUPLE "riscv32-linux-gnu"
158 | #elif defined(__loongarch__) && __loongarch_grlen == 64
159 | # define native_architecture() ARCHITECTURE_LOONGARCH
160 | # define define LIB_ARCH_TUPLE "loongarch64-linux-gnu"
161 | #elif defined(__aarch64__)
162 | # if __BYTE_ORDER == __BIG_ENDIAN
163 | # define native_architecture() ARCHITECTURE_ARM64_BE
164 | # define LIB_ARCH_TUPLE "aarch64_be-linux-gnu"
165 | # else
166 | # define native_architecture() ARCHITECTURE_ARM64
167 | # define LIB_ARCH_TUPLE "aarch64-linux-gnu"
168 | # endif
169 | #elif defined(__arm__)
170 | # if __BYTE_ORDER == __BIG_ENDIAN
171 | # define native_architecture() ARCHITECTURE_ARM_BE
172 | # if defined(__ARM_EABI__)
173 | # if defined(__ARM_PCS_VFP)
174 | # define LIB_ARCH_TUPLE "armeb-linux-gnueabihf"
175 | # else
176 | # define LIB_ARCH_TUPLE "armeb-linux-gnueabi"
177 | # endif
178 | # else
179 | # define LIB_ARCH_TUPLE "armeb-linux-gnu"
180 | # endif
181 | # else
182 | # define native_architecture() ARCHITECTURE_ARM
183 | # if defined(__ARM_EABI__)
184 | # if defined(__ARM_PCS_VFP)
185 | # define LIB_ARCH_TUPLE "arm-linux-gnueabihf"
186 | # else
187 | # define LIB_ARCH_TUPLE "arm-linux-gnueabi"
188 | # endif
189 | # else
190 | # define LIB_ARCH_TUPLE "arm-linux-gnu"
191 | # endif
192 | # endif
193 | # define PROC_CPUINFO_MODEL "model name"
194 | #elif defined(__sh64__)
195 | # define native_architecture() ARCHITECTURE_SH64
196 | # error "Missing LIB_ARCH_TUPLE for SH64"
197 | #elif defined(__sh__)
198 | # define native_architecture() ARCHITECTURE_SH
199 | # define LIB_ARCH_TUPLE "sh4-linux-gnu"
200 | #elif defined(__m68k__)
201 | # define native_architecture() ARCHITECTURE_M68K
202 | # define LIB_ARCH_TUPLE "m68k-linux-gnu"
203 | #elif defined(__tilegx__)
204 | # define native_architecture() ARCHITECTURE_TILEGX
205 | # error "Missing LIB_ARCH_TUPLE for TILEGX"
206 | #elif defined(__cris__)
207 | # define native_architecture() ARCHITECTURE_CRIS
208 | # error "Missing LIB_ARCH_TUPLE for CRIS"
209 | #else
210 | # error "Please register your architecture here!"
211 | #endif
212 |
213 | #ifndef PROC_CPUINFO_MODEL
214 | #warning "PROC_CPUINFO_MODEL not defined for your architecture"
215 | #define PROC_CPUINFO_MODEL "model name"
216 | #endif
217 |
218 | const char *architecture_to_string(int a) _const_;
219 | int architecture_from_string(const char *s) _pure_;
220 |
--------------------------------------------------------------------------------
/src/attributes.h:
--------------------------------------------------------------------------------
1 | #define _printf_(a,b) __attribute__ ((format (printf, a, b)))
2 | #define _alloc_(...) __attribute__ ((alloc_size(__VA_ARGS__)))
3 | #define _sentinel_ __attribute__ ((sentinel))
4 | #define _unused_ __attribute__ ((unused))
5 | #define _destructor_ __attribute__ ((destructor))
6 | #define _pure_ __attribute__ ((pure))
7 | #define _const_ __attribute__ ((const))
8 | #define _deprecated_ __attribute__ ((deprecated))
9 | #define _packed_ __attribute__ ((packed))
10 | #define _malloc_ __attribute__ ((malloc))
11 | #define _weak_ __attribute__ ((weak))
12 | #define _likely_(x) (__builtin_expect(!!(x),1))
13 | #define _unlikely_(x) (__builtin_expect(!!(x),0))
14 | #define _public_ __attribute__ ((visibility("default")))
15 | #define _hidden_ __attribute__ ((visibility("hidden")))
16 | #define _weakref_(x) __attribute__((weakref(#x)))
17 | #define _alignas_(x) __attribute__((aligned(__alignof(x))))
18 | #define _cleanup_(x) __attribute__((cleanup(x)))
19 |
20 | /* Define C11 thread_local attribute even on older gcc compiler
21 | * version */
22 | #ifndef thread_local
23 | /*
24 | * Don't break on glibc < 2.16 that doesn't define __STDC_NO_THREADS__
25 | * see http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53769
26 | */
27 | #if __STDC_VERSION__ >= 201112L && !(defined(__STDC_NO_THREADS__) || (defined(__GNU_LIBRARY__) && __GLIBC__ == 2 && __GLIBC_MINOR__ < 16))
28 | #define thread_local _Thread_local
29 | #else
30 | #define thread_local __thread
31 | #endif
32 | #endif
33 |
34 | /* Define C11 noreturn without and even on older gcc
35 | * compiler versions */
36 | #ifndef noreturn
37 | #if __STDC_VERSION__ >= 201112L
38 | #define noreturn _Noreturn
39 | #else
40 | #define noreturn __attribute__((noreturn))
41 | #endif
42 | #endif
43 |
--------------------------------------------------------------------------------
/src/bootchart.conf:
--------------------------------------------------------------------------------
1 | # This file is part of systemd.
2 | #
3 | # systemd is free software; you can redistribute it and/or modify it
4 | # under the terms of the GNU Lesser General Public License as published by
5 | # the Free Software Foundation; either version 2.1 of the License, or
6 | # (at your option) any later version.
7 | #
8 | # Entries in this file show the compile time defaults.
9 | # You can change settings by editing this file.
10 | # Defaults can be restored by simply deleting this file.
11 | #
12 | # See bootchart.conf(5) for details.
13 |
14 | [Bootchart]
15 | #Samples=500
16 | #Frequency=25.0
17 | #Relative=no
18 | #Filter=yes
19 | #Output=
20 | #Init=
21 | #PlotMemoryUsage=no
22 | #PlotEntropyGraph=no
23 | #ScaleX=100.0
24 | #ScaleY=20.0
25 | #ControlGroup=no
26 | #PerCPU=no
27 | #Cmdline=no
28 |
--------------------------------------------------------------------------------
/src/bootchart.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | /***
4 | This file is part of systemd.
5 |
6 | Copyright (C) 2009-2013 Intel Corporation
7 |
8 | Authors:
9 | Auke Kok
10 |
11 | systemd is free software; you can redistribute it and/or modify it
12 | under the terms of the GNU Lesser General Public License as published by
13 | the Free Software Foundation; either version 2.1 of the License, or
14 | (at your option) any later version.
15 |
16 | systemd is distributed in the hope that it will be useful, but
17 | WITHOUT ANY WARRANTY; without even the implied warranty of
18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 | Lesser General Public License for more details.
20 |
21 | You should have received a copy of the GNU Lesser General Public License
22 | along with systemd; If not, see .
23 | ***/
24 |
25 | #include
26 | #include
27 | #include
28 |
29 | #include "list.h"
30 |
31 | #define MAXCPUS 512
32 | #define MAXPIDS 4194304
33 |
34 | struct block_stat_struct {
35 | /* /proc/vmstat pgpgin & pgpgout */
36 | int bi;
37 | int bo;
38 | };
39 |
40 | /* per process, per sample data we will log */
41 | struct ps_sched_struct {
42 | /* /proc//schedstat fields 1 & 2 */
43 | double runtime;
44 | double waittime;
45 | int pss;
46 | struct list_sample_data *sampledata;
47 | struct ps_sched_struct *next;
48 | struct ps_sched_struct *prev;
49 | struct ps_sched_struct *cross; /* cross pointer */
50 | struct ps_struct *ps_new;
51 | };
52 |
53 | struct list_sample_data {
54 | double runtime[MAXCPUS];
55 | double waittime[MAXCPUS];
56 | double sampletime;
57 | int entropy_avail;
58 | struct block_stat_struct blockstat;
59 | LIST_FIELDS(struct list_sample_data, link); /* DLL */
60 | int counter;
61 | };
62 |
63 | /* process info */
64 | struct ps_struct {
65 | struct ps_struct *next_ps; /* SLL pointer */
66 | struct ps_struct *next_running; /* currently running */
67 | struct ps_struct *parent; /* ppid ref */
68 | struct ps_struct *children; /* children */
69 | struct ps_struct *next; /* siblings */
70 |
71 | /* must match - otherwise it's a new process with same PID */
72 | char name[256];
73 | int pid;
74 | int ppid;
75 | char *cgroup;
76 |
77 | /* cache fd's */
78 | int sched;
79 | int schedstat;
80 | FILE *smaps;
81 |
82 | /* used to garbage collect running process list*/
83 | bool still_running;
84 |
85 | /* pointers to first/last seen timestamps */
86 | struct ps_sched_struct *first;
87 | struct ps_sched_struct *last;
88 |
89 | /* records actual start time, may be way before bootchart runs */
90 | double starttime;
91 |
92 | /* record human readable total cpu time */
93 | double total;
94 |
95 | /* largest PSS size found */
96 | int pss_max;
97 |
98 | /* for drawing connection lines later */
99 | double pos_x;
100 | double pos_y;
101 |
102 | struct ps_sched_struct *sample;
103 | };
104 |
105 | extern bool arg_relative;
106 | extern bool arg_filter;
107 | extern bool arg_show_cmdline;
108 | extern bool arg_show_cgroup;
109 | extern bool arg_pss;
110 | extern bool arg_entropy;
111 | extern bool arg_percpu;
112 | extern bool arg_initcall;
113 | extern int arg_samples_len;
114 | extern double arg_hz;
115 | extern double arg_scale_x;
116 | extern double arg_scale_y;
117 |
118 | extern char arg_output_path[PATH_MAX];
119 | extern char arg_init_path[PATH_MAX];
120 |
--------------------------------------------------------------------------------
/src/build.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | /***
4 | This file is part of systemd.
5 |
6 | Copyright 2010 Lennart Poettering
7 |
8 | systemd is free software; you can redistribute it and/or modify it
9 | under the terms of the GNU Lesser General Public License as published by
10 | the Free Software Foundation; either version 2.1 of the License, or
11 | (at your option) any later version.
12 |
13 | systemd is distributed in the hope that it will be useful, but
14 | WITHOUT ANY WARRANTY; without even the implied warranty of
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | Lesser General Public License for more details.
17 |
18 | You should have received a copy of the GNU Lesser General Public License
19 | along with systemd; If not, see .
20 | ***/
21 |
22 | #ifdef HAVE_PAM
23 | #define _PAM_FEATURE_ "+PAM"
24 | #else
25 | #define _PAM_FEATURE_ "-PAM"
26 | #endif
27 |
28 | #ifdef HAVE_AUDIT
29 | #define _AUDIT_FEATURE_ "+AUDIT"
30 | #else
31 | #define _AUDIT_FEATURE_ "-AUDIT"
32 | #endif
33 |
34 | #ifdef HAVE_SELINUX
35 | #define _SELINUX_FEATURE_ "+SELINUX"
36 | #else
37 | #define _SELINUX_FEATURE_ "-SELINUX"
38 | #endif
39 |
40 | #ifdef HAVE_APPARMOR
41 | #define _APPARMOR_FEATURE_ "+APPARMOR"
42 | #else
43 | #define _APPARMOR_FEATURE_ "-APPARMOR"
44 | #endif
45 |
46 | #ifdef HAVE_IMA
47 | #define _IMA_FEATURE_ "+IMA"
48 | #else
49 | #define _IMA_FEATURE_ "-IMA"
50 | #endif
51 |
52 | #ifdef HAVE_SMACK
53 | #define _SMACK_FEATURE_ "+SMACK"
54 | #else
55 | #define _SMACK_FEATURE_ "-SMACK"
56 | #endif
57 |
58 | #ifdef HAVE_SYSV_COMPAT
59 | #define _SYSVINIT_FEATURE_ "+SYSVINIT"
60 | #else
61 | #define _SYSVINIT_FEATURE_ "-SYSVINIT"
62 | #endif
63 |
64 | #ifdef HAVE_UTMP
65 | #define _UTMP_FEATURE_ "+UTMP"
66 | #else
67 | #define _UTMP_FEATURE_ "-UTMP"
68 | #endif
69 |
70 | #ifdef HAVE_LIBCRYPTSETUP
71 | #define _LIBCRYPTSETUP_FEATURE_ "+LIBCRYPTSETUP"
72 | #else
73 | #define _LIBCRYPTSETUP_FEATURE_ "-LIBCRYPTSETUP"
74 | #endif
75 |
76 | #ifdef HAVE_GCRYPT
77 | #define _GCRYPT_FEATURE_ "+GCRYPT"
78 | #else
79 | #define _GCRYPT_FEATURE_ "-GCRYPT"
80 | #endif
81 |
82 | #ifdef HAVE_GNUTLS
83 | #define _GNUTLS_FEATURE_ "+GNUTLS"
84 | #else
85 | #define _GNUTLS_FEATURE_ "-GNUTLS"
86 | #endif
87 |
88 | #ifdef HAVE_ACL
89 | #define _ACL_FEATURE_ "+ACL"
90 | #else
91 | #define _ACL_FEATURE_ "-ACL"
92 | #endif
93 |
94 | #ifdef HAVE_XZ
95 | #define _XZ_FEATURE_ "+XZ"
96 | #else
97 | #define _XZ_FEATURE_ "-XZ"
98 | #endif
99 |
100 | #ifdef HAVE_LZ4
101 | #define _LZ4_FEATURE_ "+LZ4"
102 | #else
103 | #define _LZ4_FEATURE_ "-LZ4"
104 | #endif
105 |
106 | #ifdef HAVE_SECCOMP
107 | #define _SECCOMP_FEATURE_ "+SECCOMP"
108 | #else
109 | #define _SECCOMP_FEATURE_ "-SECCOMP"
110 | #endif
111 |
112 | #ifdef HAVE_BLKID
113 | #define _BLKID_FEATURE_ "+BLKID"
114 | #else
115 | #define _BLKID_FEATURE_ "-BLKID"
116 | #endif
117 |
118 | #ifdef HAVE_ELFUTILS
119 | #define _ELFUTILS_FEATURE_ "+ELFUTILS"
120 | #else
121 | #define _ELFUTILS_FEATURE_ "-ELFUTILS"
122 | #endif
123 |
124 | #ifdef HAVE_KMOD
125 | #define _KMOD_FEATURE_ "+KMOD"
126 | #else
127 | #define _KMOD_FEATURE_ "-KMOD"
128 | #endif
129 |
130 | #ifdef HAVE_LIBIDN
131 | #define _IDN_FEATURE_ "+IDN"
132 | #else
133 | #define _IDN_FEATURE_ "-IDN"
134 | #endif
135 |
136 | #define SYSTEMD_FEATURES \
137 | _PAM_FEATURE_ " " \
138 | _AUDIT_FEATURE_ " " \
139 | _SELINUX_FEATURE_ " " \
140 | _IMA_FEATURE_ " " \
141 | _APPARMOR_FEATURE_ " " \
142 | _SMACK_FEATURE_ " " \
143 | _SYSVINIT_FEATURE_ " " \
144 | _UTMP_FEATURE_ " " \
145 | _LIBCRYPTSETUP_FEATURE_ " " \
146 | _GCRYPT_FEATURE_ " " \
147 | _GNUTLS_FEATURE_ " " \
148 | _ACL_FEATURE_ " " \
149 | _XZ_FEATURE_ " " \
150 | _LZ4_FEATURE_ " " \
151 | _SECCOMP_FEATURE_ " " \
152 | _BLKID_FEATURE_ " " \
153 | _ELFUTILS_FEATURE_ " " \
154 | _KMOD_FEATURE_ " " \
155 | _IDN_FEATURE_
156 |
--------------------------------------------------------------------------------
/src/cgroup-util.c:
--------------------------------------------------------------------------------
1 | /***
2 | This file is part of systemd.
3 |
4 | Copyright 2010 Lennart Poettering
5 |
6 | systemd is free software; you can redistribute it and/or modify it
7 | under the terms of the GNU Lesser General Public License as published by
8 | the Free Software Foundation; either version 2.1 of the License, or
9 | (at your option) any later version.
10 |
11 | systemd is distributed in the hope that it will be useful, but
12 | WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | Lesser General Public License for more details.
15 |
16 | You should have received a copy of the GNU Lesser General Public License
17 | along with systemd; If not, see .
18 | ***/
19 |
20 | #include
21 | #include
22 | #include
23 | #include
24 | #include
25 | #include
26 |
27 | #include "attributes.h"
28 | #include "cgroup-util.h"
29 | #include "def.h"
30 | #include "fd-util.h"
31 | #include "fileio.h"
32 | #include "macro.h"
33 | #include "missing.h"
34 | #include "parse-util.h"
35 | #include "process-util.h"
36 | #include "string-util.h"
37 |
38 | #define F_TYPE_EQUAL(a, b) (a == (typeof(a)) b)
39 |
40 | int cg_pid_get_path(const char *controller, pid_t pid, char **path) {
41 | _cleanup_fclose_ FILE *f = NULL;
42 | char line[LINE_MAX];
43 | const char *fs;
44 | size_t cs = 0;
45 | int unified;
46 |
47 | assert(path);
48 | assert(pid >= 0);
49 |
50 | unified = cg_unified();
51 | if (unified < 0)
52 | return unified;
53 | if (unified == 0) {
54 | if (controller) {
55 | if (!cg_controller_is_valid(controller))
56 | return -EINVAL;
57 | } else
58 | controller = SYSTEMD_CGROUP_CONTROLLER;
59 |
60 | cs = strlen(controller);
61 | }
62 |
63 | fs = procfs_file_alloca(pid, "cgroup");
64 | f = fopen(fs, "re");
65 | if (!f)
66 | return errno == ENOENT ? -ESRCH : -errno;
67 |
68 | FOREACH_LINE(line, f, return -errno) {
69 | char *e, *p;
70 |
71 | truncate_nl(line);
72 |
73 | if (unified) {
74 | e = startswith(line, "0:");
75 | if (!e)
76 | continue;
77 |
78 | e = strchr(e, ':');
79 | if (!e)
80 | continue;
81 | } else {
82 | char *l;
83 | size_t k;
84 | const char *word, *state;
85 | bool found = false;
86 |
87 | l = strchr(line, ':');
88 | if (!l)
89 | continue;
90 |
91 | l++;
92 | e = strchr(l, ':');
93 | if (!e)
94 | continue;
95 |
96 | *e = 0;
97 | FOREACH_WORD_SEPARATOR(word, k, l, ",", state) {
98 | if (k == cs && memcmp(word, controller, cs) == 0) {
99 | found = true;
100 | break;
101 | }
102 | }
103 |
104 | if (!found)
105 | continue;
106 | }
107 |
108 | p = strdup(e + 1);
109 | if (!p)
110 | return -ENOMEM;
111 |
112 | *path = p;
113 | return 0;
114 | }
115 |
116 | return -ENODATA;
117 | }
118 |
119 | #define CONTROLLER_VALID \
120 | DIGITS LETTERS \
121 | "_"
122 |
123 | bool cg_controller_is_valid(const char *p) {
124 | const char *t, *s;
125 |
126 | if (!p)
127 | return false;
128 |
129 | s = startswith(p, "name=");
130 | if (s)
131 | p = s;
132 |
133 | if (*p == 0 || *p == '_')
134 | return false;
135 |
136 | for (t = p; *t; t++)
137 | if (!strchr(CONTROLLER_VALID, *t))
138 | return false;
139 |
140 | if (t - p > FILENAME_MAX)
141 | return false;
142 |
143 | return true;
144 | }
145 |
146 | static thread_local int unified_cache = -1;
147 |
148 | int cg_unified(void) {
149 | struct statfs fs;
150 |
151 | /* Checks if we support the unified hierarchy. Returns an
152 | * error when the cgroup hierarchies aren't mounted yet or we
153 | * have any other trouble determining if the unified hierarchy
154 | * is supported. */
155 |
156 | if (unified_cache >= 0)
157 | return unified_cache;
158 |
159 | if (statfs("/sys/fs/cgroup/", &fs) < 0)
160 | return -errno;
161 |
162 | if (F_TYPE_EQUAL(fs.f_type, CGROUP_SUPER_MAGIC))
163 | unified_cache = true;
164 | else if (F_TYPE_EQUAL(fs.f_type, TMPFS_MAGIC))
165 | unified_cache = false;
166 | else
167 | return -ENOMEDIUM;
168 |
169 | return unified_cache;
170 | }
171 |
172 | int cg_blkio_weight_parse(const char *s, uint64_t *ret) {
173 | uint64_t u;
174 | int r;
175 |
176 | if (isempty(s)) {
177 | *ret = CGROUP_BLKIO_WEIGHT_INVALID;
178 | return 0;
179 | }
180 |
181 | r = safe_atou64(s, &u);
182 | if (r < 0)
183 | return r;
184 |
185 | if (u < CGROUP_BLKIO_WEIGHT_MIN || u > CGROUP_BLKIO_WEIGHT_MAX)
186 | return -ERANGE;
187 |
188 | *ret = u;
189 | return 0;
190 | }
191 |
--------------------------------------------------------------------------------
/src/cgroup-util.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | /***
4 | This file is part of systemd.
5 |
6 | Copyright 2010 Lennart Poettering
7 |
8 | systemd is free software; you can redistribute it and/or modify it
9 | under the terms of the GNU Lesser General Public License as published by
10 | the Free Software Foundation; either version 2.1 of the License, or
11 | (at your option) any later version.
12 |
13 | systemd is distributed in the hope that it will be useful, but
14 | WITHOUT ANY WARRANTY; without even the implied warranty of
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | Lesser General Public License for more details.
17 |
18 | You should have received a copy of the GNU Lesser General Public License
19 | along with systemd; If not, see .
20 | ***/
21 |
22 | #include
23 | #include
24 | #include
25 |
26 | /* Special values for the cpu.shares attribute */
27 | #define CGROUP_CPU_SHARES_INVALID ((uint64_t) -1)
28 | #define CGROUP_CPU_SHARES_MIN UINT64_C(2)
29 | #define CGROUP_CPU_SHARES_MAX UINT64_C(262144)
30 | #define CGROUP_CPU_SHARES_DEFAULT UINT64_C(1024)
31 |
32 | static inline bool CGROUP_CPU_SHARES_IS_OK(uint64_t x) {
33 | return
34 | x == CGROUP_CPU_SHARES_INVALID ||
35 | (x >= CGROUP_CPU_SHARES_MIN && x <= CGROUP_CPU_SHARES_MAX);
36 | }
37 |
38 | /* Special values for the blkio.weight attribute */
39 | #define CGROUP_BLKIO_WEIGHT_INVALID ((uint64_t) -1)
40 | #define CGROUP_BLKIO_WEIGHT_MIN UINT64_C(10)
41 | #define CGROUP_BLKIO_WEIGHT_MAX UINT64_C(1000)
42 | #define CGROUP_BLKIO_WEIGHT_DEFAULT UINT64_C(500)
43 |
44 | static inline bool CGROUP_BLKIO_WEIGHT_IS_OK(uint64_t x) {
45 | return
46 | x == CGROUP_BLKIO_WEIGHT_INVALID ||
47 | (x >= CGROUP_BLKIO_WEIGHT_MIN && x <= CGROUP_BLKIO_WEIGHT_MAX);
48 | }
49 |
50 | /*
51 | * General rules:
52 | *
53 | * We accept named hierarchies in the syntax "foo" and "name=foo".
54 | *
55 | * We expect that named hierarchies do not conflict in name with a
56 | * kernel hierarchy, modulo the "name=" prefix.
57 | *
58 | * We always generate "normalized" controller names, i.e. without the
59 | * "name=" prefix.
60 | *
61 | * We require absolute cgroup paths. When returning, we will always
62 | * generate paths with multiple adjacent / removed.
63 | */
64 |
65 | int cg_migrate(const char *cfrom, const char *pfrom, const char *cto, const char *pto, bool ignore_self);
66 | int cg_migrate_recursive(const char *cfrom, const char *pfrom, const char *cto, const char *pto, bool ignore_self, bool remove);
67 | int cg_migrate_recursive_fallback(const char *cfrom, const char *pfrom, const char *cto, const char *pto, bool ignore_self, bool rem);
68 |
69 | int cg_pid_get_path(const char *controller, pid_t pid, char **path);
70 |
71 | int cg_pid_get_unit(pid_t pid, char **unit);
72 | int cg_pid_get_machine_name(pid_t pid, char **machine);
73 |
74 | bool cg_controller_is_valid(const char *p);
75 |
76 | int cg_slice_to_path(const char *unit, char **ret);
77 |
78 | int cg_unified(void);
79 |
80 | int cg_blkio_weight_parse(const char *s, uint64_t *ret);
81 |
--------------------------------------------------------------------------------
/src/conf-files.c:
--------------------------------------------------------------------------------
1 | /***
2 | This file is part of systemd.
3 |
4 | Copyright 2010 Lennart Poettering
5 |
6 | systemd is free software; you can redistribute it and/or modify it
7 | under the terms of the GNU Lesser General Public License as published by
8 | the Free Software Foundation; either version 2.1 of the License, or
9 | (at your option) any later version.
10 |
11 | systemd is distributed in the hope that it will be useful, but
12 | WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | Lesser General Public License for more details.
15 |
16 | You should have received a copy of the GNU Lesser General Public License
17 | along with systemd; If not, see .
18 | ***/
19 |
20 | #include
21 | #include
22 | #include
23 | #include
24 | #include
25 |
26 | #include "conf-files.h"
27 | #include "dirent-util.h"
28 | #include "fd-util.h"
29 | #include "hash-funcs.h"
30 | #include "hashmap.h"
31 | #include "log.h"
32 | #include "macro.h"
33 | #include "path-util.h"
34 | #include "string-util.h"
35 | #include "strv.h"
36 | #include "util.h"
37 |
38 | static int files_add(Hashmap *h, const char *root, const char *path, const char *suffix) {
39 | _cleanup_closedir_ DIR *dir = NULL;
40 | const char *dirpath;
41 | struct dirent *de;
42 | int r;
43 |
44 | assert(path);
45 | assert(suffix);
46 |
47 | dirpath = prefix_roota(root, path);
48 |
49 | dir = opendir(dirpath);
50 | if (!dir) {
51 | if (errno == ENOENT)
52 | return 0;
53 | return -errno;
54 | }
55 |
56 | FOREACH_DIRENT(de, dir, return -errno) {
57 | char *p;
58 |
59 | if (!dirent_is_file_with_suffix(de, suffix))
60 | continue;
61 |
62 | p = strjoin(dirpath, "/", de->d_name, NULL);
63 | if (!p)
64 | return -ENOMEM;
65 |
66 | r = hashmap_put(h, basename(p), p);
67 | if (r == -EEXIST) {
68 | log_debug("Skipping overridden file: %s.", p);
69 | free(p);
70 | } else if (r < 0) {
71 | free(p);
72 | return r;
73 | } else if (r == 0) {
74 | log_debug("Duplicate file %s", p);
75 | free(p);
76 | }
77 | }
78 |
79 | return 0;
80 | }
81 |
82 | static int base_cmp(const void *a, const void *b) {
83 | const char *s1, *s2;
84 |
85 | s1 = *(char * const *)a;
86 | s2 = *(char * const *)b;
87 | return strcmp(basename(s1), basename(s2));
88 | }
89 |
90 | static int conf_files_list_strv_internal(char ***strv, const char *suffix, const char *root, char **dirs) {
91 | _cleanup_hashmap_free_ Hashmap *fh = NULL;
92 | char **files, **p;
93 | int r;
94 |
95 | assert(strv);
96 | assert(suffix);
97 |
98 | /* This alters the dirs string array */
99 | if (!path_strv_resolve_uniq(dirs, root))
100 | return -ENOMEM;
101 |
102 | fh = hashmap_new(&string_hash_ops);
103 | if (!fh)
104 | return -ENOMEM;
105 |
106 | STRV_FOREACH(p, dirs) {
107 | r = files_add(fh, root, *p, suffix);
108 | if (r == -ENOMEM)
109 | return r;
110 | if (r < 0)
111 | log_debug_errno(r, "Failed to search for files in %s, ignoring: %m", *p);
112 | }
113 |
114 | files = hashmap_get_strv(fh);
115 | if (!files)
116 | return -ENOMEM;
117 |
118 | qsort_safe(files, hashmap_size(fh), sizeof(char *), base_cmp);
119 | *strv = files;
120 |
121 | return 0;
122 | }
123 |
124 | int conf_files_list_nulstr(char ***strv, const char *suffix, const char *root, const char *d) {
125 | _cleanup_strv_free_ char **dirs = NULL;
126 |
127 | assert(strv);
128 | assert(suffix);
129 |
130 | dirs = strv_split_nulstr(d);
131 | if (!dirs)
132 | return -ENOMEM;
133 |
134 | return conf_files_list_strv_internal(strv, suffix, root, dirs);
135 | }
136 |
--------------------------------------------------------------------------------
/src/conf-files.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | /***
4 | This file is part of systemd.
5 |
6 | Copyright 2010-2012 Lennart Poettering
7 | Copyright 2010-2012 Kay Sievers
8 |
9 | systemd is free software; you can redistribute it and/or modify it
10 | under the terms of the GNU Lesser General Public License as published by
11 | the Free Software Foundation; either version 2.1 of the License, or
12 | (at your option) any later version.
13 |
14 | systemd is distributed in the hope that it will be useful, but
15 | WITHOUT ANY WARRANTY; without even the implied warranty of
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | Lesser General Public License for more details.
18 |
19 | You should have received a copy of the GNU Lesser General Public License
20 | along with systemd; If not, see .
21 | ***/
22 |
23 | int conf_files_list_nulstr(char ***ret, const char *suffix, const char *root, const char *dirs);
24 |
--------------------------------------------------------------------------------
/src/def.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | /***
4 | This file is part of systemd.
5 |
6 | Copyright 2010 Lennart Poettering
7 |
8 | systemd is free software; you can redistribute it and/or modify it
9 | under the terms of the GNU Lesser General Public License as published by
10 | the Free Software Foundation; either version 2.1 of the License, or
11 | (at your option) any later version.
12 |
13 | systemd is distributed in the hope that it will be useful, but
14 | WITHOUT ANY WARRANTY; without even the implied warranty of
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | Lesser General Public License for more details.
17 |
18 | You should have received a copy of the GNU Lesser General Public License
19 | along with systemd; If not, see .
20 | ***/
21 |
22 | #include "util.h"
23 |
24 | #define DEFAULT_TIMEOUT_USEC (90*USEC_PER_SEC)
25 | #define DEFAULT_RESTART_USEC (100*USEC_PER_MSEC)
26 | #define DEFAULT_CONFIRM_USEC (30*USEC_PER_SEC)
27 |
28 | #define DEFAULT_START_LIMIT_INTERVAL (10*USEC_PER_SEC)
29 | #define DEFAULT_START_LIMIT_BURST 5
30 |
31 | /* The default time after which exit-on-idle services exit. This
32 | * should be kept lower than the watchdog timeout, because otherwise
33 | * the watchdog pings will keep the loop busy. */
34 | #define DEFAULT_EXIT_USEC (30*USEC_PER_SEC)
35 |
36 | /* The default value for the net.unix.max_dgram_qlen sysctl */
37 | #define DEFAULT_UNIX_MAX_DGRAM_QLEN 512UL
38 |
39 | #define SYSTEMD_CGROUP_CONTROLLER "name=systemd"
40 |
41 | #define SIGNALS_CRASH_HANDLER SIGSEGV,SIGILL,SIGFPE,SIGBUS,SIGQUIT,SIGABRT
42 | #define SIGNALS_IGNORE SIGPIPE
43 |
44 | #define REBOOT_PARAM_FILE "/run/systemd/reboot-param"
45 |
46 | #ifdef HAVE_SPLIT_USR
47 | #define KBD_KEYMAP_DIRS \
48 | "/usr/share/keymaps/\0" \
49 | "/usr/share/kbd/keymaps/\0" \
50 | "/usr/lib/kbd/keymaps/\0" \
51 | "/lib/kbd/keymaps/\0"
52 | #else
53 | #define KBD_KEYMAP_DIRS \
54 | "/usr/share/keymaps/\0" \
55 | "/usr/share/kbd/keymaps/\0" \
56 | "/usr/lib/kbd/keymaps/\0"
57 | #endif
58 |
59 | #define UNIX_SYSTEM_BUS_ADDRESS "unix:path=/var/run/dbus/system_bus_socket"
60 | #define KERNEL_SYSTEM_BUS_ADDRESS "kernel:path=/sys/fs/kdbus/0-system/bus"
61 | #define DEFAULT_SYSTEM_BUS_ADDRESS KERNEL_SYSTEM_BUS_ADDRESS ";" UNIX_SYSTEM_BUS_ADDRESS
62 | #define UNIX_USER_BUS_ADDRESS_FMT "unix:path=%s/bus"
63 | #define KERNEL_USER_BUS_ADDRESS_FMT "kernel:path=/sys/fs/kdbus/"UID_FMT"-user/bus"
64 |
65 | #ifndef TTY_GID
66 | #define TTY_GID 5
67 | #endif
68 |
69 | #define NOTIFY_FD_MAX 768
70 | #define NOTIFY_BUFFER_MAX PIPE_BUF
71 |
72 | #ifdef HAVE_SPLIT_USR
73 | #define _CONF_PATHS_SPLIT_USR(n) "/lib/" n "\0"
74 | #else
75 | #define _CONF_PATHS_SPLIT_USR(n)
76 | #endif
77 |
78 | /* Return a nulstr for a standard cascade of configuration paths,
79 | * suitable to pass to conf_files_list_nulstr() or config_parse_many()
80 | * to implement drop-in directories for extending configuration
81 | * files. */
82 | #define CONF_PATHS_NULSTR(n) \
83 | "/etc/" n "\0" \
84 | "/run/" n "\0" \
85 | "/usr/local/lib/" n "\0" \
86 | "/usr/lib/" n "\0" \
87 | _CONF_PATHS_SPLIT_USR(n)
88 |
--------------------------------------------------------------------------------
/src/dirent-util.c:
--------------------------------------------------------------------------------
1 | /***
2 | This file is part of systemd.
3 |
4 | Copyright 2010-2012 Lennart Poettering
5 |
6 | systemd is free software; you can redistribute it and/or modify it
7 | under the terms of the GNU Lesser General Public License as published by
8 | the Free Software Foundation; either version 2.1 of the License, or
9 | (at your option) any later version.
10 |
11 | systemd is distributed in the hope that it will be useful, but
12 | WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | Lesser General Public License for more details.
15 |
16 | You should have received a copy of the GNU Lesser General Public License
17 | along with systemd; If not, see .
18 | ***/
19 |
20 | #include "dirent-util.h"
21 | #include "macro.h"
22 | #include "string-util.h"
23 |
24 | bool dirent_is_file_with_suffix(const struct dirent *de, const char *suffix) {
25 | assert(de);
26 |
27 | if (de->d_type != DT_REG &&
28 | de->d_type != DT_LNK &&
29 | de->d_type != DT_UNKNOWN)
30 | return false;
31 |
32 | return endswith(de->d_name, suffix);
33 | }
34 |
--------------------------------------------------------------------------------
/src/dirent-util.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | /***
4 | This file is part of systemd.
5 |
6 | Copyright 2010 Lennart Poettering
7 |
8 | systemd is free software; you can redistribute it and/or modify it
9 | under the terms of the GNU Lesser General Public License as published by
10 | the Free Software Foundation; either version 2.1 of the License, or
11 | (at your option) any later version.
12 |
13 | systemd is distributed in the hope that it will be useful, but
14 | WITHOUT ANY WARRANTY; without even the implied warranty of
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | Lesser General Public License for more details.
17 |
18 | You should have received a copy of the GNU Lesser General Public License
19 | along with systemd; If not, see .
20 | ***/
21 |
22 | #include
23 | #include
24 | #include
25 |
26 | #include "attributes.h"
27 |
28 | bool dirent_is_file_with_suffix(const struct dirent *de, const char *suffix) _pure_;
29 |
30 | #define FOREACH_DIRENT(de, d, on_error) \
31 | for (errno = 0, de = readdir(d);; errno = 0, de = readdir(d)) \
32 | if (!de) { \
33 | if (errno > 0) { \
34 | on_error; \
35 | } \
36 | break; \
37 | } else
38 |
--------------------------------------------------------------------------------
/src/fd-util.c:
--------------------------------------------------------------------------------
1 | /***
2 | This file is part of systemd.
3 |
4 | Copyright 2010 Lennart Poettering
5 |
6 | systemd is free software; you can redistribute it and/or modify it
7 | under the terms of the GNU Lesser General Public License as published by
8 | the Free Software Foundation; either version 2.1 of the License, or
9 | (at your option) any later version.
10 |
11 | systemd is distributed in the hope that it will be useful, but
12 | WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | Lesser General Public License for more details.
15 |
16 | You should have received a copy of the GNU Lesser General Public License
17 | along with systemd; If not, see .
18 | ***/
19 |
20 | #include
21 | #include
22 |
23 | #include "fd-util.h"
24 | #include "macro.h"
25 | #include "util.h"
26 |
27 | int close_nointr(int fd) {
28 | assert(fd >= 0);
29 |
30 | if (close(fd) >= 0)
31 | return 0;
32 |
33 | /*
34 | * Just ignore EINTR; a retry loop is the wrong thing to do on
35 | * Linux.
36 | *
37 | * http://lkml.indiana.edu/hypermail/linux/kernel/0509.1/0877.html
38 | * https://bugzilla.gnome.org/show_bug.cgi?id=682819
39 | * http://utcc.utoronto.ca/~cks/space/blog/unix/CloseEINTR
40 | * https://sites.google.com/site/michaelsafyan/software-engineering/checkforeintrwheninvokingclosethinkagain
41 | */
42 | if (errno == EINTR)
43 | return 0;
44 |
45 | return -errno;
46 | }
47 |
48 | int safe_close(int fd) {
49 |
50 | /*
51 | * Like close_nointr() but cannot fail. Guarantees errno is
52 | * unchanged. Is a NOP with negative fds passed, and returns
53 | * -1, so that it can be used in this syntax:
54 | *
55 | * fd = safe_close(fd);
56 | */
57 |
58 | if (fd >= 0) {
59 | PROTECT_ERRNO;
60 |
61 | /* The kernel might return pretty much any error code
62 | * via close(), but the fd will be closed anyway. The
63 | * only condition we want to check for here is whether
64 | * the fd was invalid at all... */
65 |
66 | assert_se(close_nointr(fd) != -EBADF);
67 | }
68 |
69 | return -1;
70 | }
71 |
72 | int fclose_nointr(FILE *f) {
73 | assert(f);
74 |
75 | /* Same as close_nointr(), but for fclose() */
76 |
77 | if (fclose(f) == 0)
78 | return 0;
79 |
80 | if (errno == EINTR)
81 | return 0;
82 |
83 | return -errno;
84 | }
85 |
86 | FILE* safe_fclose(FILE *f) {
87 |
88 | /* Same as safe_close(), but for fclose() */
89 |
90 | if (f) {
91 | PROTECT_ERRNO;
92 |
93 | assert_se(fclose_nointr(f) != EBADF);
94 | }
95 |
96 | return NULL;
97 | }
98 |
99 | DIR* safe_closedir(DIR *d) {
100 |
101 | if (d) {
102 | PROTECT_ERRNO;
103 |
104 | assert_se(closedir(d) >= 0 || errno != EBADF);
105 | }
106 |
107 | return NULL;
108 | }
109 |
--------------------------------------------------------------------------------
/src/fd-util.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | /***
4 | This file is part of systemd.
5 |
6 | Copyright 2010 Lennart Poettering
7 |
8 | systemd is free software; you can redistribute it and/or modify it
9 | under the terms of the GNU Lesser General Public License as published by
10 | the Free Software Foundation; either version 2.1 of the License, or
11 | (at your option) any later version.
12 |
13 | systemd is distributed in the hope that it will be useful, but
14 | WITHOUT ANY WARRANTY; without even the implied warranty of
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | Lesser General Public License for more details.
17 |
18 | You should have received a copy of the GNU Lesser General Public License
19 | along with systemd; If not, see .
20 | ***/
21 |
22 | #include
23 | #include
24 | #include
25 |
26 | #include "attributes.h"
27 | #include "macro.h"
28 |
29 | /* Make sure we can distinguish fd 0 and NULL */
30 | #define FD_TO_PTR(fd) INT_TO_PTR((fd)+1)
31 | #define PTR_TO_FD(p) (PTR_TO_INT(p)-1)
32 |
33 | int close_nointr(int fd);
34 | int safe_close(int fd);
35 |
36 | int fclose_nointr(FILE *f);
37 | FILE* safe_fclose(FILE *f);
38 | DIR* safe_closedir(DIR *f);
39 |
40 | static inline void closep(int *fd) {
41 | safe_close(*fd);
42 | }
43 |
44 | static inline void fclosep(FILE **f) {
45 | safe_fclose(*f);
46 | }
47 |
48 | DEFINE_TRIVIAL_CLEANUP_FUNC(FILE*, pclose);
49 | DEFINE_TRIVIAL_CLEANUP_FUNC(DIR*, closedir);
50 |
51 | #define _cleanup_close_ _cleanup_(closep)
52 | #define _cleanup_fclose_ _cleanup_(fclosep)
53 | #define _cleanup_pclose_ _cleanup_(pclosep)
54 | #define _cleanup_closedir_ _cleanup_(closedirp)
55 |
56 | /* Hint: ENETUNREACH happens if we try to connect to "non-existing" special IP addresses, such as ::5 */
57 | #define ERRNO_IS_DISCONNECT(r) \
58 | IN_SET(r, ENOTCONN, ECONNRESET, ECONNREFUSED, ECONNABORTED, EPIPE, ENETUNREACH)
59 |
--------------------------------------------------------------------------------
/src/fileio.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | /***
4 | This file is part of systemd.
5 |
6 | Copyright 2010 Lennart Poettering
7 |
8 | systemd is free software; you can redistribute it and/or modify it
9 | under the terms of the GNU Lesser General Public License as published by
10 | the Free Software Foundation; either version 2.1 of the License, or
11 | (at your option) any later version.
12 |
13 | systemd is distributed in the hope that it will be useful, but
14 | WITHOUT ANY WARRANTY; without even the implied warranty of
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | Lesser General Public License for more details.
17 |
18 | You should have received a copy of the GNU Lesser General Public License
19 | along with systemd; If not, see .
20 | ***/
21 |
22 | #include
23 | #include
24 |
25 | #include "attributes.h"
26 |
27 | typedef enum {
28 | WRITE_STRING_FILE_CREATE = 1,
29 | WRITE_STRING_FILE_ATOMIC = 2,
30 | WRITE_STRING_FILE_AVOID_NEWLINE = 4,
31 | WRITE_STRING_FILE_VERIFY_ON_FAILURE = 8,
32 | } WriteStringFileFlags;
33 |
34 | int read_one_line_file(const char *fn, char **line);
35 | int read_full_file(const char *fn, char **contents, size_t *size);
36 | int read_full_stream(FILE *f, char **contents, size_t *size);
37 |
38 | int parse_env_file(const char *fname, const char *separator, ...) _sentinel_;
39 |
40 | int get_proc_field(const char *filename, const char *pattern, const char *terminator, char **field);
41 |
42 | #define FOREACH_LINE(line, f, on_error) \
43 | for (;;) \
44 | if (!fgets(line, sizeof(line), f)) { \
45 | if (ferror(f)) { \
46 | on_error; \
47 | } \
48 | break; \
49 | } else
50 |
--------------------------------------------------------------------------------
/src/formats-util.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | /***
4 | This file is part of systemd.
5 |
6 | Copyright 2015 Ronny Chevalier
7 |
8 | systemd is free software; you can redistribute it and/or modify it
9 | under the terms of the GNU Lesser General Public License as published by
10 | the Free Software Foundation; either version 2.1 of the License, or
11 | (at your option) any later version.
12 |
13 | systemd is distributed in the hope that it will be useful, but
14 | WITHOUT ANY WARRANTY; without even the implied warranty of
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | Lesser General Public License for more details.
17 |
18 | You should have received a copy of the GNU Lesser General Public License
19 | along with systemd; If not, see .
20 | ***/
21 |
22 | #include
23 |
24 | #if SIZEOF_PID_T == 4
25 | # define PID_PRI PRIi32
26 | #elif SIZEOF_PID_T == 2
27 | # define PID_PRI PRIi16
28 | #else
29 | # error Unknown pid_t size
30 | #endif
31 | #define PID_FMT "%" PID_PRI
32 |
33 | #if SIZEOF_UID_T == 4
34 | # define UID_FMT "%" PRIu32
35 | #elif SIZEOF_UID_T == 2
36 | # define UID_FMT "%" PRIu16
37 | #else
38 | # error Unknown uid_t size
39 | #endif
40 |
41 | #if SIZEOF_GID_T == 4
42 | # define GID_FMT "%" PRIu32
43 | #elif SIZEOF_GID_T == 2
44 | # define GID_FMT "%" PRIu16
45 | #else
46 | # error Unknown gid_t size
47 | #endif
48 |
49 | #if SIZEOF_TIME_T == 8
50 | # define PRI_TIME PRIi64
51 | #elif SIZEOF_TIME_T == 4
52 | # define PRI_TIME PRIu32
53 | #else
54 | # error Unknown time_t size
55 | #endif
56 |
57 | #if SIZEOF_RLIM_T == 8
58 | # define RLIM_FMT "%" PRIu64
59 | #elif SIZEOF_RLIM_T == 4
60 | # define RLIM_FMT "%" PRIu32
61 | #else
62 | # error Unknown rlim_t size
63 | #endif
64 |
--------------------------------------------------------------------------------
/src/fs-util.c:
--------------------------------------------------------------------------------
1 | /***
2 | This file is part of systemd.
3 |
4 | Copyright 2010 Lennart Poettering
5 |
6 | systemd is free software; you can redistribute it and/or modify it
7 | under the terms of the GNU Lesser General Public License as published by
8 | the Free Software Foundation; either version 2.1 of the License, or
9 | (at your option) any later version.
10 |
11 | systemd is distributed in the hope that it will be useful, but
12 | WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | Lesser General Public License for more details.
15 |
16 | You should have received a copy of the GNU Lesser General Public License
17 | along with systemd; If not, see .
18 | ***/
19 |
20 | #include
21 | #include
22 | #include
23 |
24 | #include "fs-util.h"
25 | #include "log.h"
26 |
27 | int fd_warn_permissions(const char *path, int fd) {
28 | struct stat st;
29 |
30 | if (fstat(fd, &st) < 0)
31 | return -errno;
32 |
33 | if (st.st_mode & 0111)
34 | log_warning("Configuration file %s is marked executable. Please remove executable permission bits. Proceeding anyway.", path);
35 |
36 | if (st.st_mode & 0002)
37 | log_warning("Configuration file %s is marked world-writable. Please remove world writability permission bits. Proceeding anyway.", path);
38 |
39 | if (getpid() == 1 && (st.st_mode & 0044) != 0044)
40 | log_warning("Configuration file %s is marked world-inaccessible. This has no effect as configuration data is accessible via APIs without restrictions. Proceeding anyway.", path);
41 |
42 | return 0;
43 | }
44 |
--------------------------------------------------------------------------------
/src/fs-util.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | /***
4 | This file is part of systemd.
5 |
6 | Copyright 2010 Lennart Poettering
7 |
8 | systemd is free software; you can redistribute it and/or modify it
9 | under the terms of the GNU Lesser General Public License as published by
10 | the Free Software Foundation; either version 2.1 of the License, or
11 | (at your option) any later version.
12 |
13 | systemd is distributed in the hope that it will be useful, but
14 | WITHOUT ANY WARRANTY; without even the implied warranty of
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | Lesser General Public License for more details.
17 |
18 | You should have received a copy of the GNU Lesser General Public License
19 | along with systemd; If not, see .
20 | ***/
21 |
22 | #include
23 | #include
24 | #include
25 | #include
26 |
27 | int fd_warn_permissions(const char *path, int fd);
28 |
29 | #define laccess(path, mode) faccessat(AT_FDCWD, (path), (mode), AT_SYMLINK_NOFOLLOW)
30 |
31 | #define INOTIFY_EVENT_MAX (sizeof(struct inotify_event) + NAME_MAX + 1)
32 |
33 | #define FOREACH_INOTIFY_EVENT(e, buffer, sz) \
34 | for ((e) = &buffer.ev; \
35 | (uint8_t*) (e) < (uint8_t*) (buffer.raw) + (sz); \
36 | (e) = (struct inotify_event*) ((uint8_t*) (e) + sizeof(struct inotify_event) + (e)->len))
37 |
38 | union inotify_event_buffer {
39 | struct inotify_event ev;
40 | uint8_t raw[INOTIFY_EVENT_MAX];
41 | };
42 |
--------------------------------------------------------------------------------
/src/hash-funcs.c:
--------------------------------------------------------------------------------
1 | /***
2 | This file is part of systemd.
3 |
4 | Copyright 2010 Lennart Poettering
5 | Copyright 2014 Michal Schmidt
6 |
7 | systemd is free software; you can redistribute it and/or modify it
8 | under the terms of the GNU Lesser General Public License as published by
9 | the Free Software Foundation; either version 2.1 of the License, or
10 | (at your option) any later version.
11 |
12 | systemd is distributed in the hope that it will be useful, but
13 | WITHOUT ANY WARRANTY; without even the implied warranty of
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 | Lesser General Public License for more details.
16 |
17 | You should have received a copy of the GNU Lesser General Public License
18 | along with systemd; If not, see .
19 | ***/
20 |
21 | #include
22 | #include
23 |
24 | #include "hash-funcs.h"
25 |
26 | void string_hash_func(const void *p, struct siphash *state) {
27 | siphash24_compress(p, strlen(p) + 1, state);
28 | }
29 |
30 | int string_compare_func(const void *a, const void *b) {
31 | return strcmp(a, b);
32 | }
33 |
34 | const struct hash_ops string_hash_ops = {
35 | .hash = string_hash_func,
36 | .compare = string_compare_func
37 | };
38 |
39 | void trivial_hash_func(const void *p, struct siphash *state) {
40 | siphash24_compress(&p, sizeof(p), state);
41 | }
42 |
43 | int trivial_compare_func(const void *a, const void *b) {
44 | return a < b ? -1 : (a > b ? 1 : 0);
45 | }
46 |
47 | const struct hash_ops trivial_hash_ops = {
48 | .hash = trivial_hash_func,
49 | .compare = trivial_compare_func
50 | };
51 |
52 | void uint64_hash_func(const void *p, struct siphash *state) {
53 | siphash24_compress(p, sizeof(uint64_t), state);
54 | }
55 |
56 | int uint64_compare_func(const void *_a, const void *_b) {
57 | uint64_t a, b;
58 | a = *(const uint64_t*) _a;
59 | b = *(const uint64_t*) _b;
60 | return a < b ? -1 : (a > b ? 1 : 0);
61 | }
62 |
63 | const struct hash_ops uint64_hash_ops = {
64 | .hash = uint64_hash_func,
65 | .compare = uint64_compare_func
66 | };
67 |
68 | #if SIZEOF_DEV_T != 8
69 | void devt_hash_func(const void *p, struct siphash *state) {
70 | siphash24_compress(p, sizeof(dev_t), state);
71 | }
72 |
73 | int devt_compare_func(const void *_a, const void *_b) {
74 | dev_t a, b;
75 | a = *(const dev_t*) _a;
76 | b = *(const dev_t*) _b;
77 | return a < b ? -1 : (a > b ? 1 : 0);
78 | }
79 |
80 | const struct hash_ops devt_hash_ops = {
81 | .hash = devt_hash_func,
82 | .compare = devt_compare_func
83 | };
84 | #endif
85 |
--------------------------------------------------------------------------------
/src/hash-funcs.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | /***
4 | This file is part of systemd.
5 |
6 | Copyright 2010 Lennart Poettering
7 | Copyright 2014 Michal Schmidt
8 |
9 | systemd is free software; you can redistribute it and/or modify it
10 | under the terms of the GNU Lesser General Public License as published by
11 | the Free Software Foundation; either version 2.1 of the License, or
12 | (at your option) any later version.
13 |
14 | systemd is distributed in the hope that it will be useful, but
15 | WITHOUT ANY WARRANTY; without even the implied warranty of
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | Lesser General Public License for more details.
18 |
19 | You should have received a copy of the GNU Lesser General Public License
20 | along with systemd; If not, see .
21 | ***/
22 |
23 | #include "attributes.h"
24 | #include "siphash24.h"
25 |
26 | typedef void (*hash_func_t)(const void *p, struct siphash *state);
27 | typedef int (*compare_func_t)(const void *a, const void *b);
28 |
29 | struct hash_ops {
30 | hash_func_t hash;
31 | compare_func_t compare;
32 | };
33 |
34 | void string_hash_func(const void *p, struct siphash *state);
35 | int string_compare_func(const void *a, const void *b) _pure_;
36 | extern const struct hash_ops string_hash_ops;
37 |
38 | /* This will compare the passed pointers directly, and will not
39 | * dereference them. This is hence not useful for strings or
40 | * suchlike. */
41 | void trivial_hash_func(const void *p, struct siphash *state);
42 | int trivial_compare_func(const void *a, const void *b) _const_;
43 | extern const struct hash_ops trivial_hash_ops;
44 |
45 | /* 32bit values we can always just embed in the pointer itself, but
46 | * in order to support 32bit archs we need store 64bit values
47 | * indirectly, since they don't fit in a pointer. */
48 | void uint64_hash_func(const void *p, struct siphash *state);
49 | int uint64_compare_func(const void *a, const void *b) _pure_;
50 | extern const struct hash_ops uint64_hash_ops;
51 |
52 | /* On some archs dev_t is 32bit, and on others 64bit. And sometimes
53 | * it's 64bit on 32bit archs, and sometimes 32bit on 64bit archs. Yuck! */
54 | #if SIZEOF_DEV_T != 8
55 | void devt_hash_func(const void *p, struct siphash *state) _pure_;
56 | int devt_compare_func(const void *a, const void *b) _pure_;
57 | extern const struct hash_ops devt_hash_ops = {
58 | .hash = devt_hash_func,
59 | .compare = devt_compare_func
60 | };
61 | #else
62 | #define devt_hash_func uint64_hash_func
63 | #define devt_compare_func uint64_compare_func
64 | #define devt_hash_ops uint64_hash_ops
65 | #endif
66 |
--------------------------------------------------------------------------------
/src/io-util.c:
--------------------------------------------------------------------------------
1 | /***
2 | This file is part of systemd.
3 |
4 | Copyright 2010 Lennart Poettering
5 |
6 | systemd is free software; you can redistribute it and/or modify it
7 | under the terms of the GNU Lesser General Public License as published by
8 | the Free Software Foundation; either version 2.1 of the License, or
9 | (at your option) any later version.
10 |
11 | systemd is distributed in the hope that it will be useful, but
12 | WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | Lesser General Public License for more details.
15 |
16 | You should have received a copy of the GNU Lesser General Public License
17 | along with systemd; If not, see .
18 | ***/
19 |
20 | #include
21 | #include
22 | #include
23 | #include
24 | #include
25 |
26 | #include "io-util.h"
27 | #include "time-util.h"
28 |
29 | ssize_t loop_read(int fd, void *buf, size_t nbytes, bool do_poll) {
30 | uint8_t *p = buf;
31 | ssize_t n = 0;
32 |
33 | assert(fd >= 0);
34 | assert(buf);
35 |
36 | /* If called with nbytes == 0, let's call read() at least
37 | * once, to validate the operation */
38 |
39 | if (nbytes > (size_t) SSIZE_MAX)
40 | return -EINVAL;
41 |
42 | do {
43 | ssize_t k;
44 |
45 | k = read(fd, p, nbytes);
46 | if (k < 0) {
47 | if (errno == EINTR)
48 | continue;
49 |
50 | if (errno == EAGAIN && do_poll) {
51 |
52 | /* We knowingly ignore any return value here,
53 | * and expect that any error/EOF is reported
54 | * via read() */
55 |
56 | (void) fd_wait_for_event(fd, POLLIN, USEC_INFINITY);
57 | continue;
58 | }
59 |
60 | return n > 0 ? n : -errno;
61 | }
62 |
63 | if (k == 0)
64 | return n;
65 |
66 | assert((size_t) k <= nbytes);
67 |
68 | p += k;
69 | nbytes -= k;
70 | n += k;
71 | } while (nbytes > 0);
72 |
73 | return n;
74 | }
75 |
76 | int loop_read_exact(int fd, void *buf, size_t nbytes, bool do_poll) {
77 | ssize_t n;
78 |
79 | n = loop_read(fd, buf, nbytes, do_poll);
80 | if (n < 0)
81 | return (int) n;
82 | if ((size_t) n != nbytes)
83 | return -EIO;
84 |
85 | return 0;
86 | }
87 |
88 | int fd_wait_for_event(int fd, int event, usec_t t) {
89 |
90 | struct pollfd pollfd = {
91 | .fd = fd,
92 | .events = event,
93 | };
94 |
95 | struct timespec ts;
96 | int r;
97 |
98 | r = ppoll(&pollfd, 1, t == USEC_INFINITY ? NULL : timespec_store(&ts, t), NULL);
99 | if (r < 0)
100 | return -errno;
101 |
102 | if (r == 0)
103 | return 0;
104 |
105 | return pollfd.revents;
106 | }
107 |
--------------------------------------------------------------------------------
/src/io-util.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | /***
4 | This file is part of systemd.
5 |
6 | Copyright 2010 Lennart Poettering
7 |
8 | systemd is free software; you can redistribute it and/or modify it
9 | under the terms of the GNU Lesser General Public License as published by
10 | the Free Software Foundation; either version 2.1 of the License, or
11 | (at your option) any later version.
12 |
13 | systemd is distributed in the hope that it will be useful, but
14 | WITHOUT ANY WARRANTY; without even the implied warranty of
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | Lesser General Public License for more details.
17 |
18 | You should have received a copy of the GNU Lesser General Public License
19 | along with systemd; If not, see .
20 | ***/
21 |
22 | #include
23 | #include
24 | #include
25 | #include
26 | #include
27 |
28 | #include "attributes.h"
29 | #include "macro.h"
30 | #include "time-util.h"
31 |
32 | ssize_t loop_read(int fd, void *buf, size_t nbytes, bool do_poll);
33 | int loop_read_exact(int fd, void *buf, size_t nbytes, bool do_poll);
34 |
35 | int fd_wait_for_event(int fd, int event, usec_t timeout);
36 |
37 | #define IOVEC_SET_STRING(i, s) \
38 | do { \
39 | struct iovec *_i = &(i); \
40 | char *_s = (char *)(s); \
41 | _i->iov_base = _s; \
42 | _i->iov_len = strlen(_s); \
43 | } while(false)
44 |
45 | static inline size_t IOVEC_TOTAL_SIZE(const struct iovec *i, unsigned n) {
46 | unsigned j;
47 | size_t r = 0;
48 |
49 | for (j = 0; j < n; j++)
50 | r += i[j].iov_len;
51 |
52 | return r;
53 | }
54 |
55 | static inline size_t IOVEC_INCREMENT(struct iovec *i, unsigned n, size_t k) {
56 | unsigned j;
57 |
58 | for (j = 0; j < n; j++) {
59 | size_t sub;
60 |
61 | if (_unlikely_(k <= 0))
62 | break;
63 |
64 | sub = MIN(i[j].iov_len, k);
65 | i[j].iov_len -= sub;
66 | i[j].iov_base = (uint8_t*) i[j].iov_base + sub;
67 | k -= sub;
68 | }
69 |
70 | return k;
71 | }
72 |
73 | static inline bool FILE_SIZE_VALID(uint64_t l) {
74 | /* ftruncate() and friends take an unsigned file size, but actually cannot deal with file sizes larger than
75 | * 2^63 since the kernel internally handles it as signed value. This call allows checking for this early. */
76 |
77 | return (l >> 63) == 0;
78 | }
79 |
80 | static inline bool FILE_SIZE_VALID_OR_INFINITY(uint64_t l) {
81 |
82 | /* Same as above, but allows one extra value: -1 as indication for infinity. */
83 |
84 | if (l == (uint64_t) -1)
85 | return true;
86 |
87 | return FILE_SIZE_VALID(l);
88 |
89 | }
90 |
--------------------------------------------------------------------------------
/src/log.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | /***
4 | This file is part of systemd.
5 |
6 | Copyright 2010 Lennart Poettering
7 |
8 | systemd is free software; you can redistribute it and/or modify it
9 | under the terms of the GNU Lesser General Public License as published by
10 | the Free Software Foundation; either version 2.1 of the License, or
11 | (at your option) any later version.
12 |
13 | systemd is distributed in the hope that it will be useful, but
14 | WITHOUT ANY WARRANTY; without even the implied warranty of
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | Lesser General Public License for more details.
17 |
18 | You should have received a copy of the GNU Lesser General Public License
19 | along with systemd; If not, see .
20 | ***/
21 |
22 | #include
23 | #include
24 | #include
25 | #include
26 |
27 | #include "alloc-util.h"
28 | #include "attributes.h"
29 |
30 | int log_get_max_level(void) _pure_;
31 |
32 | int log_internal(
33 | int level,
34 | int error,
35 | const char *file,
36 | int line,
37 | const char *func,
38 | const char *format, ...) _printf_(6,7);
39 |
40 | int log_internalv(
41 | int level,
42 | int error,
43 | const char *file,
44 | int line,
45 | const char *func,
46 | const char *format,
47 | va_list ap) _printf_(6,0);
48 |
49 | int log_struct_internal(
50 | int level,
51 | int error,
52 | const char *file,
53 | int line,
54 | const char *func,
55 | const char *format, ...) _printf_(6,0) _sentinel_;
56 |
57 | int log_oom_internal(
58 | const char *file,
59 | int line,
60 | const char *func);
61 |
62 | /* Logging for various assertions */
63 | noreturn void log_assert_failed(
64 | const char *text,
65 | const char *file,
66 | int line,
67 | const char *func);
68 |
69 | noreturn void log_assert_failed_unreachable(
70 | const char *text,
71 | const char *file,
72 | int line,
73 | const char *func);
74 |
75 | void log_assert_failed_return(
76 | const char *text,
77 | const char *file,
78 | int line,
79 | const char *func);
80 |
81 | /* Logging with level */
82 | #define log_full_errno(level, error, ...) \
83 | ({ \
84 | int _level = (level), _e = (error); \
85 | (log_get_max_level() >= LOG_PRI(_level)) \
86 | ? log_internal(_level, _e, __FILE__, __LINE__, __func__, __VA_ARGS__) \
87 | : -abs(_e); \
88 | })
89 |
90 | #define log_full(level, ...) log_full_errno(level, 0, __VA_ARGS__)
91 |
92 | /* Normal logging */
93 | #define log_debug(...) log_full(LOG_DEBUG, __VA_ARGS__)
94 | #define log_info(...) log_full(LOG_INFO, __VA_ARGS__)
95 | #define log_notice(...) log_full(LOG_NOTICE, __VA_ARGS__)
96 | #define log_warning(...) log_full(LOG_WARNING, __VA_ARGS__)
97 | #define log_error(...) log_full(LOG_ERR, __VA_ARGS__)
98 | #define log_emergency(...) log_full(getpid() == 1 ? LOG_EMERG : LOG_ERR, __VA_ARGS__)
99 |
100 | /* Logging triggered by an errno-like error */
101 | #define log_debug_errno(error, ...) log_full_errno(LOG_DEBUG, error, __VA_ARGS__)
102 | #define log_info_errno(error, ...) log_full_errno(LOG_INFO, error, __VA_ARGS__)
103 | #define log_notice_errno(error, ...) log_full_errno(LOG_NOTICE, error, __VA_ARGS__)
104 | #define log_warning_errno(error, ...) log_full_errno(LOG_WARNING, error, __VA_ARGS__)
105 | #define log_error_errno(error, ...) log_full_errno(LOG_ERR, error, __VA_ARGS__)
106 | #define log_emergency_errno(error, ...) log_full_errno(getpid() == 1 ? LOG_EMERG : LOG_ERR, error, __VA_ARGS__)
107 |
108 | #ifdef LOG_TRACE
109 | # define log_trace(...) log_debug(__VA_ARGS__)
110 | #else
111 | # define log_trace(...) do {} while(0)
112 | #endif
113 |
114 | #define log_oom() log_oom_internal(__FILE__, __LINE__, __func__)
115 |
116 | /* Helpers to prepare various fields for structured logging */
117 | #define LOG_MESSAGE(fmt, ...) "MESSAGE=" fmt, ##__VA_ARGS__
118 | #define LOG_MESSAGE_ID(x) "MESSAGE_ID=" SD_ID128_FORMAT_STR, SD_ID128_FORMAT_VAL(x)
119 |
120 | int log_syntax_internal(
121 | const char *unit,
122 | int level,
123 | const char *config_file,
124 | unsigned config_line,
125 | int error,
126 | const char *file,
127 | int line,
128 | const char *func,
129 | const char *format, ...) _printf_(9, 10);
130 |
131 | #define log_syntax(unit, level, config_file, config_line, error, ...) \
132 | ({ \
133 | int _level = (level), _e = (error); \
134 | (log_get_max_level() >= LOG_PRI(_level)) \
135 | ? log_syntax_internal(unit, _level, config_file, config_line, _e, __FILE__, __LINE__, __func__, __VA_ARGS__) \
136 | : -abs(_e); \
137 | })
138 |
139 | #define log_syntax_invalid_utf8(unit, level, config_file, config_line, rvalue) \
140 | ({ \
141 | int _level = (level); \
142 | if (log_get_max_level() >= LOG_PRI(_level)) { \
143 | _cleanup_free_ char *_p = NULL; \
144 | _p = utf8_escape_invalid(rvalue); \
145 | log_syntax_internal(unit, _level, config_file, config_line, 0, __FILE__, __LINE__, __func__, \
146 | "String is not UTF-8 clean, ignoring assignment: %s", strna(_p)); \
147 | } \
148 | -EINVAL; \
149 | })
150 |
--------------------------------------------------------------------------------
/src/mempool.c:
--------------------------------------------------------------------------------
1 | /***
2 | This file is part of systemd.
3 |
4 | Copyright 2010-2014 Lennart Poettering
5 | Copyright 2014 Michal Schmidt
6 |
7 | systemd is free software; you can redistribute it and/or modify it
8 | under the terms of the GNU Lesser General Public License as published by
9 | the Free Software Foundation; either version 2.1 of the License, or
10 | (at your option) any later version.
11 |
12 | systemd is distributed in the hope that it will be useful, but
13 | WITHOUT ANY WARRANTY; without even the implied warranty of
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 | Lesser General Public License for more details.
16 |
17 | You should have received a copy of the GNU Lesser General Public License
18 | along with systemd; If not, see .
19 | ***/
20 |
21 | #include
22 | #include
23 |
24 | #include "attributes.h"
25 | #include "macro.h"
26 | #include "mempool.h"
27 | #include "util.h"
28 |
29 | struct pool {
30 | struct pool *next;
31 | unsigned n_tiles;
32 | unsigned n_used;
33 | };
34 |
35 | void* mempool_alloc_tile(struct mempool *mp) {
36 | unsigned i;
37 |
38 | /* When a tile is released we add it to the list and simply
39 | * place the next pointer at its offset 0. */
40 |
41 | assert(mp->tile_size >= sizeof(void*));
42 | assert(mp->at_least > 0);
43 |
44 | if (mp->freelist) {
45 | void *r;
46 |
47 | r = mp->freelist;
48 | mp->freelist = * (void**) mp->freelist;
49 | return r;
50 | }
51 |
52 | if (_unlikely_(!mp->first_pool) ||
53 | _unlikely_(mp->first_pool->n_used >= mp->first_pool->n_tiles)) {
54 | unsigned n;
55 | size_t size;
56 | struct pool *p;
57 |
58 | n = mp->first_pool ? mp->first_pool->n_tiles : 0;
59 | n = MAX(mp->at_least, n * 2);
60 | size = PAGE_ALIGN(ALIGN(sizeof(struct pool)) + n*mp->tile_size);
61 | n = (size - ALIGN(sizeof(struct pool))) / mp->tile_size;
62 |
63 | p = malloc(size);
64 | if (!p)
65 | return NULL;
66 |
67 | p->next = mp->first_pool;
68 | p->n_tiles = n;
69 | p->n_used = 0;
70 |
71 | mp->first_pool = p;
72 | }
73 |
74 | i = mp->first_pool->n_used++;
75 |
76 | return ((uint8_t*) mp->first_pool) + ALIGN(sizeof(struct pool)) + i*mp->tile_size;
77 | }
78 |
79 | void* mempool_alloc0_tile(struct mempool *mp) {
80 | void *p;
81 |
82 | p = mempool_alloc_tile(mp);
83 | if (p)
84 | memzero(p, mp->tile_size);
85 | return p;
86 | }
87 |
88 | void mempool_free_tile(struct mempool *mp, void *p) {
89 | * (void**) p = mp->freelist;
90 | mp->freelist = p;
91 | }
92 |
93 | #ifdef VALGRIND
94 |
95 | void mempool_drop(struct mempool *mp) {
96 | struct pool *p = mp->first_pool;
97 | while (p) {
98 | struct pool *n;
99 | n = p->next;
100 | free(p);
101 | p = n;
102 | }
103 | }
104 |
105 | #endif
106 |
--------------------------------------------------------------------------------
/src/mempool.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | /***
4 | This file is part of systemd.
5 |
6 | Copyright 2011-2014 Lennart Poettering
7 | Copyright 2014 Michal Schmidt
8 |
9 | systemd is free software; you can redistribute it and/or modify it
10 | under the terms of the GNU Lesser General Public License as published by
11 | the Free Software Foundation; either version 2.1 of the License, or
12 | (at your option) any later version.
13 |
14 | systemd is distributed in the hope that it will be useful, but
15 | WITHOUT ANY WARRANTY; without even the implied warranty of
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | Lesser General Public License for more details.
18 |
19 | You should have received a copy of the GNU Lesser General Public License
20 | along with systemd; If not, see .
21 | ***/
22 |
23 | #include
24 |
25 | struct pool;
26 |
27 | struct mempool {
28 | struct pool *first_pool;
29 | void *freelist;
30 | size_t tile_size;
31 | unsigned at_least;
32 | };
33 |
34 | void* mempool_alloc_tile(struct mempool *mp);
35 | void* mempool_alloc0_tile(struct mempool *mp);
36 | void mempool_free_tile(struct mempool *mp, void *p);
37 |
38 | #define DEFINE_MEMPOOL(pool_name, tile_type, alloc_at_least) \
39 | static struct mempool pool_name = { \
40 | .tile_size = sizeof(tile_type), \
41 | .at_least = alloc_at_least, \
42 | }
43 |
44 |
45 | #ifdef VALGRIND
46 | void mempool_drop(struct mempool *mp);
47 | #endif
48 |
--------------------------------------------------------------------------------
/src/missing.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 |
6 | #ifndef CGROUP_SUPER_MAGIC
7 | #define CGROUP_SUPER_MAGIC 0x27e0eb
8 | #endif
9 |
10 | #ifndef TMPFS_MAGIC
11 | #define TMPFS_MAGIC 0x01021994
12 | #endif
13 |
14 | #if !HAVE_DECL_GETTID
15 | static inline pid_t gettid(void) {
16 | return (pid_t) syscall(SYS_gettid);
17 | }
18 | #endif
19 |
20 | #ifndef __NR_getrandom
21 | # if defined __x86_64__
22 | # define __NR_getrandom 318
23 | # elif defined(__i386__)
24 | # define __NR_getrandom 355
25 | # elif defined(__arm__)
26 | # define __NR_getrandom 384
27 | # elif defined(__aarch64__)
28 | # define __NR_getrandom 278
29 | # elif defined(__riscv)
30 | # define __NR_getrandom 278
31 | # elif defined(__ia64__)
32 | # define __NR_getrandom 1339
33 | # elif defined(__m68k__)
34 | # define __NR_getrandom 352
35 | # elif defined(__s390x__)
36 | # define __NR_getrandom 349
37 | # elif defined(__powerpc__)
38 | # define __NR_getrandom 359
39 | # elif defined _MIPS_SIM
40 | # if _MIPS_SIM == _MIPS_SIM_ABI32
41 | # define __NR_getrandom 4353
42 | # endif
43 | # if _MIPS_SIM == _MIPS_SIM_NABI32
44 | # define __NR_getrandom 6317
45 | # endif
46 | # if _MIPS_SIM == _MIPS_SIM_ABI64
47 | # define __NR_getrandom 5313
48 | # endif
49 | # else
50 | # warning "__NR_getrandom unknown for your architecture"
51 | # define __NR_getrandom 0xffffffff
52 | # endif
53 | #endif
54 |
55 | #if !HAVE_DECL_GETRANDOM
56 | static inline int getrandom(void *buffer, size_t count, unsigned flags) {
57 | return syscall(__NR_getrandom, buffer, count, flags);
58 | }
59 | #endif
60 |
61 | #ifndef GRND_NONBLOCK
62 | #define GRND_NONBLOCK 0x0001
63 | #endif
64 |
--------------------------------------------------------------------------------
/src/parse-util.c:
--------------------------------------------------------------------------------
1 | /***
2 | This file is part of systemd.
3 |
4 | Copyright 2010 Lennart Poettering
5 |
6 | systemd is free software; you can redistribute it and/or modify it
7 | under the terms of the GNU Lesser General Public License as published by
8 | the Free Software Foundation; either version 2.1 of the License, or
9 | (at your option) any later version.
10 |
11 | systemd is distributed in the hope that it will be useful, but
12 | WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | Lesser General Public License for more details.
15 |
16 | You should have received a copy of the GNU Lesser General Public License
17 | along with systemd; If not, see .
18 | ***/
19 |
20 | #include
21 | #include
22 | #include
23 | #include
24 |
25 | #include "macro.h"
26 | #include "parse-util.h"
27 | #include "string-util.h"
28 |
29 | int parse_boolean(const char *v) {
30 | assert(v);
31 |
32 | if (streq(v, "1") || strcaseeq(v, "yes") || strcaseeq(v, "y") || strcaseeq(v, "true") || strcaseeq(v, "t") || strcaseeq(v, "on"))
33 | return 1;
34 | else if (streq(v, "0") || strcaseeq(v, "no") || strcaseeq(v, "n") || strcaseeq(v, "false") || strcaseeq(v, "f") || strcaseeq(v, "off"))
35 | return 0;
36 |
37 | return -EINVAL;
38 | }
39 |
40 | int safe_atou(const char *s, unsigned *ret_u) {
41 | char *x = NULL;
42 | unsigned long l;
43 |
44 | assert(s);
45 | assert(ret_u);
46 |
47 | /* strtoul() is happy to parse negative values, and silently
48 | * converts them to unsigned values without generating an
49 | * error. We want a clean error, hence let's look for the "-"
50 | * prefix on our own, and generate an error. But let's do so
51 | * only after strtoul() validated that the string is clean
52 | * otherwise, so that we return EINVAL preferably over
53 | * ERANGE. */
54 |
55 | s += strspn(s, WHITESPACE);
56 |
57 | errno = 0;
58 | l = strtoul(s, &x, 0);
59 | if (errno > 0)
60 | return -errno;
61 | if (!x || x == s || *x)
62 | return -EINVAL;
63 | if (s[0] == '-')
64 | return -ERANGE;
65 | if ((unsigned long) (unsigned) l != l)
66 | return -ERANGE;
67 |
68 | *ret_u = (unsigned) l;
69 | return 0;
70 | }
71 |
72 | int safe_atoi(const char *s, int *ret_i) {
73 | char *x = NULL;
74 | long l;
75 |
76 | assert(s);
77 | assert(ret_i);
78 |
79 | errno = 0;
80 | l = strtol(s, &x, 0);
81 | if (errno > 0)
82 | return -errno;
83 | if (!x || x == s || *x)
84 | return -EINVAL;
85 | if ((long) (int) l != l)
86 | return -ERANGE;
87 |
88 | *ret_i = (int) l;
89 | return 0;
90 | }
91 |
92 | int safe_atollu(const char *s, long long unsigned *ret_llu) {
93 | char *x = NULL;
94 | unsigned long long l;
95 |
96 | assert(s);
97 | assert(ret_llu);
98 |
99 | s += strspn(s, WHITESPACE);
100 |
101 | errno = 0;
102 | l = strtoull(s, &x, 0);
103 | if (errno > 0)
104 | return -errno;
105 | if (!x || x == s || *x)
106 | return -EINVAL;
107 | if (*s == '-')
108 | return -ERANGE;
109 |
110 | *ret_llu = l;
111 | return 0;
112 | }
113 |
114 | int safe_atolli(const char *s, long long int *ret_lli) {
115 | char *x = NULL;
116 | long long l;
117 |
118 | assert(s);
119 | assert(ret_lli);
120 |
121 | errno = 0;
122 | l = strtoll(s, &x, 0);
123 | if (errno > 0)
124 | return -errno;
125 | if (!x || x == s || *x)
126 | return -EINVAL;
127 |
128 | *ret_lli = l;
129 | return 0;
130 | }
131 |
132 | int safe_atou8(const char *s, uint8_t *ret) {
133 | char *x = NULL;
134 | unsigned long l;
135 |
136 | assert(s);
137 | assert(ret);
138 |
139 | s += strspn(s, WHITESPACE);
140 |
141 | errno = 0;
142 | l = strtoul(s, &x, 0);
143 | if (errno > 0)
144 | return -errno;
145 | if (!x || x == s || *x)
146 | return -EINVAL;
147 | if (s[0] == '-')
148 | return -ERANGE;
149 | if ((unsigned long) (uint8_t) l != l)
150 | return -ERANGE;
151 |
152 | *ret = (uint8_t) l;
153 | return 0;
154 | }
155 |
156 | int safe_atou16(const char *s, uint16_t *ret) {
157 | char *x = NULL;
158 | unsigned long l;
159 |
160 | assert(s);
161 | assert(ret);
162 |
163 | s += strspn(s, WHITESPACE);
164 |
165 | errno = 0;
166 | l = strtoul(s, &x, 0);
167 | if (errno > 0)
168 | return -errno;
169 | if (!x || x == s || *x)
170 | return -EINVAL;
171 | if (s[0] == '-')
172 | return -ERANGE;
173 | if ((unsigned long) (uint16_t) l != l)
174 | return -ERANGE;
175 |
176 | *ret = (uint16_t) l;
177 | return 0;
178 | }
179 |
180 | int safe_atoi16(const char *s, int16_t *ret) {
181 | char *x = NULL;
182 | long l;
183 |
184 | assert(s);
185 | assert(ret);
186 |
187 | errno = 0;
188 | l = strtol(s, &x, 0);
189 | if (errno > 0)
190 | return -errno;
191 | if (!x || x == s || *x)
192 | return -EINVAL;
193 | if ((long) (int16_t) l != l)
194 | return -ERANGE;
195 |
196 | *ret = (int16_t) l;
197 | return 0;
198 | }
199 |
200 | int safe_atod(const char *s, double *ret_d) {
201 | char *x = NULL;
202 | double d = 0;
203 | locale_t loc;
204 |
205 | assert(s);
206 | assert(ret_d);
207 |
208 | loc = newlocale(LC_NUMERIC_MASK, "C", (locale_t) 0);
209 | if (loc == (locale_t) 0)
210 | return -errno;
211 |
212 | errno = 0;
213 | d = strtod_l(s, &x, loc);
214 | if (errno > 0) {
215 | freelocale(loc);
216 | return -errno;
217 | }
218 | if (!x || x == s || *x) {
219 | freelocale(loc);
220 | return -EINVAL;
221 | }
222 |
223 | freelocale(loc);
224 | *ret_d = (double) d;
225 | return 0;
226 | }
227 |
--------------------------------------------------------------------------------
/src/parse-util.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | /***
4 | This file is part of systemd.
5 |
6 | Copyright 2010 Lennart Poettering
7 |
8 | systemd is free software; you can redistribute it and/or modify it
9 | under the terms of the GNU Lesser General Public License as published by
10 | the Free Software Foundation; either version 2.1 of the License, or
11 | (at your option) any later version.
12 |
13 | systemd is distributed in the hope that it will be useful, but
14 | WITHOUT ANY WARRANTY; without even the implied warranty of
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | Lesser General Public License for more details.
17 |
18 | You should have received a copy of the GNU Lesser General Public License
19 | along with systemd; If not, see .
20 | ***/
21 |
22 | #include
23 | #include
24 | #include
25 |
26 | #include "attributes.h"
27 | #include "macro.h"
28 |
29 | #define MODE_INVALID ((mode_t) -1)
30 |
31 | int parse_boolean(const char *v) _pure_;
32 |
33 | int safe_atou(const char *s, unsigned *ret_u);
34 | int safe_atoi(const char *s, int *ret_i);
35 | int safe_atollu(const char *s, unsigned long long *ret_u);
36 | int safe_atolli(const char *s, long long int *ret_i);
37 |
38 | int safe_atou8(const char *s, uint8_t *ret);
39 |
40 | int safe_atou16(const char *s, uint16_t *ret);
41 | int safe_atoi16(const char *s, int16_t *ret);
42 |
43 | static inline int safe_atou32(const char *s, uint32_t *ret_u) {
44 | assert_cc(sizeof(uint32_t) == sizeof(unsigned));
45 | return safe_atou(s, (unsigned*) ret_u);
46 | }
47 |
48 | static inline int safe_atoi32(const char *s, int32_t *ret_i) {
49 | assert_cc(sizeof(int32_t) == sizeof(int));
50 | return safe_atoi(s, (int*) ret_i);
51 | }
52 |
53 | static inline int safe_atou64(const char *s, uint64_t *ret_u) {
54 | assert_cc(sizeof(uint64_t) == sizeof(unsigned long long));
55 | return safe_atollu(s, (unsigned long long*) ret_u);
56 | }
57 |
58 | static inline int safe_atoi64(const char *s, int64_t *ret_i) {
59 | assert_cc(sizeof(int64_t) == sizeof(long long int));
60 | return safe_atolli(s, (long long int*) ret_i);
61 | }
62 |
63 | #if LONG_MAX == INT_MAX
64 | static inline int safe_atolu(const char *s, unsigned long *ret_u) {
65 | assert_cc(sizeof(unsigned long) == sizeof(unsigned));
66 | return safe_atou(s, (unsigned*) ret_u);
67 | }
68 | static inline int safe_atoli(const char *s, long int *ret_u) {
69 | assert_cc(sizeof(long int) == sizeof(int));
70 | return safe_atoi(s, (int*) ret_u);
71 | }
72 | #else
73 | static inline int safe_atolu(const char *s, unsigned long *ret_u) {
74 | assert_cc(sizeof(unsigned long) == sizeof(unsigned long long));
75 | return safe_atollu(s, (unsigned long long*) ret_u);
76 | }
77 | static inline int safe_atoli(const char *s, long int *ret_u) {
78 | assert_cc(sizeof(long int) == sizeof(long long int));
79 | return safe_atolli(s, (long long int*) ret_u);
80 | }
81 | #endif
82 |
83 | int safe_atod(const char *s, double *ret_d);
84 |
--------------------------------------------------------------------------------
/src/path-util.c:
--------------------------------------------------------------------------------
1 | /***
2 | This file is part of systemd.
3 |
4 | Copyright 2010-2012 Lennart Poettering
5 |
6 | systemd is free software; you can redistribute it and/or modify it
7 | under the terms of the GNU Lesser General Public License as published by
8 | the Free Software Foundation; either version 2.1 of the License, or
9 | (at your option) any later version.
10 |
11 | systemd is distributed in the hope that it will be useful, but
12 | WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | Lesser General Public License for more details.
15 |
16 | You should have received a copy of the GNU Lesser General Public License
17 | along with systemd; If not, see .
18 | ***/
19 |
20 | #include
21 | #include
22 | #include
23 |
24 | #include "alloc-util.h"
25 | #include "macro.h"
26 | #include "path-util.h"
27 | #include "string-util.h"
28 | #include "strv.h"
29 |
30 | bool path_is_absolute(const char *p) {
31 | return p[0] == '/';
32 | }
33 |
34 | char **path_strv_resolve(char **l, const char *prefix) {
35 | char **s;
36 | unsigned k = 0;
37 | bool enomem = false;
38 |
39 | if (strv_isempty(l))
40 | return l;
41 |
42 | /* Goes through every item in the string list and canonicalize
43 | * the path. This works in place and won't rollback any
44 | * changes on failure. */
45 |
46 | STRV_FOREACH(s, l) {
47 | char *t, *u;
48 | _cleanup_free_ char *orig = NULL;
49 |
50 | if (!path_is_absolute(*s)) {
51 | free(*s);
52 | continue;
53 | }
54 |
55 | if (prefix) {
56 | orig = *s;
57 | t = strappend(prefix, orig);
58 | if (!t) {
59 | enomem = true;
60 | continue;
61 | }
62 | } else
63 | t = *s;
64 |
65 | errno = 0;
66 | u = canonicalize_file_name(t);
67 | if (!u) {
68 | if (errno == ENOENT) {
69 | if (prefix) {
70 | u = orig;
71 | orig = NULL;
72 | free(t);
73 | } else
74 | u = t;
75 | } else {
76 | free(t);
77 | if (errno == ENOMEM || errno == 0)
78 | enomem = true;
79 |
80 | continue;
81 | }
82 | } else if (prefix) {
83 | char *x;
84 |
85 | free(t);
86 | x = path_startswith(u, prefix);
87 | if (x) {
88 | /* restore the slash if it was lost */
89 | if (!startswith(x, "/"))
90 | *(--x) = '/';
91 |
92 | t = strdup(x);
93 | free(u);
94 | if (!t) {
95 | enomem = true;
96 | continue;
97 | }
98 | u = t;
99 | } else {
100 | /* canonicalized path goes outside of
101 | * prefix, keep the original path instead */
102 | free(u);
103 | u = orig;
104 | orig = NULL;
105 | }
106 | } else
107 | free(t);
108 |
109 | l[k++] = u;
110 | }
111 |
112 | l[k] = NULL;
113 |
114 | if (enomem)
115 | return NULL;
116 |
117 | return l;
118 | }
119 |
120 | char **path_strv_resolve_uniq(char **l, const char *prefix) {
121 |
122 | if (strv_isempty(l))
123 | return l;
124 |
125 | if (!path_strv_resolve(l, prefix))
126 | return NULL;
127 |
128 | return strv_uniq(l);
129 | }
130 |
131 | char *path_kill_slashes(char *path) {
132 | char *f, *t;
133 | bool slash = false;
134 |
135 | /* Removes redundant inner and trailing slashes. Modifies the
136 | * passed string in-place.
137 | *
138 | * ///foo///bar/ becomes /foo/bar
139 | */
140 |
141 | for (f = path, t = path; *f; f++) {
142 |
143 | if (*f == '/') {
144 | slash = true;
145 | continue;
146 | }
147 |
148 | if (slash) {
149 | slash = false;
150 | *(t++) = '/';
151 | }
152 |
153 | *(t++) = *f;
154 | }
155 |
156 | /* Special rule, if we are talking of the root directory, a
157 | trailing slash is good */
158 |
159 | if (t == path && slash)
160 | *(t++) = '/';
161 |
162 | *t = 0;
163 | return path;
164 | }
165 |
166 | char* path_startswith(const char *path, const char *prefix) {
167 | assert(path);
168 | assert(prefix);
169 |
170 | if ((path[0] == '/') != (prefix[0] == '/'))
171 | return NULL;
172 |
173 | for (;;) {
174 | size_t a, b;
175 |
176 | path += strspn(path, "/");
177 | prefix += strspn(prefix, "/");
178 |
179 | if (*prefix == 0)
180 | return (char*) path;
181 |
182 | if (*path == 0)
183 | return NULL;
184 |
185 | a = strcspn(path, "/");
186 | b = strcspn(prefix, "/");
187 |
188 | if (a != b)
189 | return NULL;
190 |
191 | if (memcmp(path, prefix, a) != 0)
192 | return NULL;
193 |
194 | path += a;
195 | prefix += b;
196 | }
197 | }
198 |
199 | int path_compare(const char *a, const char *b) {
200 | int d;
201 |
202 | assert(a);
203 | assert(b);
204 |
205 | /* A relative path and an abolute path must not compare as equal.
206 | * Which one is sorted before the other does not really matter.
207 | * Here a relative path is ordered before an absolute path. */
208 | d = (a[0] == '/') - (b[0] == '/');
209 | if (d != 0)
210 | return d;
211 |
212 | for (;;) {
213 | size_t j, k;
214 |
215 | a += strspn(a, "/");
216 | b += strspn(b, "/");
217 |
218 | if (*a == 0 && *b == 0)
219 | return 0;
220 |
221 | /* Order prefixes first: "/foo" before "/foo/bar" */
222 | if (*a == 0)
223 | return -1;
224 | if (*b == 0)
225 | return 1;
226 |
227 | j = strcspn(a, "/");
228 | k = strcspn(b, "/");
229 |
230 | /* Alphabetical sort: "/foo/aaa" before "/foo/b" */
231 | d = memcmp(a, b, MIN(j, k));
232 | if (d != 0)
233 | return (d > 0) - (d < 0); /* sign of d */
234 |
235 | /* Sort "/foo/a" before "/foo/aaa" */
236 | d = (j > k) - (j < k); /* sign of (j - k) */
237 | if (d != 0)
238 | return d;
239 |
240 | a += j;
241 | b += k;
242 | }
243 | }
244 |
245 | bool path_equal(const char *a, const char *b) {
246 | return path_compare(a, b) == 0;
247 | }
248 |
249 | char *file_in_same_dir(const char *path, const char *filename) {
250 | char *e, *ret;
251 | size_t k;
252 |
253 | assert(path);
254 | assert(filename);
255 |
256 | /* This removes the last component of path and appends
257 | * filename, unless the latter is absolute anyway or the
258 | * former isn't */
259 |
260 | if (path_is_absolute(filename))
261 | return strdup(filename);
262 |
263 | e = strrchr(path, '/');
264 | if (!e)
265 | return strdup(filename);
266 |
267 | k = strlen(filename);
268 | ret = new(char, (e + 1 - path) + k + 1);
269 | if (!ret)
270 | return NULL;
271 |
272 | memcpy(mempcpy(ret, path, e + 1 - path), filename, k + 1);
273 | return ret;
274 | }
275 |
--------------------------------------------------------------------------------
/src/path-util.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | /***
4 | This file is part of systemd.
5 |
6 | Copyright 2010-2012 Lennart Poettering
7 |
8 | systemd is free software; you can redistribute it and/or modify it
9 | under the terms of the GNU Lesser General Public License as published by
10 | the Free Software Foundation; either version 2.1 of the License, or
11 | (at your option) any later version.
12 |
13 | systemd is distributed in the hope that it will be useful, but
14 | WITHOUT ANY WARRANTY; without even the implied warranty of
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | Lesser General Public License for more details.
17 |
18 | You should have received a copy of the GNU Lesser General Public License
19 | along with systemd; If not, see .
20 | ***/
21 |
22 | #include
23 | #include
24 | #include
25 |
26 | #include "attributes.h"
27 |
28 | #define DEFAULT_PATH_NORMAL "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin"
29 | #define DEFAULT_PATH_SPLIT_USR DEFAULT_PATH_NORMAL ":/sbin:/bin"
30 |
31 | #ifdef HAVE_SPLIT_USR
32 | # define DEFAULT_PATH DEFAULT_PATH_SPLIT_USR
33 | #else
34 | # define DEFAULT_PATH DEFAULT_PATH_NORMAL
35 | #endif
36 |
37 | bool is_path(const char *p) _pure_;
38 | bool path_is_absolute(const char *p) _pure_;
39 | char* path_kill_slashes(char *path);
40 | char* path_startswith(const char *path, const char *prefix) _pure_;
41 | int path_compare(const char *a, const char *b) _pure_;
42 | bool path_equal(const char *a, const char *b) _pure_;
43 |
44 | char** path_strv_resolve(char **l, const char *prefix);
45 | char** path_strv_resolve_uniq(char **l, const char *prefix);
46 |
47 | /* Iterates through the path prefixes of the specified path, going up
48 | * the tree, to root. Also returns "" (and not "/"!) for the root
49 | * directory. Excludes the specified directory itself */
50 | #define PATH_FOREACH_PREFIX(prefix, path) \
51 | for (char *_slash = ({ path_kill_slashes(strcpy(prefix, path)); streq(prefix, "/") ? NULL : strrchr(prefix, '/'); }); _slash && ((*_slash = 0), true); _slash = strrchr((prefix), '/'))
52 |
53 | /* Same as PATH_FOREACH_PREFIX but also includes the specified path itself */
54 | #define PATH_FOREACH_PREFIX_MORE(prefix, path) \
55 | for (char *_slash = ({ path_kill_slashes(strcpy(prefix, path)); if (streq(prefix, "/")) prefix[0] = 0; strrchr(prefix, 0); }); _slash && ((*_slash = 0), true); _slash = strrchr((prefix), '/'))
56 |
57 | /* Similar to prefix_root(), but returns an alloca() buffer, or
58 | * possibly a const pointer into the path parameter */
59 | #define prefix_roota(root, path) \
60 | ({ \
61 | const char* _path = (path), *_root = (root), *_ret; \
62 | char *_p, *_n; \
63 | size_t _l; \
64 | while (_path[0] == '/' && _path[1] == '/') \
65 | _path ++; \
66 | if (isempty(_root) || path_equal(_root, "/")) \
67 | _ret = _path; \
68 | else { \
69 | _l = strlen(_root) + 1 + strlen(_path) + 1; \
70 | _n = alloca(_l); \
71 | _p = stpcpy(_n, _root); \
72 | while (_p > _n && _p[-1] == '/') \
73 | _p--; \
74 | if (_path[0] != '/') \
75 | *(_p++) = '/'; \
76 | strcpy(_p, _path); \
77 | _ret = _n; \
78 | } \
79 | _ret; \
80 | })
81 |
82 | char *file_in_same_dir(const char *path, const char *filename);
83 |
--------------------------------------------------------------------------------
/src/process-util.c:
--------------------------------------------------------------------------------
1 | /***
2 | This file is part of systemd.
3 |
4 | Copyright 2010 Lennart Poettering
5 |
6 | systemd is free software; you can redistribute it and/or modify it
7 | under the terms of the GNU Lesser General Public License as published by
8 | the Free Software Foundation; either version 2.1 of the License, or
9 | (at your option) any later version.
10 |
11 | systemd is distributed in the hope that it will be useful, but
12 | WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | Lesser General Public License for more details.
15 |
16 | You should have received a copy of the GNU Lesser General Public License
17 | along with systemd; If not, see .
18 | ***/
19 |
20 | #include
21 | #include
22 | #include
23 | #include
24 | #include
25 | #include
26 | #include
27 | #include
28 | #ifdef HAVE_VALGRIND_VALGRIND_H
29 | #include
30 | #endif
31 |
32 | #include "fd-util.h"
33 | #include "macro.h"
34 | #include "missing.h"
35 | #include "process-util.h"
36 |
37 | int getenv_for_pid(pid_t pid, const char *field, char **_value) {
38 | _cleanup_fclose_ FILE *f = NULL;
39 | char *value = NULL;
40 | int r;
41 | bool done = false;
42 | size_t l;
43 | const char *path;
44 |
45 | assert(pid >= 0);
46 | assert(field);
47 | assert(_value);
48 |
49 | path = procfs_file_alloca(pid, "environ");
50 |
51 | f = fopen(path, "re");
52 | if (!f) {
53 | if (errno == ENOENT)
54 | return -ESRCH;
55 | return -errno;
56 | }
57 |
58 | l = strlen(field);
59 | r = 0;
60 |
61 | do {
62 | char line[LINE_MAX];
63 | unsigned i;
64 |
65 | for (i = 0; i < sizeof(line)-1; i++) {
66 | int c;
67 |
68 | c = getc(f);
69 | if (_unlikely_(c == EOF)) {
70 | done = true;
71 | break;
72 | } else if (c == 0)
73 | break;
74 |
75 | line[i] = c;
76 | }
77 | line[i] = 0;
78 |
79 | if (memcmp(line, field, l) == 0 && line[l] == '=') {
80 | value = strdup(line + l + 1);
81 | if (!value)
82 | return -ENOMEM;
83 |
84 | r = 1;
85 | break;
86 | }
87 |
88 | } while (!done);
89 |
90 | *_value = value;
91 | return r;
92 | }
93 |
94 | bool is_main_thread(void) {
95 | static thread_local int cached = 0;
96 |
97 | if (_unlikely_(cached == 0))
98 | cached = getpid() == gettid() ? 1 : -1;
99 |
100 | return cached > 0;
101 | }
102 |
--------------------------------------------------------------------------------
/src/process-util.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | /***
4 | This file is part of systemd.
5 |
6 | Copyright 2010 Lennart Poettering
7 |
8 | systemd is free software; you can redistribute it and/or modify it
9 | under the terms of the GNU Lesser General Public License as published by
10 | the Free Software Foundation; either version 2.1 of the License, or
11 | (at your option) any later version.
12 |
13 | systemd is distributed in the hope that it will be useful, but
14 | WITHOUT ANY WARRANTY; without even the implied warranty of
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | Lesser General Public License for more details.
17 |
18 | You should have received a copy of the GNU Lesser General Public License
19 | along with systemd; If not, see .
20 | ***/
21 |
22 | #include
23 | #include
24 | #include
25 | #include
26 |
27 | #include "attributes.h"
28 | #include "formats-util.h"
29 | #include "macro.h"
30 |
31 | #define procfs_file_alloca(pid, field) \
32 | ({ \
33 | pid_t _pid_ = (pid); \
34 | const char *_r_; \
35 | if (_pid_ == 0) { \
36 | _r_ = ("/proc/self/" field); \
37 | } else { \
38 | _r_ = alloca(strlen("/proc/") + DECIMAL_STR_MAX(pid_t) + 1 + sizeof(field)); \
39 | sprintf((char*) _r_, "/proc/"PID_FMT"/" field, _pid_); \
40 | } \
41 | _r_; \
42 | })
43 |
44 | int getenv_for_pid(pid_t pid, const char *field, char **_value);
45 |
46 | bool pid_is_alive(pid_t pid);
47 |
48 | bool is_main_thread(void);
49 |
50 | #ifndef PERSONALITY_INVALID
51 | /* personality(7) documents that 0xffffffffUL is used for querying the
52 | * current personality, hence let's use that here as error
53 | * indicator. */
54 | #define PERSONALITY_INVALID 0xffffffffLU
55 | #endif
56 |
57 | int ioprio_class_to_string_alloc(int i, char **s);
58 | int ioprio_class_from_string(const char *s);
59 |
60 | const char *sigchld_code_to_string(int i) _const_;
61 | int sigchld_code_from_string(const char *s) _pure_;
62 |
63 | #define PTR_TO_PID(p) ((pid_t) ((uintptr_t) p))
64 | #define PID_TO_PTR(p) ((void*) ((uintptr_t) p))
65 |
--------------------------------------------------------------------------------
/src/random-util.c:
--------------------------------------------------------------------------------
1 | /***
2 | This file is part of systemd.
3 |
4 | Copyright 2010 Lennart Poettering
5 |
6 | systemd is free software; you can redistribute it and/or modify it
7 | under the terms of the GNU Lesser General Public License as published by
8 | the Free Software Foundation; either version 2.1 of the License, or
9 | (at your option) any later version.
10 |
11 | systemd is distributed in the hope that it will be useful, but
12 | WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | Lesser General Public License for more details.
15 |
16 | You should have received a copy of the GNU Lesser General Public License
17 | along with systemd; If not, see .
18 | ***/
19 |
20 | #include
21 | #include
22 | #include
23 | #include
24 | #include
25 | #include
26 | #include
27 |
28 | #ifdef HAVE_SYS_AUXV_H
29 | #include
30 | #endif
31 |
32 | #include "fd-util.h"
33 | #include "io-util.h"
34 | #include "missing.h"
35 | #include "random-util.h"
36 | #include "time-util.h"
37 |
38 | int dev_urandom(void *p, size_t n) {
39 | static int have_syscall = -1;
40 |
41 | _cleanup_close_ int fd = -1;
42 | int r;
43 |
44 | /* Gathers some randomness from the kernel. This call will
45 | * never block, and will always return some data from the
46 | * kernel, regardless if the random pool is fully initialized
47 | * or not. It thus makes no guarantee for the quality of the
48 | * returned entropy, but is good enough for or usual usecases
49 | * of seeding the hash functions for hashtable */
50 |
51 | /* Use the getrandom() syscall unless we know we don't have
52 | * it, or when the requested size is too large for it. */
53 | if (have_syscall != 0 || (size_t) (int) n != n) {
54 | r = getrandom(p, n, GRND_NONBLOCK);
55 | if (r == (int) n) {
56 | have_syscall = true;
57 | return 0;
58 | }
59 |
60 | if (r < 0) {
61 | if (errno == ENOSYS)
62 | /* we lack the syscall, continue with
63 | * reading from /dev/urandom */
64 | have_syscall = false;
65 | else if (errno == EAGAIN)
66 | /* not enough entropy for now. Let's
67 | * remember to use the syscall the
68 | * next time, again, but also read
69 | * from /dev/urandom for now, which
70 | * doesn't care about the current
71 | * amount of entropy. */
72 | have_syscall = true;
73 | else
74 | return -errno;
75 | } else
76 | /* too short read? */
77 | return -ENODATA;
78 | }
79 |
80 | fd = open("/dev/urandom", O_RDONLY|O_CLOEXEC|O_NOCTTY);
81 | if (fd < 0)
82 | return errno == ENOENT ? -ENOSYS : -errno;
83 |
84 | return loop_read_exact(fd, p, n, true);
85 | }
86 |
87 | void initialize_srand(void) {
88 | static bool srand_called = false;
89 | unsigned x;
90 | #ifdef HAVE_SYS_AUXV_H
91 | void *auxv;
92 | #endif
93 |
94 | if (srand_called)
95 | return;
96 |
97 | #ifdef HAVE_SYS_AUXV_H
98 | /* The kernel provides us with 16 bytes of entropy in auxv, so let's try to make use of that to seed the
99 | * pseudo-random generator. It's better than nothing... */
100 |
101 | auxv = (void*) getauxval(AT_RANDOM);
102 | if (auxv) {
103 | assert_cc(sizeof(x) < 16);
104 | memcpy(&x, auxv, sizeof(x));
105 | } else
106 | #endif
107 | x = 0;
108 |
109 |
110 | x ^= (unsigned) now(CLOCK_REALTIME);
111 | x ^= (unsigned) gettid();
112 |
113 | srand(x);
114 | srand_called = true;
115 | }
116 |
117 | void random_bytes(void *p, size_t n) {
118 | uint8_t *q;
119 | int r;
120 |
121 | r = dev_urandom(p, n);
122 | if (r >= 0)
123 | return;
124 |
125 | /* If some idiot made /dev/urandom unavailable to us, he'll
126 | * get a PRNG instead. */
127 |
128 | initialize_srand();
129 |
130 | for (q = p; q < (uint8_t*) p + n; q ++)
131 | *q = rand();
132 | }
133 |
--------------------------------------------------------------------------------
/src/random-util.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | /***
4 | This file is part of systemd.
5 |
6 | Copyright 2010 Lennart Poettering
7 |
8 | systemd is free software; you can redistribute it and/or modify it
9 | under the terms of the GNU Lesser General Public License as published by
10 | the Free Software Foundation; either version 2.1 of the License, or
11 | (at your option) any later version.
12 |
13 | systemd is distributed in the hope that it will be useful, but
14 | WITHOUT ANY WARRANTY; without even the implied warranty of
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | Lesser General Public License for more details.
17 |
18 | You should have received a copy of the GNU Lesser General Public License
19 | along with systemd; If not, see .
20 | ***/
21 |
22 | #include
23 | #include
24 |
25 | int dev_urandom(void *p, size_t n);
26 | void random_bytes(void *p, size_t n);
27 | void initialize_srand(void);
28 |
29 | static inline uint64_t random_u64(void) {
30 | uint64_t u;
31 | random_bytes(&u, sizeof(u));
32 | return u;
33 | }
34 |
35 | static inline uint32_t random_u32(void) {
36 | uint32_t u;
37 | random_bytes(&u, sizeof(u));
38 | return u;
39 | }
40 |
--------------------------------------------------------------------------------
/src/sd-messages.h:
--------------------------------------------------------------------------------
1 | #ifndef foosdmessageshfoo
2 | #define foosdmessageshfoo
3 |
4 | /***
5 | This file is part of systemd.
6 |
7 | Copyright 2012 Lennart Poettering
8 |
9 | systemd is free software; you can redistribute it and/or modify it
10 | under the terms of the GNU Lesser General Public License as published by
11 | the Free Software Foundation; either version 2.1 of the License, or
12 | (at your option) any later version.
13 |
14 | systemd is distributed in the hope that it will be useful, but
15 | WITHOUT ANY WARRANTY; without even the implied warranty of
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 | Lesser General Public License for more details.
18 |
19 | You should have received a copy of the GNU Lesser General Public License
20 | along with systemd; If not, see .
21 | ***/
22 |
23 | #ifdef HAVE_LIBSYSTEMD
24 | #include
25 |
26 | #include "_sd-common.h"
27 |
28 | _SD_BEGIN_DECLARATIONS;
29 |
30 | #define SD_MESSAGE_INVALID_CONFIGURATION SD_ID128_MAKE(c7,72,d2,4e,9a,88,4c,be,b9,ea,12,62,5c,30,6c,01)
31 | #define SD_MESSAGE_BOOTCHART SD_ID128_MAKE(9f,26,aa,56,2c,f4,40,c2,b1,6c,77,3d,04,79,b5,18)
32 |
33 | _SD_END_DECLARATIONS;
34 | #endif
35 |
36 | #endif
37 |
--------------------------------------------------------------------------------
/src/set.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | /***
4 | This file is part of systemd.
5 |
6 | Copyright 2010 Lennart Poettering
7 |
8 | systemd is free software; you can redistribute it and/or modify it
9 | under the terms of the GNU Lesser General Public License as published by
10 | the Free Software Foundation; either version 2.1 of the License, or
11 | (at your option) any later version.
12 |
13 | systemd is distributed in the hope that it will be useful, but
14 | WITHOUT ANY WARRANTY; without even the implied warranty of
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | Lesser General Public License for more details.
17 |
18 | You should have received a copy of the GNU Lesser General Public License
19 | along with systemd; If not, see .
20 | ***/
21 |
22 | #include "hashmap.h"
23 | #include "macro.h"
24 |
25 | Set *internal_set_new(const struct hash_ops *hash_ops HASHMAP_DEBUG_PARAMS);
26 | #define set_new(ops) internal_set_new(ops HASHMAP_DEBUG_SRC_ARGS)
27 |
28 | static inline Set *set_free(Set *s) {
29 | internal_hashmap_free(HASHMAP_BASE(s));
30 | return NULL;
31 | }
32 |
33 | static inline Set *set_free_free(Set *s) {
34 | internal_hashmap_free_free(HASHMAP_BASE(s));
35 | return NULL;
36 | }
37 |
38 | /* no set_free_free_free */
39 |
40 | static inline Set *set_copy(Set *s) {
41 | return (Set*) internal_hashmap_copy(HASHMAP_BASE(s));
42 | }
43 |
44 | int internal_set_ensure_allocated(Set **s, const struct hash_ops *hash_ops HASHMAP_DEBUG_PARAMS);
45 | #define set_ensure_allocated(h, ops) internal_set_ensure_allocated(h, ops HASHMAP_DEBUG_SRC_ARGS)
46 |
47 | int set_put(Set *s, const void *key);
48 | /* no set_update */
49 | /* no set_replace */
50 | static inline void *set_get(Set *s, void *key) {
51 | return internal_hashmap_get(HASHMAP_BASE(s), key);
52 | }
53 | /* no set_get2 */
54 |
55 | static inline bool set_contains(Set *s, const void *key) {
56 | return internal_hashmap_contains(HASHMAP_BASE(s), key);
57 | }
58 |
59 | static inline void *set_remove(Set *s, const void *key) {
60 | return internal_hashmap_remove(HASHMAP_BASE(s), key);
61 | }
62 |
63 | /* no set_remove2 */
64 | /* no set_remove_value */
65 | int set_remove_and_put(Set *s, const void *old_key, const void *new_key);
66 | /* no set_remove_and_replace */
67 | int set_merge(Set *s, Set *other);
68 |
69 | static inline int set_reserve(Set *h, unsigned entries_add) {
70 | return internal_hashmap_reserve(HASHMAP_BASE(h), entries_add);
71 | }
72 |
73 | static inline int set_move(Set *s, Set *other) {
74 | return internal_hashmap_move(HASHMAP_BASE(s), HASHMAP_BASE(other));
75 | }
76 |
77 | static inline int set_move_one(Set *s, Set *other, const void *key) {
78 | return internal_hashmap_move_one(HASHMAP_BASE(s), HASHMAP_BASE(other), key);
79 | }
80 |
81 | static inline unsigned set_size(Set *s) {
82 | return internal_hashmap_size(HASHMAP_BASE(s));
83 | }
84 |
85 | static inline bool set_isempty(Set *s) {
86 | return set_size(s) == 0;
87 | }
88 |
89 | static inline unsigned set_buckets(Set *s) {
90 | return internal_hashmap_buckets(HASHMAP_BASE(s));
91 | }
92 |
93 | bool set_iterate(Set *s, Iterator *i, void **value);
94 |
95 | static inline void set_clear(Set *s) {
96 | internal_hashmap_clear(HASHMAP_BASE(s));
97 | }
98 |
99 | static inline void set_clear_free(Set *s) {
100 | internal_hashmap_clear_free(HASHMAP_BASE(s));
101 | }
102 |
103 | /* no set_clear_free_free */
104 |
105 | static inline void *set_steal_first(Set *s) {
106 | return internal_hashmap_steal_first(HASHMAP_BASE(s));
107 | }
108 |
109 | /* no set_steal_first_key */
110 | /* no set_first_key */
111 | /* no set_next */
112 |
113 | static inline char **set_get_strv(Set *s) {
114 | return internal_hashmap_get_strv(HASHMAP_BASE(s));
115 | }
116 |
117 | int set_consume(Set *s, void *value);
118 | int set_put_strdup(Set *s, const char *p);
119 | int set_put_strdupv(Set *s, char **l);
120 |
121 | #define SET_FOREACH(e, s, i) \
122 | for ((i) = ITERATOR_FIRST; set_iterate((s), &(i), (void**)&(e)); )
123 |
124 | DEFINE_TRIVIAL_CLEANUP_FUNC(Set*, set_free);
125 | DEFINE_TRIVIAL_CLEANUP_FUNC(Set*, set_free_free);
126 |
127 | #define _cleanup_set_free_ _cleanup_(set_freep)
128 | #define _cleanup_set_free_free_ _cleanup_(set_free_freep)
129 |
--------------------------------------------------------------------------------
/src/siphash24.c:
--------------------------------------------------------------------------------
1 | /*
2 | SipHash reference C implementation
3 |
4 | Written in 2012 by
5 | Jean-Philippe Aumasson
6 | Daniel J. Bernstein
7 |
8 | To the extent possible under law, the author(s) have dedicated all copyright
9 | and related and neighboring rights to this software to the public domain
10 | worldwide. This software is distributed without any warranty.
11 |
12 | You should have received a copy of the CC0 Public Domain Dedication along with
13 | this software. If not, see .
14 |
15 | (Minimal changes made by Lennart Poettering, to make clean for inclusion in systemd)
16 | (Refactored by Tom Gundersen to split up in several functions and follow systemd
17 | coding style)
18 | */
19 |
20 | #include "macro.h"
21 | #include "siphash24.h"
22 | #include "unaligned.h"
23 |
24 | static inline uint64_t rotate_left(uint64_t x, uint8_t b) {
25 | assert(b < 64);
26 |
27 | return (x << b) | (x >> (64 - b));
28 | }
29 |
30 | static inline void sipround(struct siphash *state) {
31 | assert(state);
32 |
33 | state->v0 += state->v1;
34 | state->v1 = rotate_left(state->v1, 13);
35 | state->v1 ^= state->v0;
36 | state->v0 = rotate_left(state->v0, 32);
37 | state->v2 += state->v3;
38 | state->v3 = rotate_left(state->v3, 16);
39 | state->v3 ^= state->v2;
40 | state->v0 += state->v3;
41 | state->v3 = rotate_left(state->v3, 21);
42 | state->v3 ^= state->v0;
43 | state->v2 += state->v1;
44 | state->v1 = rotate_left(state->v1, 17);
45 | state->v1 ^= state->v2;
46 | state->v2 = rotate_left(state->v2, 32);
47 | }
48 |
49 | void siphash24_init(struct siphash *state, const uint8_t k[16]) {
50 | uint64_t k0, k1;
51 |
52 | assert(state);
53 | assert(k);
54 |
55 | k0 = unaligned_read_le64(k);
56 | k1 = unaligned_read_le64(k + 8);
57 |
58 | *state = (struct siphash) {
59 | /* "somepseudorandomlygeneratedbytes" */
60 | .v0 = 0x736f6d6570736575ULL ^ k0,
61 | .v1 = 0x646f72616e646f6dULL ^ k1,
62 | .v2 = 0x6c7967656e657261ULL ^ k0,
63 | .v3 = 0x7465646279746573ULL ^ k1,
64 | .padding = 0,
65 | .inlen = 0,
66 | };
67 | }
68 |
69 | void siphash24_compress(const void *_in, size_t inlen, struct siphash *state) {
70 |
71 | const uint8_t *in = _in;
72 | const uint8_t *end = in + inlen;
73 | size_t left = state->inlen & 7;
74 | uint64_t m;
75 |
76 | assert(in);
77 | assert(state);
78 |
79 | /* Update total length */
80 | state->inlen += inlen;
81 |
82 | /* If padding exists, fill it out */
83 | if (left > 0) {
84 | for ( ; in < end && left < 8; in ++, left ++)
85 | state->padding |= ((uint64_t) *in) << (left * 8);
86 |
87 | if (in == end && left < 8)
88 | /* We did not have enough input to fill out the padding completely */
89 | return;
90 |
91 | #ifdef DEBUG
92 | printf("(%3zu) v0 %08x %08x\n", state->inlen, (uint32_t) (state->v0 >> 32), (uint32_t) state->v0);
93 | printf("(%3zu) v1 %08x %08x\n", state->inlen, (uint32_t) (state->v1 >> 32), (uint32_t) state->v1);
94 | printf("(%3zu) v2 %08x %08x\n", state->inlen, (uint32_t) (state->v2 >> 32), (uint32_t) state->v2);
95 | printf("(%3zu) v3 %08x %08x\n", state->inlen, (uint32_t) (state->v3 >> 32), (uint32_t) state->v3);
96 | printf("(%3zu) compress padding %08x %08x\n", state->inlen, (uint32_t) (state->padding >> 32), (uint32_t)state->padding);
97 | #endif
98 |
99 | state->v3 ^= state->padding;
100 | sipround(state);
101 | sipround(state);
102 | state->v0 ^= state->padding;
103 |
104 | state->padding = 0;
105 | }
106 |
107 | end -= (state->inlen % sizeof(uint64_t));
108 |
109 | for ( ; in < end; in += 8) {
110 | m = unaligned_read_le64(in);
111 | #ifdef DEBUG
112 | printf("(%3zu) v0 %08x %08x\n", state->inlen, (uint32_t) (state->v0 >> 32), (uint32_t) state->v0);
113 | printf("(%3zu) v1 %08x %08x\n", state->inlen, (uint32_t) (state->v1 >> 32), (uint32_t) state->v1);
114 | printf("(%3zu) v2 %08x %08x\n", state->inlen, (uint32_t) (state->v2 >> 32), (uint32_t) state->v2);
115 | printf("(%3zu) v3 %08x %08x\n", state->inlen, (uint32_t) (state->v3 >> 32), (uint32_t) state->v3);
116 | printf("(%3zu) compress %08x %08x\n", state->inlen, (uint32_t) (m >> 32), (uint32_t) m);
117 | #endif
118 | state->v3 ^= m;
119 | sipround(state);
120 | sipround(state);
121 | state->v0 ^= m;
122 | }
123 |
124 | left = state->inlen & 7;
125 | switch (left) {
126 | case 7:
127 | state->padding |= ((uint64_t) in[6]) << 48;
128 | case 6:
129 | state->padding |= ((uint64_t) in[5]) << 40;
130 | case 5:
131 | state->padding |= ((uint64_t) in[4]) << 32;
132 | case 4:
133 | state->padding |= ((uint64_t) in[3]) << 24;
134 | case 3:
135 | state->padding |= ((uint64_t) in[2]) << 16;
136 | case 2:
137 | state->padding |= ((uint64_t) in[1]) << 8;
138 | case 1:
139 | state->padding |= ((uint64_t) in[0]);
140 | case 0:
141 | break;
142 | }
143 | }
144 |
145 | uint64_t siphash24_finalize(struct siphash *state) {
146 | uint64_t b;
147 |
148 | assert(state);
149 |
150 | b = state->padding | (((uint64_t) state->inlen) << 56);
151 |
152 | #ifdef DEBUG
153 | printf("(%3zu) v0 %08x %08x\n", state->inlen, (uint32_t) (state->v0 >> 32), (uint32_t) state->v0);
154 | printf("(%3zu) v1 %08x %08x\n", state->inlen, (uint32_t) (state->v1 >> 32), (uint32_t) state->v1);
155 | printf("(%3zu) v2 %08x %08x\n", state->inlen, (uint32_t) (state->v2 >> 32), (uint32_t) state->v2);
156 | printf("(%3zu) v3 %08x %08x\n", state->inlen, (uint32_t) (state->v3 >> 32), (uint32_t) state->v3);
157 | printf("(%3zu) padding %08x %08x\n", state->inlen, (uint32_t) (state->padding >> 32), (uint32_t) state->padding);
158 | #endif
159 |
160 | state->v3 ^= b;
161 | sipround(state);
162 | sipround(state);
163 | state->v0 ^= b;
164 |
165 | #ifdef DEBUG
166 | printf("(%3zu) v0 %08x %08x\n", state->inlen, (uint32_t) (state->v0 >> 32), (uint32_t) state->v0);
167 | printf("(%3zu) v1 %08x %08x\n", state->inlen, (uint32_t) (state->v1 >> 32), (uint32_t) state->v1);
168 | printf("(%3zu) v2 %08x %08x\n", state->inlen, (uint32_t) (state->v2 >> 32), (uint32_t) state->v2);
169 | printf("(%3zu) v3 %08x %08x\n", state->inlen, (uint32_t) (state->v3 >> 32), (uint32_t) state->v3);
170 | #endif
171 | state->v2 ^= 0xff;
172 |
173 | sipround(state);
174 | sipround(state);
175 | sipround(state);
176 | sipround(state);
177 |
178 | return state->v0 ^ state->v1 ^ state->v2 ^ state->v3;
179 | }
180 |
181 | uint64_t siphash24(const void *in, size_t inlen, const uint8_t k[16]) {
182 | struct siphash state;
183 |
184 | assert(in);
185 | assert(k);
186 |
187 | siphash24_init(&state, k);
188 | siphash24_compress(in, inlen, &state);
189 |
190 | return siphash24_finalize(&state);
191 | }
192 |
--------------------------------------------------------------------------------
/src/siphash24.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 |
6 | struct siphash {
7 | uint64_t v0;
8 | uint64_t v1;
9 | uint64_t v2;
10 | uint64_t v3;
11 | uint64_t padding;
12 | size_t inlen;
13 | };
14 |
15 | void siphash24_init(struct siphash *state, const uint8_t k[16]);
16 | void siphash24_compress(const void *in, size_t inlen, struct siphash *state);
17 | #define siphash24_compress_byte(byte, state) siphash24_compress((const uint8_t[]) { (byte) }, 1, (state))
18 |
19 | uint64_t siphash24_finalize(struct siphash *state);
20 |
21 | uint64_t siphash24(const void *in, size_t inlen, const uint8_t k[16]);
22 |
--------------------------------------------------------------------------------
/src/stdio-util.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | /***
4 | This file is part of systemd.
5 |
6 | Copyright 2010 Lennart Poettering
7 |
8 | systemd is free software; you can redistribute it and/or modify it
9 | under the terms of the GNU Lesser General Public License as published by
10 | the Free Software Foundation; either version 2.1 of the License, or
11 | (at your option) any later version.
12 |
13 | systemd is distributed in the hope that it will be useful, but
14 | WITHOUT ANY WARRANTY; without even the implied warranty of
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | Lesser General Public License for more details.
17 |
18 | You should have received a copy of the GNU Lesser General Public License
19 | along with systemd; If not, see .
20 | ***/
21 |
22 | #include
23 | #include
24 | #include
25 | #include
26 |
27 | #include "macro.h"
28 |
29 | #define xsprintf(buf, fmt, ...) \
30 | assert_message_se((size_t) snprintf(buf, ELEMENTSOF(buf), fmt, __VA_ARGS__) < ELEMENTSOF(buf), "xsprintf: " #buf "[] must be big enough")
31 |
32 |
33 | #define VA_FORMAT_ADVANCE(format, ap) \
34 | do { \
35 | int _argtypes[128]; \
36 | size_t _i, _k; \
37 | _k = parse_printf_format((format), ELEMENTSOF(_argtypes), _argtypes); \
38 | assert(_k < ELEMENTSOF(_argtypes)); \
39 | for (_i = 0; _i < _k; _i++) { \
40 | if (_argtypes[_i] & PA_FLAG_PTR) { \
41 | (void) va_arg(ap, void*); \
42 | continue; \
43 | } \
44 | \
45 | switch (_argtypes[_i]) { \
46 | case PA_INT: \
47 | case PA_INT|PA_FLAG_SHORT: \
48 | case PA_CHAR: \
49 | (void) va_arg(ap, int); \
50 | break; \
51 | case PA_INT|PA_FLAG_LONG: \
52 | (void) va_arg(ap, long int); \
53 | break; \
54 | case PA_INT|PA_FLAG_LONG_LONG: \
55 | (void) va_arg(ap, long long int); \
56 | break; \
57 | case PA_WCHAR: \
58 | (void) va_arg(ap, wchar_t); \
59 | break; \
60 | case PA_WSTRING: \
61 | case PA_STRING: \
62 | case PA_POINTER: \
63 | (void) va_arg(ap, void*); \
64 | break; \
65 | case PA_FLOAT: \
66 | case PA_DOUBLE: \
67 | (void) va_arg(ap, double); \
68 | break; \
69 | case PA_DOUBLE|PA_FLAG_LONG_DOUBLE: \
70 | (void) va_arg(ap, long double); \
71 | break; \
72 | default: \
73 | assert_not_reached("Unknown format string argument."); \
74 | } \
75 | } \
76 | } while(false)
77 |
--------------------------------------------------------------------------------
/src/store.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | /***
4 | This file is part of systemd.
5 |
6 | Copyright (C) 2009-2013 Intel Corporation
7 |
8 | Authors:
9 | Auke Kok
10 |
11 | systemd is free software; you can redistribute it and/or modify it
12 | under the terms of the GNU Lesser General Public License as published by
13 | the Free Software Foundation; either version 2.1 of the License, or
14 | (at your option) any later version.
15 |
16 | systemd is distributed in the hope that it will be useful, but
17 | WITHOUT ANY WARRANTY; without even the implied warranty of
18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 | Lesser General Public License for more details.
20 |
21 | You should have received a copy of the GNU Lesser General Public License
22 | along with systemd; If not, see .
23 | ***/
24 |
25 | #include
26 |
27 | #include "bootchart.h"
28 |
29 | double gettime_ns(void);
30 | void log_uptime(void);
31 | int log_sample(DIR *proc,
32 | int sample,
33 | struct ps_struct *ps_first,
34 | struct list_sample_data **ptr,
35 | int *pscount,
36 | int *cpus);
37 |
--------------------------------------------------------------------------------
/src/string-util.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | /***
4 | This file is part of systemd.
5 |
6 | Copyright 2010 Lennart Poettering
7 |
8 | systemd is free software; you can redistribute it and/or modify it
9 | under the terms of the GNU Lesser General Public License as published by
10 | the Free Software Foundation; either version 2.1 of the License, or
11 | (at your option) any later version.
12 |
13 | systemd is distributed in the hope that it will be useful, but
14 | WITHOUT ANY WARRANTY; without even the implied warranty of
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | Lesser General Public License for more details.
17 |
18 | You should have received a copy of the GNU Lesser General Public License
19 | along with systemd; If not, see .
20 | ***/
21 |
22 | #include
23 | #include
24 | #include
25 | #include
26 |
27 | #include "attributes.h"
28 | #include "macro.h"
29 |
30 | /* What is interpreted as whitespace? */
31 | #define WHITESPACE " \t\n\r"
32 | #define NEWLINE "\n\r"
33 | #define QUOTES "\"\'"
34 | #define COMMENTS "#;"
35 | #define GLOB_CHARS "*?["
36 | #define DIGITS "0123456789"
37 | #define LOWERCASE_LETTERS "abcdefghijklmnopqrstuvwxyz"
38 | #define UPPERCASE_LETTERS "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
39 | #define LETTERS LOWERCASE_LETTERS UPPERCASE_LETTERS
40 | #define ALPHANUMERICAL LETTERS DIGITS
41 |
42 | #define streq(a,b) (strcmp((a),(b)) == 0)
43 | #define strneq(a, b, n) (strncmp((a), (b), (n)) == 0)
44 | #define strcaseeq(a,b) (strcasecmp((a),(b)) == 0)
45 | #define strncaseeq(a, b, n) (strncasecmp((a), (b), (n)) == 0)
46 |
47 | int strcmp_ptr(const char *a, const char *b) _pure_;
48 |
49 | static inline bool streq_ptr(const char *a, const char *b) {
50 | return strcmp_ptr(a, b) == 0;
51 | }
52 |
53 | static inline const char* strempty(const char *s) {
54 | return s ? s : "";
55 | }
56 |
57 | static inline const char* strnull(const char *s) {
58 | return s ? s : "(null)";
59 | }
60 |
61 | static inline const char *strna(const char *s) {
62 | return s ? s : "n/a";
63 | }
64 |
65 | static inline bool isempty(const char *p) {
66 | return !p || !p[0];
67 | }
68 |
69 | static inline char *startswith(const char *s, const char *prefix) {
70 | size_t l;
71 |
72 | l = strlen(prefix);
73 | if (strncmp(s, prefix, l) == 0)
74 | return (char*) s + l;
75 |
76 | return NULL;
77 | }
78 |
79 | static inline char *startswith_no_case(const char *s, const char *prefix) {
80 | size_t l;
81 |
82 | l = strlen(prefix);
83 | if (strncasecmp(s, prefix, l) == 0)
84 | return (char*) s + l;
85 |
86 | return NULL;
87 | }
88 |
89 | char *endswith(const char *s, const char *postfix) _pure_;
90 |
91 | const char* split(const char **state, size_t *l, const char *separator, bool quoted);
92 |
93 | #define FOREACH_WORD(word, length, s, state) \
94 | _FOREACH_WORD(word, length, s, WHITESPACE, false, state)
95 |
96 | #define FOREACH_WORD_SEPARATOR(word, length, s, separator, state) \
97 | _FOREACH_WORD(word, length, s, separator, false, state)
98 |
99 | #define FOREACH_WORD_QUOTED(word, length, s, state) \
100 | _FOREACH_WORD(word, length, s, WHITESPACE, true, state)
101 |
102 | #define _FOREACH_WORD(word, length, s, separator, quoted, state) \
103 | for ((state) = (s), (word) = split(&(state), &(length), (separator), (quoted)); (word); (word) = split(&(state), &(length), (separator), (quoted)))
104 |
105 | char *strappend(const char *s, const char *suffix);
106 | char *strnappend(const char *s, const char *suffix, size_t length);
107 |
108 | char *strjoin(const char *x, ...) _sentinel_;
109 |
110 | #define strjoina(a, ...) \
111 | ({ \
112 | const char *_appendees_[] = { a, __VA_ARGS__ }; \
113 | char *_d_, *_p_; \
114 | int _len_ = 0; \
115 | unsigned _i_; \
116 | for (_i_ = 0; _i_ < ELEMENTSOF(_appendees_) && _appendees_[_i_]; _i_++) \
117 | _len_ += strlen(_appendees_[_i_]); \
118 | _p_ = _d_ = alloca(_len_ + 1); \
119 | for (_i_ = 0; _i_ < ELEMENTSOF(_appendees_) && _appendees_[_i_]; _i_++) \
120 | _p_ = stpcpy(_p_, _appendees_[_i_]); \
121 | *_p_ = 0; \
122 | _d_; \
123 | })
124 |
125 | char *strstrip(char *s);
126 | char *truncate_nl(char *s);
127 |
128 | static inline bool _pure_ in_charset(const char *s, const char* charset) {
129 | assert(s);
130 | assert(charset);
131 | return s[strspn(s, charset)] == '\0';
132 | }
133 |
134 | char *ellipsize_mem(const char *s, size_t old_length_bytes, size_t new_length_columns, unsigned percent);
135 | char *ellipsize(const char *s, size_t length, unsigned percent);
136 |
137 | bool nulstr_contains(const char*nulstr, const char *needle);
138 |
139 | char* strshorten(char *s, size_t l);
140 |
141 | char *strip_tab_ansi(char **p, size_t *l);
142 |
143 | char *strextend(char **x, ...) _sentinel_;
144 |
145 | char *strrep(const char *s, unsigned n);
146 |
147 | /* Normal memmem() requires haystack to be nonnull, which is annoying for zero-length buffers */
148 | static inline void *memmem_safe(const void *haystack, size_t haystacklen, const void *needle, size_t needlelen) {
149 |
150 | if (needlelen <= 0)
151 | return (void*) haystack;
152 |
153 | if (haystacklen < needlelen)
154 | return NULL;
155 |
156 | assert(haystack);
157 | assert(needle);
158 |
159 | return memmem(haystack, haystacklen, needle, needlelen);
160 | }
161 |
--------------------------------------------------------------------------------
/src/strv.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | /***
4 | This file is part of systemd.
5 |
6 | Copyright 2010 Lennart Poettering
7 |
8 | systemd is free software; you can redistribute it and/or modify it
9 | under the terms of the GNU Lesser General Public License as published by
10 | the Free Software Foundation; either version 2.1 of the License, or
11 | (at your option) any later version.
12 |
13 | systemd is distributed in the hope that it will be useful, but
14 | WITHOUT ANY WARRANTY; without even the implied warranty of
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | Lesser General Public License for more details.
17 |
18 | You should have received a copy of the GNU Lesser General Public License
19 | along with systemd; If not, see .
20 | ***/
21 |
22 | #include
23 | #include
24 | #include
25 |
26 | #include "alloc-util.h"
27 | #include "attributes.h"
28 | #include "macro.h"
29 |
30 | char *strv_find(char **l, const char *name) _pure_;
31 | char *strv_find_prefix(char **l, const char *name) _pure_;
32 | char *strv_find_startswith(char **l, const char *name) _pure_;
33 |
34 | char **strv_free(char **l);
35 | DEFINE_TRIVIAL_CLEANUP_FUNC(char**, strv_free);
36 | #define _cleanup_strv_free_ _cleanup_(strv_freep)
37 |
38 | void strv_clear(char **l);
39 |
40 | char **strv_copy(char * const *l);
41 | unsigned strv_length(char * const *l) _pure_;
42 |
43 | int strv_extend_strv(char ***a, char **b, bool filter_duplicates);
44 | int strv_extend_strv_concat(char ***a, char **b, const char *suffix);
45 | int strv_extend(char ***l, const char *value);
46 | int strv_extendf(char ***l, const char *format, ...) _printf_(2,0);
47 | int strv_push(char ***l, char *value);
48 | int strv_push_pair(char ***l, char *a, char *b);
49 | int strv_push_prepend(char ***l, char *value);
50 | int strv_consume(char ***l, char *value);
51 | int strv_consume_prepend(char ***l, char *value);
52 |
53 | char **strv_remove(char **l, const char *s);
54 | char **strv_uniq(char **l);
55 | bool strv_is_uniq(char **l);
56 |
57 | bool strv_equal(char **a, char **b);
58 |
59 | #define strv_contains(l, s) (!!strv_find((l), (s)))
60 |
61 | char **strv_new(const char *x, ...) _sentinel_;
62 | char **strv_new_ap(const char *x, va_list ap);
63 |
64 | static inline const char* STRV_IFNOTNULL(const char *x) {
65 | return x ? x : (const char *) -1;
66 | }
67 |
68 | static inline bool strv_isempty(char * const *l) {
69 | return !l || !*l;
70 | }
71 |
72 | char **strv_split(const char *s, const char *separator);
73 |
74 | char *strv_join(char **l, const char *separator);
75 |
76 | char **strv_parse_nulstr(const char *s, size_t l);
77 | char **strv_split_nulstr(const char *s);
78 |
79 | bool strv_overlap(char **a, char **b) _pure_;
80 |
81 | #define STRV_FOREACH(s, l) \
82 | for ((s) = (l); (s) && *(s); (s)++)
83 |
84 | #define STRV_FOREACH_BACKWARDS(s, l) \
85 | STRV_FOREACH(s, l) \
86 | ; \
87 | for ((s)--; (l) && ((s) >= (l)); (s)--)
88 |
89 | #define STRV_FOREACH_PAIR(x, y, l) \
90 | for ((x) = (l), (y) = (x+1); (x) && *(x) && *(y); (x) += 2, (y) = (x + 1))
91 |
92 | char **strv_sort(char **l);
93 | void strv_print(char **l);
94 |
95 | #define STRV_MAKE(...) ((char**) ((const char*[]) { __VA_ARGS__, NULL }))
96 |
97 | #define STRV_MAKE_EMPTY ((char*[1]) { NULL })
98 |
99 | #define strv_from_stdarg_alloca(first) \
100 | ({ \
101 | char **_l; \
102 | \
103 | if (!first) \
104 | _l = (char**) &first; \
105 | else { \
106 | unsigned _n; \
107 | va_list _ap; \
108 | \
109 | _n = 1; \
110 | va_start(_ap, first); \
111 | while (va_arg(_ap, char*)) \
112 | _n++; \
113 | va_end(_ap); \
114 | \
115 | _l = newa(char*, _n+1); \
116 | _l[_n = 0] = (char*) first; \
117 | va_start(_ap, first); \
118 | for (;;) { \
119 | _l[++_n] = va_arg(_ap, char*); \
120 | if (!_l[_n]) \
121 | break; \
122 | } \
123 | va_end(_ap); \
124 | } \
125 | _l; \
126 | })
127 |
128 | #define STR_IN_SET(x, ...) strv_contains(STRV_MAKE(__VA_ARGS__), x)
129 |
130 | #define FOREACH_STRING(x, ...) \
131 | for (char **_l = ({ \
132 | char **_ll = STRV_MAKE(__VA_ARGS__); \
133 | x = _ll ? _ll[0] : NULL; \
134 | _ll; \
135 | }); \
136 | _l && *_l; \
137 | x = ({ \
138 | _l ++; \
139 | _l[0]; \
140 | }))
141 |
142 | char **strv_reverse(char **l);
143 |
144 | bool strv_fnmatch(char* const* patterns, const char *s, int flags);
145 |
146 | static inline bool strv_fnmatch_or_empty(char* const* patterns, const char *s, int flags) {
147 | assert(s);
148 | return strv_isempty(patterns) ||
149 | strv_fnmatch(patterns, s, flags);
150 | }
151 |
152 | char ***strv_free_free(char ***l);
153 |
154 | char **strv_skip(char **l, size_t n);
155 |
156 | int strv_extend_n(char ***l, const char *value, size_t n);
157 |
--------------------------------------------------------------------------------
/src/strxcpyx.c:
--------------------------------------------------------------------------------
1 | /***
2 | This file is part of systemd.
3 |
4 | Copyright 2013 Kay Sievers
5 |
6 | systemd is free software; you can redistribute it and/or modify it
7 | under the terms of the GNU Lesser General Public License as published by
8 | the Free Software Foundation; either version 2.1 of the License, or
9 | (at your option) any later version.
10 |
11 | systemd is distributed in the hope that it will be useful, but
12 | WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | Lesser General Public License for more details.
15 |
16 | You should have received a copy of the GNU Lesser General Public License
17 | along with systemd; If not, see .
18 | ***/
19 |
20 | /*
21 | * Concatenates/copies strings. In any case, terminates in all cases
22 | * with '\0' * and moves the @dest pointer forward to the added '\0'.
23 | * Returns the * remaining size, and 0 if the string was truncated.
24 | */
25 |
26 | #include
27 |
28 | #include "strxcpyx.h"
29 |
30 | size_t strpcpy(char **dest, size_t size, const char *src) {
31 | size_t len;
32 |
33 | len = strlen(src);
34 | if (len >= size) {
35 | if (size > 1)
36 | *dest = mempcpy(*dest, src, size-1);
37 | size = 0;
38 | } else {
39 | if (len > 0) {
40 | *dest = mempcpy(*dest, src, len);
41 | size -= len;
42 | }
43 | }
44 | *dest[0] = '\0';
45 | return size;
46 | }
47 |
48 | size_t strscpy(char *dest, size_t size, const char *src) {
49 | char *s;
50 |
51 | s = dest;
52 | return strpcpy(&s, size, src);
53 | }
54 |
--------------------------------------------------------------------------------
/src/strxcpyx.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | /***
4 | This file is part of systemd.
5 |
6 | Copyright 2013 Kay Sievers
7 |
8 | systemd is free software; you can redistribute it and/or modify it
9 | under the terms of the GNU Lesser General Public License as published by
10 | the Free Software Foundation; either version 2.1 of the License, or
11 | (at your option) any later version.
12 |
13 | systemd is distributed in the hope that it will be useful, but
14 | WITHOUT ANY WARRANTY; without even the implied warranty of
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | Lesser General Public License for more details.
17 |
18 | You should have received a copy of the GNU Lesser General Public License
19 | along with systemd; If not, see .
20 | ***/
21 |
22 |
23 | #include
24 |
25 | size_t strpcpy(char **dest, size_t size, const char *src);
26 | size_t strscpy(char *dest, size_t size, const char *src);
27 |
--------------------------------------------------------------------------------
/src/svg.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | /***
4 | This file is part of systemd.
5 |
6 | Copyright (C) 2009-2013 Intel Corporation
7 |
8 | Authors:
9 | Auke Kok
10 |
11 | systemd is free software; you can redistribute it and/or modify it
12 | under the terms of the GNU Lesser General Public License as published by
13 | the Free Software Foundation; either version 2.1 of the License, or
14 | (at your option) any later version.
15 |
16 | systemd is distributed in the hope that it will be useful, but
17 | WITHOUT ANY WARRANTY; without even the implied warranty of
18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 | Lesser General Public License for more details.
20 |
21 | You should have received a copy of the GNU Lesser General Public License
22 | along with systemd; If not, see .
23 | ***/
24 |
25 | #include
26 | #include
27 |
28 | int svg_do(FILE *of,
29 | const char *build,
30 | struct list_sample_data *head,
31 | struct ps_struct *ps_first,
32 | int n_samples,
33 | int pscount,
34 | int n_cpus,
35 | double graph_start,
36 | double log_start,
37 | double interval,
38 | int overrun);
39 |
--------------------------------------------------------------------------------
/src/terminal-util.c:
--------------------------------------------------------------------------------
1 | /***
2 | This file is part of systemd.
3 |
4 | Copyright 2010 Lennart Poettering
5 |
6 | systemd is free software; you can redistribute it and/or modify it
7 | under the terms of the GNU Lesser General Public License as published by
8 | the Free Software Foundation; either version 2.1 of the License, or
9 | (at your option) any later version.
10 |
11 | systemd is distributed in the hope that it will be useful, but
12 | WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | Lesser General Public License for more details.
15 |
16 | You should have received a copy of the GNU Lesser General Public License
17 | along with systemd; If not, see .
18 | ***/
19 |
20 | #include
21 | #include
22 | #include
23 | #include
24 | #include
25 | #include
26 |
27 | #include "fd-util.h"
28 | #include "macro.h"
29 | #include "terminal-util.h"
30 | #include "time-util.h"
31 |
32 | static volatile unsigned cached_columns = 0;
33 | static volatile unsigned cached_lines = 0;
34 |
35 | int open_terminal(const char *name, int mode) {
36 | int fd, r;
37 | unsigned c = 0;
38 |
39 | /*
40 | * If a TTY is in the process of being closed opening it might
41 | * cause EIO. This is horribly awful, but unlikely to be
42 | * changed in the kernel. Hence we work around this problem by
43 | * retrying a couple of times.
44 | *
45 | * https://bugs.launchpad.net/ubuntu/+source/linux/+bug/554172/comments/245
46 | */
47 |
48 | if (mode & O_CREAT)
49 | return -EINVAL;
50 |
51 | for (;;) {
52 | fd = open(name, mode, 0);
53 | if (fd >= 0)
54 | break;
55 |
56 | if (errno != EIO)
57 | return -errno;
58 |
59 | /* Max 1s in total */
60 | if (c >= 20)
61 | return -errno;
62 |
63 | usleep(50 * USEC_PER_MSEC);
64 | c++;
65 | }
66 |
67 | r = isatty(fd);
68 | if (r < 0) {
69 | safe_close(fd);
70 | return -errno;
71 | }
72 |
73 | if (!r) {
74 | safe_close(fd);
75 | return -ENOTTY;
76 | }
77 |
78 | return fd;
79 | }
80 |
81 | int release_terminal(void) {
82 | static const struct sigaction sa_new = {
83 | .sa_handler = SIG_IGN,
84 | .sa_flags = SA_RESTART,
85 | };
86 |
87 | _cleanup_close_ int fd = -1;
88 | struct sigaction sa_old;
89 | int r = 0;
90 |
91 | fd = open("/dev/tty", O_RDWR|O_NOCTTY|O_CLOEXEC|O_NONBLOCK);
92 | if (fd < 0)
93 | return -errno;
94 |
95 | /* Temporarily ignore SIGHUP, so that we don't get SIGHUP'ed
96 | * by our own TIOCNOTTY */
97 | assert_se(sigaction(SIGHUP, &sa_new, &sa_old) == 0);
98 |
99 | if (ioctl(fd, TIOCNOTTY) < 0)
100 | r = -errno;
101 |
102 | assert_se(sigaction(SIGHUP, &sa_old, NULL) == 0);
103 |
104 | return r;
105 | }
106 |
--------------------------------------------------------------------------------
/src/terminal-util.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | /***
4 | This file is part of systemd.
5 |
6 | Copyright 2010 Lennart Poettering
7 |
8 | systemd is free software; you can redistribute it and/or modify it
9 | under the terms of the GNU Lesser General Public License as published by
10 | the Free Software Foundation; either version 2.1 of the License, or
11 | (at your option) any later version.
12 |
13 | systemd is distributed in the hope that it will be useful, but
14 | WITHOUT ANY WARRANTY; without even the implied warranty of
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | Lesser General Public License for more details.
17 |
18 | You should have received a copy of the GNU Lesser General Public License
19 | along with systemd; If not, see .
20 | ***/
21 |
22 | #define ANSI_RED "\x1B[0;31m"
23 | #define ANSI_GREEN "\x1B[0;32m"
24 | #define ANSI_UNDERLINE "\x1B[0;4m"
25 | #define ANSI_HIGHLIGHT "\x1B[0;1;39m"
26 | #define ANSI_HIGHLIGHT_RED "\x1B[0;1;31m"
27 | #define ANSI_HIGHLIGHT_GREEN "\x1B[0;1;32m"
28 | #define ANSI_HIGHLIGHT_YELLOW "\x1B[0;1;33m"
29 | #define ANSI_HIGHLIGHT_BLUE "\x1B[0;1;34m"
30 | #define ANSI_HIGHLIGHT_UNDERLINE "\x1B[0;1;4m"
31 | #define ANSI_NORMAL "\x1B[0m"
32 |
33 | #define ANSI_ERASE_TO_END_OF_LINE "\x1B[K"
34 |
35 | /* Set cursor to top left corner and clear screen */
36 | #define ANSI_HOME_CLEAR "\x1B[H\x1B[2J"
37 |
38 | int open_terminal(const char *name, int mode);
39 | int release_terminal(void);
40 |
41 | int make_null_stdio(void);
42 |
--------------------------------------------------------------------------------
/src/time-util.c:
--------------------------------------------------------------------------------
1 | /***
2 | This file is part of systemd.
3 |
4 | Copyright 2010 Lennart Poettering
5 |
6 | systemd is free software; you can redistribute it and/or modify it
7 | under the terms of the GNU Lesser General Public License as published by
8 | the Free Software Foundation; either version 2.1 of the License, or
9 | (at your option) any later version.
10 |
11 | systemd is distributed in the hope that it will be useful, but
12 | WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | Lesser General Public License for more details.
15 |
16 | You should have received a copy of the GNU Lesser General Public License
17 | along with systemd; If not, see .
18 | ***/
19 |
20 | #include
21 | #include
22 | #include
23 | #include
24 | #include
25 |
26 | #include "fd-util.h"
27 | #include "macro.h"
28 | #include "time-util.h"
29 |
30 | static clockid_t map_clock_id(clockid_t c) {
31 |
32 | /* Some more exotic archs (s390, ppc, …) lack the "ALARM" flavour of the clocks. Thus, clock_gettime() will
33 | * fail for them. Since they are essentially the same as their non-ALARM pendants (their only difference is
34 | * when timers are set on them), let's just map them accordingly. This way, we can get the correct time even on
35 | * those archs. */
36 |
37 | switch (c) {
38 |
39 | case CLOCK_BOOTTIME_ALARM:
40 | return CLOCK_BOOTTIME;
41 |
42 | case CLOCK_REALTIME_ALARM:
43 | return CLOCK_REALTIME;
44 |
45 | default:
46 | return c;
47 | }
48 | }
49 |
50 | usec_t now(clockid_t clock_id) {
51 | struct timespec ts;
52 |
53 | assert_se(clock_gettime(map_clock_id(clock_id), &ts) == 0);
54 |
55 | return timespec_load(&ts);
56 | }
57 |
58 | usec_t timespec_load(const struct timespec *ts) {
59 | assert(ts);
60 |
61 | if (ts->tv_sec == (time_t) -1 &&
62 | ts->tv_nsec == (long) -1)
63 | return USEC_INFINITY;
64 |
65 | if ((usec_t) ts->tv_sec > (UINT64_MAX - (ts->tv_nsec / NSEC_PER_USEC)) / USEC_PER_SEC)
66 | return USEC_INFINITY;
67 |
68 | return
69 | (usec_t) ts->tv_sec * USEC_PER_SEC +
70 | (usec_t) ts->tv_nsec / NSEC_PER_USEC;
71 | }
72 |
73 | struct timespec *timespec_store(struct timespec *ts, usec_t u) {
74 | assert(ts);
75 |
76 | if (u == USEC_INFINITY) {
77 | ts->tv_sec = (time_t) -1;
78 | ts->tv_nsec = (long) -1;
79 | return ts;
80 | }
81 |
82 | ts->tv_sec = (time_t) (u / USEC_PER_SEC);
83 | ts->tv_nsec = (long int) ((u % USEC_PER_SEC) * NSEC_PER_USEC);
84 |
85 | return ts;
86 | }
87 |
88 | clockid_t clock_boottime_or_monotonic(void) {
89 | static clockid_t clock = -1;
90 | int fd;
91 |
92 | if (clock != -1)
93 | return clock;
94 |
95 | fd = timerfd_create(CLOCK_BOOTTIME, TFD_NONBLOCK|TFD_CLOEXEC);
96 | if (fd < 0)
97 | clock = CLOCK_MONOTONIC;
98 | else {
99 | safe_close(fd);
100 | clock = CLOCK_BOOTTIME;
101 | }
102 |
103 | return clock;
104 | }
105 |
--------------------------------------------------------------------------------
/src/time-util.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | /***
4 | This file is part of systemd.
5 |
6 | Copyright 2010 Lennart Poettering
7 |
8 | systemd is free software; you can redistribute it and/or modify it
9 | under the terms of the GNU Lesser General Public License as published by
10 | the Free Software Foundation; either version 2.1 of the License, or
11 | (at your option) any later version.
12 |
13 | systemd is distributed in the hope that it will be useful, but
14 | WITHOUT ANY WARRANTY; without even the implied warranty of
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | Lesser General Public License for more details.
17 |
18 | You should have received a copy of the GNU Lesser General Public License
19 | along with systemd; If not, see .
20 | ***/
21 |
22 | #include
23 | #include
24 | #include
25 | #include
26 | #include
27 | #include
28 |
29 | #include "attributes.h"
30 |
31 | typedef uint64_t usec_t;
32 | typedef uint64_t nsec_t;
33 |
34 | #define NSEC_FMT "%" PRIu64
35 | #define USEC_FMT "%" PRIu64
36 |
37 | #include "macro.h"
38 |
39 | typedef struct dual_timestamp {
40 | usec_t realtime;
41 | usec_t monotonic;
42 | } dual_timestamp;
43 |
44 | #define USEC_INFINITY ((usec_t) -1)
45 | #define NSEC_INFINITY ((nsec_t) -1)
46 |
47 | #define MSEC_PER_SEC 1000ULL
48 | #define USEC_PER_SEC ((usec_t) 1000000ULL)
49 | #define USEC_PER_MSEC ((usec_t) 1000ULL)
50 | #define NSEC_PER_SEC ((nsec_t) 1000000000ULL)
51 | #define NSEC_PER_MSEC ((nsec_t) 1000000ULL)
52 | #define NSEC_PER_USEC ((nsec_t) 1000ULL)
53 |
54 | #define USEC_PER_MINUTE ((usec_t) (60ULL*USEC_PER_SEC))
55 | #define NSEC_PER_MINUTE ((nsec_t) (60ULL*NSEC_PER_SEC))
56 | #define USEC_PER_HOUR ((usec_t) (60ULL*USEC_PER_MINUTE))
57 | #define NSEC_PER_HOUR ((nsec_t) (60ULL*NSEC_PER_MINUTE))
58 | #define USEC_PER_DAY ((usec_t) (24ULL*USEC_PER_HOUR))
59 | #define NSEC_PER_DAY ((nsec_t) (24ULL*NSEC_PER_HOUR))
60 | #define USEC_PER_WEEK ((usec_t) (7ULL*USEC_PER_DAY))
61 | #define NSEC_PER_WEEK ((nsec_t) (7ULL*NSEC_PER_DAY))
62 | #define USEC_PER_MONTH ((usec_t) (2629800ULL*USEC_PER_SEC))
63 | #define NSEC_PER_MONTH ((nsec_t) (2629800ULL*NSEC_PER_SEC))
64 | #define USEC_PER_YEAR ((usec_t) (31557600ULL*USEC_PER_SEC))
65 | #define NSEC_PER_YEAR ((nsec_t) (31557600ULL*NSEC_PER_SEC))
66 |
67 | #define TIME_T_MAX (time_t)((UINTMAX_C(1) << ((sizeof(time_t) << 3) - 1)) - 1)
68 |
69 | #define DUAL_TIMESTAMP_NULL ((struct dual_timestamp) { 0ULL, 0ULL })
70 |
71 | usec_t now(clockid_t clock);
72 |
73 | static inline bool dual_timestamp_is_set(dual_timestamp *ts) {
74 | return ((ts->realtime > 0 && ts->realtime != USEC_INFINITY) ||
75 | (ts->monotonic > 0 && ts->monotonic != USEC_INFINITY));
76 | }
77 |
78 | usec_t timespec_load(const struct timespec *ts) _pure_;
79 | struct timespec *timespec_store(struct timespec *ts, usec_t u);
80 |
81 | clockid_t clock_boottime_or_monotonic(void);
82 |
83 | #define xstrftime(buf, fmt, tm) \
84 | assert_message_se(strftime(buf, ELEMENTSOF(buf), fmt, tm) > 0, \
85 | "xstrftime: " #buf "[] must be big enough")
86 |
87 | static inline usec_t usec_add(usec_t a, usec_t b) {
88 | usec_t c;
89 |
90 | /* Adds two time values, and makes sure USEC_INFINITY as input results as USEC_INFINITY in output, and doesn't
91 | * overflow. */
92 |
93 | c = a + b;
94 | if (c < a || c < b) /* overflow check */
95 | return USEC_INFINITY;
96 |
97 | return c;
98 | }
99 |
100 | static inline usec_t usec_sub(usec_t timestamp, int64_t delta) {
101 | if (delta < 0)
102 | return usec_add(timestamp, (usec_t) (-delta));
103 |
104 | if (timestamp == USEC_INFINITY) /* Make sure infinity doesn't degrade */
105 | return USEC_INFINITY;
106 |
107 | if (timestamp < (usec_t) delta)
108 | return 0;
109 |
110 | return timestamp - delta;
111 | }
112 |
--------------------------------------------------------------------------------
/src/unaligned.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | /***
4 | This file is part of systemd.
5 |
6 | Copyright 2014 Tom Gundersen
7 |
8 | systemd is free software; you can redistribute it and/or modify it
9 | under the terms of the GNU Lesser General Public License as published by
10 | the Free Software Foundation; either version 2.1 of the License, or
11 | (at your option) any later version.
12 |
13 | systemd is distributed in the hope that it will be useful, but
14 | WITHOUT ANY WARRANTY; without even the implied warranty of
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | Lesser General Public License for more details.
17 |
18 | You should have received a copy of the GNU Lesser General Public License
19 | along with systemd; If not, see .
20 | ***/
21 |
22 | #include
23 | #include
24 |
25 | /* BE */
26 |
27 | static inline uint16_t unaligned_read_be16(const void *_u) {
28 | const uint8_t *u = _u;
29 |
30 | return (((uint16_t) u[0]) << 8) |
31 | ((uint16_t) u[1]);
32 | }
33 |
34 | static inline uint32_t unaligned_read_be32(const void *_u) {
35 | const uint8_t *u = _u;
36 |
37 | return (((uint32_t) unaligned_read_be16(u)) << 16) |
38 | ((uint32_t) unaligned_read_be16(u + 2));
39 | }
40 |
41 | static inline uint64_t unaligned_read_be64(const void *_u) {
42 | const uint8_t *u = _u;
43 |
44 | return (((uint64_t) unaligned_read_be32(u)) << 32) |
45 | ((uint64_t) unaligned_read_be32(u + 4));
46 | }
47 |
48 | static inline void unaligned_write_be16(void *_u, uint16_t a) {
49 | uint8_t *u = _u;
50 |
51 | u[0] = (uint8_t) (a >> 8);
52 | u[1] = (uint8_t) a;
53 | }
54 |
55 | static inline void unaligned_write_be32(void *_u, uint32_t a) {
56 | uint8_t *u = _u;
57 |
58 | unaligned_write_be16(u, (uint16_t) (a >> 16));
59 | unaligned_write_be16(u + 2, (uint16_t) a);
60 | }
61 |
62 | static inline void unaligned_write_be64(void *_u, uint64_t a) {
63 | uint8_t *u = _u;
64 |
65 | unaligned_write_be32(u, (uint32_t) (a >> 32));
66 | unaligned_write_be32(u + 4, (uint32_t) a);
67 | }
68 |
69 | /* LE */
70 |
71 | static inline uint16_t unaligned_read_le16(const void *_u) {
72 | const uint8_t *u = _u;
73 |
74 | return (((uint16_t) u[1]) << 8) |
75 | ((uint16_t) u[0]);
76 | }
77 |
78 | static inline uint32_t unaligned_read_le32(const void *_u) {
79 | const uint8_t *u = _u;
80 |
81 | return (((uint32_t) unaligned_read_le16(u + 2)) << 16) |
82 | ((uint32_t) unaligned_read_le16(u));
83 | }
84 |
85 | static inline uint64_t unaligned_read_le64(const void *_u) {
86 | const uint8_t *u = _u;
87 |
88 | return (((uint64_t) unaligned_read_le32(u + 4)) << 32) |
89 | ((uint64_t) unaligned_read_le32(u));
90 | }
91 |
92 | static inline void unaligned_write_le16(void *_u, uint16_t a) {
93 | uint8_t *u = _u;
94 |
95 | u[0] = (uint8_t) a;
96 | u[1] = (uint8_t) (a >> 8);
97 | }
98 |
99 | static inline void unaligned_write_le32(void *_u, uint32_t a) {
100 | uint8_t *u = _u;
101 |
102 | unaligned_write_le16(u, (uint16_t) a);
103 | unaligned_write_le16(u + 2, (uint16_t) (a >> 16));
104 | }
105 |
106 | static inline void unaligned_write_le64(void *_u, uint64_t a) {
107 | uint8_t *u = _u;
108 |
109 | unaligned_write_le32(u, (uint32_t) a);
110 | unaligned_write_le32(u + 4, (uint32_t) (a >> 32));
111 | }
112 |
--------------------------------------------------------------------------------
/src/utf8.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | /***
4 | This file is part of systemd.
5 |
6 | Copyright 2012 Lennart Poettering
7 |
8 | systemd is free software; you can redistribute it and/or modify it
9 | under the terms of the GNU Lesser General Public License as published by
10 | the Free Software Foundation; either version 2.1 of the License, or
11 | (at your option) any later version.
12 |
13 | systemd is distributed in the hope that it will be useful, but
14 | WITHOUT ANY WARRANTY; without even the implied warranty of
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | Lesser General Public License for more details.
17 |
18 | You should have received a copy of the GNU Lesser General Public License
19 | along with systemd; If not, see .
20 | ***/
21 |
22 | #include
23 | #include
24 | #include
25 |
26 | #include "attributes.h"
27 |
28 | #define UTF8_REPLACEMENT_CHARACTER "\xef\xbf\xbd"
29 |
30 | bool unichar_is_valid(char32_t c);
31 |
32 | const char *utf8_is_valid(const char *s) _pure_;
33 |
34 | bool utf8_is_printable_newline(const char* str, size_t length, bool newline) _pure_;
35 | #define utf8_is_printable(str, length) utf8_is_printable_newline(str, length, true)
36 |
37 | char *utf8_escape_invalid(const char *s);
38 | char *utf8_escape_non_printable(const char *str);
39 |
40 | int utf8_encoded_valid_unichar(const char *str);
41 | int utf8_encoded_to_unichar(const char *str, char32_t *ret_unichar);
42 |
43 | static inline bool utf16_is_surrogate(char16_t c) {
44 | return (0xd800 <= c && c <= 0xdfff);
45 | }
46 |
47 | static inline bool utf16_is_trailing_surrogate(char16_t c) {
48 | return (0xdc00 <= c && c <= 0xdfff);
49 | }
50 |
51 | static inline char32_t utf16_surrogate_pair_to_unichar(char16_t lead, char16_t trail) {
52 | return ((lead - 0xd800) << 10) + (trail - 0xdc00) + 0x10000;
53 | }
54 |
--------------------------------------------------------------------------------
/src/util.c:
--------------------------------------------------------------------------------
1 | /***
2 | This file is part of systemd.
3 |
4 | Copyright 2010 Lennart Poettering
5 |
6 | systemd is free software; you can redistribute it and/or modify it
7 | under the terms of the GNU Lesser General Public License as published by
8 | the Free Software Foundation; either version 2.1 of the License, or
9 | (at your option) any later version.
10 |
11 | systemd is distributed in the hope that it will be useful, but
12 | WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | Lesser General Public License for more details.
15 |
16 | You should have received a copy of the GNU Lesser General Public License
17 | along with systemd; If not, see .
18 | ***/
19 |
20 | #include
21 | #include
22 | #include
23 |
24 | #include "build.h"
25 | #include "macro.h"
26 | #include "util.h"
27 |
28 | /* Put this test here for a lack of better place */
29 | assert_cc(EAGAIN == EWOULDBLOCK);
30 |
31 | int saved_argc = 0;
32 | char **saved_argv = NULL;
33 |
34 | size_t page_size(void) {
35 | static thread_local size_t pgsz = 0;
36 | long r;
37 |
38 | if (_likely_(pgsz > 0))
39 | return pgsz;
40 |
41 | r = sysconf(_SC_PAGESIZE);
42 | assert(r > 0);
43 |
44 | pgsz = (size_t) r;
45 | return pgsz;
46 | }
47 |
48 | int version(void) {
49 | puts(PACKAGE_STRING "\n"
50 | SYSTEMD_FEATURES);
51 | return 0;
52 | }
53 |
--------------------------------------------------------------------------------
/src/util.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | /***
4 | This file is part of systemd.
5 |
6 | Copyright 2010 Lennart Poettering
7 |
8 | systemd is free software; you can redistribute it and/or modify it
9 | under the terms of the GNU Lesser General Public License as published by
10 | the Free Software Foundation; either version 2.1 of the License, or
11 | (at your option) any later version.
12 |
13 | systemd is distributed in the hope that it will be useful, but
14 | WITHOUT ANY WARRANTY; without even the implied warranty of
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | Lesser General Public License for more details.
17 |
18 | You should have received a copy of the GNU Lesser General Public License
19 | along with systemd; If not, see .
20 | ***/
21 |
22 | #include
23 | #include
24 | #include
25 | #include
26 | #include
27 | #include
28 |
29 | #include "attributes.h"
30 | #include "macro.h"
31 |
32 | size_t page_size(void) _pure_;
33 | #define PAGE_ALIGN(l) ALIGN_TO((l), page_size())
34 |
35 | static inline const char* yes_no(bool b) {
36 | return b ? "yes" : "no";
37 | }
38 |
39 | static inline const char* true_false(bool b) {
40 | return b ? "true" : "false";
41 | }
42 |
43 | static inline const char* one_zero(bool b) {
44 | return b ? "1" : "0";
45 | }
46 |
47 | #define NULSTR_FOREACH(i, l) \
48 | for ((i) = (l); (i) && *(i); (i) = strchr((i), 0)+1)
49 |
50 | #define NULSTR_FOREACH_PAIR(i, j, l) \
51 | for ((i) = (l), (j) = strchr((i), 0)+1; (i) && *(i); (i) = strchr((j), 0)+1, (j) = *(i) ? strchr((i), 0)+1 : (i))
52 |
53 | extern int saved_argc;
54 | extern char **saved_argv;
55 |
56 | /**
57 | * Normal qsort requires base to be nonnull. Here were require
58 | * that only if nmemb > 0.
59 | */
60 | static inline void qsort_safe(void *base, size_t nmemb, size_t size, comparison_fn_t compar) {
61 | if (nmemb <= 1)
62 | return;
63 |
64 | assert(base);
65 | qsort(base, nmemb, size, compar);
66 | }
67 |
68 | /**
69 | * Normal memcpy requires src to be nonnull. We do nothing if n is 0.
70 | */
71 | static inline void memcpy_safe(void *dst, const void *src, size_t n) {
72 | if (n == 0)
73 | return;
74 | assert(src);
75 | memcpy(dst, src, n);
76 | }
77 |
78 | #define memzero(x,l) (memset((x), 0, (l)))
79 | #define zero(x) (memzero(&(x), sizeof(x)))
80 |
81 | static inline void *mempset(void *s, int c, size_t n) {
82 | memset(s, c, n);
83 | return (uint8_t*)s + n;
84 | }
85 |
86 | static inline void _reset_errno_(int *saved_errno) {
87 | errno = *saved_errno;
88 | }
89 |
90 | #define PROTECT_ERRNO _cleanup_(_reset_errno_) __attribute__((unused)) int _saved_errno_ = errno
91 |
92 | static inline int negative_errno(void) {
93 | /* This helper should be used to shut up gcc if you know 'errno' is
94 | * negative. Instead of "return -errno;", use "return negative_errno();"
95 | * It will suppress bogus gcc warnings in case it assumes 'errno' might
96 | * be 0 and thus the caller's error-handling might not be triggered. */
97 | assert_return(errno > 0, -EINVAL);
98 | return -errno;
99 | }
100 |
101 | static inline unsigned u64log2(uint64_t n) {
102 | #if __SIZEOF_LONG_LONG__ == 8
103 | return (n > 1) ? (unsigned) __builtin_clzll(n) ^ 63U : 0;
104 | #else
105 | #error "Wut?"
106 | #endif
107 | }
108 |
109 | static inline unsigned u32ctz(uint32_t n) {
110 | #if __SIZEOF_INT__ == 4
111 | return __builtin_ctz(n);
112 | #else
113 | #error "Wut?"
114 | #endif
115 | }
116 |
117 | static inline unsigned log2i(int x) {
118 | assert(x > 0);
119 |
120 | return __SIZEOF_INT__ * 8 - __builtin_clz(x) - 1;
121 | }
122 |
123 | static inline unsigned log2u(unsigned x) {
124 | assert(x > 0);
125 |
126 | return sizeof(unsigned) * 8 - __builtin_clz(x) - 1;
127 | }
128 |
129 | static inline unsigned log2u_round_up(unsigned x) {
130 | assert(x > 0);
131 |
132 | if (x == 1)
133 | return 0;
134 |
135 | return log2u(x - 1) + 1;
136 | }
137 |
138 | int version(void);
139 |
--------------------------------------------------------------------------------
/tests/run:
--------------------------------------------------------------------------------
1 | #! /bin/sh
2 | d=
3 | cleanup() {
4 | if [ -n "$d" ]; then
5 | d=
6 | rm -rf "$d"
7 | fi
8 | }
9 | trap cleanup EXIT
10 | d=`mktemp -d`
11 |
12 | test_runs=0
13 | test_failures=0
14 |
15 | t() {
16 | "$@"
17 | local r=$?
18 | : $((test_runs=test_runs+1))
19 | if [ $r -ne 0 ]; then
20 | : $((test_failures=test_failures+1))
21 | echo "not ok $test_runs - $*"
22 | fi
23 | }
24 |
25 | echo 1..3
26 | t ./systemd-bootchart -o "$d" -n 2 -r
27 | t ./systemd-bootchart -o "$d" -n 10 -r
28 | t ./systemd-bootchart -o "$d" -n 10 -r -p
29 |
30 | if [ $test_failures -ne 0 ]; then
31 | echo "# Failed $test_failures out of $test_runs tests"
32 | exit 1
33 | fi
34 |
--------------------------------------------------------------------------------
/units/.gitignore:
--------------------------------------------------------------------------------
1 | /systemd-bootchart.service
2 |
--------------------------------------------------------------------------------
/units/systemd-bootchart.service.in:
--------------------------------------------------------------------------------
1 | # This file is part of systemd.
2 | #
3 | # systemd is free software; you can redistribute it and/or modify it
4 | # under the terms of the GNU Lesser General Public License as published by
5 | # the Free Software Foundation; either version 2.1 of the License, or
6 | # (at your option) any later version.
7 |
8 | # Note: it's usually a better idea to run systemd-bootchart via the
9 | # init= kernel command line switch. See the man page for details.
10 |
11 | [Unit]
12 | Description=Boot Process Profiler
13 | Documentation=man:systemd-bootchart(1) man:bootchart.conf(5)
14 | DefaultDependencies=no
15 |
16 | [Service]
17 | ExecStart=@rootlibexecdir@/systemd-bootchart -r
18 |
19 | [Install]
20 | WantedBy=sysinit.target
21 |
--------------------------------------------------------------------------------