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 98