xref: /haiku/src/bin/debug/strace/fcntl.cpp (revision 344ded80d400028c8f561b4b876257b94c12db4a)
1 /*
2  * Copyright 2022-2023, Haiku Inc. All rights reserved.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *		Copyright 2022, Jérôme Duval, jerome.duval@gmail.com
7  */
8 
9 
10 #include <fcntl.h>
11 
12 #include "strace.h"
13 #include "Syscall.h"
14 #include "TypeHandler.h"
15 
16 
17 #define FLAG_INFO_ENTRY(name) \
18 	{ name, #name }
19 
20 static const FlagsTypeHandler::FlagInfo kOpenFlagInfos[] = {
21 	FLAG_INFO_ENTRY(O_WRONLY),
22 	FLAG_INFO_ENTRY(O_RDWR),
23 
24 	FLAG_INFO_ENTRY(O_EXCL),
25 	FLAG_INFO_ENTRY(O_CREAT),
26 	FLAG_INFO_ENTRY(O_TRUNC),
27 	FLAG_INFO_ENTRY(O_NOCTTY),
28 	FLAG_INFO_ENTRY(O_NOTRAVERSE),
29 
30 	FLAG_INFO_ENTRY(O_CLOEXEC),
31 	FLAG_INFO_ENTRY(O_NONBLOCK),
32 	FLAG_INFO_ENTRY(O_APPEND),
33 	FLAG_INFO_ENTRY(O_SYNC),
34 	FLAG_INFO_ENTRY(O_RSYNC),
35 	FLAG_INFO_ENTRY(O_DSYNC),
36 	FLAG_INFO_ENTRY(O_NOFOLLOW),
37 	FLAG_INFO_ENTRY(O_DIRECT),
38 
39 	FLAG_INFO_ENTRY(O_DIRECTORY),
40 
41 	{ 0, NULL }
42 };
43 
44 
45 struct fcntl_info {
46 	unsigned int index;
47 	const char *name;
48 	TypeHandler *handler;
49 };
50 
51 #define FCNTL_INFO_ENTRY(name) \
52 	{ name, #name, NULL }
53 
54 #define FCNTL_INFO_ENTRY_TYPE(name, type) \
55 	{ name, #name, TypeHandlerFactory<type>::Create() }
56 
57 static const fcntl_info kFcntls[] = {
58 	FCNTL_INFO_ENTRY_TYPE(F_DUPFD, int),
59 	FCNTL_INFO_ENTRY(F_GETFD),
60 	FCNTL_INFO_ENTRY_TYPE(F_SETFD, int),
61 	FCNTL_INFO_ENTRY(F_GETFL),
62 	FCNTL_INFO_ENTRY(F_SETFL),
63 	FCNTL_INFO_ENTRY_TYPE(F_GETLK, struct flock*),
64 	FCNTL_INFO_ENTRY_TYPE(F_SETLK, struct flock*),
65 	FCNTL_INFO_ENTRY_TYPE(F_SETLKW, struct flock*),
66 	{ 0, NULL, NULL }
67 };
68 
69 static FlagsTypeHandler::FlagsList kOpenFlags;
70 static EnumTypeHandler::EnumMap kFcntlNames;
71 static TypeHandlerSelector::SelectMap kFcntlTypeHandlers;
72 
73 void
74 patch_fcntl()
75 {
76 	for (int i = 0; kOpenFlagInfos[i].name != NULL; i++) {
77 		kOpenFlags.push_back(kOpenFlagInfos[i]);
78 	}
79 
80 	for (int i = 0; kFcntls[i].name != NULL; i++) {
81 		kFcntlNames[kFcntls[i].index] = kFcntls[i].name;
82 		if (kFcntls[i].handler != NULL)
83 			kFcntlTypeHandlers[kFcntls[i].index] = kFcntls[i].handler;
84 	}
85 
86 	kFcntlTypeHandlers[F_SETFL] = new FlagsTypeHandler(kOpenFlags);
87 
88 	Syscall *open = get_syscall("_kern_open");
89 	open->GetParameter("openMode")->SetHandler(new FlagsTypeHandler(kOpenFlags));
90 
91 	Syscall *fcntl = get_syscall("_kern_fcntl");
92 	fcntl->GetParameter("op")->SetHandler(new EnumTypeHandler(kFcntlNames));
93 	fcntl->GetParameter("argument")->SetHandler(
94 		new TypeHandlerSelector(kFcntlTypeHandlers,
95 				1, TypeHandlerFactory<void *>::Create()));
96 
97 	Syscall *createPipe = get_syscall("_kern_create_pipe");
98 	createPipe->ParameterAt(0)->SetOut(true);
99 	createPipe->ParameterAt(0)->SetCount(2);
100 	createPipe->GetParameter("flags")->SetHandler(new FlagsTypeHandler(kOpenFlags));
101 
102 	Syscall *dup2 = get_syscall("_kern_dup2");
103 	dup2->GetParameter("flags")->SetHandler(new FlagsTypeHandler(kOpenFlags));
104 
105 }
106 
107