summaryrefslogtreecommitdiff
path: root/src/ioprio.c
blob: 16c9e6dbebc0c36318ec1606667988cb5dfc7fbb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
/*
 * Copyright (c) 2015 Dmitry V. Levin <ldv@strace.io>
 * Copyright (c) 2014-2021 The strace developers.
 * All rights reserved.
 *
 * SPDX-License-Identifier: LGPL-2.1-or-later
 */

#include "defs.h"
#include "xstring.h"

#include "xlat/ioprio_who.h"
#include "xlat/ioprio_class.h"

#define IOPRIO_CLASS_SHIFT	(13)
#define IOPRIO_PRIO_MASK	((1ul << IOPRIO_CLASS_SHIFT) - 1)

#define IOPRIO_PRIO_CLASS(mask)	((mask) >> IOPRIO_CLASS_SHIFT)
#define IOPRIO_PRIO_DATA(mask)	((mask) & IOPRIO_PRIO_MASK)

static const char *
sprint_ioprio(unsigned int ioprio)
{
	static char outstr[256];
	char class_buf[64];
	unsigned int class, data;

	class = IOPRIO_PRIO_CLASS(ioprio);
	data = IOPRIO_PRIO_DATA(ioprio);
	sprintxval(class_buf, sizeof(class_buf), ioprio_class, class,
		   "IOPRIO_CLASS_???");
	xsprintf(outstr, "IOPRIO_PRIO_VALUE(%s, %d)", class_buf, data);

	return outstr;
}

void
print_ioprio(unsigned int ioprio)
{
	if (xlat_verbose(xlat_verbosity) != XLAT_STYLE_ABBREV)
		PRINT_VAL_X(ioprio);

	if (xlat_verbose(xlat_verbosity) == XLAT_STYLE_RAW)
		return;

	if (xlat_verbose(xlat_verbosity) == XLAT_STYLE_VERBOSE)
		tprint_comment_begin();

	unsigned int class = IOPRIO_PRIO_CLASS(ioprio);
	unsigned int data = IOPRIO_PRIO_DATA(ioprio);

	tprints_arg_begin("IOPRIO_PRIO_VALUE");
	printxval_ex(ioprio_class, class,
		     xlat_verbose(xlat_verbosity) == XLAT_STYLE_VERBOSE
			? NULL : "IOPRIO_CLASS_???",
		     XLAT_STYLE_ABBREV);
	tprint_arg_next();
	PRINT_VAL_U(data);
	tprint_arg_end();

	if (xlat_verbose(xlat_verbosity) == XLAT_STYLE_VERBOSE)
		tprint_comment_end();
}

static void
ioprio_print_who(struct tcb *tcp, int which, int who)
{
	switch (which) {
	case IOPRIO_WHO_USER:
		printuid(who);
		break;
	case IOPRIO_WHO_PROCESS:
		printpid(tcp, who, PT_TGID);
		break;
	case IOPRIO_WHO_PGRP:
		printpid(tcp, who, PT_PGID);
		break;
	default:
		PRINT_VAL_D(who);
		break;
	}
}

SYS_FUNC(ioprio_get)
{
	if (entering(tcp)) {
		/* which */
		printxval(ioprio_who, tcp->u_arg[0], "IOPRIO_WHO_???");
		tprint_arg_next();

		/* who */
		ioprio_print_who(tcp, tcp->u_arg[0], tcp->u_arg[1]);
		return 0;
	} else {
		if (syserror(tcp))
			return 0;
		if (xlat_verbose(xlat_verbosity) != XLAT_STYLE_RAW)
			tcp->auxstr = sprint_ioprio(tcp->u_rval);
		return RVAL_STR;
	}
}

SYS_FUNC(ioprio_set)
{
	/* which */
	printxval(ioprio_who, tcp->u_arg[0], "IOPRIO_WHO_???");
	tprint_arg_next();

	/* who */
	ioprio_print_who(tcp, tcp->u_arg[0], tcp->u_arg[1]);
	tprint_arg_next();

	/* ioprio */
	print_ioprio(tcp->u_arg[2]);

	return RVAL_DECODED;
}