162306a36Sopenharmony_ci// SPDX-License-Identifier: LGPL-2.1 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * trace/beauty/fcntl.c 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright (C) 2017, Red Hat Inc, Arnaldo Carvalho de Melo <acme@redhat.com> 662306a36Sopenharmony_ci */ 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci#include "trace/beauty/beauty.h" 962306a36Sopenharmony_ci#include <linux/kernel.h> 1062306a36Sopenharmony_ci#include <uapi/linux/fcntl.h> 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_cistatic size_t fcntl__scnprintf_getfd(unsigned long val, char *bf, size_t size, bool show_prefix) 1362306a36Sopenharmony_ci{ 1462306a36Sopenharmony_ci return val ? scnprintf(bf, size, "%s", "0") : 1562306a36Sopenharmony_ci scnprintf(bf, size, "%s%s", show_prefix ? "FD_" : "", "CLOEXEC"); 1662306a36Sopenharmony_ci} 1762306a36Sopenharmony_ci 1862306a36Sopenharmony_cistatic size_t syscall_arg__scnprintf_fcntl_getfd(char *bf, size_t size, struct syscall_arg *arg) 1962306a36Sopenharmony_ci{ 2062306a36Sopenharmony_ci return fcntl__scnprintf_getfd(arg->val, bf, size, arg->show_string_prefix); 2162306a36Sopenharmony_ci} 2262306a36Sopenharmony_ci 2362306a36Sopenharmony_cistatic size_t fcntl__scnprintf_getlease(unsigned long val, char *bf, size_t size, bool show_prefix) 2462306a36Sopenharmony_ci{ 2562306a36Sopenharmony_ci static const char *fcntl_setlease[] = { "RDLCK", "WRLCK", "UNLCK", }; 2662306a36Sopenharmony_ci static DEFINE_STRARRAY(fcntl_setlease, "F_"); 2762306a36Sopenharmony_ci 2862306a36Sopenharmony_ci return strarray__scnprintf(&strarray__fcntl_setlease, bf, size, "%x", show_prefix, val); 2962306a36Sopenharmony_ci} 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_cistatic size_t syscall_arg__scnprintf_fcntl_getlease(char *bf, size_t size, struct syscall_arg *arg) 3262306a36Sopenharmony_ci{ 3362306a36Sopenharmony_ci return fcntl__scnprintf_getlease(arg->val, bf, size, arg->show_string_prefix); 3462306a36Sopenharmony_ci} 3562306a36Sopenharmony_ci 3662306a36Sopenharmony_cisize_t syscall_arg__scnprintf_fcntl_cmd(char *bf, size_t size, struct syscall_arg *arg) 3762306a36Sopenharmony_ci{ 3862306a36Sopenharmony_ci if (arg->val == F_GETFL) { 3962306a36Sopenharmony_ci syscall_arg__set_ret_scnprintf(arg, syscall_arg__scnprintf_open_flags); 4062306a36Sopenharmony_ci goto mask_arg; 4162306a36Sopenharmony_ci } 4262306a36Sopenharmony_ci if (arg->val == F_GETFD) { 4362306a36Sopenharmony_ci syscall_arg__set_ret_scnprintf(arg, syscall_arg__scnprintf_fcntl_getfd); 4462306a36Sopenharmony_ci goto mask_arg; 4562306a36Sopenharmony_ci } 4662306a36Sopenharmony_ci if (arg->val == F_DUPFD_CLOEXEC || arg->val == F_DUPFD) { 4762306a36Sopenharmony_ci syscall_arg__set_ret_scnprintf(arg, syscall_arg__scnprintf_fd); 4862306a36Sopenharmony_ci goto out; 4962306a36Sopenharmony_ci } 5062306a36Sopenharmony_ci if (arg->val == F_GETOWN) { 5162306a36Sopenharmony_ci syscall_arg__set_ret_scnprintf(arg, syscall_arg__scnprintf_pid); 5262306a36Sopenharmony_ci goto mask_arg; 5362306a36Sopenharmony_ci } 5462306a36Sopenharmony_ci if (arg->val == F_GETLEASE) { 5562306a36Sopenharmony_ci syscall_arg__set_ret_scnprintf(arg, syscall_arg__scnprintf_fcntl_getlease); 5662306a36Sopenharmony_ci goto mask_arg; 5762306a36Sopenharmony_ci } 5862306a36Sopenharmony_ci /* 5962306a36Sopenharmony_ci * Some commands ignore the third fcntl argument, "arg", so mask it 6062306a36Sopenharmony_ci */ 6162306a36Sopenharmony_ci if (arg->val == F_GET_SEALS || 6262306a36Sopenharmony_ci arg->val == F_GETSIG) { 6362306a36Sopenharmony_cimask_arg: 6462306a36Sopenharmony_ci arg->mask |= (1 << 2); 6562306a36Sopenharmony_ci } 6662306a36Sopenharmony_ciout: 6762306a36Sopenharmony_ci return syscall_arg__scnprintf_strarrays(bf, size, arg); 6862306a36Sopenharmony_ci} 6962306a36Sopenharmony_ci 7062306a36Sopenharmony_cisize_t syscall_arg__scnprintf_fcntl_arg(char *bf, size_t size, struct syscall_arg *arg) 7162306a36Sopenharmony_ci{ 7262306a36Sopenharmony_ci bool show_prefix = arg->show_string_prefix; 7362306a36Sopenharmony_ci int cmd = syscall_arg__val(arg, 1); 7462306a36Sopenharmony_ci 7562306a36Sopenharmony_ci if (cmd == F_DUPFD) 7662306a36Sopenharmony_ci return syscall_arg__scnprintf_fd(bf, size, arg); 7762306a36Sopenharmony_ci 7862306a36Sopenharmony_ci if (cmd == F_SETFD) 7962306a36Sopenharmony_ci return fcntl__scnprintf_getfd(arg->val, bf, size, show_prefix); 8062306a36Sopenharmony_ci 8162306a36Sopenharmony_ci if (cmd == F_SETFL) 8262306a36Sopenharmony_ci return open__scnprintf_flags(arg->val, bf, size, show_prefix); 8362306a36Sopenharmony_ci 8462306a36Sopenharmony_ci if (cmd == F_SETOWN) 8562306a36Sopenharmony_ci return syscall_arg__scnprintf_pid(bf, size, arg); 8662306a36Sopenharmony_ci 8762306a36Sopenharmony_ci if (cmd == F_SETLEASE) 8862306a36Sopenharmony_ci return fcntl__scnprintf_getlease(arg->val, bf, size, show_prefix); 8962306a36Sopenharmony_ci /* 9062306a36Sopenharmony_ci * We still don't grab the contents of pointers on entry or exit, 9162306a36Sopenharmony_ci * so just print them as hex numbers 9262306a36Sopenharmony_ci */ 9362306a36Sopenharmony_ci if (cmd == F_SETLK || cmd == F_SETLKW || cmd == F_GETLK || 9462306a36Sopenharmony_ci cmd == F_OFD_SETLK || cmd == F_OFD_SETLKW || cmd == F_OFD_GETLK || 9562306a36Sopenharmony_ci cmd == F_GETOWN_EX || cmd == F_SETOWN_EX || 9662306a36Sopenharmony_ci cmd == F_GET_RW_HINT || cmd == F_SET_RW_HINT || 9762306a36Sopenharmony_ci cmd == F_GET_FILE_RW_HINT || cmd == F_SET_FILE_RW_HINT) 9862306a36Sopenharmony_ci return syscall_arg__scnprintf_hex(bf, size, arg); 9962306a36Sopenharmony_ci 10062306a36Sopenharmony_ci return syscall_arg__scnprintf_long(bf, size, arg); 10162306a36Sopenharmony_ci} 102