| 1 | /*++ |
| 2 | |
| 3 | Copyright (c) Microsoft. All rights reserved. |
| 4 | |
| 5 | Module Name: |
| 6 | |
| 7 | lxtutil.h |
| 8 | |
| 9 | Abstract: |
| 10 | |
| 11 | This file contains lx test common utility functions that log appropriately. |
| 12 | |
| 13 | --*/ |
| 14 | |
| 15 | #ifndef _LXT_UTIL |
| 16 | #define _LXT_UTIL |
| 17 | |
| 18 | #include "lxtlog.h" |
| 19 | |
| 20 | #if defined(__aarch64__) |
| 21 | |
| 22 | #define __ARCH_WANT_SYSCALL_DEPRECATED |
| 23 | |
| 24 | #endif |
| 25 | |
| 26 | #include <sys/types.h> |
| 27 | #include <sys/stat.h> |
| 28 | #include <sys/syscall.h> |
| 29 | #include <signal.h> |
| 30 | #include <sched.h> |
| 31 | #include <stdbool.h> |
| 32 | #include <stdint.h> |
| 33 | |
| 34 | #define LXT_WAITPID_DEFAULT_TIMEOUT 10 |
| 35 | |
| 36 | #define LXT_CHECK_DIRECTORY_CONTENTS_READ_FILES (0x1) |
| 37 | |
| 38 | #define LXT_ROUND_UP_COUNT(Count, Pow2) (((Count) + (Pow2) - 1) & (~(((Pow2)) - 1))) |
| 39 | |
| 40 | #define LXT_CLONE_STACK_SIZE (1024 * 1024) |
| 41 | |
| 42 | #define LxtCheckClose(_Fd) \ |
| 43 | { \ |
| 44 | LxtCheckResult(LxtClose(_Fd)); \ |
| 45 | (_Fd) = -1; \ |
| 46 | } |
| 47 | |
| 48 | typedef struct _LXT_ARGS |
| 49 | { |
| 50 | LxtLogType LogType; |
| 51 | bool LogAppend; |
| 52 | unsigned long long VariationMask; |
| 53 | bool HelpRequested; |
| 54 | int Argc; |
| 55 | char** Argv; |
| 56 | } LXT_ARGS, *PLXT_ARGS; |
| 57 | |
| 58 | typedef int LXT_VARIATION_HANDLER(PLXT_ARGS Args); |
| 59 | |
| 60 | typedef struct _LXT_VARIATION |
| 61 | { |
| 62 | const char* Name; |
| 63 | LXT_VARIATION_HANDLER* Variation; |
| 64 | } LXT_VARIATION, *PLXT_VARIATION; |
| 65 | |
| 66 | typedef const LXT_VARIATION* PCLXT_VARIATION; |
| 67 | |
| 68 | typedef unsigned char BOOLEAN; |
| 69 | |
| 70 | #define TRUE 1 |
| 71 | #define FALSE 0 |
| 72 | |
| 73 | #define LXT_COUNT_OF(x) (sizeof(x) / sizeof((x)[0])) |
| 74 | |
| 75 | #define LXT_INIT_PID ((pid_t)1) |
| 76 | |
| 77 | #define LXT_DEFAULT_EXIT_CODE 0 |
| 78 | |
| 79 | typedef struct _LXT_CHILD_INFO |
| 80 | { |
| 81 | const char* Name; |
| 82 | unsigned char FileType; |
| 83 | } LXT_CHILD_INFO, *PLXT_CHILD_INFO; |
| 84 | |
| 85 | // |
| 86 | // Test framework code |
| 87 | // |
| 88 | |
| 89 | int LxtCheckDirectoryContents(const char* Path, const LXT_CHILD_INFO* Children, size_t Count); |
| 90 | |
| 91 | int LxtCheckDirectoryContentsEx(const char* Path, const LXT_CHILD_INFO* Children, size_t Count, int Flags); |
| 92 | |
| 93 | int LxtCheckFdPath(int Fd, char* ExpectedPath); |
| 94 | |
| 95 | int LxtCheckLinkTarget(const char* Path, const char* ExpectedTarget); |
| 96 | |
| 97 | int LxtCheckRead(const char* FullPath, unsigned char FileType); |
| 98 | |
| 99 | int LxtCheckStat(const char* FullPath, unsigned long long ExpectedInode, unsigned char FileType); |
| 100 | |
| 101 | int LxtCheckWslPathTranslation(char* Path, const char* ExpectedPath, bool WinPath); |
| 102 | |
| 103 | int LxtCompareMemory(const void* First, const void* Second, size_t Size, const char* FirstDescription, const char* SecondDescription); |
| 104 | |
| 105 | int LxtCopyFile(const char* Source, const char* Destination); |
| 106 | |
| 107 | int LxtInitialize(int Argc, char* Argv[], PLXT_ARGS Args, const char* TestName); |
| 108 | |
| 109 | int LxtRunVariations(PLXT_ARGS Args, PCLXT_VARIATION Variations, unsigned int VariationCount); |
| 110 | |
| 111 | int LxtRunVariationsForked(PLXT_ARGS Args, PCLXT_VARIATION Variations, unsigned int VariationCount); |
| 112 | |
| 113 | int LxtCheckWrite(const char* FullPath, const char* Value); |
| 114 | |
| 115 | void LxtUninitialize(void); |
| 116 | |
| 117 | // |
| 118 | // stdlib wrappers |
| 119 | // |
| 120 | |
| 121 | void* LxtAlloc(size_t Size); |
| 122 | |
| 123 | void LxtFree(void* Allocation); |
| 124 | |
| 125 | // |
| 126 | // syscall wrappers |
| 127 | // |
| 128 | |
| 129 | #define LxtExit(_status) (syscall(1, _status)) |
| 130 | #define LxtRt_SigAction(_signal, _action, _oaction, _setsize) (syscall(SYS_rt_sigaction, _signal, _action, _oaction, _setsize)) |
| 131 | #define LxtRt_SigProcMask(_how, _set, _oset, _setsize) (syscall(SYS_rt_sigprocmask, _how, _set, _oset, _setsize)) |
| 132 | #define LxtTKill(_tid, _sig) (syscall(SYS_tkill, _tid, _sig)) |
| 133 | #define LxtTgKill(_tgid, _tid, _sig) (syscall(SYS_tgkill, _tgid, _tid, _sig)) |
| 134 | #define LxtRead(_fd, _buffer, _count) (syscall(SYS_read, _fd, _buffer, _count)) |
| 135 | #define LxtWrite(_fd, _buffer, _count) (syscall(SYS_write, _fd, _buffer, _count)) |
| 136 | #define LxtGetTid() (syscall(SYS_gettid)) |
| 137 | #define gettid() LxtGetTid() |
| 138 | #define LxtPipe2(_pipefds, _flags) (syscall(__NR_pipe2, _pipefds, _flags)) |
| 139 | #define LxtFutex(_uaddr, _op, _val, _timeout, _uaddr2, _val3) (syscall(SYS_futex, _uaddr, _op, _val, _timeout, _uaddr2, _val3)) |
| 140 | #define LxtCapGet(_header, _data) (syscall(SYS_capget, _header, _data)) |
| 141 | #define LxtCapSet(_header, _data) (syscall(SYS_capset, _header, _data)) |
| 142 | #define LxtExecve(_Filename, _Argv, _Envp) syscall(SYS_execve, (_Filename), (_Argv), (_Envp)) |
| 143 | #define LxtWaitId(_idtype, _id, _infop, _options, _rusage) syscall(SYS_waitid, (_idtype), (_id), (_infop), (_options), (_rusage)) |
| 144 | #define LxtSetUid(_uid) syscall(SYS_setuid, (_uid)) |
| 145 | #if !defined(__amd64__) |
| 146 | #define LxtCloneSyscall(_flags, _stack, _ptid, _ctid, _tls) (syscall(SYS_clone, _flags, _stack, _ptid, _tls, _ctid)) |
| 147 | #else |
| 148 | #define LxtCloneSyscall(_flags, _stack, _ptid, _ctid, _tls) (syscall(SYS_clone, _flags, _stack, _ptid, _ctid, _tls)) |
| 149 | #endif |
| 150 | #define LxtTimer_Create(_clockid, _sevp, _timerid) syscall(SYS_timer_create, (_clockid), (_sevp), (_timerid)) |
| 151 | #define LxtTimer_SetTime(_timerid, _flags, _new_value, _old_value) \ |
| 152 | syscall(SYS_timer_settime, (_timerid), (_flags), (_new_value), (_old_value)) |
| 153 | #define LxtTimer_GetTime(_timerid, _curr_value) syscall(SYS_timer_gettime, (_timerid), (_curr_value)) |
| 154 | #define LxtTimer_GetOverrun(_timerid) syscall(SYS_timer_getoverrun, (_timerid)) |
| 155 | #define LxtTimer_Delete(_timerid) syscall(SYS_timer_delete, (_timerid)) |
| 156 | #define LxtClock_Nanosleep(_clockid, _flags, _request, _remain) \ |
| 157 | syscall(SYS_clock_nanosleep, (_clockid), (_flags), (_request), (_remain)) |
| 158 | #define LxtGetrandom(_buffer, _size, _flags) syscall(SYS_getrandom, (_buffer), (_size), (_flags)) |
| 159 | #define LxtShmAt(_id, _address, _flags) (void*)(syscall(SYS_shmat, (_id), (_address), (_flags))) |
| 160 | #define LxtShmCtl(_id, _cmd, _buffer) syscall(SYS_shmctl, (_id), (_cmd), (_buffer)) |
| 161 | #define LxtShmDt(_address) syscall(SYS_shmdt, (_address)) |
| 162 | #define LxtShmGet(_key, _size, _flags) syscall(SYS_shmget, (_key), (_size), (_flags)) |
| 163 | #define LxtMremap(_oldAddress, _oldSize, _newSize, _flags, _newAddress) \ |
| 164 | (void*)(syscall(SYS_mremap, _oldAddress, _oldSize, _newSize, _flags, _newAddress)) |
| 165 | #define LxtSemCtl(_id, _number, _command, _buffer) syscall(SYS_semctl, (_id), (_number), (_command), (_buffer)) |
| 166 | #define LxtSemGet(_key, _count, _flags) syscall(SYS_semget, (_key), (_count), (_flags)) |
| 167 | #define LxtSemOp(_id, _operations, _opcount) syscall(SYS_semop, (_id), (_operations), (_opcount)) |
| 168 | #define LxtSemTimedOp(_id, _operations, _opcount, _timeout) syscall(SYS_semtimedop, (_id), (_operations), (_opcount), (_timeout)) |
| 169 | #define LxtIoprio_get(_which, _who) syscall(__NR_ioprio_get, (_which), (_who)) |
| 170 | #define LxtIoprio_set(_which, _who, _prio) syscall(__NR_ioprio_set, (_which), (_who), (_prio)) |
| 171 | #define LxtSched_GetAffinity(_pid, _cpusetsize, _mask) syscall(__NR_sched_getaffinity, (_pid), (_cpusetsize), (_mask)) |
| 172 | #define LxtSched_SetAffinity(_pid, _cpusetsize, _mask) syscall(__NR_sched_setaffinity, (_pid), (_cpusetsize), (_mask)) |
| 173 | #define LxtListxattr(_path, _buffer, _size) (syscall(SYS_listxattr, (_path), (_buffer), (_size))) |
| 174 | #define LxtLlistxattr(_path, _buffer, _size) (syscall(SYS_llistxattr, (_path), (_buffer), (_size))) |
| 175 | #define LxtFlistxattr(_fd, _buffer, _size) (syscall(SYS_flistxattr, (_fd), (_buffer), (_size))) |
| 176 | #define LxtGetxattr(_path, _name, _buffer, _size) (syscall(SYS_getxattr, (_path), (_name), (_buffer), (_size))) |
| 177 | #define LxtLgetxattr(_path, _name, _buffer, _size) (syscall(SYS_lgetxattr, (_path), (_name), (_buffer), (_size))) |
| 178 | #define LxtFgetxattr(_fd, _name, _buffer, _size) (syscall(SYS_fgetxattr, (_fd), (_name), (_buffer), (_size))) |
| 179 | #define LxtSetxattr(_path, _name, _buffer, _size, _flags) (syscall(SYS_setxattr, (_path), (_name), (_buffer), (_size), (_flags))) |
| 180 | #define LxtLsetxattr(_path, _name, _buffer, _size, _flags) \ |
| 181 | (syscall(SYS_lsetxattr, (_path), (_name), (_buffer), (_size), (_flags))) |
| 182 | #define LxtFsetxattr(_fd, _name, _buffer, _size, _flags) (syscall(SYS_fsetxattr, (_fd), (_name), (_buffer), (_size), (_flags))) |
| 183 | #define LxtRemovexattr(_path, _name) (syscall(SYS_removexattr, (_path), (_name))) |
| 184 | #define LxtLremovexattr(_path, _name) (syscall(SYS_lremovexattr, (_path), (_name))) |
| 185 | #define LxtFremovexattr(_fd, _name) (syscall(SYS_fremovexattr, (_fd), (_name))) |
| 186 | #define LxtGetresuid(_real, _effective, _saved) (syscall(SYS_getresuid, (_real), (_effective), (_saved))) |
| 187 | #define LxtSetresuid(_real, _effective, _saved) (syscall(SYS_setresuid, (_real), (_effective), (_saved))) |
| 188 | #define LxtSetresgid(_real, _effective, _saved) (syscall(SYS_setresgid, (_real), (_effective), (_saved))) |
| 189 | #define LxtSetfsgid(_gid) syscall(__NR_setfsgid, (_gid)) |
| 190 | #define LxtSetfsuid(_uid) syscall(__NR_setfsuid, (_uid)) |
| 191 | #define LxtPrlimit64(_pid, _resource, _newvalue, _oldvalue) syscall(__NR_prlimit64, (_pid), (_resource), (_newvalue), (_oldvalue)) |
| 192 | //__NR_getdents has been removed from newer versions of libc |
| 193 | #ifdef __NR_getdents |
| 194 | #define LxtGetdents(_fd, _buffer, _size) syscall(__NR_getdents, (_fd), (_buffer), (_size)) |
| 195 | #endif |
| 196 | #define LxtGetdents64(_fd, _buffer, _size) syscall(__NR_getdents64, (_fd), (_buffer), (_size)) |
| 197 | #define LxtGetcwd(_buffer, _size) syscall(SYS_getcwd, (_buffer), (_size)) |
| 198 | |
| 199 | #if defined(__aarch64__) |
| 200 | #define LxtFStatAt64(_dirfd, _path, _buffer, _flags) fstatat(_dirfd, _path, _buffer, _flags) |
| 201 | #elif !defined(__amd64__) |
| 202 | #define LxtFStatAt64(_dirfd, _path, _buffer, _flags) syscall(SYS_fstatat64, _dirfd, _path, _buffer, _flags) |
| 203 | #else |
| 204 | #define LxtFStatAt64(_dirfd, _path, _buffer, _flags) fstatat64(_dirfd, _path, _buffer, _flags) |
| 205 | #endif |
| 206 | |
| 207 | #ifndef clock_gettime |
| 208 | #define LxtClockGetTime(_clockid, _timespec) syscall(__NR_clock_gettime, _clockid, _timespec) |
| 209 | #else |
| 210 | #define LxtClockGetTime(_clockid, _timespec) clock_gettime(_clockid, _timespec) |
| 211 | #endif |
| 212 | |
| 213 | #define LxtClockGetRes(_clockid, _timespec) syscall(__NR_clock_getres, _clockid, _timespec) |
| 214 | |
| 215 | #ifndef timerfd_create |
| 216 | #define timerfd_create(ClockId, Flags) syscall(__NR_timerfd_create, ClockId, Flags) |
| 217 | #endif |
| 218 | |
| 219 | #ifndef timerfd_gettime |
| 220 | #define timerfd_gettime(Fd, CurrentValue) syscall(__NR_timerfd_gettime, Fd, CurrentValue) |
| 221 | #endif |
| 222 | |
| 223 | #ifndef timerfd_settime |
| 224 | #define timerfd_settime(Fd, Flags, NewValue, OldValue) syscall(__NR_timerfd_settime, Fd, Flags, NewValue, OldValue) |
| 225 | #endif |
| 226 | |
| 227 | #define LXT_CLONE_FLAGS_DEFAULT (CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | CLONE_THREAD | CLONE_SYSVSEM) |
| 228 | |
| 229 | typedef long long kernel_sigset_t; |
| 230 | |
| 231 | typedef struct _LXT_RT_SIG_ACTION |
| 232 | { |
| 233 | void* Handler; |
| 234 | int Flags; |
| 235 | void* Restorer; |
| 236 | kernel_sigset_t Mask; |
| 237 | } LXT_RT_SIG_ACTION, *PLXT_RT_SIG_ACTION; |
| 238 | |
| 239 | typedef struct _LXT_CLONE_ARGS |
| 240 | { |
| 241 | char* Stack; |
| 242 | pid_t CloneId; |
| 243 | } LXT_CLONE_ARGS, *PLXT_CLONE_ARGS; |
| 244 | |
| 245 | typedef struct _LXT_PIPE |
| 246 | { |
| 247 | int Read; |
| 248 | int Write; |
| 249 | } LXT_PIPE, *PLXT_PIPE; |
| 250 | |
| 251 | typedef struct _LXT_SOCKET_PAIR |
| 252 | { |
| 253 | int Parent; |
| 254 | int Child; |
| 255 | } LXT_SOCKET_PAIR, *PLXT_SOCKET_PAIR; |
| 256 | |
| 257 | int LxtAcceptPoll(int Socket); |
| 258 | |
| 259 | int LxtClone(int (*Entry)(void* Parameter), void* Parameter, int Flags, PLXT_CLONE_ARGS Args); |
| 260 | |
| 261 | int LxtClosePipe(PLXT_PIPE Pipe); |
| 262 | |
| 263 | int LxtCreatePipe(PLXT_PIPE Pipe); |
| 264 | |
| 265 | int LxtExecuteAndReadOutput(char** Argv, char* OutputBuffer, size_t OutputBufferSize, int ExpectedExitCode); |
| 266 | |
| 267 | int LxtExecuteWslPath(char* Path, bool WinPath, char* OutputBuffer, size_t OutputBufferSize, int ExpectedExitCode); |
| 268 | |
| 269 | int LxtJoinThread(pid_t* Tid); |
| 270 | |
| 271 | int LxtReceiveMessage(int Socket, const char* ExpectedMessage); |
| 272 | |
| 273 | int LxtSendMessage(int Socket, const char* Message); |
| 274 | |
| 275 | int LxtSignalBlock(int Signal); |
| 276 | |
| 277 | int LxtSignalDefault(int Signal); |
| 278 | |
| 279 | int LxtSignalIgnore(int Signal); |
| 280 | |
| 281 | int LxtSignalCheckInfoReceived(int Signal, int Code, pid_t Pid, uid_t Uid); |
| 282 | |
| 283 | int LxtSignalCheckNoSignal(void); |
| 284 | |
| 285 | int LxtSignalCheckReceived(int Signal); |
| 286 | |
| 287 | int LxtSignalCheckSigChldReceived(int Code, pid_t Pid, uid_t Uid, int Status); |
| 288 | |
| 289 | int LxtSignalGetCount(void); |
| 290 | |
| 291 | int LxtSignalGetInfo(siginfo_t* SignalInfo); |
| 292 | |
| 293 | int LxtSignalInitialize(void); |
| 294 | |
| 295 | int LxtSignalInitializeThread(void); |
| 296 | |
| 297 | void LxtSignalResetReceived(void); |
| 298 | |
| 299 | void LxtSignalSetAllowMultiple(BOOLEAN AllowMultiple); |
| 300 | |
| 301 | int LxtSignalSetupHandler(int Signal, int Flags); |
| 302 | |
| 303 | int LxtSignalTimedWait(sigset_t* Set, siginfo_t* SignalInfo, struct timespec* Timeout); |
| 304 | |
| 305 | int LxtSignalUnblock(int Signal); |
| 306 | |
| 307 | void LxtSignalWait(void); |
| 308 | |
| 309 | int LxtSignalWaitBlocked(int Signal, pid_t FromPid, int TimeoutSeconds); |
| 310 | |
| 311 | int LxtSignalCheckSigChldReceived(int Code, pid_t Pid, uid_t Uid, int Status); |
| 312 | |
| 313 | int LxtSocketPairClose(PLXT_SOCKET_PAIR SocketPair); |
| 314 | |
| 315 | int LxtSocketPairCloseChild(PLXT_SOCKET_PAIR SocketPair); |
| 316 | |
| 317 | int LxtSocketPairCloseParent(PLXT_SOCKET_PAIR SocketPair); |
| 318 | |
| 319 | int LxtSocketPairCreate(PLXT_SOCKET_PAIR SocketPair); |
| 320 | |
| 321 | int LxtWaitPidPoll(pid_t ChildPid, int ExpectedWaitStatus); |
| 322 | |
| 323 | int LxtWaitPidPollOptions(pid_t ChildPid, int ExpectedWaitStatus, int Options, int TimeoutSeconds); |
| 324 | |
| 325 | int LxtClose(int FileDescriptor); |
| 326 | |
| 327 | int LxtMunmap(void* Address, size_t Length); |
| 328 | |
| 329 | int LxtWslVersion(void); |
| 330 | |
| 331 | #endif // _LXT_UTIL |