(root)/
strace-6.5/
src/
fcntl.c
       1  /*
       2   * Copyright (c) 1991, 1992 Paul Kranenburg <pk@cs.few.eur.nl>
       3   * Copyright (c) 1993 Branko Lankester <branko@hacktic.nl>
       4   * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com>
       5   * Copyright (c) 1996-1999 Wichert Akkerman <wichert@cistron.nl>
       6   * Copyright (c) 1999-2022 The strace developers.
       7   * All rights reserved.
       8   *
       9   * SPDX-License-Identifier: LGPL-2.1-or-later
      10   */
      11  
      12  #include "defs.h"
      13  #include <linux/fcntl.h>
      14  
      15  /* Working around UAPI breakage in v5.19-rc1~89^2~9^2~18 */
      16  #ifndef F_GETLK64
      17  # ifdef __mips__
      18  #  define F_GETLK64	33
      19  #  define F_SETLK64	34
      20  #  define F_SETLKW64	35
      21  # else
      22  #  define F_GETLK64	12
      23  #  define F_SETLK64	13
      24  #  define F_SETLKW64	14
      25  # endif
      26  #endif /* !F_GETLK64 */
      27  
      28  #include "xlat/f_owner_types.h"
      29  #include "xlat/f_seals.h"
      30  #include "xlat/fcntlcmds.h"
      31  #include "xlat/fdflags.h"
      32  #include "xlat/lockfcmds.h"
      33  #include "xlat/notifyflags.h"
      34  
      35  static void
      36  print_struct_flock64(struct tcb *const tcp, const struct flock64 *fl, const int getlk)
      37  {
      38  	tprint_struct_begin();
      39  	PRINT_FIELD_XVAL(*fl, l_type, lockfcmds, "F_???");
      40  	tprint_struct_next();
      41  	PRINT_FIELD_XVAL(*fl, l_whence, whence_codes, "SEEK_???");
      42  	tprint_struct_next();
      43  	PRINT_FIELD_D(*fl, l_start);
      44  	tprint_struct_next();
      45  	PRINT_FIELD_D(*fl, l_len);
      46  	if (getlk) {
      47  		tprint_struct_next();
      48  		PRINT_FIELD_TGID(*fl, l_pid, tcp);
      49  	}
      50  	tprint_struct_end();
      51  }
      52  
      53  static void
      54  printflock64(struct tcb *const tcp, const kernel_ulong_t addr, const int getlk)
      55  {
      56  	struct flock64 fl;
      57  
      58  	if (fetch_struct_flock64(tcp, addr, &fl))
      59  		print_struct_flock64(tcp, &fl, getlk);
      60  }
      61  
      62  static void
      63  printflock(struct tcb *const tcp, const kernel_ulong_t addr, const int getlk)
      64  {
      65  	struct flock64 fl;
      66  
      67  	if (fetch_struct_flock(tcp, addr, &fl))
      68  		print_struct_flock64(tcp, &fl, getlk);
      69  }
      70  
      71  static void
      72  print_f_owner_ex(struct tcb *const tcp, const kernel_ulong_t addr)
      73  {
      74  	struct { int type, pid; } owner;
      75  
      76  	if (umove_or_printaddr(tcp, addr, &owner))
      77  		return;
      78  
      79  	tprint_struct_begin();
      80  	PRINT_FIELD_XVAL(owner, type, f_owner_types, "F_OWNER_???");
      81  
      82  	enum pid_type pid_type = PT_NONE;
      83  	switch (owner.type)
      84  	{
      85  	case F_OWNER_TID:
      86  		pid_type = PT_TID;
      87  		break;
      88  	case F_OWNER_PID:
      89  		pid_type = PT_TGID;
      90  		break;
      91  	case F_OWNER_PGRP:
      92  		pid_type = PT_PGID;
      93  		break;
      94  	}
      95  	tprint_struct_next();
      96  	tprints_field_name("pid");
      97  	printpid(tcp, owner.pid, pid_type);
      98  	tprint_struct_end();
      99  }
     100  
     101  static int
     102  print_fcntl(struct tcb *tcp)
     103  {
     104  	const unsigned int cmd = tcp->u_arg[1];
     105  
     106  	switch (cmd) {
     107  	case F_SETFD:
     108  		tprint_arg_next();
     109  		printflags(fdflags, tcp->u_arg[2], "FD_???");
     110  		break;
     111  	case F_SETOWN:
     112  		tprint_arg_next();
     113  		printpid_tgid_pgid(tcp, tcp->u_arg[2]);
     114  		break;
     115  	case F_SETPIPE_SZ:
     116  		tprint_arg_next();
     117  		PRINT_VAL_D(tcp->u_arg[2]);
     118  		break;
     119  	case F_DUPFD:
     120  	case F_DUPFD_CLOEXEC:
     121  		tprint_arg_next();
     122  		PRINT_VAL_D(tcp->u_arg[2]);
     123  		return RVAL_DECODED | RVAL_FD;
     124  	case F_SETFL:
     125  		tprint_arg_next();
     126  		tprint_open_modes(tcp->u_arg[2]);
     127  		break;
     128  	case F_SETLK:
     129  	case F_SETLKW:
     130  		tprint_arg_next();
     131  		printflock(tcp, tcp->u_arg[2], 0);
     132  		break;
     133  	case F_OFD_SETLK:
     134  	case F_OFD_SETLKW:
     135  		tprint_arg_next();
     136  		printflock64(tcp, tcp->u_arg[2], 0);
     137  		break;
     138  	case F_SETOWN_EX:
     139  		tprint_arg_next();
     140  		print_f_owner_ex(tcp, tcp->u_arg[2]);
     141  		break;
     142  	case F_NOTIFY:
     143  		tprint_arg_next();
     144  		printflags64(notifyflags, tcp->u_arg[2], "DN_???");
     145  		break;
     146  	case F_SETLEASE:
     147  		tprint_arg_next();
     148  		printxval64(lockfcmds, tcp->u_arg[2], "F_???");
     149  		break;
     150  	case F_ADD_SEALS:
     151  		tprint_arg_next();
     152  		printflags64(f_seals, tcp->u_arg[2], "F_SEAL_???");
     153  		break;
     154  	case F_SETSIG:
     155  		tprint_arg_next();
     156  		printsignal(tcp->u_arg[2]);
     157  		break;
     158  	case F_GETOWN:
     159  		return RVAL_DECODED |
     160  		       ((int) tcp->u_rval < 0 ? RVAL_PGID : RVAL_TGID);
     161  	case F_GETPIPE_SZ:
     162  		break;
     163  	case F_GETFD:
     164  		if (entering(tcp) || syserror(tcp) || tcp->u_rval == 0)
     165  			return 0;
     166  		tcp->auxstr = sprintflags("flags ", fdflags,
     167  					  (kernel_ulong_t) tcp->u_rval);
     168  		return RVAL_HEX | RVAL_STR;
     169  	case F_GETFL:
     170  		if (entering(tcp) || syserror(tcp))
     171  			return 0;
     172  		tcp->auxstr = sprint_open_modes(tcp->u_rval);
     173  		return RVAL_HEX | RVAL_STR;
     174  	case F_GETLK:
     175  		if (entering(tcp))
     176  			return 0;
     177  		tprint_arg_next();
     178  		printflock(tcp, tcp->u_arg[2], 1);
     179  		break;
     180  	case F_OFD_GETLK:
     181  		if (entering(tcp))
     182  			return 0;
     183  		tprint_arg_next();
     184  		printflock64(tcp, tcp->u_arg[2], 1);
     185  		break;
     186  	case F_GETOWN_EX:
     187  		if (entering(tcp))
     188  			return 0;
     189  		tprint_arg_next();
     190  		print_f_owner_ex(tcp, tcp->u_arg[2]);
     191  		break;
     192  	case F_GETLEASE:
     193  		if (entering(tcp) || syserror(tcp))
     194  			return 0;
     195  		tcp->auxstr = xlookup(lockfcmds, (kernel_ulong_t) tcp->u_rval);
     196  		return RVAL_HEX | RVAL_STR;
     197  	case F_GET_SEALS:
     198  		if (entering(tcp) || syserror(tcp) || tcp->u_rval == 0)
     199  			return 0;
     200  		tcp->auxstr = sprintflags("seals ", f_seals,
     201  					  (kernel_ulong_t) tcp->u_rval);
     202  		return RVAL_HEX | RVAL_STR;
     203  	case F_GETSIG:
     204  		if (entering(tcp) || syserror(tcp) || tcp->u_rval == 0)
     205  			return 0;
     206  		tcp->auxstr = signame(tcp->u_rval);
     207  		return RVAL_STR;
     208  	default:
     209  		tprint_arg_next();
     210  		PRINT_VAL_X(tcp->u_arg[2]);
     211  		break;
     212  	}
     213  	return RVAL_DECODED;
     214  }
     215  
     216  SYS_FUNC(fcntl)
     217  {
     218  	if (entering(tcp)) {
     219  		/* fd */
     220  		printfd(tcp, tcp->u_arg[0]);
     221  		tprint_arg_next();
     222  
     223  		/* cmd */
     224  		printxval(fcntlcmds, tcp->u_arg[1], "F_???");
     225  	}
     226  	return print_fcntl(tcp);
     227  }
     228  
     229  SYS_FUNC(fcntl64)
     230  {
     231  	const unsigned int cmd = tcp->u_arg[1];
     232  	if (entering(tcp)) {
     233  		/* fd */
     234  		printfd(tcp, tcp->u_arg[0]);
     235  		tprint_arg_next();
     236  
     237  		/* cmd */
     238  		printxval(fcntlcmds, cmd, "F_???");
     239  	}
     240  	switch (cmd) {
     241  		case F_SETLK64:
     242  		case F_SETLKW64:
     243  			tprint_arg_next();
     244  			printflock64(tcp, tcp->u_arg[2], 0);
     245  			return RVAL_DECODED;
     246  		case F_GETLK64:
     247  			if (exiting(tcp)) {
     248  				tprint_arg_next();
     249  				printflock64(tcp, tcp->u_arg[2], 1);
     250  			}
     251  			return 0;
     252  	}
     253  	return print_fcntl(tcp);
     254  }