Compare commits
326 commits
stable/v2.
...
master
Author | SHA1 | Date | |
---|---|---|---|
|
689c03b416 | ||
|
6462dbe2ef | ||
|
96de80b659 | ||
|
3e2e4c32e8 | ||
|
c8e36ed4db | ||
|
452801e4f6 | ||
|
5098291b2c | ||
|
85c9a0af07 | ||
|
95e853892f | ||
|
e9ddea7912 | ||
|
a753fb6520 | ||
|
5a17b1b626 | ||
|
46fe78989d | ||
|
b9abaae312 | ||
|
136f4874f4 | ||
|
971244fdc7 | ||
|
a8d0195462 | ||
|
2b48beb44e | ||
|
32c7870520 | ||
|
d191a7bef8 | ||
|
65c4be5fc2 | ||
|
0cac072b64 | ||
|
618dd71be4 | ||
|
0fb52dabba | ||
|
b1fc5d61f0 | ||
|
214e668c84 | ||
|
369007a5b7 | ||
|
7cbec02a47 | ||
|
fb978312aa | ||
|
8aa5b7c9d0 | ||
|
1225e6d0fb | ||
|
fb062800be | ||
|
b0d4d09379 | ||
|
fa6ac102dc | ||
|
08b35072b9 | ||
|
3a4d70419c | ||
|
0904cff4a5 | ||
|
ceb13fa9e8 | ||
|
55b0cc7106 | ||
|
69e7e599c0 | ||
|
c0ac6d590a | ||
|
c985e0742e | ||
|
2da0200327 | ||
|
af9fc22d03 | ||
|
3c5402640d | ||
|
af5efcd810 | ||
|
dc1d0f8dd1 | ||
|
4bcc2ed30d | ||
|
01a6d803b5 | ||
|
253c991da1 | ||
|
ee72ea94c5 | ||
|
ae62db7250 | ||
|
6a28c2f90a | ||
|
7111160934 | ||
|
cd8f11b7cb | ||
|
7b37d5b566 | ||
|
2235cf919a | ||
|
b0d003023c | ||
|
b4b8f8c293 | ||
|
f5b49efe42 | ||
|
ab7fe95ad7 | ||
|
76cf1753f4 | ||
|
14fee76fc1 | ||
|
42497e7d92 | ||
|
c34f86326d | ||
|
92e0e017d8 | ||
|
de7e11495b | ||
|
30ac13fa20 | ||
|
92c00d7215 | ||
|
cb233a3e03 | ||
|
9ac2c69dbd | ||
|
251319838d | ||
|
60c81b3272 | ||
|
4d34493450 | ||
|
33e347832e | ||
|
79feaa6022 | ||
|
278f76ae88 | ||
|
7293d66314 | ||
|
d7f1fc1839 | ||
|
b11005d90f | ||
|
a96b486d17 | ||
|
640e93f480 | ||
|
cd256c9f22 | ||
|
123ba32ae7 | ||
|
17bc58e018 | ||
|
44806f659f | ||
|
b9040ac267 | ||
|
07e7d1c781 | ||
|
334939a19d | ||
|
d6418774ab | ||
|
444753601c | ||
|
157a469671 | ||
|
6b58fb5f45 | ||
|
5e0e9730ca | ||
|
c1a26ac8f1 | ||
|
c032850e8f | ||
|
88ad4e7462 | ||
|
565eebbc45 | ||
|
b5fc1d120e | ||
|
c9fbfd99ad | ||
|
793e8d2ab8 | ||
|
1c8a51701d | ||
|
48554a4165 | ||
|
6182debc20 | ||
|
ed41386a03 | ||
|
69e98d12a9 | ||
|
765b4a147b | ||
|
0cc8e82a49 | ||
|
cee78467be | ||
|
07641fd93c | ||
|
1cb3c90ca5 | ||
|
8f49b3693d | ||
|
cb3dee5a14 | ||
|
fb8c224eae | ||
|
a13574b1de | ||
|
60d457f529 | ||
|
39032646fe | ||
|
6591ddf6b0 | ||
|
4012622ab4 | ||
|
82e8be5a3d | ||
|
b22d1e541a | ||
|
fd6b4d94ff | ||
|
97d60d6699 | ||
|
0dbf5504dc | ||
|
00f254a8f0 | ||
|
71b01d2a37 | ||
|
7db2e6373b | ||
|
b7dd45f6c8 | ||
|
57cd868ed1 | ||
|
2beb17a641 | ||
|
783807a511 | ||
|
16d8b1e2a6 | ||
|
7816bcb9da | ||
|
ed59afeefb | ||
|
63feafbae8 | ||
|
baadd080d3 | ||
|
50f73920c5 | ||
|
188b7d64bb | ||
|
1fa1856471 | ||
|
564d954a86 | ||
|
520f03a241 | ||
|
70b1623ca6 | ||
|
0dc26444be | ||
|
0a0c726e77 | ||
|
dd458e6585 | ||
|
326e4be479 | ||
|
9bd8074862 | ||
|
1b2efad216 | ||
|
11d0724f78 | ||
|
7140635881 | ||
|
d2f4b5c83b | ||
|
6f052eaa1e | ||
|
9b6ad16fd9 | ||
|
37b2b3fa46 | ||
|
ed3fd21fe2 | ||
|
3a14fb35be | ||
|
45552ef260 | ||
|
90b12595bb | ||
|
edc4e52533 | ||
|
b660e0c4df | ||
|
d53284bb1e | ||
|
023e77d26a | ||
|
a5b093698a | ||
|
25a70dcb2e | ||
|
58c16c8442 | ||
|
d975467d8f | ||
|
ae20b7fb4c | ||
|
754c030f29 | ||
|
99e7f7101a | ||
|
edbd9ee562 | ||
|
142738e861 | ||
|
423bf01e7e | ||
|
ddf41df9e9 | ||
|
84a8f5edb2 | ||
|
565eae0cf4 | ||
|
9ff6f9d9ab | ||
|
efb18899d2 | ||
|
0c7df652e2 | ||
|
4869b259d6 | ||
|
cba97be9fb | ||
|
96c8ff27a4 | ||
|
9bd0ed6fba | ||
|
e97637ec6f | ||
|
ac2fc8b442 | ||
|
f271f09bd6 | ||
|
bf416aeca3 | ||
|
c2e2dd6008 | ||
|
3062a58f0b | ||
|
36d4e61c65 | ||
|
63d4806055 | ||
|
f94a7760ed | ||
|
12c616b029 | ||
|
27675c5c62 | ||
|
24a10f06e9 | ||
|
c3f8cba1d4 | ||
|
de9ec7ee36 | ||
|
c1cb27357c | ||
|
916b44a59a | ||
|
d5ca01c0f4 | ||
|
ccd4e14285 | ||
|
d289149385 | ||
|
c345a4002b | ||
|
3e0bbb1222 | ||
|
e2cd74462e | ||
|
29e3f73784 | ||
|
fc5018e801 | ||
|
9d48efbbe7 | ||
|
ffdd75ccee | ||
|
fb889bab8b | ||
|
c733db6114 | ||
|
3429accb62 | ||
|
f6fb7fa713 | ||
|
e1cd4002c8 | ||
|
f265b43296 | ||
|
54e94f8669 | ||
|
99550bf5aa | ||
|
9105d3cdd8 | ||
|
a5eba5046d | ||
|
a5e0e06cc2 | ||
|
fe0b1e793c | ||
|
51a97767db | ||
|
d6850a7611 | ||
|
330555c481 | ||
|
29bcb60ee6 | ||
|
e2d6f5e30e | ||
|
ad0569880f | ||
|
c0267687fd | ||
|
096800a0df | ||
|
59dc323560 | ||
|
518026915b | ||
|
f1cd43964d | ||
|
c8ecfe1e39 | ||
|
0045193005 | ||
|
3dae5ca16a | ||
|
e20944db44 | ||
|
b39f5764b9 | ||
|
392d864b75 | ||
|
f644f33089 | ||
|
8128908d32 | ||
|
ccd06765ce | ||
|
cc665f33f4 | ||
|
8a53082787 | ||
|
ced82526a1 | ||
|
1bd85b6463 | ||
|
47035719fc | ||
|
c0f31b79f5 | ||
|
33980996d0 | ||
|
e5009e773f | ||
|
8b36444f44 | ||
|
06e05eb0f7 | ||
|
5f7c4093e2 | ||
|
9b1cf2bc69 | ||
|
d36705f402 | ||
|
cf652a7278 | ||
|
c249602368 | ||
|
9c9d03e064 | ||
|
43d4d1cc1d | ||
|
6c1bd545cb | ||
|
1808882ad3 | ||
|
7eba8f98bd | ||
|
babcf0896c | ||
|
821efb4f6f | ||
|
5ba67aeabd | ||
|
26406d1a72 | ||
|
90317e2a12 | ||
|
d4fea4d089 | ||
|
e62d587334 | ||
|
f9263edc9b | ||
|
1c2ab17ecd | ||
|
79ec864eaa | ||
|
e283500c05 | ||
|
55c857ae09 | ||
|
8c2ca9c973 | ||
|
4a3d70fed3 | ||
|
1e83b1fc6f | ||
|
007e405b1e | ||
|
c0d75916b6 | ||
|
b83e58a55c | ||
|
01a0a55601 | ||
|
03a8f430c5 | ||
|
a82df27f5d | ||
|
d3edf0f8de | ||
|
bd2ebbd4ea | ||
|
372e026e09 | ||
|
976157c821 | ||
|
747fe9946a | ||
|
afb669afed | ||
|
4b1538c754 | ||
|
69e542bd2d | ||
|
5e248716e6 | ||
|
7f104027e2 | ||
|
9e8fb1f5ed | ||
|
ae03abcf56 | ||
|
ac5267423d | ||
|
a3fdbe0c4f | ||
|
13d1cbced2 | ||
|
344ba205c1 | ||
|
4290056351 | ||
|
113356e95d | ||
|
58fe26362c | ||
|
165fbfd46e | ||
|
7626054ca8 | ||
|
f080b635a1 | ||
|
cba52cc194 | ||
|
bb2b071f54 | ||
|
42de8aba28 | ||
|
bbf5bf8a88 | ||
|
8b70b9e32a | ||
|
6aa8d17b6b | ||
|
b1580bd760 | ||
|
ed3d33faff | ||
|
84ec6f99f7 | ||
|
b0826e8c98 | ||
|
d996ff1dc6 | ||
|
4832fd9f36 | ||
|
91ea38e91d | ||
|
a61bbb3709 | ||
|
1bf9c6915e | ||
|
2ed0190535 | ||
|
575d71fde1 | ||
|
d4b1d901c5 | ||
|
12252002ad | ||
|
bcebab29a7 | ||
|
ad6d9fd50c | ||
|
5b175fa9f0 | ||
|
acb72212eb |
292 changed files with 20382 additions and 92886 deletions
5
.github/workflows/cibuild-setup-ubuntu.sh
vendored
5
.github/workflows/cibuild-setup-ubuntu.sh
vendored
|
@ -29,6 +29,7 @@ PACKAGES=(
|
|||
iproute2
|
||||
dmsetup
|
||||
python3-dev
|
||||
gawk
|
||||
)
|
||||
|
||||
PACKAGES_OPTIONAL=(
|
||||
|
@ -59,7 +60,9 @@ bash -c "echo 'deb-src http://archive.ubuntu.com/ubuntu/ $RELEASE main restricte
|
|||
# cov-build fails to compile util-linux when CC is set to gcc-*
|
||||
# so let's just install and use the default compiler
|
||||
if [[ "$COMPILER_VERSION" == "" ]]; then
|
||||
PACKAGES+=("$COMPILER")
|
||||
if [[ "$COMPILER" != "none" ]]; then
|
||||
PACKAGES+=("$COMPILER")
|
||||
fi
|
||||
elif [[ "$COMPILER" == clang ]]; then
|
||||
# Latest LLVM stack deb packages provided by https://apt.llvm.org/
|
||||
# Following snippet was borrowed from https://apt.llvm.org/llvm.sh
|
||||
|
|
31
.github/workflows/cibuild.sh
vendored
31
.github/workflows/cibuild.sh
vendored
|
@ -1,5 +1,5 @@
|
|||
#!/bin/bash
|
||||
|
||||
|
||||
set -ex
|
||||
|
||||
PHASES=(${@:-CONFIGURE MAKE INSTALL CHECK DISTCHECK})
|
||||
|
@ -87,9 +87,7 @@ for phase in "${PHASES[@]}"; do
|
|||
)
|
||||
|
||||
if [[ "$COVERAGE" == "yes" ]]; then
|
||||
CFLAGS+=(--coverage)
|
||||
CXXFLAGS+=(--coverage)
|
||||
LDFLAGS+=(--coverage)
|
||||
opts+=(--enable-coverage)
|
||||
fi
|
||||
|
||||
if [[ "$SANITIZE" == "yes" ]]; then
|
||||
|
@ -104,6 +102,11 @@ for phase in "${PHASES[@]}"; do
|
|||
CXXFLAGS+=(-shared-libasan)
|
||||
fi
|
||||
|
||||
if [[ "$HOST_TRIPLET" != "" ]]; then
|
||||
opts+=(--host "$HOST_TRIPLET")
|
||||
fi
|
||||
|
||||
git config --global --add safe.directory "$PWD"
|
||||
git clean -xdf
|
||||
|
||||
./autogen.sh
|
||||
|
@ -123,9 +126,9 @@ for phase in "${PHASES[@]}"; do
|
|||
ninja -C build
|
||||
;;
|
||||
CODECHECK)
|
||||
make checklibdoc
|
||||
make checkxalloc
|
||||
;;
|
||||
make checklibdoc
|
||||
make checkxalloc
|
||||
;;
|
||||
CHECK)
|
||||
if [[ "$SANITIZE" == "yes" ]]; then
|
||||
# All the following black magic is to make test/eject/umount work, since
|
||||
|
@ -157,6 +160,20 @@ for phase in "${PHASES[@]}"; do
|
|||
fi
|
||||
fi
|
||||
|
||||
if [[ "$COVERAGE" == "yes" ]]; then
|
||||
# Make (almost) everything under current directory readable/writable
|
||||
# for everyone to allow gcov to write the .gcda files even with
|
||||
# dropped privileges
|
||||
find . tests/helpers/ -maxdepth 1 -type d ! -name . ! -name tests \
|
||||
-exec setfacl -R -m 'd:g::rwX,d:o::rwX' -m 'g::rwX,o::rwX' '{}' \;
|
||||
# Make sure we can access $PWD as an unpriv user
|
||||
path="$PWD"
|
||||
while [[ "$path" != / ]]; do
|
||||
chmod o+rx "$path"
|
||||
path="$(dirname "$path")"
|
||||
done
|
||||
fi
|
||||
|
||||
./tests/run.sh --show-diff
|
||||
|
||||
if [[ "$COVERAGE" == "yes" ]]; then
|
||||
|
|
110
.github/workflows/cibuild.yml
vendored
110
.github/workflows/cibuild.yml
vendored
|
@ -20,14 +20,18 @@ permissions:
|
|||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ toJSON(matrix.env) }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
env:
|
||||
- { COMPILER: "gcc", COMPILER_VERSION: "10", SANITIZE: "yes" }
|
||||
- { COMPILER: "gcc", COMPILER_VERSION: "10", SANITIZE: "no" }
|
||||
- { COMPILER: "clang", COMPILER_VERSION: "15", SANITIZE: "yes" }
|
||||
- { COMPILER: "clang", COMPILER_VERSION: "15", SANITIZE: "no" }
|
||||
# gcc-13 has false-positives with ubsan
|
||||
- { COMPILER: "gcc", COMPILER_VERSION: "11", SANITIZE: "yes" }
|
||||
- { COMPILER: "gcc", COMPILER_VERSION: "13", SANITIZE: "no" }
|
||||
- { COMPILER: "clang", COMPILER_VERSION: "16", SANITIZE: "yes" }
|
||||
- { COMPILER: "clang", COMPILER_VERSION: "16", SANITIZE: "no" }
|
||||
env: ${{ matrix.env }}
|
||||
steps:
|
||||
- name: Repository checkout
|
||||
|
@ -44,13 +48,16 @@ jobs:
|
|||
run: sudo -E .github/workflows/cibuild.sh CHECK
|
||||
- name: Make install
|
||||
run: .github/workflows/cibuild.sh INSTALL
|
||||
|
||||
coveralls:
|
||||
permissions:
|
||||
contents: read # to fetch code (actions/checkout)
|
||||
checks: write # to create new checks (coverallsapp/github-action)
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
if: github.repository == 'util-linux/util-linux'
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-coveralls-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
env:
|
||||
COMPILER: gcc
|
||||
COMPILER_VERSION: 10
|
||||
|
@ -70,9 +77,13 @@ jobs:
|
|||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
path-to-lcov: ./coverage.info
|
||||
|
||||
meson:
|
||||
needs: build
|
||||
runs-on: ubuntu-latest
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-meson-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
env:
|
||||
COMPILER: gcc
|
||||
COMPILER_VERSION: 10
|
||||
|
@ -86,9 +97,13 @@ jobs:
|
|||
run: .github/workflows/cibuild.sh MESONCONF
|
||||
- name: Meson build
|
||||
run: .github/workflows/cibuild.sh MESONBUILD
|
||||
|
||||
distcheck:
|
||||
needs: build
|
||||
runs-on: ubuntu-latest
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-distcheck-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
env:
|
||||
COMPILER: gcc
|
||||
COMPILER_VERSION: 10
|
||||
|
@ -103,9 +118,42 @@ jobs:
|
|||
run: .github/workflows/cibuild.sh CONFIGURE
|
||||
- name: Make distcheck
|
||||
run: .github/workflows/cibuild.sh DISTCHECK
|
||||
|
||||
build-compat:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- image: ubuntu:18.04
|
||||
name: build (compat, ${{ matrix.image }})
|
||||
runs-on: ubuntu-latest
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-build-compat-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
env:
|
||||
COMPILER: none
|
||||
container:
|
||||
image: ${{ matrix.image }}
|
||||
steps:
|
||||
- name: Repository checkout
|
||||
uses: actions/checkout@v1
|
||||
- name: Ubuntu setup
|
||||
run: .github/workflows/cibuild-setup-ubuntu.sh
|
||||
- name: Configure
|
||||
run: .github/workflows/cibuild.sh CONFIGURE
|
||||
- name: Code checks
|
||||
run: .github/workflows/cibuild.sh CODECHECK
|
||||
- name: Configure & Make
|
||||
run: .github/workflows/cibuild.sh MAKE
|
||||
- name: Check
|
||||
run: .github/workflows/cibuild.sh CHECK
|
||||
|
||||
build-arch:
|
||||
name: build (qemu-user, ${{ matrix.arch }})
|
||||
runs-on: ubuntu-latest
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ toJSON(matrix) }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
|
@ -133,3 +181,55 @@ jobs:
|
|||
.github/workflows/cibuild.sh CONFIGURE MAKE
|
||||
# Check
|
||||
.github/workflows/cibuild.sh CHECK
|
||||
|
||||
build-openwrt:
|
||||
name: build (openwrt, ${{ matrix.target }})
|
||||
runs-on: ubuntu-latest
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ toJSON(matrix) }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- target: ipq40xx
|
||||
subtarget: generic
|
||||
abi: musl_eabi
|
||||
- target: ath79
|
||||
subtarget: generic
|
||||
abi: musl
|
||||
- target: bcm63xx
|
||||
subtarget: generic
|
||||
abi: musl
|
||||
- target: mpc85xx
|
||||
subtarget: p2020
|
||||
abi: musl
|
||||
- target: archs38
|
||||
subtarget: generic
|
||||
abi: glibc
|
||||
env:
|
||||
COMPILER: none
|
||||
steps:
|
||||
- name: Repository checkout
|
||||
uses: actions/checkout@v1
|
||||
- name: Ubuntu setup
|
||||
run: sudo -E .github/workflows/cibuild-setup-ubuntu.sh
|
||||
- name: OpenWrt environment
|
||||
run: |
|
||||
OPENWRT_RELEASE=22.03.5
|
||||
OPENWRT_SDK=openwrt-sdk-$OPENWRT_RELEASE-${{ matrix.target }}-${{ matrix.subtarget }}_gcc-11.2.0_${{ matrix.abi }}.Linux-x86_64
|
||||
echo "COMPILER=$COMPILER" >> $GITHUB_ENV
|
||||
echo "OPENWRT_RELEASE=$OPENWRT_RELEASE" >> $GITHUB_ENV
|
||||
echo "OPENWRT_SDK=$OPENWRT_SDK" >> $GITHUB_ENV
|
||||
- name: Download toolchain
|
||||
run: |
|
||||
curl -o ~/${{ env.OPENWRT_SDK }}.tar.xz -C - https://downloads.cdn.openwrt.org/releases/${{ env.OPENWRT_RELEASE }}/targets/${{ matrix.target }}/${{ matrix.subtarget }}/${{ env.OPENWRT_SDK }}.tar.xz
|
||||
tar xf ~/${{ env.OPENWRT_SDK }}.tar.xz -C ~
|
||||
- name: Configure
|
||||
run: |
|
||||
source .github/workflows/openwrt-sdk-env.sh ~/${{ env.OPENWRT_SDK }}
|
||||
.github/workflows/cibuild.sh CONFIGURE
|
||||
- name: Make
|
||||
run: |
|
||||
source .github/workflows/openwrt-sdk-env.sh ~/${{ env.OPENWRT_SDK }}
|
||||
.github/workflows/cibuild.sh MAKE
|
||||
|
|
3
.github/workflows/cifuzz.yml
vendored
3
.github/workflows/cifuzz.yml
vendored
|
@ -23,6 +23,9 @@ jobs:
|
|||
|
||||
runs-on: ubuntu-latest
|
||||
if: github.repository == 'util-linux/util-linux'
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ matrix.sanitizer }}-${{ matrix.architecture }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
|
|
17
.github/workflows/openwrt-sdk-env.sh
vendored
Executable file
17
.github/workflows/openwrt-sdk-env.sh
vendored
Executable file
|
@ -0,0 +1,17 @@
|
|||
#!/bin/sh
|
||||
|
||||
sdk="$(realpath $1)"
|
||||
|
||||
STAGING_DIR="$(echo "$sdk"/staging_dir/toolchain-*)"
|
||||
|
||||
. "$STAGING_DIR/info.mk"
|
||||
|
||||
PATH="$sdk/staging_dir/host/bin:$PATH"
|
||||
CC="$STAGING_DIR/bin/${TARGET_CROSS}gcc"
|
||||
BISON_PKGDATADIR="$sdk/staging_dir/host/share/bison"
|
||||
M4="$sdk/staging_dir/host/bin/m4"
|
||||
HOST_TRIPLET="$("$CC" -dumpmachine)"
|
||||
|
||||
echo "Building for $HOST_TRIPLET from $sdk"
|
||||
|
||||
export STAGING_DIR PATH CC BISON_PKGDATADIR M4 HOST_TRIPLET
|
12
.gitignore
vendored
12
.gitignore
vendored
|
@ -46,6 +46,10 @@ config/test-driver
|
|||
configure
|
||||
cscope.out
|
||||
depcomp
|
||||
GPATH
|
||||
GRTAGS
|
||||
GTAGS
|
||||
GSYMS
|
||||
INSTALL
|
||||
install-sh
|
||||
libtool
|
||||
|
@ -58,22 +62,20 @@ mkinstalldirs
|
|||
stamp-h
|
||||
stamp-h.in
|
||||
stamp-h1
|
||||
syscalls.h
|
||||
tags
|
||||
test-suite.log
|
||||
tests/run.sh.log
|
||||
tests/run.sh.trs
|
||||
update.log
|
||||
ylwrap
|
||||
GPATH
|
||||
GRTAGS
|
||||
GTAGS
|
||||
GSYMS
|
||||
|
||||
#
|
||||
# binaries
|
||||
#
|
||||
/addpart
|
||||
/agetty
|
||||
/build*/
|
||||
/blkdiscard
|
||||
/blkid
|
||||
/blkpr
|
||||
|
@ -95,6 +97,7 @@ GSYMS
|
|||
/delpart
|
||||
/dmesg
|
||||
/eject
|
||||
/enosys
|
||||
/fadvise
|
||||
/fallocate
|
||||
/fdformat
|
||||
|
@ -197,4 +200,3 @@ GSYMS
|
|||
/wipefs
|
||||
/write
|
||||
/zramctl
|
||||
/build*/
|
||||
|
|
2
AUTHORS
2
AUTHORS
|
@ -397,7 +397,6 @@ CONTRIBUTORS:
|
|||
Helmut Grohne <helmut@subdivi.de>
|
||||
Hendrik Lönngren <wikibugs@googlemail.com>
|
||||
Henne Vogelsang <hvogel@opensuse.org>
|
||||
Hennie Botha <42469385+theHenMan@users.noreply.github.com>
|
||||
Hideki EIRAKU <hdk@igel.co.jp>
|
||||
Hill Ma <maahiuzeon@gmail.com>
|
||||
Hiroaki Sengoku <sengoku@senri.gcd.org>
|
||||
|
@ -751,7 +750,6 @@ CONTRIBUTORS:
|
|||
ratijas <me@ratijas.tk>
|
||||
Raul Gutierrez Segales <rgs@itevenworks.net>
|
||||
Ray Wang <wanglei1123@gmail.com>
|
||||
Remus-Gabriel Chelu <remusgabriel.chelu@disroot.org>
|
||||
Rian Hunter <rian@alum.mit.edu>
|
||||
Richard Allen <rsaxvc@rsaxvc.net>
|
||||
Richard Fuchs <rfuchs@sipwise.com>
|
||||
|
|
|
@ -1,117 +0,0 @@
|
|||
util-linux v2.39.1 Release Notes
|
||||
================================
|
||||
|
||||
The main objective of this maintenance release is to address bugs in libmount and
|
||||
resolve the regression that occurred due to the v2.39 rewrite for the new kernel
|
||||
mount interface.
|
||||
|
||||
The meson build system has also been enhanced.
|
||||
|
||||
|
||||
Changes between v2.39 and v2.39.1
|
||||
---------------------------------
|
||||
|
||||
blkzone:
|
||||
- don't take address of struct blk_zone [Thomas Weißschuh]
|
||||
build-sys:
|
||||
- add --disable-waitpid [Frantisek Sumsal]
|
||||
- don't call pkg-config --static if unnecessary [Karel Zak]
|
||||
- fix typo in waitpid check [Thomas Weißschuh]
|
||||
- only pass --failure-level if supported [Thomas Weißschuh]
|
||||
cal:
|
||||
- fix error message for bad -c argument [Jakub Wilk]
|
||||
- fix long option name for -c [Jakub Wilk]
|
||||
ci:
|
||||
- prevent prompts during installation [Thomas Weißschuh]
|
||||
dmesg:
|
||||
- make kmsg read() buffer big enough for kernel [anteater]
|
||||
docs:
|
||||
- update AUTHORS file [Karel Zak]
|
||||
enosys:
|
||||
- add support for MIPS, PowerPC and ARC [Thomas Weißschuh]
|
||||
- add support for loongarch [Thomas Weißschuh]
|
||||
- add support for sparc [Thomas Weißschuh]
|
||||
- split audit arch detection into dedicated header [Thomas Weißschuh]
|
||||
hardlink:
|
||||
- (man) add missing comma [Jakub Wilk]
|
||||
lib:
|
||||
- remove pager.c from libcommon [Karel Zak]
|
||||
lib/ include/:
|
||||
- cleanup license headers [Karel Zak]
|
||||
lib/color-names:
|
||||
- fix license header [Karel Zak]
|
||||
lib/loopdev:
|
||||
- consistently return error values from loopcxt_find_unused() [Thomas Weißschuh]
|
||||
- document function return values [Thomas Weißschuh]
|
||||
lib/strutils:
|
||||
- fix typo [Jakub Wilk]
|
||||
libblkid:
|
||||
- (bcache) also calculate checksum over journal buckets [Thomas Weißschuh]
|
||||
- (bcache) extend superblock definition [Thomas Weißschuh]
|
||||
- jfs - avoid undefined shift [Milan Broz]
|
||||
libmount:
|
||||
- (optlist) correctly detect ro status [Thomas Weißschuh]
|
||||
- always ignore user=<name> [Karel Zak]
|
||||
- check for availability of mount_setattr [Thomas Weißschuh]
|
||||
- cleanup enosys returns from mount hoop [Karel Zak]
|
||||
- don't call hooks after mount.<type> helper [Karel Zak]
|
||||
- don't call mount.<type> helper with usernames [Karel Zak]
|
||||
- don't pass option "defaults" to helper [Thomas Weißschuh]
|
||||
- fix options prepend/insert and merging [Karel Zak]
|
||||
- fix sync options between context and fs structs [Karel Zak]
|
||||
- introduce LIBMOUNT_FORCE_MOUNT2={always,never,auto} [Karel Zak]
|
||||
libsmartcols:
|
||||
- (samples) fix format truncation warning [Thomas Weißschuh]
|
||||
logger:
|
||||
- initialize socket credentials contol union [Karel Zak]
|
||||
losetup:
|
||||
- deduplicate find_unused() logic [Thomas Weißschuh]
|
||||
lsfd:
|
||||
- (filter) weakly support ARRAY_STRING and ARRAY_NUMBER json types [Masatake YAMATO]
|
||||
- (tests) fix typo [Thomas Weißschuh]
|
||||
- use ARRAY_STRING for ENDPOINTS column in JSON output mode [Masatake YAMATO]
|
||||
meson:
|
||||
- add conditionalization for test progs [Zbigniew Jędrzejewski-Szmek]
|
||||
- check for _NL_TIME_WEEK_1STDAY in langinfo.h [Christian Hesse]
|
||||
- conditionalize waitpid [Zbigniew Jędrzejewski-Szmek]
|
||||
- implement HAVE_PTY [Zbigniew Jędrzejewski-Szmek]
|
||||
- include bash-completion for newgrp [Christian Hesse]
|
||||
- include bash-completion for write [Christian Hesse]
|
||||
- install chfn setuid [Christian Hesse]
|
||||
- install chsh setuid [Christian Hesse]
|
||||
- install mount setuid [Christian Hesse]
|
||||
- install newgrp setuid [Christian Hesse]
|
||||
- install su setuid [Christian Hesse]
|
||||
- install symlink for vigr man page [Christian Hesse]
|
||||
- install umount setuid [Christian Hesse]
|
||||
- install wall setgid [Christian Hesse]
|
||||
- install write setgid [Christian Hesse]
|
||||
- require 0.57 [Thomas Weißschuh]
|
||||
mkfs.minix:
|
||||
- handle 64bit time on 32bit system [Thomas Weißschuh]
|
||||
po:
|
||||
- merge changes [Karel Zak]
|
||||
- update hr.po (from translationproject.org) [Božidar Putanec]
|
||||
po-man:
|
||||
- add ko.po (from translationproject.org) [Seong-ho Cho]
|
||||
- add ro.po (from translationproject.org) [Remus-Gabriel Chelu]
|
||||
- merge changes [Karel Zak]
|
||||
- update uk.po (from translationproject.org) [Yuri Chornoivan]
|
||||
sfdisk:
|
||||
- add hint about duplicate UUIDs when use dump [Karel Zak]
|
||||
test_enosys:
|
||||
- fix build on old kernels [Thomas Weißschuh]
|
||||
test_uuidd:
|
||||
- make pthread_t formatting more robust [Thomas Weißschuh]
|
||||
tests:
|
||||
- (lsfd) add a case for verifying ENDPOINTS column output in JSON mode [Masatake YAMATO]
|
||||
- (run.sh) detect builddir from working directory [Thomas Weißschuh]
|
||||
- backport mount_setattr test [Karel Zak]
|
||||
- backport special mount script [Karel Zak]
|
||||
- fix update special mount test output [Karel Zak]
|
||||
tools:
|
||||
- (asciidoctor) explicitly require extensions module [Thomas Weißschuh]
|
||||
unshare:
|
||||
- fix error message for unexpected time offsets [Thomas Weißschuh]
|
||||
waitpid:
|
||||
- only build when pidfd_open is available [Thomas Weißschuh]
|
|
@ -17,9 +17,14 @@ AM_CPPFLAGS += \
|
|||
endif
|
||||
endif
|
||||
|
||||
if WITH_COVERAGE
|
||||
AM_CPPFLAGS += \
|
||||
-include $(top_srcdir)/include/coverage.h
|
||||
endif
|
||||
|
||||
AM_CFLAGS = -fsigned-char $(WARN_CFLAGS)
|
||||
AM_CXXFLAGS = $(AM_CFLAGS)
|
||||
AM_LDFLAGS = $(ASAN_LDFLAGS) $(UBSAN_LDFLAGS) $(FUZZING_ENGINE_LDFLAGS)
|
||||
AM_LDFLAGS = $(ASAN_LDFLAGS) $(UBSAN_LDFLAGS) $(FUZZING_ENGINE_LDFLAGS) $(COVERAGE_LDFLAGS)
|
||||
|
||||
# Add gettext stuff to the global LDADD for systems with separate libintl
|
||||
# library. The LTLIBINTL is generated by AM_GNU_GETTEXT macro.
|
||||
|
|
4
NEWS
4
NEWS
|
@ -1,7 +1,3 @@
|
|||
util-linux 2.39.1: Jun 27 2023
|
||||
* see Documentation/releases/v2.39.1-ReleaseNotes or the complete changelog at
|
||||
https://www.kernel.org/pub/linux/utils/util-linux/v2.39/v2.39.1-ChangeLog
|
||||
|
||||
util-linux 2.39: May 17 2023
|
||||
* see Documentation/releases/v2.39-ReleaseNotes or the complete changelog at
|
||||
https://www.kernel.org/pub/linux/utils/util-linux/v2.39/v2.39-ChangeLog
|
||||
|
|
|
@ -344,5 +344,11 @@ endif
|
|||
if BUILD_WAITPID
|
||||
dist_bashcompletion_DATA += bash-completion/waitpid
|
||||
endif
|
||||
if BUILD_ENOSYS
|
||||
dist_bashcompletion_DATA += bash-completion/enosys
|
||||
endif
|
||||
if BUILD_LSCLOCKS
|
||||
dist_bashcompletion_DATA += bash-completion/lsclocks
|
||||
endif
|
||||
|
||||
endif # BUILD_BASH_COMPLETION
|
||||
|
|
|
@ -13,6 +13,7 @@ _blockdev_module()
|
|||
--getro
|
||||
--getdiscardzeroes
|
||||
--getdiskseq
|
||||
--getzonesz
|
||||
--getss
|
||||
--getpbsz
|
||||
--getiomin
|
||||
|
|
37
bash-completion/enosys
Normal file
37
bash-completion/enosys
Normal file
|
@ -0,0 +1,37 @@
|
|||
_waitpid_module()
|
||||
{
|
||||
local cur prev OPTS
|
||||
COMPREPLY=()
|
||||
cur="${COMP_WORDS[COMP_CWORD]}"
|
||||
prev="${COMP_WORDS[COMP_CWORD-1]}"
|
||||
case $prev in
|
||||
'-s'|'--syscall')
|
||||
return 0
|
||||
;;
|
||||
'-l'|'--list')
|
||||
return 0
|
||||
;;
|
||||
'-h'|'--help'|'-V'|'--version')
|
||||
return 0
|
||||
;;
|
||||
esac
|
||||
case $cur in
|
||||
-*)
|
||||
OPTS="--syscall
|
||||
--list
|
||||
--help
|
||||
--version"
|
||||
COMPREPLY=( $(compgen -W "${OPTS[*]}" -- $cur) )
|
||||
return 0
|
||||
;;
|
||||
*)
|
||||
_pids
|
||||
return 0
|
||||
;;
|
||||
esac
|
||||
local IFS=$'\n'
|
||||
compopt -o filenames
|
||||
COMPREPLY=( $(compgen -u -- $cur) )
|
||||
return 0
|
||||
}
|
||||
complete -F _enosys_module enosys
|
|
@ -28,6 +28,7 @@ _hexdump_module()
|
|||
case $cur in
|
||||
-*)
|
||||
OPTS=" --one-byte-octal
|
||||
--one-byte-hex
|
||||
--one-byte-char
|
||||
--canonical
|
||||
--two-bytes-decimal
|
||||
|
|
|
@ -54,6 +54,8 @@ _hwclock_module()
|
|||
--epoch
|
||||
--param-get
|
||||
--param-set
|
||||
--vl-read
|
||||
--vl-clear
|
||||
--update-drift
|
||||
--noadjfile
|
||||
--adjfile
|
||||
|
|
48
bash-completion/lsclocks
Normal file
48
bash-completion/lsclocks
Normal file
|
@ -0,0 +1,48 @@
|
|||
_lsclocks_module()
|
||||
{
|
||||
local cur prev OPTS
|
||||
COMPREPLY=()
|
||||
cur="${COMP_WORDS[COMP_CWORD]}"
|
||||
prev="${COMP_WORDS[COMP_CWORD-1]}"
|
||||
|
||||
case $prev in
|
||||
'-J'|'--json')
|
||||
return 0
|
||||
;;
|
||||
'-n'|'--noheadings')
|
||||
return 0
|
||||
;;
|
||||
'-o'|'--output')
|
||||
return 0
|
||||
;;
|
||||
'-r'|'--raw')
|
||||
return 0
|
||||
;;
|
||||
'-t'|'--time')
|
||||
clocks="$(command "$1" --noheadings --raw --output NAME)"
|
||||
COMPREPLY=( $(compgen -W "$clocks" -- "$cur") )
|
||||
return 0
|
||||
;;
|
||||
'-h'|'--help'|'-V'|'--version')
|
||||
return 0
|
||||
;;
|
||||
esac
|
||||
case $cur in
|
||||
-*)
|
||||
OPTS="--json
|
||||
--noheadings
|
||||
--output
|
||||
--raw
|
||||
--time
|
||||
--help
|
||||
--version"
|
||||
COMPREPLY=( $(compgen -W "${OPTS[*]}" -- $cur) )
|
||||
return 0
|
||||
;;
|
||||
*)
|
||||
return 0
|
||||
;;
|
||||
esac
|
||||
return 0
|
||||
}
|
||||
complete -F _lsclocks_module lsclocks
|
|
@ -21,13 +21,17 @@ _mkswap_module()
|
|||
COMPREPLY=( $(compgen -W "$(uuidgen -r)" -- $cur) )
|
||||
return 0
|
||||
;;
|
||||
'-o'|'--offset')
|
||||
COMPREPLY=( $(compgen -W "bytes" -- $cur) )
|
||||
return 0
|
||||
;;
|
||||
'-h'|'--help'|'-V'|'--version')
|
||||
return 0
|
||||
;;
|
||||
esac
|
||||
case $cur in
|
||||
-*)
|
||||
OPTS="--check --force --pagesize --lock --label --swapversion --uuid --verbose --version --help"
|
||||
OPTS="--check --force --pagesize --lock --label --swapversion --uuid --offset --verbose --version --help"
|
||||
COMPREPLY=( $(compgen -W "${OPTS[*]}" -- $cur) )
|
||||
return 0
|
||||
;;
|
||||
|
|
|
@ -42,9 +42,11 @@ _nsenter_module()
|
|||
--pid=
|
||||
--cgroup=
|
||||
--user=
|
||||
--user-parent
|
||||
--time=
|
||||
--setuid
|
||||
--setgid
|
||||
--keep-caps
|
||||
--preserve-credentials
|
||||
--root=
|
||||
--wd=
|
||||
|
|
35
configure.ac
35
configure.ac
|
@ -29,7 +29,7 @@ PACKAGE_VERSION_RELEASE=$(echo $PACKAGE_VERSION | awk -F. '{
|
|||
|
||||
dnl libblkid version
|
||||
LIBBLKID_VERSION="$PACKAGE_VERSION_MAJOR.$PACKAGE_VERSION_MINOR.$PACKAGE_VERSION_RELEASE"
|
||||
LIBBLKID_DATE="27-Jun-2023"
|
||||
LIBBLKID_DATE="17-May-2023"
|
||||
LIBBLKID_LT_MAJOR=1
|
||||
LIBBLKID_LT_MINOR=1
|
||||
LIBBLKID_LT_MICRO=0
|
||||
|
@ -215,6 +215,17 @@ AC_PROG_CXX
|
|||
AM_CONDITIONAL([FUZZING_ENGINE], [test "x$enable_fuzzing_engine" = xyes])
|
||||
AM_CONDITIONAL([OSS_FUZZ], [test "x$LIB_FUZZING_ENGINE" != x])
|
||||
|
||||
AC_ARG_ENABLE([coverage],
|
||||
AS_HELP_STRING([--enable-coverage], [compile with gcov]),
|
||||
[], [enable_coverage=no]
|
||||
)
|
||||
AS_IF([test "x$enable_coverage" = xyes], [
|
||||
UL_WARN_ADD([--coverage])
|
||||
COVERAGE_LDFLAGS="--coverage"
|
||||
])
|
||||
AC_SUBST([COVERAGE_LDFLAGS])
|
||||
AM_CONDITIONAL([WITH_COVERAGE], [test "x$enable_coverage" = xyes])
|
||||
|
||||
dnl libtool-2
|
||||
LT_INIT
|
||||
|
||||
|
@ -729,6 +740,9 @@ AS_IF([test x"$have_dirfd" = xno], [
|
|||
|
||||
AM_CONDITIONAL([HAVE_DIRFD], [test "x$have_dirfd" = xyes || test "x$have_ddfd" = xyes])
|
||||
|
||||
MQ_LIBS=
|
||||
AC_CHECK_LIB([rt], [mq_open], [MQ_LIBS="-lrt"])
|
||||
AC_SUBST([MQ_LIBS])
|
||||
|
||||
AC_MSG_CHECKING([whether program_invocation_short_name is defined])
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
|
||||
|
@ -1867,6 +1881,22 @@ UL_REQUIRES_LINUX([waitpid])
|
|||
UL_REQUIRES_SYSCALL_CHECK([waitpid], [UL_CHECK_SYSCALL([pidfd_open])], [pidfd_open])
|
||||
AM_CONDITIONAL([BUILD_WAITPID], [test "x$build_waitpid" = xyes])
|
||||
|
||||
UL_BUILD_INIT([enosys], [check])
|
||||
UL_REQUIRES_LINUX([enosys])
|
||||
AS_IF([test "x$build_enosys" = xyes], [
|
||||
AC_MSG_CHECKING([for valid audit arch])
|
||||
AC_COMPILE_IFELSE(
|
||||
[AC_LANG_PROGRAM([[#include "${srcdir}/include/audit-arch.h"]])],
|
||||
[AC_MSG_RESULT([yes])],
|
||||
[AC_MSG_RESULT([no])
|
||||
build_enosys=no
|
||||
])
|
||||
])
|
||||
AM_CONDITIONAL([BUILD_ENOSYS], [test "x$build_enosys" = xyes])
|
||||
|
||||
UL_BUILD_INIT([lsclocks], [yes])
|
||||
AM_CONDITIONAL([BUILD_LSCLOCKS], [test "x$build_lsclocks" = xyes])
|
||||
|
||||
UL_BUILD_INIT([getopt], [yes])
|
||||
AM_CONDITIONAL([BUILD_GETOPT], [test "x$build_getopt" = xyes])
|
||||
|
||||
|
@ -2875,7 +2905,8 @@ AC_MSG_RESULT([
|
|||
ldflags: ${LDFLAGS}
|
||||
suid ldflags: ${SUID_LDFLAGS}
|
||||
ASAN enabled: ${enable_asan}
|
||||
Fuzzing enabled: ${enable_fuzzing_engine}
|
||||
Fuzzing enabled: ${enable_fuzzing_engine}
|
||||
Coverage enabled ${enable_coverage}
|
||||
|
||||
cflags: ${CFLAGS}
|
||||
|
||||
|
|
|
@ -60,6 +60,9 @@ Get discard zeroes support status.
|
|||
*--getdiskseq*::
|
||||
Get disk sequence number.
|
||||
|
||||
*--getzonesz*::
|
||||
Get zone size in 512-byte sectors.
|
||||
|
||||
*--getfra*::
|
||||
Get filesystem readahead in 512-byte sectors.
|
||||
|
||||
|
|
|
@ -10,6 +10,9 @@
|
|||
#include <unistd.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <errno.h>
|
||||
#ifdef HAVE_LINUX_BLKZONED_H
|
||||
#include <linux/blkzoned.h>
|
||||
#endif
|
||||
|
||||
#include "c.h"
|
||||
#include "nls.h"
|
||||
|
@ -175,6 +178,14 @@ static const struct bdc bdcms[] =
|
|||
.argval = -1,
|
||||
.help = N_("get disk sequence number")
|
||||
},{
|
||||
#ifdef BLKGETZONESZ
|
||||
IOCTL_ENTRY(BLKGETZONESZ),
|
||||
.name = "--getzonesz",
|
||||
.argtype = ARG_UINT,
|
||||
.argval = -1,
|
||||
.help = N_("get zone size")
|
||||
},{
|
||||
#endif
|
||||
IOCTL_ENTRY(BLKFLSBUF),
|
||||
.name = "--flushbufs",
|
||||
.help = N_("flush buffers")
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* cfdisk.c - Display or manipulate a disk partition table.
|
||||
*
|
||||
* Copyright (C) 2014-2015 Karel Zak <kzak@redhat.com>
|
||||
* Copyright (C) 2014-2023 Karel Zak <kzak@redhat.com>
|
||||
* Copyright (C) 1994 Kevin E. Martin (martin@cs.unc.edu)
|
||||
*
|
||||
* The original cfdisk was inspired by the fdisk program
|
||||
|
@ -21,6 +21,7 @@
|
|||
#include <assert.h>
|
||||
#include <libsmartcols.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <rpmatch.h>
|
||||
#include <libfdisk.h>
|
||||
|
||||
#ifdef HAVE_LIBMOUNT
|
||||
|
@ -2256,7 +2257,8 @@ static int ui_help(void)
|
|||
" ",
|
||||
N_("Command Meaning"),
|
||||
N_("------- -------"),
|
||||
N_(" b Toggle bootable flag of the current partition"),
|
||||
N_(" b Toggle bootable flag of the current partition;"),
|
||||
N_(" implemented for DOS (MBR) and SGI labels only"),
|
||||
N_(" d Delete the current partition"),
|
||||
N_(" h Print this screen"),
|
||||
N_(" n Create new partition from free space"),
|
||||
|
@ -2280,7 +2282,7 @@ static int ui_help(void)
|
|||
N_("Use lsblk(8) or partx(8) to see more details about the device."),
|
||||
" ",
|
||||
" ",
|
||||
"Copyright (C) 2014-2017 Karel Zak <kzak@redhat.com>"
|
||||
"Copyright (C) 2014-2023 Karel Zak <kzak@redhat.com>"
|
||||
};
|
||||
|
||||
erase();
|
||||
|
@ -2523,11 +2525,15 @@ static int main_menu_action(struct cfdisk *cf, int key)
|
|||
if (rc)
|
||||
warn = _("Failed to write disklabel.");
|
||||
else {
|
||||
size_t q_idx = 0;
|
||||
|
||||
if (cf->device_is_used)
|
||||
fdisk_reread_changes(cf->cxt, cf->original_layout);
|
||||
else
|
||||
fdisk_reread_partition_table(cf->cxt);
|
||||
info = _("The partition table has been altered.");
|
||||
if (menu_get_menuitem_by_key(cf, 'q', &q_idx))
|
||||
ui_menu_goto(cf, q_idx);
|
||||
}
|
||||
cf->nwrites++;
|
||||
break;
|
||||
|
@ -2587,11 +2593,17 @@ static int ui_run(struct cfdisk *cf)
|
|||
DBG(UI, ul_debug("start cols=%zu, lines=%zu", ui_cols, ui_lines));
|
||||
|
||||
if (fdisk_get_collision(cf->cxt)) {
|
||||
ui_warnx(_("Device already contains a %s signature; it will be removed by a write command."),
|
||||
fdisk_get_collision(cf->cxt));
|
||||
fdisk_enable_wipe(cf->cxt, 1);
|
||||
ui_hint(_("Press a key to continue."));
|
||||
getch();
|
||||
ui_warnx(_("Device already contains a %s signature."), fdisk_get_collision(cf->cxt));
|
||||
if (fdisk_is_readonly(cf->cxt)) {
|
||||
ui_hint(_("Press a key to continue."));
|
||||
getch();
|
||||
} else {
|
||||
char buf[64] = { 0 };
|
||||
rc = ui_get_string(_("Do you want to remove it? [Y]es/[N]o: "), NULL,
|
||||
buf, sizeof(buf));
|
||||
fdisk_enable_wipe(cf->cxt,
|
||||
rc > 0 && rpmatch(buf) == RPMATCH_YES ? 1 : 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (!fdisk_has_label(cf->cxt) || cf->zero_start) {
|
||||
|
|
|
@ -73,6 +73,9 @@ generate a new time-based UUID
|
|||
*-e*, *--endianness* _ENDIANNESS_::
|
||||
Specify the _ENDIANNESS_ to use, valid arguments are *native*, *little* or *big*. The default is *native*.
|
||||
|
||||
*-o*, *--offset* _offset_::
|
||||
Specify the _offset_ to write the swap area to.
|
||||
|
||||
*-v*, *--swapversion 1*::
|
||||
Specify the swap-space version. (This option is currently pointless, as the old *-v 0* option has become obsolete and now only *-v 1* is supported. The kernel has not supported v0 swap-space format since 2.5.22 (June 2002). The new version v1 is supported since 2.1.117 (August 1998).)
|
||||
|
||||
|
|
|
@ -76,6 +76,7 @@ struct mkswap_control {
|
|||
|
||||
int user_pagesize; /* --pagesize */
|
||||
int pagesize; /* final pagesize used for the header */
|
||||
off_t offset; /* offset of the header in the target */
|
||||
|
||||
char *opt_label; /* LABEL as specified on command line */
|
||||
unsigned char *uuid; /* UUID parsed by libbuuid */
|
||||
|
@ -194,6 +195,7 @@ static void __attribute__((__noreturn__)) usage(void)
|
|||
fprintf(out,
|
||||
_(" -e, --endianness=<value> specify the endianness to use "
|
||||
"(%s, %s or %s)\n"), "native", "little", "big");
|
||||
fputs(_(" -o, --offset OFFSET specify the offset in the device\n"), out);
|
||||
fputs(_(" --verbose verbose output\n"), out);
|
||||
|
||||
fprintf(out,
|
||||
|
@ -347,6 +349,9 @@ static unsigned long long get_size(const struct mkswap_control *ctl)
|
|||
err(EXIT_FAILURE, _("cannot open %s"), ctl->devname);
|
||||
if (blkdev_get_size(fd, &size) < 0)
|
||||
err(EXIT_FAILURE, _("cannot determine size of %s"), ctl->devname);
|
||||
if ((unsigned long long) ctl->offset > size)
|
||||
errx(EXIT_FAILURE, _("offset larger than file size"));
|
||||
size -= ctl->offset;
|
||||
size /= ctl->pagesize;
|
||||
|
||||
close(fd);
|
||||
|
@ -465,11 +470,15 @@ static void wipe_device(struct mkswap_control *ctl)
|
|||
|
||||
static void write_header_to_device(struct mkswap_control *ctl)
|
||||
{
|
||||
off_t offset;
|
||||
|
||||
assert(ctl);
|
||||
assert(ctl->fd > -1);
|
||||
assert(ctl->signature_page);
|
||||
|
||||
if (lseek(ctl->fd, SIGNATURE_OFFSET, SEEK_SET) != SIGNATURE_OFFSET)
|
||||
offset = SIGNATURE_OFFSET + ctl->offset;
|
||||
|
||||
if (lseek(ctl->fd, offset, SEEK_SET) != offset)
|
||||
errx(EXIT_FAILURE, _("unable to rewind swap-device"));
|
||||
|
||||
if (write_all(ctl->fd, (char *) ctl->signature_page + SIGNATURE_OFFSET,
|
||||
|
@ -503,6 +512,7 @@ int main(int argc, char **argv)
|
|||
{ "swapversion", required_argument, NULL, 'v' },
|
||||
{ "uuid", required_argument, NULL, 'U' },
|
||||
{ "endianness", required_argument, NULL, 'e' },
|
||||
{ "offset", required_argument, NULL, 'o' },
|
||||
{ "version", no_argument, NULL, 'V' },
|
||||
{ "help", no_argument, NULL, 'h' },
|
||||
{ "lock", optional_argument, NULL, OPT_LOCK },
|
||||
|
@ -521,7 +531,7 @@ int main(int argc, char **argv)
|
|||
textdomain(PACKAGE);
|
||||
close_stdout_atexit();
|
||||
|
||||
while((c = getopt_long(argc, argv, "cfp:qL:v:U:e:Vh", longopts, NULL)) != -1) {
|
||||
while((c = getopt_long(argc, argv, "cfp:qL:v:U:e:o:Vh", longopts, NULL)) != -1) {
|
||||
|
||||
err_exclusive_options(c, longopts, excl, excl_st);
|
||||
|
||||
|
@ -567,6 +577,10 @@ int main(int argc, char **argv)
|
|||
_("invalid endianness %s is not supported"), optarg);
|
||||
}
|
||||
break;
|
||||
case 'o':
|
||||
ctl.offset = str2unum_or_err(optarg,
|
||||
10, _("Invalid offset"), SINT_MAX(off_t));
|
||||
break;
|
||||
case 'V':
|
||||
print_version(EXIT_SUCCESS);
|
||||
break;
|
||||
|
|
|
@ -75,14 +75,14 @@ enum {
|
|||
|
||||
/* column names */
|
||||
struct colinfo {
|
||||
const char *name; /* header */
|
||||
double whint; /* width hint (N < 1 is in percent of termwidth) */
|
||||
int flags; /* SCOLS_FL_* */
|
||||
const char *help;
|
||||
const char * const name; /* header */
|
||||
double whint; /* width hint (N < 1 is in percent of termwidth) */
|
||||
int flags; /* SCOLS_FL_* */
|
||||
const char *help;
|
||||
};
|
||||
|
||||
/* columns descriptions */
|
||||
static struct colinfo infos[] = {
|
||||
static const struct colinfo infos[] = {
|
||||
[COL_PARTNO] = { "NR", 0.25, SCOLS_FL_RIGHT, N_("partition number") },
|
||||
[COL_START] = { "START", 0.30, SCOLS_FL_RIGHT, N_("start of the partition in sectors") },
|
||||
[COL_END] = { "END", 0.30, SCOLS_FL_RIGHT, N_("end of the partition in sectors") },
|
||||
|
@ -141,7 +141,7 @@ static inline int get_column_id(int num)
|
|||
return columns[num];
|
||||
}
|
||||
|
||||
static inline struct colinfo *get_column_info(int num)
|
||||
static inline const struct colinfo *get_column_info(int num)
|
||||
{
|
||||
return &infos[ get_column_id(num) ];
|
||||
}
|
||||
|
@ -674,7 +674,7 @@ static int show_parts(blkid_partlist ls, int scols_flags, int lower, int upper)
|
|||
scols_table_enable_noheadings(table, !!(scols_flags & PARTX_NOHEADINGS));
|
||||
|
||||
for (i = 0; (size_t)i < ncolumns; i++) {
|
||||
struct colinfo *col = get_column_info(i);
|
||||
const struct colinfo *col = get_column_info(i);
|
||||
|
||||
if (!scols_table_new_column(table, col->name, col->whint, col->flags)) {
|
||||
warnx(_("failed to allocate output column"));
|
||||
|
|
|
@ -13,6 +13,7 @@ dist_noinst_HEADERS += \
|
|||
include/closestream.h \
|
||||
include/colors.h \
|
||||
include/color-names.h \
|
||||
include/coverage.h \
|
||||
include/cpuset.h \
|
||||
include/crc32.h \
|
||||
include/crc32c.h \
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
# define be16toh(x) betoh16(x)
|
||||
# define be32toh(x) betoh32(x)
|
||||
# define be64toh(x) betoh64(x)
|
||||
#elif defined(__NetBSD__) || defined(__FreeBSD__) || defined(__DragonFly__)
|
||||
#elif defined(__NetBSD__) || defined(__DragonFly__)
|
||||
# define bswap_16(x) bswap16(x)
|
||||
# define bswap_32(x) bswap32(x)
|
||||
# define bswap_64(x) bswap64(x)
|
||||
|
|
|
@ -294,6 +294,9 @@ void __err_oom(const char *file, unsigned int line)
|
|||
}
|
||||
#define err_oom() __err_oom(__FILE__, __LINE__)
|
||||
|
||||
#define err_nosys(exitcode, ...) \
|
||||
err(errno == ENOSYS ? EXIT_NOTSUPP : exitcode, __VA_ARGS__)
|
||||
|
||||
|
||||
/* Don't use inline function to avoid '#include "nls.h"' in c.h
|
||||
*/
|
||||
|
|
|
@ -31,4 +31,6 @@ extern int capget(cap_user_header_t header, const cap_user_data_t data);
|
|||
|
||||
extern int cap_last_cap(void);
|
||||
|
||||
extern void cap_permitted_to_ambient(void);
|
||||
|
||||
#endif /* CAPUTILS_H */
|
||||
|
|
25
include/coverage.h
Normal file
25
include/coverage.h
Normal file
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* No copyright is claimed. This code is in the public domain; do with
|
||||
* it what you wish.
|
||||
*/
|
||||
#ifndef UTIL_LINUX_COVERAGE_H
|
||||
#define UTIL_LINUX_COVERAGE_H
|
||||
|
||||
/* When built with --coverage (gcov) we need to explicitly call __gcov_dump()
|
||||
* in places where we use _exit(), since _exit() skips at-exit hooks resulting
|
||||
* in lost coverage.
|
||||
*
|
||||
* To make sure we don't miss any _exit() calls, this header file is included
|
||||
* explicitly on the compiler command line via the -include directive (only
|
||||
* when built with --coverage/-Db_coverage=true)
|
||||
*/
|
||||
void __gcov_dump(void);
|
||||
void _exit(int);
|
||||
|
||||
__attribute__((noreturn)) static inline void _coverage__exit(int status) {
|
||||
__gcov_dump();
|
||||
_exit(status);
|
||||
}
|
||||
#define _exit(x) _coverage__exit(x)
|
||||
|
||||
#endif
|
|
@ -1,3 +1,7 @@
|
|||
/* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* This file is licensed under the MIT License.
|
||||
*/
|
||||
#ifndef UL_CRC64_H
|
||||
#define UL_CRC64_H
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@ struct dos_partition {
|
|||
#define MBR_PT_OFFSET 0x1be
|
||||
#define MBR_PT_BOOTBITS_SIZE 440
|
||||
|
||||
static inline struct dos_partition *mbr_get_partition(unsigned char *mbr, int i)
|
||||
static inline struct dos_partition *mbr_get_partition(const unsigned char *mbr, int i)
|
||||
{
|
||||
return (struct dos_partition *)
|
||||
(mbr + MBR_PT_OFFSET + (i * sizeof(struct dos_partition)));
|
||||
|
@ -42,7 +42,7 @@ static inline void __dos_store_4le(unsigned char *p, unsigned int val)
|
|||
p[3] = ((val >> 24) & 0xff);
|
||||
}
|
||||
|
||||
static inline unsigned int dos_partition_get_start(struct dos_partition *p)
|
||||
static inline unsigned int dos_partition_get_start(const struct dos_partition *p)
|
||||
{
|
||||
return __dos_assemble_4le(&(p->start_sect[0]));
|
||||
}
|
||||
|
@ -52,7 +52,7 @@ static inline void dos_partition_set_start(struct dos_partition *p, unsigned int
|
|||
__dos_store_4le(p->start_sect, n);
|
||||
}
|
||||
|
||||
static inline unsigned int dos_partition_get_size(struct dos_partition *p)
|
||||
static inline unsigned int dos_partition_get_size(const struct dos_partition *p)
|
||||
{
|
||||
return __dos_assemble_4le(&(p->nr_sects[0]));
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include <stdio.h>
|
||||
#include <inttypes.h>
|
||||
#include <sys/time.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
typedef uint64_t usec_t;
|
||||
typedef uint64_t nsec_t;
|
||||
|
@ -56,8 +57,10 @@ enum {
|
|||
ISO_TIMEZONE = (1 << 2),
|
||||
ISO_DOTUSEC = (1 << 3),
|
||||
ISO_COMMAUSEC = (1 << 4),
|
||||
ISO_T = (1 << 5),
|
||||
ISO_GMTIME = (1 << 6),
|
||||
ISO_DOTNSEC = (1 << 5),
|
||||
ISO_COMMANSEC = (1 << 6),
|
||||
ISO_T = (1 << 7),
|
||||
ISO_GMTIME = (1 << 8),
|
||||
ISO_TIMESTAMP = ISO_DATE | ISO_TIME | ISO_TIMEZONE,
|
||||
ISO_TIMESTAMP_T = ISO_TIMESTAMP | ISO_T,
|
||||
ISO_TIMESTAMP_DOT = ISO_TIMESTAMP | ISO_DOTUSEC,
|
||||
|
@ -71,9 +74,10 @@ enum {
|
|||
#define CTIME_BUFSIZ 26
|
||||
#define ISO_BUFSIZ 42
|
||||
|
||||
int strtimeval_iso(struct timeval *tv, int flags, char *buf, size_t bufsz);
|
||||
int strtm_iso(struct tm *tm, int flags, char *buf, size_t bufsz);
|
||||
int strtimeval_iso(const struct timeval *tv, int flags, char *buf, size_t bufsz);
|
||||
int strtm_iso(const struct tm *tm, int flags, char *buf, size_t bufsz);
|
||||
int strtime_iso(const time_t *t, int flags, char *buf, size_t bufsz);
|
||||
int strtimespec_iso(const struct timespec *t, int flags, char *buf, size_t bufsz);
|
||||
|
||||
#define UL_SHORTTIME_THISYEAR_HHMM (1 << 1)
|
||||
|
||||
|
@ -102,4 +106,9 @@ static inline struct timeval usec_to_timeval(usec_t t)
|
|||
return r;
|
||||
}
|
||||
|
||||
static inline bool is_timespecset(const struct timespec *t)
|
||||
{
|
||||
return t->tv_sec || t->tv_nsec;
|
||||
}
|
||||
|
||||
#endif /* UTIL_LINUX_TIME_UTIL_H */
|
||||
|
|
|
@ -88,6 +88,7 @@ struct chardata {
|
|||
extern int get_terminal_dimension(int *cols, int *lines);
|
||||
extern int get_terminal_width(int default_width);
|
||||
extern int get_terminal_type(const char **type);
|
||||
extern char *get_terminal_default_type(const char *ttyname, int is_serial);
|
||||
extern int get_terminal_stdfd(void);
|
||||
extern int get_terminal_name(const char **path, const char **name,
|
||||
const char **number);
|
||||
|
|
|
@ -46,6 +46,18 @@ void *xrealloc(void *ptr, const size_t size)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static inline
|
||||
__ul_calloc_size(2, 3)
|
||||
__ul_returns_nonnull
|
||||
void *xreallocarray(void *ptr, const size_t nelems, const size_t size)
|
||||
{
|
||||
void *ret = reallocarray(ptr, nelems, size);
|
||||
|
||||
if (!ret && size && nelems)
|
||||
err(XALLOC_EXIT_CODE, "cannot allocate %zu bytes", size);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline
|
||||
__ul_calloc_size(1, 2)
|
||||
__ul_returns_nonnull
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "caputils.h"
|
||||
#include "pathnames.h"
|
||||
#include "procfs.h"
|
||||
#include "nls.h"
|
||||
|
||||
static int test_cap(unsigned int cap)
|
||||
{
|
||||
|
@ -87,6 +88,43 @@ int cap_last_cap(void)
|
|||
return cap;
|
||||
}
|
||||
|
||||
void cap_permitted_to_ambient(void)
|
||||
{
|
||||
/* We use capabilities system calls to propagate the permitted
|
||||
* capabilities into the ambient set because we may have
|
||||
* already forked so be in async-signal-safe context. */
|
||||
struct __user_cap_header_struct header = {
|
||||
.version = _LINUX_CAPABILITY_VERSION_3,
|
||||
.pid = 0,
|
||||
};
|
||||
struct __user_cap_data_struct payload[_LINUX_CAPABILITY_U32S_3] = {{ 0 }};
|
||||
uint64_t effective, cap;
|
||||
|
||||
if (capget(&header, payload) < 0)
|
||||
err(EXIT_FAILURE, _("capget failed"));
|
||||
|
||||
/* In order the make capabilities ambient, we first need to ensure
|
||||
* that they are all inheritable. */
|
||||
payload[0].inheritable = payload[0].permitted;
|
||||
payload[1].inheritable = payload[1].permitted;
|
||||
|
||||
if (capset(&header, payload) < 0)
|
||||
err(EXIT_FAILURE, _("capset failed"));
|
||||
|
||||
effective = ((uint64_t)payload[1].effective << 32) | (uint64_t)payload[0].effective;
|
||||
|
||||
for (cap = 0; cap < (sizeof(effective) * 8); cap++) {
|
||||
/* This is the same check as cap_valid(), but using
|
||||
* the runtime value for the last valid cap. */
|
||||
if (cap > (uint64_t) cap_last_cap())
|
||||
continue;
|
||||
|
||||
if ((effective & (1ULL << cap))
|
||||
&& prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, cap, 0, 0) < 0)
|
||||
err(EXIT_FAILURE, _("prctl(PR_CAP_AMBIENT) failed"));
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef TEST_PROGRAM_CAPUTILS
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
|
|
11
lib/shells.c
11
lib/shells.c
|
@ -21,8 +21,8 @@ extern int is_known_shell(const char *shell_name)
|
|||
#if defined (HAVE_LIBECONF) && defined (USE_VENDORDIR)
|
||||
size_t size = 0;
|
||||
econf_err error;
|
||||
char **keys;
|
||||
econf_file *key_file;
|
||||
char **keys = NULL;
|
||||
econf_file *key_file = NULL;
|
||||
|
||||
error = econf_readDirs(&key_file,
|
||||
_PATH_VENDORDIR,
|
||||
|
@ -43,17 +43,18 @@ extern int is_known_shell(const char *shell_name)
|
|||
syslog(LOG_ALERT,
|
||||
_("Cannot evaluate entries in shells files: %s"),
|
||||
econf_errString(error));
|
||||
econf_free (key_file);
|
||||
econf_free(key_file);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < size; i++) {
|
||||
if (strcmp (keys[i], shell_name) == 0) {
|
||||
if (strcmp(keys[i], shell_name) == 0) {
|
||||
ret = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
econf_free (key_file);
|
||||
econf_free(keys);
|
||||
econf_free(key_file);
|
||||
#else
|
||||
char *s;
|
||||
|
||||
|
|
|
@ -448,8 +448,9 @@ int get_gmtoff(const struct tm *tp)
|
|||
#endif
|
||||
}
|
||||
|
||||
static int format_iso_time(struct tm *tm, suseconds_t usec, int flags, char *buf, size_t bufsz)
|
||||
static int format_iso_time(const struct tm *tm, uint32_t nsec, int flags, char *buf, size_t bufsz)
|
||||
{
|
||||
uint32_t usec = nsec / NSEC_PER_USEC;
|
||||
char *p = buf;
|
||||
int len;
|
||||
|
||||
|
@ -479,15 +480,28 @@ static int format_iso_time(struct tm *tm, suseconds_t usec, int flags, char *buf
|
|||
p += len;
|
||||
}
|
||||
|
||||
if (flags & ISO_DOTUSEC) {
|
||||
len = snprintf(p, bufsz, ".%06"PRId64, (int64_t) usec);
|
||||
if (flags & ISO_DOTNSEC) {
|
||||
len = snprintf(p, bufsz, ".%09"PRIu32, nsec);
|
||||
if (len < 0 || (size_t) len > bufsz)
|
||||
goto err;
|
||||
bufsz -= len;
|
||||
p += len;
|
||||
|
||||
} else if (flags & ISO_COMMANSEC) {
|
||||
len = snprintf(p, bufsz, ",%09"PRIu32, nsec);
|
||||
if (len < 0 || (size_t) len > bufsz)
|
||||
goto err;
|
||||
bufsz -= len;
|
||||
p += len;
|
||||
} else if (flags & ISO_DOTUSEC) {
|
||||
len = snprintf(p, bufsz, ".%06"PRIu32, usec);
|
||||
if (len < 0 || (size_t) len > bufsz)
|
||||
goto err;
|
||||
bufsz -= len;
|
||||
p += len;
|
||||
|
||||
} else if (flags & ISO_COMMAUSEC) {
|
||||
len = snprintf(p, bufsz, ",%06"PRId64, (int64_t) usec);
|
||||
len = snprintf(p, bufsz, ",%06"PRIu32, usec);
|
||||
if (len < 0 || (size_t) len > bufsz)
|
||||
goto err;
|
||||
bufsz -= len;
|
||||
|
@ -508,26 +522,37 @@ static int format_iso_time(struct tm *tm, suseconds_t usec, int flags, char *buf
|
|||
return -1;
|
||||
}
|
||||
|
||||
/* timeval to ISO 8601 */
|
||||
int strtimeval_iso(struct timeval *tv, int flags, char *buf, size_t bufsz)
|
||||
/* timespec to ISO 8601 */
|
||||
int strtimespec_iso(const struct timespec *ts, int flags, char *buf, size_t bufsz)
|
||||
{
|
||||
struct tm tm;
|
||||
struct tm *rc;
|
||||
|
||||
if (flags & ISO_GMTIME)
|
||||
rc = gmtime_r(&tv->tv_sec, &tm);
|
||||
rc = gmtime_r(&ts->tv_sec, &tm);
|
||||
else
|
||||
rc = localtime_r(&tv->tv_sec, &tm);
|
||||
rc = localtime_r(&ts->tv_sec, &tm);
|
||||
|
||||
if (rc)
|
||||
return format_iso_time(&tm, tv->tv_usec, flags, buf, bufsz);
|
||||
return format_iso_time(&tm, ts->tv_nsec, flags, buf, bufsz);
|
||||
|
||||
warnx(_("time %"PRId64" is out of range."), (int64_t)(tv->tv_sec));
|
||||
warnx(_("time %"PRId64" is out of range."), (int64_t)(ts->tv_sec));
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* timeval to ISO 8601 */
|
||||
int strtimeval_iso(const struct timeval *tv, int flags, char *buf, size_t bufsz)
|
||||
{
|
||||
struct timespec ts = {
|
||||
.tv_sec = tv->tv_sec,
|
||||
.tv_nsec = tv->tv_usec * NSEC_PER_USEC,
|
||||
};
|
||||
|
||||
return strtimespec_iso(&ts, flags, buf, bufsz);
|
||||
}
|
||||
|
||||
/* struct tm to ISO 8601 */
|
||||
int strtm_iso(struct tm *tm, int flags, char *buf, size_t bufsz)
|
||||
int strtm_iso(const struct tm *tm, int flags, char *buf, size_t bufsz)
|
||||
{
|
||||
return format_iso_time(tm, 0, flags, buf, bufsz);
|
||||
}
|
||||
|
|
|
@ -7,9 +7,40 @@
|
|||
#include <ctype.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifdef HAVE_GETTTYNAM
|
||||
# include <ttyent.h>
|
||||
#endif
|
||||
|
||||
#include "c.h"
|
||||
#include "ttyutils.h"
|
||||
|
||||
#ifdef __linux__
|
||||
# ifndef DEFAULT_VCTERM
|
||||
# define DEFAULT_VCTERM "linux"
|
||||
# endif
|
||||
# if defined (__s390__) || defined (__s390x__)
|
||||
# define DEFAULT_TTYS0 "dumb"
|
||||
# define DEFAULT_TTY32 "ibm327x"
|
||||
# define DEFAULT_TTYS1 "vt220"
|
||||
# endif
|
||||
# ifndef DEFAULT_STERM
|
||||
# define DEFAULT_STERM "vt102"
|
||||
# endif
|
||||
#elif defined(__GNU__)
|
||||
# ifndef DEFAULT_VCTERM
|
||||
# define DEFAULT_VCTERM "hurd"
|
||||
# endif
|
||||
# ifndef DEFAULT_STERM
|
||||
# define DEFAULT_STERM "vt102"
|
||||
# endif
|
||||
#else
|
||||
# ifndef DEFAULT_VCTERM
|
||||
# define DEFAULT_VCTERM "vt100"
|
||||
# endif
|
||||
# ifndef DEFAULT_STERM
|
||||
# define DEFAULT_STERM "vt100"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
static int get_env_int(const char *name)
|
||||
{
|
||||
|
@ -130,6 +161,35 @@ int get_terminal_type(const char **type)
|
|||
return 0;
|
||||
}
|
||||
|
||||
char *get_terminal_default_type(const char *ttyname, int is_serial)
|
||||
{
|
||||
if (ttyname) {
|
||||
#ifdef HAVE_GETTTYNAM
|
||||
struct ttyent *ent = getttynam(ttyname);
|
||||
|
||||
if (ent && ent->ty_type)
|
||||
return strdup(ent->ty_type);
|
||||
#endif
|
||||
|
||||
#if defined (__s390__) || defined (__s390x__)
|
||||
/*
|
||||
* Special terminal on first serial line on a S/390(x) which
|
||||
* is due legacy reasons a block terminal of type 3270 or
|
||||
* higher. Whereas the second serial line on a S/390(x) is
|
||||
* a real character terminal which is compatible with VT220.
|
||||
*/
|
||||
if (strcmp(ttyname, "ttyS0") == 0) /* linux/drivers/s390/char/con3215.c */
|
||||
return strdup(DEFAULT_TTYS0);
|
||||
else if (strncmp(ttyname, "3270/tty", 8) == 0) /* linux/drivers/s390/char/con3270.c */
|
||||
return strdup(DEFAULT_TTY32);
|
||||
else if (strcmp(ttyname, "ttyS1") == 0) /* linux/drivers/s390/char/sclp_vt220.c */
|
||||
return strdup(DEFAULT_TTYS1);
|
||||
#endif
|
||||
}
|
||||
|
||||
return strdup(is_serial ? DEFAULT_STERM : DEFAULT_VCTERM);
|
||||
}
|
||||
|
||||
#ifdef TEST_PROGRAM_TTYUTILS
|
||||
# include <stdlib.h>
|
||||
int main(void)
|
||||
|
@ -138,13 +198,21 @@ int main(void)
|
|||
int c, l;
|
||||
|
||||
if (get_terminal_name(&path, &name, &num) == 0) {
|
||||
fprintf(stderr, "tty path: %s\n", path);
|
||||
fprintf(stderr, "tty name: %s\n", name);
|
||||
fprintf(stderr, "tty number: %s\n", num);
|
||||
char *term;
|
||||
|
||||
fprintf(stderr, "tty path: %s\n", path);
|
||||
fprintf(stderr, "tty name: %s\n", name);
|
||||
fprintf(stderr, "tty number: %s\n", num);
|
||||
|
||||
fprintf(stderr, "tty term: %s\n", getenv("TERM"));
|
||||
|
||||
term = get_terminal_default_type(name, 0);
|
||||
fprintf(stderr, "tty dflt term: %s\n", term);
|
||||
free(term);
|
||||
}
|
||||
get_terminal_dimension(&c, &l);
|
||||
fprintf(stderr, "tty cols: %d\n", c);
|
||||
fprintf(stderr, "tty lines: %d\n", l);
|
||||
fprintf(stderr, "tty cols: %d\n", c);
|
||||
fprintf(stderr, "tty lines: %d\n", l);
|
||||
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
|
|
|
@ -412,12 +412,12 @@ extern int blkdid_probe_is_opal_locked(blkid_probe pr)
|
|||
__attribute__((nonnull))
|
||||
__attribute__((warn_unused_result));
|
||||
|
||||
extern unsigned char *blkid_probe_get_buffer(blkid_probe pr,
|
||||
extern const unsigned char *blkid_probe_get_buffer(blkid_probe pr,
|
||||
uint64_t off, uint64_t len)
|
||||
__attribute__((nonnull))
|
||||
__attribute__((warn_unused_result));
|
||||
|
||||
extern unsigned char *blkid_probe_get_sector(blkid_probe pr, unsigned int sector)
|
||||
extern const unsigned char *blkid_probe_get_sector(blkid_probe pr, unsigned int sector)
|
||||
__attribute__((nonnull))
|
||||
__attribute__((warn_unused_result));
|
||||
|
||||
|
@ -434,7 +434,7 @@ extern int blkid_probe_get_idmag(blkid_probe pr, const struct blkid_idinfo *id,
|
|||
__attribute__((nonnull(1)));
|
||||
|
||||
/* returns superblock according to 'struct blkid_idmag' */
|
||||
extern unsigned char *blkid_probe_get_sb_buffer(blkid_probe pr, const struct blkid_idmag *mag, size_t size);
|
||||
extern const unsigned char *blkid_probe_get_sb_buffer(blkid_probe pr, const struct blkid_idmag *mag, size_t size);
|
||||
#define blkid_probe_get_sb(_pr, _mag, type) \
|
||||
((type *) blkid_probe_get_sb_buffer((_pr), _mag, sizeof(type)))
|
||||
|
||||
|
|
|
@ -47,7 +47,7 @@ static int probe_bsd_pt(blkid_probe pr, const struct blkid_idmag *mag)
|
|||
blkid_partition parent;
|
||||
blkid_partlist ls;
|
||||
int i, nparts = BSD_MAXPARTITIONS;
|
||||
unsigned char *data;
|
||||
const unsigned char *data;
|
||||
int rc = BLKID_PROBE_NONE;
|
||||
uint32_t abs_offset = 0;
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ static const struct dos_subtypes {
|
|||
{ MBR_MINIX_PARTITION, &minix_pt_idinfo }
|
||||
};
|
||||
|
||||
static inline int is_extended(struct dos_partition *p)
|
||||
static inline int is_extended(const struct dos_partition *p)
|
||||
{
|
||||
return (p->sys_ind == MBR_DOS_EXTENDED_PARTITION ||
|
||||
p->sys_ind == MBR_W95_EXTENDED_PARTITION ||
|
||||
|
@ -46,7 +46,7 @@ static int parse_dos_extended(blkid_probe pr, blkid_parttable tab,
|
|||
{
|
||||
blkid_partlist ls = blkid_probe_get_partlist(pr);
|
||||
uint32_t cur_start = ex_start, cur_size = ex_size;
|
||||
unsigned char *data;
|
||||
const unsigned char *data;
|
||||
int ct_nodata = 0; /* count ext.partitions without data partitions */
|
||||
int i;
|
||||
|
||||
|
@ -57,7 +57,7 @@ static int parse_dos_extended(blkid_probe pr, blkid_parttable tab,
|
|||
}
|
||||
|
||||
while (1) {
|
||||
struct dos_partition *p, *p0;
|
||||
const struct dos_partition *p, *p0;
|
||||
uint32_t start = 0, size;
|
||||
|
||||
if (++ct_nodata > 100)
|
||||
|
@ -156,9 +156,9 @@ static inline int is_lvm(blkid_probe pr)
|
|||
return (v && v->data && strcmp((char *) v->data, "LVM2_member") == 0);
|
||||
}
|
||||
|
||||
static inline int is_empty_mbr(unsigned char *mbr)
|
||||
static inline int is_empty_mbr(const unsigned char *mbr)
|
||||
{
|
||||
struct dos_partition *p = mbr_get_partition(mbr, 0);
|
||||
const struct dos_partition *p = mbr_get_partition(mbr, 0);
|
||||
int i, nparts = 0;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
|
@ -177,8 +177,8 @@ static int probe_dos_pt(blkid_probe pr,
|
|||
int ssf;
|
||||
blkid_parttable tab = NULL;
|
||||
blkid_partlist ls;
|
||||
struct dos_partition *p0, *p;
|
||||
unsigned char *data;
|
||||
const struct dos_partition *p0, *p;
|
||||
const unsigned char *data;
|
||||
uint32_t start, size, id;
|
||||
char idstr[UUID_STR_LEN];
|
||||
|
||||
|
|
|
@ -109,7 +109,7 @@ static inline uint32_t count_crc32(const unsigned char *buf, size_t len,
|
|||
return (ul_crc32_exclude_offset(~0L, buf, len, exclude_off, exclude_len) ^ ~0L);
|
||||
}
|
||||
|
||||
static inline unsigned char *get_lba_buffer(blkid_probe pr,
|
||||
static inline const unsigned char *get_lba_buffer(blkid_probe pr,
|
||||
uint64_t lba, size_t bytes)
|
||||
{
|
||||
return blkid_probe_get_buffer(pr,
|
||||
|
@ -161,8 +161,8 @@ static int last_lba(blkid_probe pr, uint64_t *lba)
|
|||
static int is_pmbr_valid(blkid_probe pr, int *has)
|
||||
{
|
||||
int flags = blkid_partitions_get_flags(pr);
|
||||
unsigned char *data;
|
||||
struct dos_partition *p;
|
||||
const unsigned char *data;
|
||||
const struct dos_partition *p;
|
||||
int i;
|
||||
|
||||
if (has)
|
||||
|
|
|
@ -56,7 +56,7 @@ struct mac_driver_desc {
|
|||
/* there is more stuff after this that we don't need */
|
||||
} __attribute__((packed));
|
||||
|
||||
static inline unsigned char *get_mac_block(
|
||||
static inline const unsigned char *get_mac_block(
|
||||
blkid_probe pr,
|
||||
uint16_t block_size,
|
||||
uint32_t num)
|
||||
|
|
|
@ -17,11 +17,11 @@
|
|||
static int probe_minix_pt(blkid_probe pr,
|
||||
const struct blkid_idmag *mag __attribute__((__unused__)))
|
||||
{
|
||||
struct dos_partition *p;
|
||||
const struct dos_partition *p;
|
||||
blkid_parttable tab = NULL;
|
||||
blkid_partition parent;
|
||||
blkid_partlist ls;
|
||||
unsigned char *data;
|
||||
const unsigned char *data;
|
||||
int i;
|
||||
|
||||
data = blkid_probe_get_sector(pr, 0);
|
||||
|
|
|
@ -37,8 +37,8 @@ struct ultrix_disklabel {
|
|||
static int probe_ultrix_pt(blkid_probe pr,
|
||||
const struct blkid_idmag *mag __attribute__((__unused__)))
|
||||
{
|
||||
unsigned char *data;
|
||||
struct ultrix_disklabel *l;
|
||||
const unsigned char *data;
|
||||
const struct ultrix_disklabel *l;
|
||||
blkid_parttable tab = NULL;
|
||||
blkid_partlist ls;
|
||||
int i;
|
||||
|
@ -50,7 +50,7 @@ static int probe_ultrix_pt(blkid_probe pr,
|
|||
goto nothing;
|
||||
}
|
||||
|
||||
l = (struct ultrix_disklabel *) (data + ULTRIX_OFFSET);
|
||||
l = (const struct ultrix_disklabel *) (data + ULTRIX_OFFSET);
|
||||
|
||||
if (l->pt_magic != ULTRIX_MAGIC || l->pt_valid != 1)
|
||||
goto nothing;
|
||||
|
|
|
@ -669,7 +669,7 @@ static int hide_buffer(blkid_probe pr, uint64_t off, uint64_t len)
|
|||
* Note that @off is offset within probing area, the probing area is defined by
|
||||
* pr->off and pr->size.
|
||||
*/
|
||||
unsigned char *blkid_probe_get_buffer(blkid_probe pr, uint64_t off, uint64_t len)
|
||||
const unsigned char *blkid_probe_get_buffer(blkid_probe pr, uint64_t off, uint64_t len)
|
||||
{
|
||||
struct blkid_bufinfo *bf = NULL;
|
||||
uint64_t real_off = pr->off + off;
|
||||
|
@ -1136,7 +1136,7 @@ int blkid_probe_set_dimension(blkid_probe pr, uint64_t off, uint64_t size)
|
|||
return 0;
|
||||
}
|
||||
|
||||
unsigned char *blkid_probe_get_sb_buffer(blkid_probe pr, const struct blkid_idmag *mag, size_t size)
|
||||
const unsigned char *blkid_probe_get_sb_buffer(blkid_probe pr, const struct blkid_idmag *mag, size_t size)
|
||||
{
|
||||
uint64_t hint_offset;
|
||||
|
||||
|
@ -1164,7 +1164,7 @@ int blkid_probe_get_idmag(blkid_probe pr, const struct blkid_idinfo *id,
|
|||
|
||||
/* try to detect by magic string */
|
||||
while(mag && mag->magic) {
|
||||
unsigned char *buf;
|
||||
const unsigned char *buf;
|
||||
uint64_t kboff;
|
||||
uint64_t hint_offset;
|
||||
|
||||
|
@ -1690,7 +1690,7 @@ done:
|
|||
}
|
||||
|
||||
/* same sa blkid_probe_get_buffer() but works with 512-sectors */
|
||||
unsigned char *blkid_probe_get_sector(blkid_probe pr, unsigned int sector)
|
||||
const unsigned char *blkid_probe_get_sector(blkid_probe pr, unsigned int sector)
|
||||
{
|
||||
return blkid_probe_get_buffer(pr, ((uint64_t) sector) << 9, 0x200);
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "superblocks.h"
|
||||
#include "crc32c.h"
|
||||
|
@ -184,9 +185,18 @@ static int probe_bcache (blkid_probe pr, const struct blkid_idmag *mag)
|
|||
if (le64_to_cpu(bcs->offset) != BCACHE_SB_OFF / 512)
|
||||
return BLKID_PROBE_NONE;
|
||||
|
||||
if (blkid_probe_sprintf_version(pr, "%"PRIu64, le64_to_cpu(bcs->version)) < 0)
|
||||
return BLKID_PROBE_NONE;
|
||||
|
||||
if (blkid_probe_set_uuid(pr, bcs->uuid) < 0)
|
||||
return BLKID_PROBE_NONE;
|
||||
|
||||
if (blkid_probe_set_label(pr, bcs->label, sizeof(bcs->label)) < 0)
|
||||
return BLKID_PROBE_NONE;
|
||||
|
||||
if (blkid_probe_set_block_size(pr, le16_to_cpu(bcs->block_size) * 512))
|
||||
return BLKID_PROBE_NONE;
|
||||
|
||||
blkid_probe_set_wiper(pr, 0, BCACHE_SB_OFF);
|
||||
|
||||
return BLKID_PROBE_OK;
|
||||
|
@ -214,7 +224,7 @@ static void probe_bcachefs_sb_members(blkid_probe pr,
|
|||
blkid_probe_set_fssize(pr, sectors * BCACHEFS_SECTOR_SIZE);
|
||||
}
|
||||
|
||||
static int is_within_range(void *start, uint64_t size, void *end)
|
||||
static int is_within_range(const void *start, uint64_t size, const void *end)
|
||||
{
|
||||
ptrdiff_t diff;
|
||||
|
||||
|
@ -226,9 +236,9 @@ static int is_within_range(void *start, uint64_t size, void *end)
|
|||
}
|
||||
|
||||
static void probe_bcachefs_sb_fields(blkid_probe pr, const struct bcachefs_super_block *bcs,
|
||||
unsigned char *sb_start, unsigned char *sb_end)
|
||||
const unsigned char *sb_start, const unsigned char *sb_end)
|
||||
{
|
||||
unsigned char *field_addr = sb_start + BCACHEFS_SB_FIELDS_OFF;
|
||||
const unsigned char *field_addr = sb_start + BCACHEFS_SB_FIELDS_OFF;
|
||||
|
||||
while (1) {
|
||||
struct bcachefs_sb_field *field = (struct bcachefs_sb_field *) field_addr;
|
||||
|
@ -258,10 +268,10 @@ static void probe_bcachefs_sb_fields(blkid_probe pr, const struct bcachefs_super
|
|||
}
|
||||
|
||||
static int bcachefs_validate_checksum(blkid_probe pr, const struct bcachefs_super_block *bcs,
|
||||
unsigned char *sb, unsigned char *sb_end)
|
||||
const unsigned char *sb, const unsigned char *sb_end)
|
||||
{
|
||||
uint8_t checksum_type = be64_to_cpu(bcs->flags[0]) >> 58;
|
||||
unsigned char *checksummed_data_start = sb + sizeof(bcs->csum);
|
||||
const unsigned char *checksummed_data_start = sb + sizeof(bcs->csum);
|
||||
size_t checksummed_data_size = sb_end - checksummed_data_start;
|
||||
|
||||
switch (checksum_type) {
|
||||
|
@ -288,7 +298,7 @@ static int bcachefs_validate_checksum(blkid_probe pr, const struct bcachefs_supe
|
|||
static int probe_bcachefs(blkid_probe pr, const struct blkid_idmag *mag)
|
||||
{
|
||||
struct bcachefs_super_block *bcs;
|
||||
unsigned char *sb, *sb_end;
|
||||
const unsigned char *sb, *sb_end;
|
||||
uint64_t sb_size, blocksize;
|
||||
|
||||
bcs = blkid_probe_get_sb(pr, mag, struct bcachefs_super_block);
|
||||
|
|
|
@ -122,7 +122,7 @@ struct bplustree_node {
|
|||
char name[0];
|
||||
} __attribute__((packed));
|
||||
|
||||
static unsigned char *get_block_run(blkid_probe pr, const struct befs_super_block *bs,
|
||||
static const unsigned char *get_block_run(blkid_probe pr, const struct befs_super_block *bs,
|
||||
const struct block_run *br, int fs_le)
|
||||
{
|
||||
return blkid_probe_get_buffer(pr,
|
||||
|
@ -135,7 +135,7 @@ static unsigned char *get_block_run(blkid_probe pr, const struct befs_super_bloc
|
|||
<< FS32_TO_CPU(bs->block_shift, fs_le));
|
||||
}
|
||||
|
||||
static unsigned char *get_custom_block_run(blkid_probe pr,
|
||||
static const unsigned char *get_custom_block_run(blkid_probe pr,
|
||||
const struct befs_super_block *bs,
|
||||
const struct block_run *br,
|
||||
int64_t offset, uint32_t length, int fs_le)
|
||||
|
@ -154,7 +154,7 @@ static unsigned char *get_custom_block_run(blkid_probe pr,
|
|||
length);
|
||||
}
|
||||
|
||||
static unsigned char *get_tree_node(blkid_probe pr, const struct befs_super_block *bs,
|
||||
static const unsigned char *get_tree_node(blkid_probe pr, const struct befs_super_block *bs,
|
||||
const struct data_stream *ds,
|
||||
int64_t start, uint32_t length, int fs_le)
|
||||
{
|
||||
|
|
|
@ -55,7 +55,7 @@ static int cramfs_verify_csum(blkid_probe pr, const struct blkid_idmag *mag,
|
|||
struct cramfs_super *cs, int le)
|
||||
{
|
||||
uint32_t crc, expected, csummed_size;
|
||||
unsigned char *csummed;
|
||||
const unsigned char *csummed;
|
||||
|
||||
expected = cfs32_to_cpu(le, cs->info.crc);
|
||||
csummed_size = cfs32_to_cpu(le, cs->size);
|
||||
|
@ -67,9 +67,10 @@ static int cramfs_verify_csum(blkid_probe pr, const struct blkid_idmag *mag,
|
|||
csummed = blkid_probe_get_sb_buffer(pr, mag, csummed_size);
|
||||
if (!csummed)
|
||||
return 0;
|
||||
memset(csummed + offsetof(struct cramfs_super, info.crc), 0, sizeof(uint32_t));
|
||||
|
||||
crc = ~ul_crc32(~0LL, csummed, csummed_size);
|
||||
crc = ~ul_crc32_exclude_offset(~0LL, csummed, csummed_size,
|
||||
offsetof(struct cramfs_super, info.crc),
|
||||
sizeof_member(struct cramfs_super, info.crc));
|
||||
|
||||
return blkid_probe_verify_csum(pr, crc, expected);
|
||||
}
|
||||
|
|
|
@ -106,7 +106,7 @@ static int probe_ddf(blkid_probe pr,
|
|||
|
||||
if (lba > 0) {
|
||||
/* check primary header */
|
||||
unsigned char *buf;
|
||||
const unsigned char *buf;
|
||||
|
||||
buf = blkid_probe_get_buffer(pr,
|
||||
lba << 9, sizeof(ddf->signature));
|
||||
|
|
|
@ -46,7 +46,7 @@ static int erofs_verify_checksum(blkid_probe pr, const struct blkid_idmag *mag,
|
|||
{
|
||||
uint32_t expected, csum;
|
||||
size_t csummed_size;
|
||||
unsigned char *csummed;
|
||||
const unsigned char *csummed;
|
||||
|
||||
if (!(le32_to_cpu(sb->feature_compat) & EROFS_FEATURE_SB_CSUM))
|
||||
return 1;
|
||||
|
|
|
@ -119,7 +119,7 @@ static struct exfat_entry_label *find_label(blkid_probe pr,
|
|||
}
|
||||
|
||||
/* From https://docs.microsoft.com/en-us/windows/win32/fileio/exfat-specification#34-main-and-backup-boot-checksum-sub-regions */
|
||||
static uint32_t exfat_boot_checksum(unsigned char *sectors,
|
||||
static uint32_t exfat_boot_checksum(const unsigned char *sectors,
|
||||
size_t sector_size)
|
||||
{
|
||||
uint32_t n_bytes = sector_size * 11;
|
||||
|
@ -141,7 +141,7 @@ static int exfat_validate_checksum(blkid_probe pr,
|
|||
{
|
||||
size_t sector_size = BLOCK_SIZE(sb);
|
||||
/* 11 sectors will be checksummed, the 12th contains the expected */
|
||||
unsigned char *data = blkid_probe_get_buffer(pr, 0, sector_size * 12);
|
||||
const unsigned char *data = blkid_probe_get_buffer(pr, 0, sector_size * 12);
|
||||
if (!data)
|
||||
return 0;
|
||||
|
||||
|
|
|
@ -67,14 +67,14 @@ static int f2fs_validate_checksum(blkid_probe pr, size_t sb_off,
|
|||
if (csum_off + sizeof(uint32_t) > 4096)
|
||||
return 0;
|
||||
|
||||
unsigned char *csum_data = blkid_probe_get_buffer(pr,
|
||||
const unsigned char *csum_data = blkid_probe_get_buffer(pr,
|
||||
sb_off + csum_off, sizeof(uint32_t));
|
||||
if (!csum_data)
|
||||
return 0;
|
||||
|
||||
uint32_t expected = le32_to_cpu(*(uint32_t *) csum_data);
|
||||
|
||||
unsigned char *csummed = blkid_probe_get_buffer(pr, sb_off, csum_off);
|
||||
const unsigned char *csummed = blkid_probe_get_buffer(pr, sb_off, csum_off);
|
||||
if (!csummed)
|
||||
return 0;
|
||||
|
||||
|
|
|
@ -183,11 +183,11 @@ static int probe_hfs(blkid_probe pr, const struct blkid_idmag *mag)
|
|||
static int probe_hfsplus(blkid_probe pr, const struct blkid_idmag *mag)
|
||||
{
|
||||
struct hfsplus_extent extents[HFSPLUS_EXTENT_COUNT];
|
||||
struct hfsplus_bnode_descriptor *descr;
|
||||
struct hfsplus_bheader_record *bnode;
|
||||
struct hfsplus_catalog_key *key;
|
||||
struct hfsplus_vol_header *hfsplus;
|
||||
struct hfs_mdb *sbd;
|
||||
const struct hfsplus_bnode_descriptor *descr;
|
||||
const struct hfsplus_bheader_record *bnode;
|
||||
const struct hfsplus_catalog_key *key;
|
||||
const struct hfsplus_vol_header *hfsplus;
|
||||
const struct hfs_mdb *sbd;
|
||||
unsigned int alloc_block_size;
|
||||
unsigned int alloc_first_block;
|
||||
unsigned int embed_first_block;
|
||||
|
@ -203,7 +203,7 @@ static int probe_hfsplus(blkid_probe pr, const struct blkid_idmag *mag)
|
|||
unsigned int leaf_block;
|
||||
int ext;
|
||||
uint64_t leaf_off;
|
||||
unsigned char *buf;
|
||||
const unsigned char *buf;
|
||||
|
||||
sbd = blkid_probe_get_sb(pr, mag, struct hfs_mdb);
|
||||
if (!sbd)
|
||||
|
@ -225,7 +225,7 @@ static int probe_hfsplus(blkid_probe pr, const struct blkid_idmag *mag)
|
|||
buf = blkid_probe_get_buffer(pr,
|
||||
off + (mag->kboff * 1024),
|
||||
sizeof(struct hfsplus_vol_header));
|
||||
hfsplus = (struct hfsplus_vol_header *) buf;
|
||||
hfsplus = (const struct hfsplus_vol_header *) buf;
|
||||
|
||||
} else
|
||||
hfsplus = blkid_probe_get_sb(pr, mag,
|
||||
|
|
|
@ -232,7 +232,7 @@ static int probe_iso9660(blkid_probe pr, const struct blkid_idmag *mag)
|
|||
return probe_iso9660_hsfs(pr, mag);
|
||||
|
||||
for (i = 0, off += ISO_SUPERBLOCK_OFFSET; i < ISO_VD_MAX && (!boot || !pvd || !joliet); i++, off += ISO_SECTOR_SIZE) {
|
||||
unsigned char *desc =
|
||||
const unsigned char *desc =
|
||||
blkid_probe_get_buffer(pr,
|
||||
off,
|
||||
max(sizeof(struct boot_record),
|
||||
|
|
|
@ -187,15 +187,14 @@ static int raid1_verify_csum(blkid_probe pr, off_t off,
|
|||
{
|
||||
size_t csummed_size = sizeof(struct mdp1_super_block)
|
||||
+ le32_to_cpu(mdp1->max_dev) * sizeof(mdp1->dev_roles[0]);
|
||||
unsigned char *csummed = blkid_probe_get_buffer(pr, off, csummed_size);
|
||||
const unsigned char *csummed = blkid_probe_get_buffer(pr, off, csummed_size);
|
||||
if (!csummed)
|
||||
return 1;
|
||||
|
||||
memset(csummed + offsetof(struct mdp1_super_block, sb_csum), 0,
|
||||
sizeof(mdp1->sb_csum));
|
||||
|
||||
uint64_t csum = 0;
|
||||
|
||||
csum -= le32_to_cpu(*(uint32_t *) (csummed + offsetof(struct mdp1_super_block, sb_csum)));
|
||||
|
||||
while (csummed_size >= 4) {
|
||||
csum += le32_to_cpu(*(uint32_t *) csummed);
|
||||
csummed_size -= 4;
|
||||
|
|
|
@ -76,7 +76,7 @@ static int probe_lvm2(blkid_probe pr, const struct blkid_idmag *mag)
|
|||
int sector = mag->kboff << 1;
|
||||
struct lvm2_pv_label_header *label;
|
||||
char uuid[LVM2_ID_LEN + 7];
|
||||
unsigned char *buf;
|
||||
const unsigned char *buf;
|
||||
|
||||
buf = blkid_probe_get_buffer(pr,
|
||||
mag->kboff << 10,
|
||||
|
|
|
@ -74,7 +74,7 @@ static int get_minix_version(const unsigned char *data, int *other_endian)
|
|||
static int probe_minix(blkid_probe pr,
|
||||
const struct blkid_idmag *mag __attribute__((__unused__)))
|
||||
{
|
||||
unsigned char *ext;
|
||||
const unsigned char *ext;
|
||||
const unsigned char *data;
|
||||
int version = 0, swabme = 0;
|
||||
unsigned long zones, ninodes, imaps, zmaps;
|
||||
|
|
|
@ -80,13 +80,13 @@ struct file_attribute {
|
|||
|
||||
static int __probe_ntfs(blkid_probe pr, const struct blkid_idmag *mag, int save_info)
|
||||
{
|
||||
struct ntfs_super_block *ns;
|
||||
struct master_file_table_record *mft;
|
||||
const struct ntfs_super_block *ns;
|
||||
const struct master_file_table_record *mft;
|
||||
|
||||
uint32_t sectors_per_cluster, mft_record_size;
|
||||
uint16_t sector_size;
|
||||
uint64_t nr_clusters, off, attr_off;
|
||||
unsigned char *buf_mft;
|
||||
const unsigned char *buf_mft;
|
||||
|
||||
ns = blkid_probe_get_sb(pr, mag, struct ntfs_super_block);
|
||||
if (!ns)
|
||||
|
|
|
@ -100,7 +100,7 @@ struct oracle_asm_disk_label {
|
|||
|
||||
static int probe_ocfs(blkid_probe pr, const struct blkid_idmag *mag)
|
||||
{
|
||||
unsigned char *buf;
|
||||
const unsigned char *buf;
|
||||
struct ocfs_volume_header ovh;
|
||||
struct ocfs_volume_label ovl;
|
||||
uint32_t maj, min;
|
||||
|
|
|
@ -29,7 +29,7 @@ static int romfs_verify_csum(blkid_probe pr, const struct blkid_idmag *mag,
|
|||
{
|
||||
uint32_t csummed_size = min((uint32_t) 512,
|
||||
be32_to_cpu(ros->ros_full_size));
|
||||
unsigned char *csummed;
|
||||
const unsigned char *csummed;
|
||||
uint32_t csum;
|
||||
|
||||
if (csummed_size % sizeof(uint32_t) != 0)
|
||||
|
|
|
@ -49,7 +49,7 @@ const char STRATIS_MAGIC[] = "!Stra0tis\x86\xff\x02^\x41rh";
|
|||
#define MAGIC_OFFSET_COPY_1 (FIRST_COPY_OFFSET + _MAGIC_OFFSET)
|
||||
#define MAGIC_OFFSET_COPY_2 (SECOND_COPY_OFFSET + _MAGIC_OFFSET)
|
||||
|
||||
static int stratis_valid_sb(uint8_t *p)
|
||||
static int stratis_valid_sb(const uint8_t *p)
|
||||
{
|
||||
const struct stratis_sb *stratis = (const struct stratis_sb *)p;
|
||||
uint32_t crc = 0;
|
||||
|
@ -83,7 +83,7 @@ static int probe_stratis(blkid_probe pr,
|
|||
const struct blkid_idmag *mag __attribute__((__unused__)))
|
||||
{
|
||||
const struct stratis_sb *stratis = NULL;
|
||||
uint8_t *buf = blkid_probe_get_buffer(pr, 0, SB_AREA_SIZE);
|
||||
const uint8_t *buf = blkid_probe_get_buffer(pr, 0, SB_AREA_SIZE);
|
||||
unsigned char uuid[STRATIS_UUID_STR_LEN];
|
||||
|
||||
if (!buf)
|
||||
|
|
|
@ -91,7 +91,7 @@ static int swap_set_info(blkid_probe pr, const struct blkid_idmag *mag,
|
|||
|
||||
static int probe_swap(blkid_probe pr, const struct blkid_idmag *mag)
|
||||
{
|
||||
unsigned char *buf;
|
||||
const unsigned char *buf;
|
||||
|
||||
if (!mag)
|
||||
return 1;
|
||||
|
|
|
@ -351,7 +351,7 @@ static int probe_vfat(blkid_probe pr, const struct blkid_idmag *mag)
|
|||
version = "FAT16";
|
||||
|
||||
} else if (vs->vs_fat32_length) {
|
||||
unsigned char *buf;
|
||||
const unsigned char *buf;
|
||||
uint16_t fsinfo_sect;
|
||||
int maxloop = 100;
|
||||
|
||||
|
|
|
@ -49,7 +49,7 @@ static int probe_vmfs_fs(blkid_probe pr, const struct blkid_idmag *mag)
|
|||
static int probe_vmfs_volume(blkid_probe pr, const struct blkid_idmag *mag)
|
||||
{
|
||||
struct vmfs_volume_info *header;
|
||||
unsigned char *lvm_uuid;
|
||||
const unsigned char *lvm_uuid;
|
||||
|
||||
header = blkid_probe_get_sb(pr, mag, struct vmfs_volume_info);
|
||||
if (header == NULL)
|
||||
|
|
|
@ -206,7 +206,7 @@ static int xfs_verify_sb(struct xfs_super_block *ondisk, blkid_probe pr,
|
|||
|
||||
if ((sbp->sb_versionnum & 0x0f) == 5) {
|
||||
uint32_t expected, crc;
|
||||
unsigned char *csummed;
|
||||
const unsigned char *csummed;
|
||||
|
||||
if (!(sbp->sb_versionnum & XFS_SB_VERSION_MOREBITSBIT))
|
||||
return 0;
|
||||
|
@ -331,7 +331,7 @@ static int probe_xfs_log(blkid_probe pr,
|
|||
{
|
||||
int i;
|
||||
struct xlog_rec_header *rhead;
|
||||
unsigned char *buf;
|
||||
const unsigned char *buf;
|
||||
|
||||
buf = blkid_probe_get_buffer(pr, 0, 256*1024);
|
||||
if (!buf)
|
||||
|
|
|
@ -71,13 +71,13 @@ struct nvlist {
|
|||
struct nvpair nvl_nvpair;
|
||||
};
|
||||
|
||||
static void zfs_process_value(blkid_probe pr, char *name, size_t namelen,
|
||||
void *value, size_t max_value_size, unsigned directory_level)
|
||||
static void zfs_process_value(blkid_probe pr, const char *name, size_t namelen,
|
||||
const void *value, size_t max_value_size, unsigned directory_level)
|
||||
{
|
||||
if (strncmp(name, "name", namelen) == 0 &&
|
||||
sizeof(struct nvstring) <= max_value_size &&
|
||||
!directory_level) {
|
||||
struct nvstring *nvs = value;
|
||||
const struct nvstring *nvs = value;
|
||||
uint32_t nvs_type = be32_to_cpu(nvs->nvs_type);
|
||||
uint32_t nvs_strlen = be32_to_cpu(nvs->nvs_strlen);
|
||||
|
||||
|
@ -92,7 +92,7 @@ static void zfs_process_value(blkid_probe pr, char *name, size_t namelen,
|
|||
} else if (strncmp(name, "guid", namelen) == 0 &&
|
||||
sizeof(struct nvuint64) <= max_value_size &&
|
||||
!directory_level) {
|
||||
struct nvuint64 *nvu = value;
|
||||
const struct nvuint64 *nvu = value;
|
||||
uint32_t nvu_type = be32_to_cpu(nvu->nvu_type);
|
||||
uint64_t nvu_value;
|
||||
|
||||
|
@ -110,7 +110,7 @@ static void zfs_process_value(blkid_probe pr, char *name, size_t namelen,
|
|||
} else if (strncmp(name, "pool_guid", namelen) == 0 &&
|
||||
sizeof(struct nvuint64) <= max_value_size &&
|
||||
!directory_level) {
|
||||
struct nvuint64 *nvu = value;
|
||||
const struct nvuint64 *nvu = value;
|
||||
uint32_t nvu_type = be32_to_cpu(nvu->nvu_type);
|
||||
uint64_t nvu_value;
|
||||
|
||||
|
@ -128,7 +128,7 @@ static void zfs_process_value(blkid_probe pr, char *name, size_t namelen,
|
|||
"%"PRIu64, nvu_value);
|
||||
} else if (strncmp(name, "ashift", namelen) == 0 &&
|
||||
sizeof(struct nvuint64) <= max_value_size) {
|
||||
struct nvuint64 *nvu = value;
|
||||
const struct nvuint64 *nvu = value;
|
||||
uint32_t nvu_type = be32_to_cpu(nvu->nvu_type);
|
||||
uint64_t nvu_value;
|
||||
|
||||
|
@ -147,9 +147,9 @@ static void zfs_process_value(blkid_probe pr, char *name, size_t namelen,
|
|||
|
||||
static void zfs_extract_guid_name(blkid_probe pr, loff_t offset)
|
||||
{
|
||||
unsigned char *p;
|
||||
struct nvlist *nvl;
|
||||
struct nvpair *nvp;
|
||||
const unsigned char *p;
|
||||
const struct nvlist *nvl;
|
||||
const struct nvpair *nvp;
|
||||
size_t left = 4096;
|
||||
unsigned directory_level = 0;
|
||||
|
||||
|
@ -166,16 +166,16 @@ static void zfs_extract_guid_name(blkid_probe pr, loff_t offset)
|
|||
DBG(LOWPROBE, ul_debug("zfs_extract: nvlist offset %jd",
|
||||
(intmax_t)offset));
|
||||
|
||||
nvl = (struct nvlist *) p;
|
||||
nvl = (const struct nvlist *) p;
|
||||
nvp = &nvl->nvl_nvpair;
|
||||
left -= (unsigned char *)nvp - p; /* Already used up 12 bytes */
|
||||
left -= (const unsigned char *)nvp - p; /* Already used up 12 bytes */
|
||||
|
||||
while (left > sizeof(*nvp)) {
|
||||
uint32_t nvp_size = be32_to_cpu(nvp->nvp_size);
|
||||
uint32_t nvp_namelen = be32_to_cpu(nvp->nvp_namelen);
|
||||
uint64_t namesize = ((uint64_t)nvp_namelen + 3) & ~3;
|
||||
size_t max_value_size;
|
||||
void *value;
|
||||
const void *value;
|
||||
|
||||
if (!nvp->nvp_size) {
|
||||
if (!directory_level)
|
||||
|
@ -201,7 +201,7 @@ static void zfs_extract_guid_name(blkid_probe pr, loff_t offset)
|
|||
value = nvp->nvp_name + namesize;
|
||||
|
||||
if (sizeof(struct nvdirectory) <= max_value_size) {
|
||||
struct nvdirectory *nvu = value;
|
||||
const struct nvdirectory *nvu = value;
|
||||
if (be32_to_cpu(nvu->nvd_type) == DATA_TYPE_DIRECTORY) {
|
||||
nvp_size = sizeof(*nvp) + namesize + sizeof(*nvu);
|
||||
directory_level++;
|
||||
|
@ -259,7 +259,7 @@ static int probe_zfs(blkid_probe pr,
|
|||
struct zfs_uberblock *ub = NULL;
|
||||
loff_t offset = 0, ub_offset = 0;
|
||||
int label_no, found = 0, found_in_label;
|
||||
void *label;
|
||||
const void *label;
|
||||
loff_t blk_align = (pr->size % (256 * 1024ULL));
|
||||
|
||||
DBG(PROBE, ul_debug("probe_zfs"));
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
static const struct topology_val {
|
||||
|
||||
/* /sys/dev/block/<maj>:<min>/<ATTR> */
|
||||
const char *attr;
|
||||
const char * const attr;
|
||||
|
||||
/* functions to set probing result */
|
||||
int (*set_ulong)(blkid_probe, unsigned long);
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
*
|
||||
*/
|
||||
|
||||
static const char *bsd_dktypenames[] = {
|
||||
static const char * const bsd_dktypenames[] = {
|
||||
"unknown",
|
||||
"SMD",
|
||||
"MSCP",
|
||||
|
|
|
@ -792,7 +792,7 @@ static void get_partition_table_geometry(struct fdisk_context *cxt,
|
|||
unsigned char *bufp = cxt->firstsector;
|
||||
struct { unsigned int c, h, o, v; } t[8];
|
||||
unsigned int n1, n2, n3, n4, n5, n6;
|
||||
struct dos_partition *p;
|
||||
const struct dos_partition *p;
|
||||
unsigned int c, h, s, l;
|
||||
unsigned int hh, ss;
|
||||
unsigned int sects;
|
||||
|
|
|
@ -75,6 +75,7 @@ int fdisk_set_wipe_area(struct fdisk_context *cxt,
|
|||
free(wp);
|
||||
return 1;
|
||||
}
|
||||
DBG(WIPE, ul_debug("not requested"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ if BUILD_LIBMOUNT
|
|||
|
||||
include libmount/src/Makemodule.am
|
||||
include libmount/python/Makemodule.am
|
||||
include libmount/samples/Makemodule.am
|
||||
|
||||
if ENABLE_GTK_DOC
|
||||
# Docs uses separate Makefiles
|
||||
|
|
|
@ -117,6 +117,7 @@ libmount_tests = [
|
|||
'context',
|
||||
'lock',
|
||||
'optstr',
|
||||
'optlist',
|
||||
'tab',
|
||||
'tab_diff',
|
||||
'monitor',
|
||||
|
|
|
@ -1175,43 +1175,17 @@ static PyObject *Context_repr(ContextObjext *self)
|
|||
|
||||
PyTypeObject ContextType = {
|
||||
PyVarObject_HEAD_INIT(NULL, 0)
|
||||
"libmount.Context", /*tp_name*/
|
||||
sizeof(ContextObjext), /*tp_basicsize*/
|
||||
0, /*tp_itemsize*/
|
||||
(destructor)Context_dealloc, /*tp_dealloc*/
|
||||
0, /*tp_print*/
|
||||
NULL, /*tp_getattr*/
|
||||
NULL, /*tp_setattr*/
|
||||
NULL, /*tp_compare*/
|
||||
(reprfunc) Context_repr,
|
||||
NULL, /*tp_as_number*/
|
||||
NULL, /*tp_as_sequence*/
|
||||
NULL, /*tp_as_mapping*/
|
||||
NULL, /*tp_hash */
|
||||
NULL, /*tp_call*/
|
||||
NULL, /*tp_str*/
|
||||
NULL, /*tp_getattro*/
|
||||
NULL, /*tp_setattro*/
|
||||
NULL, /*tp_as_buffer*/
|
||||
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
|
||||
Context_HELP, /* tp_doc */
|
||||
NULL, /* tp_traverse */
|
||||
NULL, /* tp_clear */
|
||||
NULL, /* tp_richcompare */
|
||||
0, /* tp_weaklistoffset */
|
||||
NULL, /* tp_iter */
|
||||
NULL, /* tp_iternext */
|
||||
Context_methods, /* tp_methods */
|
||||
Context_members, /* tp_members */
|
||||
Context_getseters, /* tp_getset */
|
||||
NULL, /* tp_base */
|
||||
NULL, /* tp_dict */
|
||||
NULL, /* tp_descr_get */
|
||||
NULL, /* tp_descr_set */
|
||||
0, /* tp_dictoffset */
|
||||
(initproc)Context_init, /* tp_init */
|
||||
NULL, /* tp_alloc */
|
||||
Context_new, /* tp_new */
|
||||
.tp_name = "libmount.Context",
|
||||
.tp_basicsize = sizeof(ContextObjext),
|
||||
.tp_dealloc = (destructor)Context_dealloc,
|
||||
.tp_repr = (reprfunc) Context_repr,
|
||||
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
|
||||
.tp_doc = Context_HELP,
|
||||
.tp_methods = Context_methods,
|
||||
.tp_members = Context_members,
|
||||
.tp_getset = Context_getseters,
|
||||
.tp_init = (initproc)Context_init,
|
||||
.tp_new = Context_new,
|
||||
};
|
||||
|
||||
void Context_AddModuleObject(PyObject *mod)
|
||||
|
|
|
@ -832,43 +832,17 @@ static PyObject *Fs_copy_fs(FsObject *self, PyObject *args, PyObject *kwds)
|
|||
|
||||
PyTypeObject FsType = {
|
||||
PyVarObject_HEAD_INIT(NULL, 0)
|
||||
"libmount.Fs", /*tp_name*/
|
||||
sizeof(FsObject), /*tp_basicsize*/
|
||||
0, /*tp_itemsize*/
|
||||
(destructor)Fs_destructor, /*tp_dealloc*/
|
||||
0, /*tp_print*/
|
||||
NULL, /*tp_getattr*/
|
||||
NULL, /*tp_setattr*/
|
||||
NULL, /*tp_compare*/
|
||||
(reprfunc)Fs_repr, /*tp_repr*/
|
||||
NULL, /*tp_as_number*/
|
||||
NULL, /*tp_as_sequence*/
|
||||
NULL, /*tp_as_mapping*/
|
||||
NULL, /*tp_hash */
|
||||
NULL, /*tp_call*/
|
||||
NULL, /*tp_str*/
|
||||
NULL, /*tp_getattro*/
|
||||
NULL, /*tp_setattro*/
|
||||
NULL, /*tp_as_buffer*/
|
||||
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
|
||||
Fs_HELP, /* tp_doc */
|
||||
NULL, /* tp_traverse */
|
||||
NULL, /* tp_clear */
|
||||
NULL, /* tp_richcompare */
|
||||
0, /* tp_weaklistoffset */
|
||||
NULL, /* tp_iter */
|
||||
NULL, /* tp_iternext */
|
||||
Fs_methods, /* tp_methods */
|
||||
Fs_members, /* tp_members */
|
||||
Fs_getseters, /* tp_getset */
|
||||
NULL, /* tp_base */
|
||||
NULL, /* tp_dict */
|
||||
NULL, /* tp_descr_get */
|
||||
NULL, /* tp_descr_set */
|
||||
0, /* tp_dictoffset */
|
||||
(initproc)Fs_init, /* tp_init */
|
||||
NULL, /* tp_alloc */
|
||||
Fs_new, /* tp_new */
|
||||
.tp_name = "libmount.Fs",
|
||||
.tp_basicsize = sizeof(FsObject),
|
||||
.tp_dealloc = (destructor)Fs_destructor,
|
||||
.tp_repr = (reprfunc)Fs_repr,
|
||||
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
|
||||
.tp_doc = Fs_HELP,
|
||||
.tp_methods = Fs_methods,
|
||||
.tp_members = Fs_members,
|
||||
.tp_getset = Fs_getseters,
|
||||
.tp_init = (initproc)Fs_init,
|
||||
.tp_new = Fs_new,
|
||||
};
|
||||
|
||||
void FS_AddModuleObject(PyObject *mod)
|
||||
|
|
|
@ -731,43 +731,17 @@ static PyObject *Table_repr(TableObject *self)
|
|||
|
||||
PyTypeObject TableType = {
|
||||
PyVarObject_HEAD_INIT(NULL, 0)
|
||||
"libmount.Table", /*tp_name*/
|
||||
sizeof(TableObject), /*tp_basicsize*/
|
||||
0, /*tp_itemsize*/
|
||||
(destructor)Table_destructor, /*tp_dealloc*/
|
||||
0, /*tp_print*/
|
||||
NULL, /*tp_getattr*/
|
||||
NULL, /*tp_setattr*/
|
||||
NULL, /*tp_compare*/
|
||||
(reprfunc) Table_repr, /*tp_repr*/
|
||||
NULL, /*tp_as_number*/
|
||||
NULL, /*tp_as_sequence*/
|
||||
NULL, /*tp_as_mapping*/
|
||||
NULL, /*tp_hash */
|
||||
NULL, /*tp_call*/
|
||||
NULL, /*tp_str*/
|
||||
NULL, /*tp_getattro*/
|
||||
NULL, /*tp_setattro*/
|
||||
NULL, /*tp_as_buffer*/
|
||||
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
|
||||
Table_HELP, /* tp_doc */
|
||||
NULL, /* tp_traverse */
|
||||
NULL, /* tp_clear */
|
||||
NULL, /* tp_richcompare */
|
||||
0, /* tp_weaklistoffset */
|
||||
NULL, /* tp_iter */
|
||||
NULL, /* tp_iternext */
|
||||
Table_methods, /* tp_methods */
|
||||
Table_members, /* tp_members */
|
||||
Table_getseters, /* tp_getset */
|
||||
NULL, /* tp_base */
|
||||
NULL, /* tp_dict */
|
||||
NULL, /* tp_descr_get */
|
||||
NULL, /* tp_descr_set */
|
||||
0, /* tp_dictoffset */
|
||||
(initproc)Table_init, /* tp_init */
|
||||
NULL, /* tp_alloc */
|
||||
Table_new, /* tp_new */
|
||||
.tp_name = "libmount.Table",
|
||||
.tp_basicsize = sizeof(TableObject),
|
||||
.tp_dealloc = (destructor)Table_destructor,
|
||||
.tp_repr = (reprfunc) Table_repr,
|
||||
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
|
||||
.tp_doc = Table_HELP,
|
||||
.tp_methods = Table_methods,
|
||||
.tp_members = Table_members,
|
||||
.tp_getset = Table_getseters,
|
||||
.tp_init = (initproc)Table_init,
|
||||
.tp_new = Table_new,
|
||||
};
|
||||
|
||||
void Table_AddModuleObject(PyObject *mod)
|
||||
|
|
12
libmount/samples/Makemodule.am
Normal file
12
libmount/samples/Makemodule.am
Normal file
|
@ -0,0 +1,12 @@
|
|||
|
||||
check_PROGRAMS += \
|
||||
sample-mount-overwrite
|
||||
|
||||
sample_mount_cflags = $(AM_CFLAGS) $(NO_UNUSED_WARN_CFLAGS) \
|
||||
-I$(ul_libmount_incdir)
|
||||
sample_mount_ldadd = libmount.la $(LDADD)
|
||||
|
||||
|
||||
sample_mount_overwrite_SOURCES = libmount/samples/overwrite.c
|
||||
sample_mount_overwrite_LDADD = $(sample_mount_ldadd)
|
||||
sample_mount_overwrite_CFLAGS = $(sample_mount_cflags)
|
58
libmount/samples/overwrite.c
Normal file
58
libmount/samples/overwrite.c
Normal file
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* Copyright (C) 2023 Karel Zak <kzak@redhat.com>
|
||||
*
|
||||
* This file may be redistributed under the terms of the
|
||||
* GNU Lesser General Public License.
|
||||
*
|
||||
*
|
||||
* This sample reads the mountpoint entry from /etc/fstab and mounts it to the
|
||||
* different (on the command line specified) mountpoint. The mount options
|
||||
* settings are read from fstab.
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "c.h"
|
||||
|
||||
#include "libmount.h"
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char *target, *fstab_target;
|
||||
struct libmnt_table *tab;
|
||||
struct libmnt_fs *fs;
|
||||
struct libmnt_context *cxt;
|
||||
int rc;
|
||||
|
||||
if (argc != 3)
|
||||
errx(EXIT_FAILURE, "usage: %s <mnt-from-fstab> <target>",
|
||||
program_invocation_short_name);
|
||||
|
||||
fstab_target = argv[1];
|
||||
target = argv[2];
|
||||
|
||||
printf("Mounting %s from fstab to %s\n", fstab_target, target);
|
||||
|
||||
tab = mnt_new_table_from_file("/etc/fstab");
|
||||
if (!tab)
|
||||
err(EXIT_FAILURE, "failed to parse fstab");
|
||||
|
||||
fs = mnt_table_find_target(tab, fstab_target, MNT_ITER_FORWARD);
|
||||
if (!fs)
|
||||
err(EXIT_FAILURE, "cannot found %s in fstab", argv[1]);
|
||||
|
||||
cxt = mnt_new_context();
|
||||
if (!cxt)
|
||||
err(EXIT_FAILURE, "cannot allocate context");
|
||||
|
||||
mnt_context_set_fs(cxt, fs);
|
||||
mnt_context_set_target(cxt, target);
|
||||
|
||||
rc = mnt_context_mount(cxt);
|
||||
|
||||
printf("Done: rc=%d status=%d\n", rc, mnt_context_get_status(cxt));
|
||||
|
||||
mnt_free_context(cxt);
|
||||
mnt_unref_table(tab);
|
||||
return rc == 0 && mnt_context_get_status(cxt) == 1 ? EXIT_SUCCESS : EXIT_FAILURE;
|
||||
}
|
|
@ -1560,7 +1560,6 @@ int mnt_context_get_mount_excode(
|
|||
*/
|
||||
syserr = mnt_context_get_syscall_errno(cxt);
|
||||
|
||||
|
||||
switch(syserr) {
|
||||
case EPERM:
|
||||
if (!buf)
|
||||
|
@ -1603,10 +1602,8 @@ int mnt_context_get_mount_excode(
|
|||
return MNT_EX_SUCCESS;
|
||||
if (buf)
|
||||
snprintf(buf, bufsz, _("special device %s does not exist"), src);
|
||||
} else if (buf) {
|
||||
errno = syserr;
|
||||
snprintf(buf, bufsz, _("mount(2) system call failed: %m"));
|
||||
}
|
||||
} else
|
||||
goto generic_error;
|
||||
break;
|
||||
|
||||
case ENOTDIR:
|
||||
|
@ -1619,10 +1616,8 @@ int mnt_context_get_mount_excode(
|
|||
if (buf)
|
||||
snprintf(buf, bufsz, _("special device %s does not exist "
|
||||
"(a path prefix is not a directory)"), src);
|
||||
} else if (buf) {
|
||||
errno = syserr;
|
||||
snprintf(buf, bufsz, _("mount(2) system call failed: %m"));
|
||||
}
|
||||
} else
|
||||
goto generic_error;
|
||||
break;
|
||||
|
||||
case EINVAL:
|
||||
|
@ -1703,10 +1698,8 @@ int mnt_context_get_mount_excode(
|
|||
snprintf(buf, bufsz, _("cannot remount %s read-write, is write-protected"), src);
|
||||
else if (mflags & MS_BIND)
|
||||
snprintf(buf, bufsz, _("bind %s failed"), src);
|
||||
else {
|
||||
errno = syserr;
|
||||
snprintf(buf, bufsz, _("mount(2) system call failed: %m"));
|
||||
}
|
||||
else
|
||||
goto generic_error;
|
||||
break;
|
||||
|
||||
case ENOMEDIUM:
|
||||
|
@ -1726,9 +1719,11 @@ int mnt_context_get_mount_excode(
|
|||
/* fallthrough */
|
||||
|
||||
default:
|
||||
generic_error:
|
||||
if (buf) {
|
||||
errno = syserr;
|
||||
snprintf(buf, bufsz, _("mount(2) system call failed: %m"));
|
||||
snprintf(buf, bufsz, _("%s system call failed: %m"),
|
||||
cxt->syscall_name ? : "mount");
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -46,6 +46,7 @@
|
|||
#include "mountP.h"
|
||||
#include "fileutils.h" /* statx() fallback */
|
||||
#include "mount-api-utils.h"
|
||||
#include "linux_version.h"
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
|
@ -462,7 +463,7 @@ static int hook_set_propagation(struct libmnt_context *cxt,
|
|||
(uint64_t) attr.propagation));
|
||||
|
||||
rc = mount_setattr(api->fd_tree, "", flgs, &attr, sizeof(attr));
|
||||
set_syscall_status(cxt, "move_setattr", rc == 0);
|
||||
set_syscall_status(cxt, "mount_setattr", rc == 0);
|
||||
|
||||
if (rc && errno == EINVAL)
|
||||
return -MNT_ERR_APPLYFLAGS;
|
||||
|
@ -719,6 +720,13 @@ static int hook_prepare(struct libmnt_context *cxt,
|
|||
if (!rc
|
||||
&& cxt->helper == NULL
|
||||
&& (set != 0 || clr != 0 || (flags & MS_REMOUNT))) {
|
||||
/*
|
||||
* mount_setattr() supported, but not usable for remount
|
||||
* https://github.com/torvalds/linux/commit/dd8b477f9a3d8edb136207acb3652e1a34a661b7
|
||||
*/
|
||||
if (get_linux_version() < KERNEL_VERSION(5, 14, 0))
|
||||
goto enosys;
|
||||
|
||||
if (!mount_setattr_is_supported())
|
||||
goto enosys;
|
||||
|
||||
|
|
|
@ -188,7 +188,8 @@ enum {
|
|||
/**
|
||||
* MNT_ERR_APPLYFLAGS:
|
||||
*
|
||||
* failed to apply MS_PROPAGATION flags
|
||||
* failed to apply MS_PROPAGATION flags, and MOUNT_ATTR_* attributes for
|
||||
* mount_setattr(2)
|
||||
*/
|
||||
#define MNT_ERR_APPLYFLAGS 5005
|
||||
/**
|
||||
|
|
|
@ -1386,6 +1386,35 @@ static int test_get_flg(struct libmnt_test *ts, int argc, char *argv[])
|
|||
return rc;
|
||||
}
|
||||
|
||||
static int test_split(struct libmnt_test *ts, int argc, char *argv[])
|
||||
{
|
||||
struct libmnt_optlist *ol;
|
||||
int rc;
|
||||
struct libmnt_iter itr;
|
||||
struct libmnt_opt *opt;
|
||||
const char *name, *value;
|
||||
|
||||
if (argc != 2)
|
||||
return -EINVAL;
|
||||
rc = mk_optlist(&ol, argv[1]);
|
||||
if (rc)
|
||||
goto done;
|
||||
|
||||
mnt_reset_iter(&itr, MNT_ITER_FORWARD);
|
||||
|
||||
while (mnt_optlist_next_opt(ol, &itr, &opt) == 0) {
|
||||
name = mnt_opt_get_name(opt);
|
||||
value = mnt_opt_get_value(opt);
|
||||
|
||||
printf("%s = %s\n", name, value ?: "(null)");
|
||||
}
|
||||
|
||||
done:
|
||||
mnt_unref_optlist(ol);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
struct libmnt_test tss[] = {
|
||||
|
@ -1396,6 +1425,7 @@ int main(int argc, char *argv[])
|
|||
{ "--set-flg", test_set_flg, "<list> <flg> linux|user set to the list" },
|
||||
{ "--get-str", test_get_str, "<list> [linux|user] all options in string" },
|
||||
{ "--get-flg", test_get_flg, "<list> linux|user all options by flags" },
|
||||
{ "--split", test_split, "<list> split options into key-value pairs"},
|
||||
|
||||
{ NULL }
|
||||
};
|
||||
|
|
|
@ -148,6 +148,14 @@ _/etc/pam.d/remote_,
|
|||
_/etc/hushlogins_,
|
||||
_$HOME/.hushlogin_
|
||||
|
||||
== CREDENTIALS
|
||||
|
||||
*login* supports configuration via systemd credentials (see https://systemd.io/CREDENTIALS/). *login* reads the following systemd credentials:
|
||||
|
||||
*login.noauth* (boolean)::
|
||||
|
||||
If set, configures *login* to skip login authentication, similarly to the *-f* option.
|
||||
|
||||
== BUGS
|
||||
|
||||
The undocumented BSD *-r* option is not supported. This may be required by some *rlogind*(8) programs.
|
||||
|
|
|
@ -46,6 +46,7 @@
|
|||
#include <grp.h>
|
||||
#include <pwd.h>
|
||||
#include <utmpx.h>
|
||||
#include <path.h>
|
||||
|
||||
#ifdef HAVE_LASTLOG_H
|
||||
# include <lastlog.h>
|
||||
|
@ -1287,6 +1288,38 @@ static void __attribute__((__noreturn__)) usage(void)
|
|||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
static void load_credentials(struct login_context *cxt) {
|
||||
char *env;
|
||||
DIR *dir;
|
||||
struct dirent *d;
|
||||
struct path_cxt *pc;
|
||||
|
||||
env = safe_getenv("CREDENTIALS_DIRECTORY");
|
||||
if (!env)
|
||||
return;
|
||||
|
||||
pc = ul_new_path("%s", env);
|
||||
if (!pc) {
|
||||
syslog(LOG_WARNING, _("failed to initialize path context"));
|
||||
return;
|
||||
}
|
||||
|
||||
dir = ul_path_opendir(pc, NULL);
|
||||
if (!dir) {
|
||||
syslog(LOG_WARNING, _("failed to open credentials directory"));
|
||||
return;
|
||||
}
|
||||
|
||||
while ((d = xreaddir(dir))) {
|
||||
char str[32] = { 0 };
|
||||
|
||||
if (strcmp(d->d_name, "login.noauth") == 0
|
||||
&& ul_path_read_buffer(pc, str, sizeof(str), d->d_name) > 0
|
||||
&& *str && strcmp(str, "yes") == 0)
|
||||
cxt->noauth = 1;
|
||||
}
|
||||
}
|
||||
|
||||
static void initialize(int argc, char **argv, struct login_context *cxt)
|
||||
{
|
||||
int c;
|
||||
|
@ -1318,6 +1351,8 @@ static void initialize(int argc, char **argv, struct login_context *cxt)
|
|||
setpriority(PRIO_PROCESS, 0, 0);
|
||||
process_title_init(argc, argv);
|
||||
|
||||
load_credentials(cxt);
|
||||
|
||||
while ((c = getopt_long(argc, argv, "fHh:pV", longopts, NULL)) != -1)
|
||||
switch (c) {
|
||||
case 'f':
|
||||
|
|
|
@ -64,7 +64,7 @@
|
|||
* column description
|
||||
*/
|
||||
struct lslogins_coldesc {
|
||||
const char *name;
|
||||
const char * const name;
|
||||
const char *help;
|
||||
const char *pretty_name;
|
||||
|
||||
|
|
|
@ -270,23 +270,21 @@ static void tcfinal(struct console *con)
|
|||
{
|
||||
struct termios *tio = &con->tio;
|
||||
const int fd = con->fd;
|
||||
char *term, *ttyname = NULL;
|
||||
|
||||
if (con->flags & CON_EIO)
|
||||
return;
|
||||
if ((con->flags & CON_SERIAL) == 0) {
|
||||
xsetenv("TERM", "linux", 0);
|
||||
return;
|
||||
}
|
||||
if (con->flags & CON_NOTTY) {
|
||||
xsetenv("TERM", "dumb", 0);
|
||||
return;
|
||||
if (con->tty)
|
||||
ttyname = strncmp(con->tty, "/dev/", 5) == 0 ?
|
||||
con->tty + 5 : con->tty;
|
||||
|
||||
term = get_terminal_default_type(ttyname, con->flags & CON_SERIAL);
|
||||
if (term) {
|
||||
xsetenv("TERM", term, 0);
|
||||
free(term);
|
||||
}
|
||||
|
||||
#if defined (__s390__) || defined (__s390x__)
|
||||
xsetenv("TERM", "dumb", 0);
|
||||
#else
|
||||
xsetenv("TERM", "vt102", 0);
|
||||
#endif
|
||||
if (!(con->flags & CON_SERIAL) || (con->flags & CON_NOTTY))
|
||||
return;
|
||||
|
||||
tio->c_iflag |= (IXON | IXOFF);
|
||||
tio->c_lflag |= (ICANON | ISIG | ECHO|ECHOE|ECHOK|ECHOKE);
|
||||
tio->c_oflag |= OPOST;
|
||||
|
|
|
@ -108,7 +108,7 @@ static void print_utline(struct utmpx *ut, FILE *out)
|
|||
addr_string = inet_ntop(AF_INET, &(ut->ut_addr_v6), buffer, sizeof(buffer));
|
||||
|
||||
tv.tv_sec = ut->ut_tv.tv_sec;
|
||||
tv.tv_usec = ut->ut_tv.tv_usec;
|
||||
tv.tv_usec = ut->ut_tv.tv_usec < (int32_t) USEC_PER_SEC ? ut->ut_tv.tv_usec : 0;
|
||||
|
||||
if (strtimeval_iso(&tv, ISO_TIMESTAMP_COMMA_GT, time_string,
|
||||
sizeof(time_string)) != 0)
|
||||
|
|
41
meson.build
41
meson.build
|
@ -3,6 +3,7 @@ project('util-linux', 'c',
|
|||
meson_version: '>=0.57.0',
|
||||
license : 'GPLv2+')
|
||||
|
||||
fs = import('fs')
|
||||
pkgconfig = import('pkgconfig')
|
||||
|
||||
libblkid_version = '1.1.0'
|
||||
|
@ -2886,6 +2887,40 @@ if LINUX and conf.get('HAVE_PIDFD_OPEN') != false
|
|||
endif
|
||||
endif
|
||||
|
||||
syscalls_h = custom_target('syscalls.h',
|
||||
input : 'tools/all_syscalls',
|
||||
output : 'syscalls.h',
|
||||
command : ['bash', '@INPUT@', cc.cmd_array()],
|
||||
)
|
||||
|
||||
if cc.compiles(fs.read('include/audit-arch.h'), name : 'has AUDIT_ARCH_NATIVE')
|
||||
exe = executable(
|
||||
'enosys',
|
||||
'misc-utils/enosys.c', syscalls_h,
|
||||
include_directories : includes,
|
||||
link_with : [lib_common],
|
||||
install_dir : usrbin_exec_dir,
|
||||
install : true)
|
||||
if not is_disabler(exe)
|
||||
exes += exe
|
||||
manadocs += ['misc-utils/enosys.1.adoc']
|
||||
bashcompletions += ['enosys']
|
||||
endif
|
||||
endif
|
||||
|
||||
exe = executable(
|
||||
'lsclocks',
|
||||
lsclocks_sources,
|
||||
include_directories : includes,
|
||||
link_with : [lib_common, lib_smartcols],
|
||||
install_dir : usrbin_exec_dir,
|
||||
install : true)
|
||||
if not is_disabler(exe)
|
||||
exes += exe
|
||||
manadocs += ['misc-utils/lsclocks.1.adoc']
|
||||
bashcompletions += ['lsclocks']
|
||||
endif
|
||||
|
||||
############################################################
|
||||
|
||||
opt = not get_option('build-schedutils').disabled()
|
||||
|
@ -3270,11 +3305,15 @@ exe = executable(
|
|||
include_directories : includes)
|
||||
exes += exe
|
||||
|
||||
mq_libs = []
|
||||
mq_libs += cc.find_library('rt', required : true)
|
||||
|
||||
if LINUX
|
||||
exe = executable(
|
||||
'test_mkfds',
|
||||
'tests/helpers/test_mkfds.c',
|
||||
include_directories : includes)
|
||||
include_directories : includes,
|
||||
dependencies : mq_libs)
|
||||
exes += exe
|
||||
endif
|
||||
|
||||
|
|
|
@ -297,3 +297,30 @@ waitpid_SOURCES = misc-utils/waitpid.c
|
|||
waitpid_LDADD = $(LDADD) libcommon.la
|
||||
waitpid_CFLAGS = $(AM_CFLAGS)
|
||||
endif
|
||||
|
||||
if BUILD_ENOSYS
|
||||
|
||||
misc-utils/enosys.c: syscalls.h
|
||||
|
||||
syscalls.h: $(top_srcdir)/tools/all_syscalls
|
||||
@echo ' GEN $@'
|
||||
@$(top_srcdir)/tools/all_syscalls $(CC) $(CFLAGS)
|
||||
|
||||
-include syscalls.h.deps
|
||||
CLEANFILES += syscalls.h syscalls.h.deps
|
||||
|
||||
usrbin_exec_PROGRAMS += enosys
|
||||
MANPAGES += misc-utils/enosys.1
|
||||
dist_noinst_DATA += misc-utils/enosys.1.adoc
|
||||
enosys_SOURCES = misc-utils/enosys.c
|
||||
enosys_LDADD = $(LDADD) libcommon.la
|
||||
enosys_CFLAGS = $(AM_CFLAGS)
|
||||
endif
|
||||
|
||||
if BUILD_LSCLOCKS
|
||||
usrbin_exec_PROGRAMS += lsclocks
|
||||
MANPAGES += misc-utils/lsclocks.1
|
||||
lsclocks_SOURCES = misc-utils/lsclocks.c
|
||||
lsclocks_LDADD = $(LDADD) libcommon.la libsmartcols.la
|
||||
lsclocks_CFLAGS = $(AM_CFLAGS) -I$(ul_libsmartcols_incdir)
|
||||
endif
|
||||
|
|
60
misc-utils/enosys.1.adoc
Normal file
60
misc-utils/enosys.1.adoc
Normal file
|
@ -0,0 +1,60 @@
|
|||
//po4a: entry man manual
|
||||
= enosys(1)
|
||||
:doctype: manpage
|
||||
:man manual: User Commands
|
||||
:man source: util-linux {release-version}
|
||||
:page-layout: base
|
||||
:command: enosys
|
||||
|
||||
== NAME
|
||||
|
||||
enosys - utility make syscalls fail with ENOSYS
|
||||
|
||||
== SYNOPSIS
|
||||
|
||||
*enosys* [*--syscall*|*-s* _syscall_] command
|
||||
|
||||
== DESCRIPTION
|
||||
|
||||
*enosys* is a simple command to execute a child process for which certain
|
||||
syscalls fail with errno ENOSYS.
|
||||
|
||||
It can be used to test the behavior of applications in the face of missing
|
||||
syscalls as would happen when running on old kernels.
|
||||
|
||||
== OPTIONS
|
||||
|
||||
*-s*, *--syscall*::
|
||||
Syscall to block. Can be specified multiple times.
|
||||
|
||||
*-l*, *--list*::
|
||||
List syscalls known to *enosys*.
|
||||
|
||||
include::man-common/help-version.adoc[]
|
||||
|
||||
== EXIT STATUS
|
||||
|
||||
*enosys* exits with the status code of the executed process.
|
||||
The following values have special meanings:
|
||||
|
||||
*1*::
|
||||
internal error
|
||||
|
||||
*2*::
|
||||
system does not provide the necessary functionality
|
||||
|
||||
== AUTHORS
|
||||
|
||||
mailto:thomas@t-8ch.de[Thomas Weißschuh]
|
||||
|
||||
== SEE ALSO
|
||||
|
||||
*syscall*(2)
|
||||
|
||||
include::man-common/bugreports.adoc[]
|
||||
|
||||
include::man-common/footer.adoc[]
|
||||
|
||||
ifdef::translation[]
|
||||
include::man-common/translation.adoc[]
|
||||
endif::[]
|
192
misc-utils/enosys.c
Normal file
192
misc-utils/enosys.c
Normal file
|
@ -0,0 +1,192 @@
|
|||
/*
|
||||
* Copyright (C) 2023 Thomas Weißschuh <thomas@t-8ch.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it would be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
#include <getopt.h>
|
||||
|
||||
#include <linux/unistd.h>
|
||||
#include <linux/filter.h>
|
||||
#include <linux/seccomp.h>
|
||||
#include <linux/audit.h>
|
||||
#include <sys/prctl.h>
|
||||
#include <sys/syscall.h>
|
||||
|
||||
#include "c.h"
|
||||
#include "exitcodes.h"
|
||||
#include "nls.h"
|
||||
#include "bitops.h"
|
||||
#include "audit-arch.h"
|
||||
|
||||
#define UL_BPF_NOP (struct sock_filter) BPF_JUMP(BPF_JMP | BPF_JA, 0, 0, 0)
|
||||
#define IS_LITTLE_ENDIAN (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
|
||||
|
||||
#define syscall_nr (offsetof(struct seccomp_data, nr))
|
||||
#define syscall_arch (offsetof(struct seccomp_data, arch))
|
||||
#define syscall_arg(n) (offsetof(struct seccomp_data, args[n]))
|
||||
|
||||
static int set_seccomp_filter(const void *prog)
|
||||
{
|
||||
#if defined(__NR_seccomp) && defined(SECCOMP_SET_MODE_FILTER) && defined(SECCOMP_FILTER_FLAG_SPEC_ALLOW)
|
||||
if (!syscall(__NR_seccomp, SECCOMP_SET_MODE_FILTER, SECCOMP_FILTER_FLAG_SPEC_ALLOW, prog))
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
return prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, prog);
|
||||
}
|
||||
|
||||
struct syscall {
|
||||
const char *const name;
|
||||
long number;
|
||||
};
|
||||
|
||||
static const struct syscall syscalls[] = {
|
||||
#define UL_SYSCALL(name, nr) { name, nr },
|
||||
#include "syscalls.h"
|
||||
#undef UL_SYSCALL
|
||||
};
|
||||
static_assert(sizeof(syscalls) > 0, "no syscalls found");
|
||||
|
||||
static void __attribute__((__noreturn__)) usage(void)
|
||||
{
|
||||
FILE *out = stdout;
|
||||
|
||||
fputs(USAGE_HEADER, out);
|
||||
fprintf(out, _(" %s [options] -- <command>\n"), program_invocation_short_name);
|
||||
|
||||
fputs(USAGE_OPTIONS, out);
|
||||
fputs(_(" -s, --syscall syscall to block\n"), out);
|
||||
fputs(_(" -l, --list list known syscalls\n"), out);
|
||||
|
||||
fputs(USAGE_SEPARATOR, out);
|
||||
fprintf(out, USAGE_HELP_OPTIONS(25));
|
||||
|
||||
fprintf(out, USAGE_MAN_TAIL("enosys(1)"));
|
||||
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int c;
|
||||
size_t i;
|
||||
bool found;
|
||||
static const struct option longopts[] = {
|
||||
{ "syscall", required_argument, NULL, 's' },
|
||||
{ "list", no_argument, NULL, 'l' },
|
||||
{ "version", no_argument, NULL, 'V' },
|
||||
{ "help", no_argument, NULL, 'h' },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
bool blocked_syscalls[ARRAY_SIZE(syscalls)] = {};
|
||||
|
||||
setlocale(LC_ALL, "");
|
||||
bindtextdomain(PACKAGE, LOCALEDIR);
|
||||
textdomain(PACKAGE);
|
||||
|
||||
while ((c = getopt_long (argc, argv, "+Vhs:l", longopts, NULL)) != -1) {
|
||||
switch (c) {
|
||||
case 's':
|
||||
found = 0;
|
||||
for (i = 0; i < ARRAY_SIZE(syscalls); i++) {
|
||||
if (strcmp(optarg, syscalls[i].name) == 0) {
|
||||
blocked_syscalls[i] = true;
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
errx(EXIT_FAILURE, _("Unknown syscall '%s'"), optarg);
|
||||
break;
|
||||
case 'l':
|
||||
for (i = 0; i < ARRAY_SIZE(syscalls); i++)
|
||||
printf("%s\n", syscalls[i].name);
|
||||
return EXIT_SUCCESS;
|
||||
case 'V':
|
||||
print_version(EXIT_SUCCESS);
|
||||
case 'h':
|
||||
usage();
|
||||
default:
|
||||
errtryhelp(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
if (optind >= argc)
|
||||
errtryhelp(EXIT_FAILURE);
|
||||
|
||||
#define N_FILTERS (ARRAY_SIZE(syscalls) * 2 + 12)
|
||||
|
||||
struct sock_filter filter[N_FILTERS] = {
|
||||
[0] = BPF_STMT(BPF_LD | BPF_W | BPF_ABS, syscall_arch),
|
||||
[1] = BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, SECCOMP_ARCH_NATIVE, 1, 0),
|
||||
[2] = BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_TRAP),
|
||||
|
||||
/* Blocking "execve" normally would also block our own call to
|
||||
* it and the end of main. To distinguish between our execve
|
||||
* and the execve to be blocked, compare the environ pointer.
|
||||
*
|
||||
* See https://lore.kernel.org/all/CAAnLoWnS74dK9Wq4EQ-uzQ0qCRfSK-dLqh+HCais-5qwDjrVzg@mail.gmail.com/
|
||||
*/
|
||||
[3] = BPF_STMT(BPF_LD | BPF_W | BPF_ABS, syscall_nr),
|
||||
[4] = BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_execve, 0, 5),
|
||||
[5] = BPF_STMT(BPF_LD | BPF_W | BPF_ABS, syscall_arg(2) + 4 * !IS_LITTLE_ENDIAN),
|
||||
[6] = BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, (uint64_t)(uintptr_t) environ, 0, 3),
|
||||
[7] = BPF_STMT(BPF_LD | BPF_W | BPF_ABS, syscall_arg(2) + 4 * IS_LITTLE_ENDIAN),
|
||||
[8] = BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, (uint64_t)(uintptr_t) environ >> 32, 0, 1),
|
||||
[9] = BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
|
||||
|
||||
[10] = BPF_STMT(BPF_LD | BPF_W | BPF_ABS, syscall_nr),
|
||||
|
||||
[N_FILTERS - 1] = BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
|
||||
};
|
||||
static_assert(ARRAY_SIZE(filter) <= BPF_MAXINSNS, "bpf filter too big");
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(syscalls); i++) {
|
||||
struct sock_filter *f = &filter[11 + i * 2];
|
||||
|
||||
*f = (struct sock_filter) BPF_JUMP(
|
||||
BPF_JMP | BPF_JEQ | BPF_K,
|
||||
syscalls[i].number,
|
||||
0, 1);
|
||||
*(f + 1) = blocked_syscalls[i]
|
||||
? (struct sock_filter) BPF_STMT(
|
||||
BPF_RET | BPF_K, SECCOMP_RET_ERRNO | ENOSYS)
|
||||
: UL_BPF_NOP;
|
||||
}
|
||||
|
||||
struct sock_fprog prog = {
|
||||
.len = ARRAY_SIZE(filter),
|
||||
.filter = filter,
|
||||
};
|
||||
|
||||
/* *SET* below will return EINVAL when either the filter is invalid or
|
||||
* seccomp is not supported. To distinguish those cases do a *GET* here
|
||||
*/
|
||||
if (prctl(PR_GET_SECCOMP) == -1 && errno == EINVAL)
|
||||
err(EXIT_NOTSUPP, _("Seccomp non-functional"));
|
||||
|
||||
if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0))
|
||||
err_nosys(EXIT_FAILURE, _("Could not run prctl(PR_SET_NO_NEW_PRIVS)"));
|
||||
|
||||
if (set_seccomp_filter(&prog))
|
||||
err_nosys(EXIT_FAILURE, _("Could not seccomp filter"));
|
||||
|
||||
if (execvp(argv[optind], argv + optind))
|
||||
err(EXIT_NOTSUPP, _("Could not exec"));
|
||||
}
|
|
@ -44,7 +44,7 @@
|
|||
|
||||
|
||||
struct colinfo {
|
||||
const char *name;
|
||||
const char * const name;
|
||||
double whint;
|
||||
int flags;
|
||||
const char *help;
|
||||
|
@ -57,7 +57,7 @@ enum {
|
|||
COL_RES
|
||||
};
|
||||
|
||||
static struct colinfo infos[] = {
|
||||
static const struct colinfo infos[] = {
|
||||
[COL_PAGES] = { "PAGES", 1, SCOLS_FL_RIGHT, N_("file data resident in memory in pages")},
|
||||
[COL_RES] = { "RES", 5, SCOLS_FL_RIGHT, N_("file data resident in memory in bytes")},
|
||||
[COL_SIZE] = { "SIZE", 5, SCOLS_FL_RIGHT, N_("size of the file")},
|
||||
|
|
|
@ -90,7 +90,7 @@ enum {
|
|||
|
||||
/* column names */
|
||||
struct colinfo {
|
||||
const char *name; /* header */
|
||||
const char * const name; /* header */
|
||||
double whint; /* width hint (N < 1 is in percent of termwidth) */
|
||||
int flags; /* libsmartcols flags */
|
||||
const char *help; /* column description */
|
||||
|
|
|
@ -158,7 +158,7 @@ enum {
|
|||
|
||||
/* column names */
|
||||
struct colinfo {
|
||||
const char *name; /* header */
|
||||
const char * const name; /* header */
|
||||
double whint; /* width hint (N < 1 is in percent of termwidth) */
|
||||
int flags; /* SCOLS_FL_* */
|
||||
const char *help;
|
||||
|
@ -166,7 +166,7 @@ struct colinfo {
|
|||
};
|
||||
|
||||
/* columns descriptions */
|
||||
static struct colinfo infos[] = {
|
||||
static const struct colinfo infos[] = {
|
||||
[COL_ALIOFF] = { "ALIGNMENT", 6, SCOLS_FL_RIGHT, N_("alignment offset"), COLTYPE_NUM },
|
||||
[COL_ID] = { "ID", 0.1, SCOLS_FL_NOEXTREMES, N_("udev ID (based on ID-LINK)") },
|
||||
[COL_IDLINK] = { "ID-LINK", 0.1, SCOLS_FL_NOEXTREMES, N_("the shortest udev /dev/disk/by-id link name") },
|
||||
|
@ -324,7 +324,7 @@ static int get_column_id(int num)
|
|||
}
|
||||
|
||||
/* Returns column description for the column sequential number */
|
||||
static struct colinfo *get_column_info(int num)
|
||||
static const struct colinfo *get_column_info(int num)
|
||||
{
|
||||
return &infos[ get_column_id(num) ];
|
||||
}
|
||||
|
@ -2364,7 +2364,7 @@ int main(int argc, char *argv[])
|
|||
}
|
||||
|
||||
for (i = 0; i < ncolumns; i++) {
|
||||
struct colinfo *ci = get_column_info(i);
|
||||
const struct colinfo *ci = get_column_info(i);
|
||||
struct libscols_column *cl;
|
||||
int id = get_column_id(i), fl = ci->flags;
|
||||
|
||||
|
|
81
misc-utils/lsclocks.1.adoc
Normal file
81
misc-utils/lsclocks.1.adoc
Normal file
|
@ -0,0 +1,81 @@
|
|||
//po4a: entry man manual
|
||||
= lsclocks(1)
|
||||
:doctype: manpage
|
||||
:man manual: User Commands
|
||||
:man source: util-linux {release-version}
|
||||
:page-layout: base
|
||||
:command: lsclocks
|
||||
|
||||
== NAME
|
||||
|
||||
lsclocks - display system clocks
|
||||
|
||||
== SYNOPSIS
|
||||
|
||||
*lsclocks* [option]
|
||||
|
||||
== DESCRIPTION
|
||||
|
||||
*lsclocks* is a simple command to display system clocks.
|
||||
|
||||
It allows to display information like current time and resolutionof clocks like
|
||||
CLOCK_MONOTONIC, CLOCK_REALTIME and CLOCK_BOOTTIME.
|
||||
|
||||
== OPTIONS
|
||||
|
||||
*-J*, *--json*::
|
||||
Use JSON output format.
|
||||
|
||||
*-n*, *--noheadings*::
|
||||
Don't print headings.
|
||||
|
||||
*-o*, *--output* _list_::
|
||||
Specify which output columns to print. See the *OUTPUT COLUMNS*
|
||||
section for details of available columns.
|
||||
|
||||
*-r*, *--raw*::
|
||||
Use raw output format.
|
||||
|
||||
*-r*, *--time* _clock_
|
||||
Show current time of one specific clocks.
|
||||
|
||||
include::man-common/help-version.adoc[]
|
||||
|
||||
== OUTPUT COLUMNS
|
||||
|
||||
Each column has a type. Types are surround by < and >.
|
||||
|
||||
ID <``number``>::
|
||||
Numeric clock ID.
|
||||
|
||||
CLOCK <``string``>::
|
||||
Name in the form *CLOCK_*
|
||||
|
||||
NAME <``string``>::
|
||||
Shorter, easier to read name.
|
||||
|
||||
TIME <``number``>::
|
||||
Current clock timestamp as returned by *clock_gettime()*.
|
||||
|
||||
ISO_TIME <``string``>::
|
||||
ISO8601 formatted version of *TIME*.
|
||||
|
||||
RESOLUTION <``number``>::
|
||||
Clock resolution as returned by *clock_getres()*.
|
||||
|
||||
|
||||
== AUTHORS
|
||||
|
||||
mailto:thomas@t-8ch.de[Thomas Weißschuh]
|
||||
|
||||
== SEE ALSO
|
||||
|
||||
*clock_getres*(2) *clock_gettime*(2)
|
||||
|
||||
include::man-common/bugreports.adoc[]
|
||||
|
||||
include::man-common/footer.adoc[]
|
||||
|
||||
ifdef::translation[]
|
||||
include::man-common/translation.adoc[]
|
||||
endif::[]
|
366
misc-utils/lsclocks.c
Normal file
366
misc-utils/lsclocks.c
Normal file
|
@ -0,0 +1,366 @@
|
|||
/*
|
||||
* lsclocks(1) - display system clocks
|
||||
*
|
||||
* Copyright (C) 2023 Thomas Weißschuh <thomas@t-8ch.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it would be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <time.h>
|
||||
#include <inttypes.h>
|
||||
#include <getopt.h>
|
||||
|
||||
#include <libsmartcols.h>
|
||||
|
||||
#include "c.h"
|
||||
#include "nls.h"
|
||||
#include "strutils.h"
|
||||
#include "timeutils.h"
|
||||
#include "closestream.h"
|
||||
#include "xalloc.h"
|
||||
|
||||
#define CLOCKFD 3
|
||||
#define FD_TO_CLOCKID(fd) ((~(clockid_t) (fd) << 3) | CLOCKFD)
|
||||
|
||||
#ifndef CLOCK_REALTIME
|
||||
#define CLOCK_REALTIME 0
|
||||
#endif
|
||||
|
||||
#ifndef CLOCK_MONOTONIC
|
||||
#define CLOCK_MONOTONIC 1
|
||||
#endif
|
||||
|
||||
#ifndef CLOCK_MONOTONIC_RAW
|
||||
#define CLOCK_MONOTONIC_RAW 4
|
||||
#endif
|
||||
|
||||
#ifndef CLOCK_REALTIME_COARSE
|
||||
#define CLOCK_REALTIME_COARSE 5
|
||||
#endif
|
||||
|
||||
#ifndef CLOCK_MONOTONIC_COARSE
|
||||
#define CLOCK_MONOTONIC_COARSE 6
|
||||
#endif
|
||||
|
||||
#ifndef CLOCK_BOOTTIME
|
||||
#define CLOCK_BOOTTIME 7
|
||||
#endif
|
||||
|
||||
#ifndef CLOCK_REALTIME_ALARM
|
||||
#define CLOCK_REALTIME_ALARM 8
|
||||
#endif
|
||||
|
||||
#ifndef CLOCK_BOOTTIME_ALARM
|
||||
#define CLOCK_BOOTTIME_ALARM 9
|
||||
#endif
|
||||
|
||||
#ifndef CLOCK_TAI
|
||||
#define CLOCK_TAI 11
|
||||
#endif
|
||||
|
||||
struct clockinfo {
|
||||
clockid_t id;
|
||||
const char * const id_name;
|
||||
const char * const name;
|
||||
};
|
||||
|
||||
static const struct clockinfo clocks[] = {
|
||||
{ CLOCK_REALTIME, "CLOCK_REALTIME", "realtime" },
|
||||
{ CLOCK_MONOTONIC, "CLOCK_MONOTONIC", "monotonic" },
|
||||
{ CLOCK_MONOTONIC_RAW, "CLOCK_MONOTONIC_RAW", "monotonic-raw" },
|
||||
{ CLOCK_REALTIME_COARSE, "CLOCK_REALTIME_COARSE", "realtime-coarse" },
|
||||
{ CLOCK_MONOTONIC_COARSE, "CLOCK_MONOTONIC_COARSE", "monotonic-coarse" },
|
||||
{ CLOCK_BOOTTIME, "CLOCK_BOOTTIME", "boottime" },
|
||||
{ CLOCK_REALTIME_ALARM, "CLOCK_REALTIME_ALARM", "realtime-alarm" },
|
||||
{ CLOCK_BOOTTIME_ALARM, "CLOCK_BOOTTIME_ALARM", "boottime-alarm" },
|
||||
{ CLOCK_TAI, "CLOCK_TAI", "tai" },
|
||||
};
|
||||
|
||||
/* column IDs */
|
||||
enum {
|
||||
COL_ID,
|
||||
COL_CLOCK,
|
||||
COL_NAME,
|
||||
COL_TIME,
|
||||
COL_ISO_TIME,
|
||||
COL_RESOLUTION,
|
||||
};
|
||||
|
||||
/* column names */
|
||||
struct colinfo {
|
||||
const char * const name; /* header */
|
||||
double whint; /* width hint (N < 1 is in percent of termwidth) */
|
||||
int flags; /* SCOLS_FL_* */
|
||||
int json_type; /* SCOLS_JSON_* */
|
||||
const char * const help;
|
||||
};
|
||||
|
||||
/* columns descriptions */
|
||||
static const struct colinfo infos[] = {
|
||||
[COL_ID] = { "ID", 1, SCOLS_FL_RIGHT, SCOLS_JSON_NUMBER, N_("numeric id") },
|
||||
[COL_CLOCK] = { "CLOCK", 1, 0, SCOLS_JSON_STRING, N_("symbolic name") },
|
||||
[COL_NAME] = { "NAME", 1, 0, SCOLS_JSON_STRING, N_("readable name") },
|
||||
[COL_TIME] = { "TIME", 1, SCOLS_FL_RIGHT, SCOLS_JSON_NUMBER, N_("numeric time") },
|
||||
[COL_ISO_TIME] = { "ISO_TIME", 1, SCOLS_FL_RIGHT, SCOLS_JSON_STRING, N_("human readable ISO time") },
|
||||
[COL_RESOLUTION] = { "RESOLUTION", 1, SCOLS_FL_RIGHT, SCOLS_JSON_NUMBER, N_("resolution") },
|
||||
};
|
||||
|
||||
static int column_name_to_id(const char *name, size_t namesz)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(infos); i++) {
|
||||
const char *cn = infos[i].name;
|
||||
|
||||
if (!strncasecmp(name, cn, namesz) && !*(cn + namesz))
|
||||
return i;
|
||||
}
|
||||
warnx(_("unknown column: %s"), name);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void __attribute__((__noreturn__)) usage(void)
|
||||
{
|
||||
FILE *out = stdout;
|
||||
size_t i;
|
||||
|
||||
fputs(USAGE_HEADER, out);
|
||||
fprintf(out, _(" %s [options]\n"), program_invocation_short_name);
|
||||
|
||||
fputs(USAGE_OPTIONS, out);
|
||||
fputs(_(" -J, --json use JSON output format\n"), out);
|
||||
fputs(_(" -n, --noheadings don't print headings\n"), out);
|
||||
fputs(_(" -o, --output <list> output columns\n"), out);
|
||||
fputs(_(" -r, --raw use raw output format\n"), out);
|
||||
fputs(_(" -t, --time <clock> show current time of single clock\n"), out);
|
||||
|
||||
fputs(USAGE_SEPARATOR, out);
|
||||
printf(USAGE_HELP_OPTIONS(25));
|
||||
|
||||
fprintf(out, USAGE_COLUMNS);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(infos); i++)
|
||||
fprintf(out, " %16s %-10s%s\n", infos[i].name,
|
||||
infos[i].json_type == SCOLS_JSON_STRING? "<string>":
|
||||
infos[i].json_type == SCOLS_JSON_ARRAY_STRING? "<string>":
|
||||
infos[i].json_type == SCOLS_JSON_ARRAY_NUMBER? "<string>":
|
||||
infos[i].json_type == SCOLS_JSON_NUMBER? "<number>":
|
||||
"<boolean>",
|
||||
_(infos[i].help));
|
||||
|
||||
printf(USAGE_MAN_TAIL("lslocks(1)"));
|
||||
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
__attribute__ ((__format__ (__printf__, 3, 4)))
|
||||
static void scols_line_asprintf(struct libscols_line *ln, size_t n, const char *format, ...)
|
||||
{
|
||||
char *data;
|
||||
va_list args;
|
||||
|
||||
va_start(args, format);
|
||||
xvasprintf(&data, format, args);
|
||||
va_end(args);
|
||||
|
||||
scols_line_refer_data(ln, n, data);
|
||||
}
|
||||
|
||||
static void scols_line_format_timespec(struct libscols_line *ln, size_t n, const struct timespec *ts)
|
||||
{
|
||||
scols_line_asprintf(ln, n, "%ju.%09" PRId32, (uintmax_t) ts->tv_sec, (uint32_t) ts->tv_nsec);
|
||||
}
|
||||
|
||||
static clockid_t parse_clock(const char *name)
|
||||
{
|
||||
size_t i;
|
||||
uint32_t id = -1;
|
||||
int rc;
|
||||
|
||||
rc = ul_strtou32(name, &id, 10);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(clocks); i++) {
|
||||
if (!strcmp(name, clocks[i].id_name)
|
||||
|| !strcmp(name, clocks[i].name))
|
||||
return clocks[i].id;
|
||||
if (rc == 0 && (clockid_t) id == clocks[i].id)
|
||||
return id;
|
||||
}
|
||||
|
||||
errx(EXIT_FAILURE, _("Unknown clock: %s"), name);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
size_t i, j;
|
||||
char c;
|
||||
int rc;
|
||||
const struct colinfo *colinfo;
|
||||
const struct clockinfo *clockinfo;
|
||||
|
||||
struct libscols_table *tb;
|
||||
struct libscols_line *ln;
|
||||
struct libscols_column *col;
|
||||
|
||||
bool noheadings = false, raw = false, json = false;
|
||||
const char *outarg = NULL;
|
||||
int columns[ARRAY_SIZE(infos) * 2];
|
||||
size_t ncolumns = 0;
|
||||
clockid_t clock = -1;
|
||||
|
||||
struct timespec resolution, now;
|
||||
char buf[FORMAT_TIMESTAMP_MAX];
|
||||
|
||||
static const struct option longopts[] = {
|
||||
{ "noheadings", no_argument, NULL, 'n' },
|
||||
{ "output", required_argument, NULL, 'o' },
|
||||
{ "version", no_argument, NULL, 'V' },
|
||||
{ "help", no_argument, NULL, 'h' },
|
||||
{ "json", no_argument, NULL, 'J' },
|
||||
{ "raw", no_argument, NULL, 'r' },
|
||||
{ "time", required_argument, NULL, 't' },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
setlocale(LC_ALL, "");
|
||||
bindtextdomain(PACKAGE, LOCALEDIR);
|
||||
textdomain(PACKAGE);
|
||||
close_stdout_atexit();
|
||||
|
||||
while ((c = getopt_long(argc, argv, "no:Jrt:Vh", longopts, NULL)) != -1) {
|
||||
switch (c) {
|
||||
case 'n':
|
||||
noheadings = true;
|
||||
break;
|
||||
case 'o':
|
||||
outarg = optarg;
|
||||
break;
|
||||
case 'J':
|
||||
json = true;
|
||||
break;
|
||||
case 'r':
|
||||
raw = true;
|
||||
break;
|
||||
case 't':
|
||||
clock = parse_clock(optarg);
|
||||
break;
|
||||
case 'V':
|
||||
print_version(EXIT_SUCCESS);
|
||||
case 'h':
|
||||
usage();
|
||||
default:
|
||||
errtryhelp(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
if (argv[optind])
|
||||
errtryhelp(EXIT_FAILURE);
|
||||
|
||||
if (clock != -1) {
|
||||
rc = clock_gettime(clock, &now);
|
||||
if (rc)
|
||||
err(EXIT_FAILURE, _("failed to get time"));
|
||||
printf("%ju.%09"PRId32"\n", (uintmax_t) now.tv_sec, (uint32_t) now.tv_nsec);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
if (!ncolumns) {
|
||||
columns[ncolumns++] = COL_ID;
|
||||
columns[ncolumns++] = COL_CLOCK;
|
||||
columns[ncolumns++] = COL_NAME;
|
||||
columns[ncolumns++] = COL_TIME;
|
||||
columns[ncolumns++] = COL_ISO_TIME;
|
||||
columns[ncolumns++] = COL_RESOLUTION;
|
||||
}
|
||||
|
||||
if (outarg && string_add_to_idarray(outarg, columns, ARRAY_SIZE(columns),
|
||||
&ncolumns, column_name_to_id) < 0)
|
||||
return EXIT_FAILURE;
|
||||
|
||||
scols_init_debug(0);
|
||||
|
||||
tb = scols_new_table();
|
||||
if (!tb)
|
||||
errx(EXIT_FAILURE, _("failed to allocate output table"));
|
||||
scols_table_set_name(tb, "clocks");
|
||||
|
||||
for (i = 0; i < ncolumns; i++) {
|
||||
colinfo = &infos[columns[i]];
|
||||
|
||||
col = scols_table_new_column(tb, colinfo->name, colinfo->whint, colinfo->flags);
|
||||
if (!col)
|
||||
errx(EXIT_FAILURE, _("failed to allocate output column"));
|
||||
|
||||
scols_column_set_json_type(col, colinfo->json_type);
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(clocks); i++) {
|
||||
clockinfo = &clocks[i];
|
||||
|
||||
ln = scols_table_new_line(tb, NULL);
|
||||
if (!ln)
|
||||
errx(EXIT_FAILURE, _("failed to allocate output line"));
|
||||
|
||||
/* outside the loop to guarantee consistency between COL_TIME and COL_ISO_TIME */
|
||||
rc = clock_gettime(clockinfo->id, &now);
|
||||
if (rc)
|
||||
now.tv_nsec = -1;
|
||||
|
||||
for (j = 0; j < ncolumns; j++) {
|
||||
switch (columns[j]) {
|
||||
case COL_ID:
|
||||
scols_line_asprintf(ln, j, "%ju", (uintmax_t) clockinfo->id);
|
||||
break;
|
||||
case COL_CLOCK:
|
||||
scols_line_set_data(ln, j, clockinfo->id_name);
|
||||
break;
|
||||
case COL_NAME:
|
||||
scols_line_set_data(ln, j, clockinfo->name);
|
||||
break;
|
||||
case COL_TIME:
|
||||
if (now.tv_nsec == -1)
|
||||
break;
|
||||
|
||||
scols_line_format_timespec(ln, j, &now);
|
||||
break;
|
||||
case COL_ISO_TIME:
|
||||
if (now.tv_nsec == -1)
|
||||
break;
|
||||
|
||||
rc = strtimespec_iso(&now,
|
||||
ISO_GMTIME | ISO_DATE | ISO_TIME | ISO_T | ISO_DOTNSEC | ISO_TIMEZONE,
|
||||
buf, sizeof(buf));
|
||||
if (rc)
|
||||
errx(EXIT_FAILURE, _("failed to format iso time"));
|
||||
scols_line_set_data(ln, j, buf);
|
||||
break;
|
||||
case COL_RESOLUTION:
|
||||
rc = clock_getres(clockinfo->id, &resolution);
|
||||
if (!rc)
|
||||
scols_line_format_timespec(ln, j, &resolution);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
scols_table_enable_json(tb, json);
|
||||
scols_table_enable_raw(tb, raw);
|
||||
scols_table_enable_noheadings(tb, noheadings);
|
||||
scols_print_table(tb);
|
||||
scols_unref_table(tb);
|
||||
}
|
|
@ -33,70 +33,74 @@ struct miscdev {
|
|||
char *name;
|
||||
};
|
||||
|
||||
struct cdev {
|
||||
struct file file;
|
||||
const char *devdrv;
|
||||
const struct cdev_ops *cdev_ops;
|
||||
void *cdev_data;
|
||||
};
|
||||
|
||||
struct cdev_ops {
|
||||
const struct cdev_ops *parent;
|
||||
bool (*probe)(const struct cdev *);
|
||||
char * (*get_name)(struct cdev *);
|
||||
bool (*fill_column)(struct proc *,
|
||||
struct cdev *,
|
||||
struct libscols_line *,
|
||||
int,
|
||||
size_t,
|
||||
char **);
|
||||
void (*init)(const struct cdev *);
|
||||
void (*free)(const struct cdev *);
|
||||
int (*handle_fdinfo)(struct cdev *, const char *, const char *);
|
||||
};
|
||||
|
||||
static bool cdev_fill_column(struct proc *proc __attribute__((__unused__)),
|
||||
struct file *file __attribute__((__unused__)),
|
||||
struct file *file,
|
||||
struct libscols_line *ln,
|
||||
int column_id,
|
||||
size_t column_index)
|
||||
{
|
||||
struct cdev *cdev = (struct cdev *)file;
|
||||
const struct cdev_ops *ops = cdev->cdev_ops;
|
||||
char *str = NULL;
|
||||
const char *devdrv;
|
||||
const char *miscdev;
|
||||
|
||||
switch(column_id) {
|
||||
case COL_NAME:
|
||||
if (cdev->cdev_ops->get_name) {
|
||||
str = cdev->cdev_ops->get_name(cdev);
|
||||
if (str)
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
case COL_TYPE:
|
||||
if (scols_line_set_data(ln, column_index, "CHR"))
|
||||
err(EXIT_FAILURE, _("failed to add output data"));
|
||||
return true;
|
||||
case COL_MISCDEV:
|
||||
devdrv = get_chrdrv(major(file->stat.st_rdev));
|
||||
if (devdrv && strcmp(devdrv, "misc") == 0) {
|
||||
miscdev = get_miscdev(minor(file->stat.st_rdev));
|
||||
if (miscdev)
|
||||
str = xstrdup(miscdev);
|
||||
else
|
||||
xasprintf(&str, "%u",
|
||||
minor(file->stat.st_rdev));
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
case COL_DEVTYPE:
|
||||
if (scols_line_set_data(ln, column_index,
|
||||
"char"))
|
||||
err(EXIT_FAILURE, _("failed to add output data"));
|
||||
return true;
|
||||
case COL_CHRDRV:
|
||||
devdrv = get_chrdrv(major(file->stat.st_rdev));
|
||||
if (devdrv)
|
||||
str = xstrdup(devdrv);
|
||||
if (cdev->devdrv)
|
||||
str = xstrdup(cdev->devdrv);
|
||||
else
|
||||
xasprintf(&str, "%u",
|
||||
major(file->stat.st_rdev));
|
||||
break;
|
||||
case COL_SOURCE:
|
||||
devdrv = get_chrdrv(major(file->stat.st_rdev));
|
||||
miscdev = NULL;
|
||||
if (devdrv && strcmp(devdrv, "misc") == 0)
|
||||
miscdev = get_miscdev(minor(file->stat.st_rdev));
|
||||
if (devdrv) {
|
||||
if (miscdev) {
|
||||
xasprintf(&str, "misc:%s", miscdev);
|
||||
} else {
|
||||
xasprintf(&str, "%s:%u", devdrv,
|
||||
minor(file->stat.st_rdev));
|
||||
}
|
||||
break;
|
||||
}
|
||||
/* FALL THROUGH */
|
||||
case COL_MAJMIN:
|
||||
xasprintf(&str, "%u:%u",
|
||||
major(file->stat.st_rdev),
|
||||
minor(file->stat.st_rdev));
|
||||
break;
|
||||
default:
|
||||
while (ops) {
|
||||
if (ops->fill_column
|
||||
&& ops->fill_column(proc, cdev, ln,
|
||||
column_id, column_index, &str))
|
||||
goto out;
|
||||
ops = ops->parent;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
out:
|
||||
if (!str)
|
||||
err(EXIT_FAILURE, _("failed to add output data"));
|
||||
if (scols_line_refer_data(ln, column_index, str))
|
||||
|
@ -168,11 +172,220 @@ const char *get_miscdev(unsigned long minor)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* generic (fallback implementation)
|
||||
*/
|
||||
static bool cdev_generic_probe(const struct cdev *cdev __attribute__((__unused__))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool cdev_generic_fill_column(struct proc *proc __attribute__((__unused__)),
|
||||
struct cdev *cdev,
|
||||
struct libscols_line *ln __attribute__((__unused__)),
|
||||
int column_id,
|
||||
size_t column_index __attribute__((__unused__)),
|
||||
char **str)
|
||||
{
|
||||
struct file *file = &cdev->file;
|
||||
|
||||
switch(column_id) {
|
||||
case COL_SOURCE:
|
||||
if (cdev->devdrv) {
|
||||
xasprintf(str, "%s:%u", cdev->devdrv,
|
||||
minor(file->stat.st_rdev));
|
||||
return true;
|
||||
}
|
||||
/* FALL THROUGH */
|
||||
case COL_MAJMIN:
|
||||
xasprintf(str, "%u:%u",
|
||||
major(file->stat.st_rdev),
|
||||
minor(file->stat.st_rdev));
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static struct cdev_ops cdev_generic_ops = {
|
||||
.probe = cdev_generic_probe,
|
||||
.fill_column = cdev_generic_fill_column,
|
||||
};
|
||||
|
||||
/*
|
||||
* misc device driver
|
||||
*/
|
||||
static bool cdev_misc_probe(const struct cdev *cdev) {
|
||||
return cdev->devdrv && strcmp(cdev->devdrv, "misc") == 0;
|
||||
}
|
||||
|
||||
static bool cdev_misc_fill_column(struct proc *proc __attribute__((__unused__)),
|
||||
struct cdev *cdev,
|
||||
struct libscols_line *ln __attribute__((__unused__)),
|
||||
int column_id,
|
||||
size_t column_index __attribute__((__unused__)),
|
||||
char **str)
|
||||
{
|
||||
struct file *file = &cdev->file;
|
||||
const char *miscdev;
|
||||
|
||||
switch(column_id) {
|
||||
case COL_MISCDEV:
|
||||
miscdev = get_miscdev(minor(file->stat.st_rdev));
|
||||
if (miscdev)
|
||||
*str = xstrdup(miscdev);
|
||||
else
|
||||
xasprintf(str, "%u",
|
||||
minor(file->stat.st_rdev));
|
||||
return true;
|
||||
case COL_SOURCE:
|
||||
miscdev = get_miscdev(minor(file->stat.st_rdev));
|
||||
if (miscdev)
|
||||
xasprintf(str, "misc:%s", miscdev);
|
||||
else
|
||||
xasprintf(str, "misc:%u",
|
||||
minor(file->stat.st_rdev));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static struct cdev_ops cdev_misc_ops = {
|
||||
.parent = &cdev_generic_ops,
|
||||
.probe = cdev_misc_probe,
|
||||
.fill_column = cdev_misc_fill_column,
|
||||
};
|
||||
|
||||
/*
|
||||
* tun devcie driver
|
||||
*/
|
||||
static bool cdev_tun_probe(const struct cdev *cdev)
|
||||
{
|
||||
const char *miscdev;
|
||||
|
||||
if ((!cdev->devdrv) || strcmp(cdev->devdrv, "misc"))
|
||||
return false;
|
||||
|
||||
miscdev = get_miscdev(minor(cdev->file.stat.st_rdev));
|
||||
if (miscdev && strcmp(miscdev, "tun") == 0)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static void cdev_tun_free(const struct cdev *cdev)
|
||||
{
|
||||
if (cdev->cdev_data)
|
||||
free(cdev->cdev_data);
|
||||
}
|
||||
|
||||
static char * cdev_tun_get_name(struct cdev *cdev)
|
||||
{
|
||||
char *str = NULL;
|
||||
|
||||
if (cdev->cdev_data == NULL)
|
||||
return NULL;
|
||||
|
||||
xasprintf(&str, "iface=%s", (const char *)cdev->cdev_data);
|
||||
return str;
|
||||
}
|
||||
|
||||
static bool cdev_tun_fill_column(struct proc *proc __attribute__((__unused__)),
|
||||
struct cdev *cdev,
|
||||
struct libscols_line *ln __attribute__((__unused__)),
|
||||
int column_id,
|
||||
size_t column_index __attribute__((__unused__)),
|
||||
char **str)
|
||||
{
|
||||
switch(column_id) {
|
||||
case COL_MISCDEV:
|
||||
*str = xstrdup("tun");
|
||||
return true;
|
||||
case COL_SOURCE:
|
||||
*str = xstrdup("misc:tun");
|
||||
return true;
|
||||
case COL_TUN_IFACE:
|
||||
if (cdev->cdev_data) {
|
||||
*str = xstrdup(cdev->cdev_data);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static int cdev_tun_handle_fdinfo(struct cdev *cdev, const char *key, const char *val)
|
||||
{
|
||||
if (strcmp(key, "iff") == 0 && cdev->cdev_data == NULL) {
|
||||
cdev->cdev_data = xstrdup(val);
|
||||
return 1;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static struct cdev_ops cdev_tun_ops = {
|
||||
.parent = &cdev_misc_ops,
|
||||
.probe = cdev_tun_probe,
|
||||
.free = cdev_tun_free,
|
||||
.get_name = cdev_tun_get_name,
|
||||
.fill_column = cdev_tun_fill_column,
|
||||
.handle_fdinfo = cdev_tun_handle_fdinfo,
|
||||
};
|
||||
|
||||
static const struct cdev_ops *cdev_ops[] = {
|
||||
&cdev_tun_ops,
|
||||
&cdev_misc_ops,
|
||||
&cdev_generic_ops /* This must be at the end. */
|
||||
};
|
||||
|
||||
static const struct cdev_ops *cdev_probe(const struct cdev *cdev)
|
||||
{
|
||||
const struct cdev_ops *r = NULL;
|
||||
|
||||
for (size_t i = 0; i < ARRAY_SIZE(cdev_ops); i++) {
|
||||
if (cdev_ops[i]->probe(cdev)) {
|
||||
r = cdev_ops[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
assert(r);
|
||||
return r;
|
||||
}
|
||||
|
||||
static void init_cdev_content(struct file *file)
|
||||
{
|
||||
struct cdev *cdev = (struct cdev *)file;
|
||||
|
||||
cdev->devdrv = get_chrdrv(major(file->stat.st_rdev));
|
||||
|
||||
cdev->cdev_data = NULL;
|
||||
cdev->cdev_ops = cdev_probe(cdev);
|
||||
if (cdev->cdev_ops->init)
|
||||
cdev->cdev_ops->init(cdev);
|
||||
}
|
||||
|
||||
static void free_cdev_content(struct file *file)
|
||||
{
|
||||
struct cdev *cdev = (struct cdev *)file;
|
||||
|
||||
if (cdev->cdev_ops->free)
|
||||
cdev->cdev_ops->free(cdev);
|
||||
}
|
||||
|
||||
static int cdev_handle_fdinfo(struct file *file, const char *key, const char *value)
|
||||
{
|
||||
struct cdev *cdev = (struct cdev *)file;
|
||||
|
||||
if (cdev->cdev_ops->handle_fdinfo)
|
||||
return cdev->cdev_ops->handle_fdinfo(cdev, key, value);
|
||||
return 0; /* Should be handled in parents */
|
||||
}
|
||||
|
||||
const struct file_class cdev_class = {
|
||||
.super = &file_class,
|
||||
.size = sizeof(struct file),
|
||||
.size = sizeof(struct cdev),
|
||||
.initialize_class = cdev_class_initialize,
|
||||
.finalize_class = cdev_class_finalize,
|
||||
.fill_column = cdev_fill_column,
|
||||
.free_content = NULL,
|
||||
.initialize_content = init_cdev_content,
|
||||
.free_content = free_cdev_content,
|
||||
.handle_fdinfo = cdev_handle_fdinfo,
|
||||
};
|
||||
|
|
|
@ -68,8 +68,8 @@ static bool fifo_fill_column(struct proc *proc __attribute__((__unused__)),
|
|||
case COL_ENDPOINTS: {
|
||||
struct fifo *this = (struct fifo *)file;
|
||||
struct list_head *e;
|
||||
char *estr;
|
||||
list_for_each_backwardly(e, &this->endpoint.ipc->endpoints) {
|
||||
foreach_endpoint(e, this->endpoint) {
|
||||
char *estr;
|
||||
struct fifo *other = list_entry(e, struct fifo, endpoint.endpoints);
|
||||
if (this == other)
|
||||
continue;
|
||||
|
@ -107,6 +107,7 @@ static bool fifo_is_suitable_ipc(struct ipc *ipc, struct file *file)
|
|||
static const struct ipc_class *fifo_get_ipc_class(struct file *file __attribute__((__unused__)))
|
||||
{
|
||||
static const struct ipc_class fifo_ipc_class = {
|
||||
.size = sizeof(struct fifo_ipc),
|
||||
.get_hash = fifo_get_hash,
|
||||
.is_suitable_ipc = fifo_is_suitable_ipc,
|
||||
.free = NULL,
|
||||
|
@ -120,22 +121,18 @@ static void fifo_initialize_content(struct file *file)
|
|||
struct ipc *ipc;
|
||||
unsigned int hash;
|
||||
|
||||
INIT_LIST_HEAD(&fifo->endpoint.endpoints);
|
||||
init_endpoint(&fifo->endpoint);
|
||||
ipc = get_ipc(file);
|
||||
if (ipc)
|
||||
goto link;
|
||||
|
||||
ipc = xmalloc(sizeof(struct fifo_ipc));
|
||||
ipc->class = fifo_get_ipc_class(file);
|
||||
INIT_LIST_HEAD(&ipc->endpoints);
|
||||
INIT_LIST_HEAD(&ipc->ipcs);
|
||||
ipc = new_ipc(fifo_get_ipc_class(file));
|
||||
((struct fifo_ipc *)ipc)->ino = file->stat.st_ino;
|
||||
|
||||
hash = fifo_get_hash(file);
|
||||
add_ipc(ipc, hash);
|
||||
link:
|
||||
fifo->endpoint.ipc = ipc;
|
||||
list_add(&fifo->endpoint.endpoints, &ipc->endpoints);
|
||||
add_endpoint(&fifo->endpoint, ipc);
|
||||
}
|
||||
|
||||
const struct file_class fifo_class = {
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
# endif
|
||||
#endif
|
||||
#include <linux/sched.h>
|
||||
#include <sys/shm.h>
|
||||
|
||||
#include "xalloc.h"
|
||||
#include "nls.h"
|
||||
|
@ -39,12 +40,15 @@
|
|||
#include "idcache.h"
|
||||
#include "strutils.h"
|
||||
|
||||
#include "procfs.h"
|
||||
#include "libsmartcols.h"
|
||||
|
||||
#include "lsfd.h"
|
||||
|
||||
static struct idcache *username_cache;
|
||||
|
||||
static size_t pagesize;
|
||||
|
||||
static const char *assocstr[N_ASSOCS] = {
|
||||
[ASSOC_CWD] = "cwd",
|
||||
[ASSOC_EXE] = "exe",
|
||||
|
@ -102,18 +106,60 @@ static uint64_t get_map_length(struct file *file)
|
|||
{
|
||||
uint64_t res = 0;
|
||||
|
||||
if (is_association(file, SHM) || is_association(file, MEM)) {
|
||||
static size_t pagesize = 0;
|
||||
|
||||
if (!pagesize)
|
||||
pagesize = getpagesize();
|
||||
|
||||
if (is_association(file, SHM) || is_association(file, MEM))
|
||||
res = (file->map_end - file->map_start) / pagesize;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void decode_source(char *buf, size_t bufsize,
|
||||
unsigned int dev_major, unsigned int dev_minor,
|
||||
enum decode_source_level level)
|
||||
{
|
||||
if (bufsize == 0)
|
||||
return;
|
||||
|
||||
buf[0] = '\0';
|
||||
|
||||
if (level & DECODE_SOURCE_FILESYS_BIT) {
|
||||
if (dev_major == 0) {
|
||||
const char *filesystem = get_nodev_filesystem(dev_minor);
|
||||
if (filesystem) {
|
||||
xstrncpy(buf, filesystem, bufsize);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (level & DECODE_SOURCE_PARTITION_BIT) {
|
||||
dev_t dev = makedev(dev_major, dev_minor);
|
||||
const char *partition = get_partition(dev);
|
||||
if (partition) {
|
||||
xstrncpy(buf, partition, bufsize);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (level & DECODE_SOURCE_MAJMIN_BIT)
|
||||
snprintf(buf, bufsize, "%u:%u",
|
||||
dev_major,
|
||||
dev_minor);
|
||||
}
|
||||
|
||||
static char *strnrstr(const char *haystack, const char *needle, size_t needle_len)
|
||||
{
|
||||
char *last = strstr(haystack, needle);
|
||||
if (last == NULL)
|
||||
return NULL;
|
||||
|
||||
do {
|
||||
char *current = strstr(last + needle_len, needle);
|
||||
if (current == NULL)
|
||||
return last;
|
||||
last = current;
|
||||
} while (1);
|
||||
}
|
||||
|
||||
static bool file_fill_column(struct proc *proc,
|
||||
struct file *file,
|
||||
struct libscols_line *ln,
|
||||
|
@ -122,7 +168,7 @@ static bool file_fill_column(struct proc *proc,
|
|||
{
|
||||
char *str = NULL;
|
||||
mode_t ftype;
|
||||
const char *partition;
|
||||
char buf[BUFSIZ];
|
||||
|
||||
switch(column_id) {
|
||||
case COL_COMMAND:
|
||||
|
@ -130,8 +176,22 @@ static bool file_fill_column(struct proc *proc,
|
|||
&& scols_line_set_data(ln, column_index, proc->command))
|
||||
err(EXIT_FAILURE, _("failed to add output data"));
|
||||
return true;
|
||||
case COL_KNAME:
|
||||
case COL_NAME:
|
||||
if (file->name && file->stat.st_nlink == 0) {
|
||||
char *d = strnrstr(file->name, "(deleted)",
|
||||
sizeof("(deleted)") - 1);
|
||||
if (d) {
|
||||
int r;
|
||||
*d = '\0';
|
||||
r = scols_line_set_data(ln, column_index, file->name);
|
||||
*d = '(';
|
||||
if (r)
|
||||
err(EXIT_FAILURE, _("failed to add output data"));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
/* FALL THROUGH */
|
||||
case COL_KNAME:
|
||||
if (file->name
|
||||
&& scols_line_set_data(ln, column_index, file->name))
|
||||
err(EXIT_FAILURE, _("failed to add output data"));
|
||||
|
@ -172,33 +232,27 @@ static bool file_fill_column(struct proc *proc,
|
|||
int assoc = file->association * -1;
|
||||
if (assoc >= N_ASSOCS)
|
||||
return false; /* INTERNAL ERROR */
|
||||
xasprintf(&str, "%s", assocstr[assoc]);
|
||||
str = xstrdup(assocstr[assoc]);
|
||||
}
|
||||
break;
|
||||
case COL_INODE:
|
||||
xasprintf(&str, "%llu", (unsigned long long)file->stat.st_ino);
|
||||
break;
|
||||
case COL_SOURCE:
|
||||
if (major(file->stat.st_dev) == 0) {
|
||||
const char *filesystem = get_nodev_filesystem(minor(file->stat.st_dev));
|
||||
if (filesystem) {
|
||||
xasprintf(&str, "%s", filesystem);
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* FALL THROUGH */
|
||||
decode_source(buf, sizeof(buf), major(file->stat.st_dev), minor(file->stat.st_dev),
|
||||
DECODE_SOURCE_FILESYS);
|
||||
str = xstrdup(buf);
|
||||
break;
|
||||
case COL_PARTITION:
|
||||
partition = get_partition(file->stat.st_dev);
|
||||
if (partition) {
|
||||
str = xstrdup(partition);
|
||||
break;
|
||||
}
|
||||
/* FALL THROUGH */
|
||||
decode_source(buf, sizeof(buf), major(file->stat.st_dev), minor(file->stat.st_dev),
|
||||
DECODE_SOURCE_PARTITION);
|
||||
str = xstrdup(buf);
|
||||
break;
|
||||
case COL_DEV:
|
||||
case COL_MAJMIN:
|
||||
xasprintf(&str, "%u:%u",
|
||||
major(file->stat.st_dev),
|
||||
minor(file->stat.st_dev));
|
||||
decode_source(buf, sizeof(buf), major(file->stat.st_dev), minor(file->stat.st_dev),
|
||||
DECODE_SOURCE_MAJMIN);
|
||||
str = xstrdup(buf);
|
||||
break;
|
||||
case COL_RDEV:
|
||||
xasprintf(&str, "%u:%u",
|
||||
|
@ -242,6 +296,19 @@ static bool file_fill_column(struct proc *proc,
|
|||
else
|
||||
xasprintf(&str, "---");
|
||||
break;
|
||||
case COL_XMODE: {
|
||||
char r, w, x;
|
||||
char D = file->stat.st_nlink == 0? 'D': '-';
|
||||
if (does_file_has_fdinfo_alike(file)) {
|
||||
r = file->mode & S_IRUSR? 'r': '-';
|
||||
w = file->mode & S_IWUSR? 'w': '-';
|
||||
x = (is_mapped_file(file)
|
||||
&& file->mode & S_IXUSR)? 'x': '-';
|
||||
} else
|
||||
r = w = x = '-';
|
||||
xasprintf(&str, "%c%c%c%c", r, w, x, D);
|
||||
break;
|
||||
}
|
||||
case COL_POS:
|
||||
xasprintf(&str, "%" PRIu64,
|
||||
(does_file_has_fdinfo_alike(file))? file->pos: 0);
|
||||
|
@ -268,7 +335,7 @@ static bool file_fill_column(struct proc *proc,
|
|||
break;
|
||||
default:
|
||||
return false;
|
||||
};
|
||||
}
|
||||
|
||||
if (!str)
|
||||
err(EXIT_FAILURE, _("failed to add output data"));
|
||||
|
@ -304,11 +371,63 @@ static void file_free_content(struct file *file)
|
|||
free(file->name);
|
||||
}
|
||||
|
||||
static unsigned long get_minor_for_sysvipc(void)
|
||||
{
|
||||
int id;
|
||||
void *start;
|
||||
|
||||
pid_t self = getpid();
|
||||
struct path_cxt *pc = NULL;
|
||||
char map_file[sizeof("map_files/0000000000000000-ffffffffffffffff")];
|
||||
|
||||
struct stat sb;
|
||||
unsigned long m = 0;
|
||||
|
||||
id = shmget(IPC_PRIVATE, pagesize, IPC_CREAT | 0600);
|
||||
if (id == -1)
|
||||
return 0;
|
||||
|
||||
start = shmat(id, NULL, SHM_RDONLY);
|
||||
if (start == (void *) -1) {
|
||||
shmctl(id, IPC_RMID, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
pc = ul_new_path(NULL);
|
||||
if (!pc)
|
||||
goto out;
|
||||
|
||||
if (procfs_process_init_path(pc, self) != 0)
|
||||
goto out;
|
||||
|
||||
snprintf(map_file, sizeof(map_file),
|
||||
"map_files/%lx-%lx", (long)start, (long)start + pagesize);
|
||||
if (ul_path_stat(pc, &sb, 0, map_file) < 0)
|
||||
goto out;
|
||||
|
||||
m = minor(sb.st_dev);
|
||||
out:
|
||||
if (pc)
|
||||
ul_unref_path(pc);
|
||||
shmdt(start);
|
||||
shmctl(id, IPC_RMID, NULL);
|
||||
return m;
|
||||
}
|
||||
|
||||
static void file_class_initialize(void)
|
||||
{
|
||||
unsigned long m;
|
||||
|
||||
if (!pagesize)
|
||||
pagesize = getpagesize();
|
||||
|
||||
username_cache = new_idcache();
|
||||
if (!username_cache)
|
||||
err(EXIT_FAILURE, _("failed to allocate UID cache"));
|
||||
|
||||
m = get_minor_for_sysvipc();
|
||||
if (m)
|
||||
add_nodev(m, "tmpfs");
|
||||
}
|
||||
|
||||
static void file_class_finalize(void)
|
||||
|
@ -463,3 +582,122 @@ const struct file_class nsfs_file_class = {
|
|||
.fill_column = nsfs_file_fill_column,
|
||||
.handle_fdinfo = NULL,
|
||||
};
|
||||
|
||||
/*
|
||||
* POSIX Mqueue
|
||||
*/
|
||||
struct mqueue_file {
|
||||
struct file file;
|
||||
struct ipc_endpoint endpoint;
|
||||
};
|
||||
|
||||
struct mqueue_file_ipc {
|
||||
struct ipc ipc;
|
||||
ino_t ino;
|
||||
};
|
||||
|
||||
bool is_mqueue_dev(dev_t dev)
|
||||
{
|
||||
const char *fs = get_nodev_filesystem(minor(dev));
|
||||
|
||||
if (fs && (strcmp (fs, "mqueue") == 0))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline char *mqueue_file_xstrendpoint(struct file *file)
|
||||
{
|
||||
char *str = NULL;
|
||||
xasprintf(&str, "%d,%s,%d%c%c",
|
||||
file->proc->pid, file->proc->command, file->association,
|
||||
(file->mode & S_IRUSR)? 'r': '-',
|
||||
(file->mode & S_IWUSR)? 'w': '-');
|
||||
return str;
|
||||
}
|
||||
|
||||
static bool mqueue_file_fill_column(struct proc *proc __attribute__((__unused__)),
|
||||
struct file *file __attribute__((__unused__)),
|
||||
struct libscols_line *ln,
|
||||
int column_id,
|
||||
size_t column_index)
|
||||
{
|
||||
switch (column_id) {
|
||||
case COL_TYPE:
|
||||
if (scols_line_set_data(ln, column_index, "mqueue"))
|
||||
err(EXIT_FAILURE, _("failed to add output data"));
|
||||
return true;
|
||||
case COL_ENDPOINTS: {
|
||||
char *str = NULL;
|
||||
struct mqueue_file *this = (struct mqueue_file *)file;
|
||||
struct list_head *e;
|
||||
foreach_endpoint(e, this->endpoint) {
|
||||
char *estr;
|
||||
struct mqueue_file *other = list_entry(e, struct mqueue_file,
|
||||
endpoint.endpoints);
|
||||
if (this == other)
|
||||
continue;
|
||||
if (str)
|
||||
xstrputc(&str, '\n');
|
||||
estr = mqueue_file_xstrendpoint(&other->file);
|
||||
xstrappend(&str, estr);
|
||||
free(estr);
|
||||
}
|
||||
if (!str)
|
||||
return false;
|
||||
if (scols_line_refer_data(ln, column_index, str))
|
||||
err(EXIT_FAILURE, _("failed to add output data"));
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned int mqueue_file_get_hash(struct file *file)
|
||||
{
|
||||
return (unsigned int)(file->stat.st_ino % UINT_MAX);
|
||||
}
|
||||
|
||||
static bool mqueue_file_is_suitable_ipc(struct ipc *ipc, struct file *file)
|
||||
{
|
||||
return ((struct mqueue_file_ipc *)ipc)->ino == file->stat.st_ino;
|
||||
}
|
||||
|
||||
static const struct ipc_class *mqueue_file_get_ipc_class(struct file *file __attribute__((__unused__)))
|
||||
{
|
||||
static const struct ipc_class mqueue_file_ipc_class = {
|
||||
.size = sizeof(struct mqueue_file_ipc),
|
||||
.get_hash = mqueue_file_get_hash,
|
||||
.is_suitable_ipc = mqueue_file_is_suitable_ipc,
|
||||
};
|
||||
return &mqueue_file_ipc_class;
|
||||
}
|
||||
|
||||
static void init_mqueue_file_content(struct file *file)
|
||||
{
|
||||
struct mqueue_file *mqueue_file = (struct mqueue_file *)file;
|
||||
struct ipc *ipc;
|
||||
unsigned int hash;
|
||||
|
||||
init_endpoint(&mqueue_file->endpoint);
|
||||
ipc = get_ipc(file);
|
||||
if (ipc)
|
||||
goto link;
|
||||
|
||||
ipc = new_ipc(mqueue_file_get_ipc_class(file));
|
||||
((struct mqueue_file_ipc *)ipc)->ino = file->stat.st_ino;
|
||||
|
||||
hash = mqueue_file_get_hash(file);
|
||||
add_ipc(ipc, hash);
|
||||
link:
|
||||
add_endpoint(&mqueue_file->endpoint, ipc);
|
||||
}
|
||||
|
||||
const struct file_class mqueue_file_class = {
|
||||
.super = &file_class,
|
||||
.size = sizeof(struct mqueue_file),
|
||||
.initialize_content = init_mqueue_file_content,
|
||||
.fill_column = mqueue_file_fill_column,
|
||||
.get_ipc_class = mqueue_file_get_ipc_class,
|
||||
};
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue