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
patch_fcntl()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