1 /// Linux platform specific functions 2 module mecca.platform.os.linux; 3 4 // Licensed under the Boost license. Full copyright information in the AUTHORS file 5 6 import mecca.log: notrace; 7 8 version(linux): 9 version(X86_64): 10 11 public import mecca.platform.os.linux.ucontext; 12 public import mecca.platform.os.linux.time; 13 14 enum Syscall: int { 15 NR_read = 0, 16 NR_write = 1, 17 NR_open = 2, 18 NR_close = 3, 19 NR_stat = 4, 20 NR_fstat = 5, 21 NR_lstat = 6, 22 NR_poll = 7, 23 NR_lseek = 8, 24 NR_mmap = 9, 25 NR_mprotect = 10, 26 NR_munmap = 11, 27 NR_brk = 12, 28 NR_rt_sigaction = 13, 29 NR_rt_sigprocmask = 14, 30 NR_rt_sigreturn = 15, 31 NR_ioctl = 16, 32 NR_pread64 = 17, 33 NR_pwrite64 = 18, 34 NR_readv = 19, 35 NR_writev = 20, 36 NR_access = 21, 37 NR_pipe = 22, 38 NR_select = 23, 39 NR_sched_yield = 24, 40 NR_mremap = 25, 41 NR_msync = 26, 42 NR_mincore = 27, 43 NR_madvise = 28, 44 NR_shmget = 29, 45 NR_shmat = 30, 46 NR_shmctl = 31, 47 NR_dup = 32, 48 NR_dup2 = 33, 49 NR_pause = 34, 50 NR_nanosleep = 35, 51 NR_getitimer = 36, 52 NR_alarm = 37, 53 NR_setitimer = 38, 54 NR_getpid = 39, 55 NR_sendfile = 40, 56 NR_socket = 41, 57 NR_connect = 42, 58 NR_accept = 43, 59 NR_sendto = 44, 60 NR_recvfrom = 45, 61 NR_sendmsg = 46, 62 NR_recvmsg = 47, 63 NR_shutdown = 48, 64 NR_bind = 49, 65 NR_listen = 50, 66 NR_getsockname = 51, 67 NR_getpeername = 52, 68 NR_socketpair = 53, 69 NR_setsockopt = 54, 70 NR_getsockopt = 55, 71 NR_clone = 56, 72 NR_fork = 57, 73 NR_vfork = 58, 74 NR_execve = 59, 75 NR_exit = 60, 76 NR_wait4 = 61, 77 NR_kill = 62, 78 NR_uname = 63, 79 NR_semget = 64, 80 NR_semop = 65, 81 NR_semctl = 66, 82 NR_shmdt = 67, 83 NR_msgget = 68, 84 NR_msgsnd = 69, 85 NR_msgrcv = 70, 86 NR_msgctl = 71, 87 NR_fcntl = 72, 88 NR_flock = 73, 89 NR_fsync = 74, 90 NR_fdatasync = 75, 91 NR_truncate = 76, 92 NR_ftruncate = 77, 93 NR_getdents = 78, 94 NR_getcwd = 79, 95 NR_chdir = 80, 96 NR_fchdir = 81, 97 NR_rename = 82, 98 NR_mkdir = 83, 99 NR_rmdir = 84, 100 NR_creat = 85, 101 NR_link = 86, 102 NR_unlink = 87, 103 NR_symlink = 88, 104 NR_readlink = 89, 105 NR_chmod = 90, 106 NR_fchmod = 91, 107 NR_chown = 92, 108 NR_fchown = 93, 109 NR_lchown = 94, 110 NR_umask = 95, 111 NR_gettimeofday = 96, 112 NR_getrlimit = 97, 113 NR_getrusage = 98, 114 NR_sysinfo = 99, 115 NR_times = 100, 116 NR_ptrace = 101, 117 NR_getuid = 102, 118 NR_syslog = 103, 119 NR_getgid = 104, 120 NR_setuid = 105, 121 NR_setgid = 106, 122 NR_geteuid = 107, 123 NR_getegid = 108, 124 NR_setpgid = 109, 125 NR_getppid = 110, 126 NR_getpgrp = 111, 127 NR_setsid = 112, 128 NR_setreuid = 113, 129 NR_setregid = 114, 130 NR_getgroups = 115, 131 NR_setgroups = 116, 132 NR_setresuid = 117, 133 NR_getresuid = 118, 134 NR_setresgid = 119, 135 NR_getresgid = 120, 136 NR_getpgid = 121, 137 NR_setfsuid = 122, 138 NR_setfsgid = 123, 139 NR_getsid = 124, 140 NR_capget = 125, 141 NR_capset = 126, 142 NR_rt_sigpending = 127, 143 NR_rt_sigtimedwait = 128, 144 NR_rt_sigqueueinfo = 129, 145 NR_rt_sigsuspend = 130, 146 NR_sigaltstack = 131, 147 NR_utime = 132, 148 NR_mknod = 133, 149 NR_uselib = 134, 150 NR_personality = 135, 151 NR_ustat = 136, 152 NR_statfs = 137, 153 NR_fstatfs = 138, 154 NR_sysfs = 139, 155 NR_getpriority = 140, 156 NR_setpriority = 141, 157 NR_sched_setparam = 142, 158 NR_sched_getparam = 143, 159 NR_sched_setscheduler = 144, 160 NR_sched_getscheduler = 145, 161 NR_sched_get_priority_max = 146, 162 NR_sched_get_priority_min = 147, 163 NR_sched_rr_get_interval = 148, 164 NR_mlock = 149, 165 NR_munlock = 150, 166 NR_mlockall = 151, 167 NR_munlockall = 152, 168 NR_vhangup = 153, 169 NR_modify_ldt = 154, 170 NR_pivot_root = 155, 171 NR__sysctl = 156, 172 NR_prctl = 157, 173 NR_arch_prctl = 158, 174 NR_adjtimex = 159, 175 NR_setrlimit = 160, 176 NR_chroot = 161, 177 NR_sync = 162, 178 NR_acct = 163, 179 NR_settimeofday = 164, 180 NR_mount = 165, 181 NR_umount2 = 166, 182 NR_swapon = 167, 183 NR_swapoff = 168, 184 NR_reboot = 169, 185 NR_sethostname = 170, 186 NR_setdomainname = 171, 187 NR_iopl = 172, 188 NR_ioperm = 173, 189 NR_create_module = 174, 190 NR_init_module = 175, 191 NR_delete_module = 176, 192 NR_get_kernel_syms = 177, 193 NR_query_module = 178, 194 NR_quotactl = 179, 195 NR_nfsservctl = 180, 196 NR_getpmsg = 181, 197 NR_putpmsg = 182, 198 NR_afs_syscall = 183, 199 NR_tuxcall = 184, 200 NR_security = 185, 201 NR_gettid = 186, 202 NR_readahead = 187, 203 NR_setxattr = 188, 204 NR_lsetxattr = 189, 205 NR_fsetxattr = 190, 206 NR_getxattr = 191, 207 NR_lgetxattr = 192, 208 NR_fgetxattr = 193, 209 NR_listxattr = 194, 210 NR_llistxattr = 195, 211 NR_flistxattr = 196, 212 NR_removexattr = 197, 213 NR_lremovexattr = 198, 214 NR_fremovexattr = 199, 215 NR_tkill = 200, 216 NR_time = 201, 217 NR_futex = 202, 218 NR_sched_setaffinity = 203, 219 NR_sched_getaffinity = 204, 220 NR_set_thread_area = 205, 221 NR_io_setup = 206, 222 NR_io_destroy = 207, 223 NR_io_getevents = 208, 224 NR_io_submit = 209, 225 NR_io_cancel = 210, 226 NR_get_thread_area = 211, 227 NR_lookup_dcookie = 212, 228 NR_epoll_create = 213, 229 NR_epoll_ctl_old = 214, 230 NR_epoll_wait_old = 215, 231 NR_remap_file_pages = 216, 232 NR_getdents64 = 217, 233 NR_set_tid_address = 218, 234 NR_restart_syscall = 219, 235 NR_semtimedop = 220, 236 NR_fadvise64 = 221, 237 NR_timer_create = 222, 238 NR_timer_settime = 223, 239 NR_timer_gettime = 224, 240 NR_timer_getoverrun = 225, 241 NR_timer_delete = 226, 242 NR_clock_settime = 227, 243 NR_clock_gettime = 228, 244 NR_clock_getres = 229, 245 NR_clock_nanosleep = 230, 246 NR_exit_group = 231, 247 NR_epoll_wait = 232, 248 NR_epoll_ctl = 233, 249 NR_tgkill = 234, 250 NR_utimes = 235, 251 NR_vserver = 236, 252 NR_mbind = 237, 253 NR_set_mempolicy = 238, 254 NR_get_mempolicy = 239, 255 NR_mq_open = 240, 256 NR_mq_unlink = 241, 257 NR_mq_timedsend = 242, 258 NR_mq_timedreceive = 243, 259 NR_mq_notify = 244, 260 NR_mq_getsetattr = 245, 261 NR_kexec_load = 246, 262 NR_waitid = 247, 263 NR_add_key = 248, 264 NR_request_key = 249, 265 NR_keyctl = 250, 266 NR_ioprio_set = 251, 267 NR_ioprio_get = 252, 268 NR_inotify_init = 253, 269 NR_inotify_add_watch = 254, 270 NR_inotify_rm_watch = 255, 271 NR_migrate_pages = 256, 272 NR_openat = 257, 273 NR_mkdirat = 258, 274 NR_mknodat = 259, 275 NR_fchownat = 260, 276 NR_futimesat = 261, 277 NR_newfstatat = 262, 278 NR_unlinkat = 263, 279 NR_renameat = 264, 280 NR_linkat = 265, 281 NR_symlinkat = 266, 282 NR_readlinkat = 267, 283 NR_fchmodat = 268, 284 NR_faccessat = 269, 285 NR_pselect6 = 270, 286 NR_ppoll = 271, 287 NR_unshare = 272, 288 NR_set_robust_list = 273, 289 NR_get_robust_list = 274, 290 NR_splice = 275, 291 NR_tee = 276, 292 NR_sync_file_range = 277, 293 NR_vmsplice = 278, 294 NR_move_pages = 279, 295 NR_utimensat = 280, 296 NR_epoll_pwait = 281, 297 NR_signalfd = 282, 298 NR_timerfd_create = 283, 299 NR_eventfd = 284, 300 NR_fallocate = 285, 301 NR_timerfd_settime = 286, 302 NR_timerfd_gettime = 287, 303 NR_accept4 = 288, 304 NR_signalfd4 = 289, 305 NR_eventfd2 = 290, 306 NR_epoll_create1 = 291, 307 NR_dup3 = 292, 308 NR_pipe2 = 293, 309 NR_inotify_init1 = 294, 310 NR_preadv = 295, 311 NR_pwritev = 296, 312 NR_rt_tgsigqueueinfo = 297, 313 NR_perf_event_open = 298, 314 NR_recvmmsg = 299, 315 NR_fanotify_init = 300, 316 NR_fanotify_mark = 301, 317 NR_prlimit64 = 302, 318 NR_name_to_handle_at = 303, 319 NR_open_by_handle_at = 304, 320 NR_clock_adjtime = 305, 321 NR_syncfs = 306, 322 NR_sendmmsg = 307, 323 NR_setns = 308, 324 NR_getcpu = 309, 325 NR_process_vm_readv = 310, 326 NR_process_vm_writev = 311, 327 NR_kcmp = 312, 328 NR_finit_module = 313, 329 NR_sched_setattr = 314, 330 NR_sched_getattr = 315, 331 NR_renameat2 = 316, 332 NR_seccomp = 317, 333 } 334 335 extern(C) nothrow @system @nogc { 336 long syscall(int number, ...) nothrow; 337 338 @notrace 339 int syscall_int(ARGS...)(int number, auto ref ARGS args) nothrow { 340 return cast(int)syscall(number, args); 341 } 342 343 @notrace 344 int gettid() nothrow @trusted { 345 return syscall_int(Syscall.NR_gettid); 346 } 347 348 @notrace 349 int tgkill(int tgid, int tid, int sig) nothrow @trusted { 350 return syscall_int(Syscall.NR_tgkill, tgid, tid, sig); 351 } 352 } 353 354 unittest { 355 import core.thread: thread_isMainThread; 356 import core.sys.posix.unistd: getpid; 357 assert (thread_isMainThread()); 358 assert (gettid() == getpid()); 359 } 360 361 enum OSSignal: uint { 362 SIGNONE = 0, /// Invalid signal 363 SIGHUP = 1, /// Hangup (POSIX). 364 SIGINT = 2, /// Interrupt (ANSI). 365 SIGQUIT = 3, /// Quit (POSIX). 366 SIGILL = 4, /// Illegal instruction (ANSI). 367 SIGTRAP = 5, /// Trace trap (POSIX). 368 SIGABRT = 6, /// Abort (ANSI). 369 SIGBUS = 7, /// BUS error (4.2 BSD). 370 SIGFPE = 8, /// Floating-point exception (ANSI). 371 SIGKILL = 9, /// Kill, unblockable (POSIX). 372 SIGUSR1 = 10, /// User-defined signal 1 (POSIX). 373 SIGSEGV = 11, /// Segmentation violation (ANSI). 374 SIGUSR2 = 12, /// User-defined signal 2 (POSIX). 375 SIGPIPE = 13, /// Broken pipe (POSIX). 376 SIGALRM = 14, /// Alarm clock (POSIX). 377 SIGTERM = 15, /// Termination (ANSI). 378 SIGSTKFLT = 16, /// Stack fault. 379 SIGCHLD = 17, /// Child status has changed (POSIX). 380 SIGCONT = 18, /// Continue (POSIX). 381 SIGSTOP = 19, /// Stop, unblockable (POSIX). 382 SIGTSTP = 20, /// Keyboard stop (POSIX). 383 SIGTTIN = 21, /// Background read from tty (POSIX). 384 SIGTTOU = 22, /// Background write to tty (POSIX). 385 SIGURG = 23, /// Urgent condition on socket (4.2 BSD). 386 SIGXCPU = 24, /// CPU limit exceeded (4.2 BSD). 387 SIGXFSZ = 25, /// File size limit exceeded (4.2 BSD). 388 SIGVTALRM = 26, /// Virtual alarm clock (4.2 BSD). 389 SIGPROF = 27, /// Profiling alarm clock (4.2 BSD). 390 SIGWINCH = 28, /// Window size change (4.3 BSD, Sun). 391 SIGIO = 29, /// I/O now possible (4.2 BSD). 392 SIGPOLL = SIGIO, /// ditto 393 SIGPWR = 30, /// Power failure restart (System V). 394 SIGSYS = 31, /// Bad system call. 395 } 396 397 /* _NSIG: Biggest signal number + 1 (including real-time signals). */ 398 enum NUM_SIGS = 65; 399 400 public import core.sys.posix.signal: SIGRTMIN, SIGRTMAX; 401 402 unittest { 403 assert (SIGRTMIN > OSSignal.SIGSYS); 404 assert (SIGRTMAX < NUM_SIGS); 405 } 406 407 408 extern(C) nothrow /*@nogc*/ { 409 public alias CloneFunction = extern(C) int function(void*) nothrow /*@nogc*/; 410 public int clone(CloneFunction fn, void* child_stack, int flags, void* args); 411 public int unshare(int flags); 412 public int chroot(const char* dirname); 413 public enum { 414 CSIGNAL = 0x000000ff, // signal mask to be sent at exit 415 CLONE_VM = 0x00000100, // set if VM shared between processes 416 CLONE_FS = 0x00000200, // set if fs info shared between processes 417 CLONE_FILES = 0x00000400, // set if open files shared between processes 418 CLONE_SIGHAND = 0x00000800, // set if signal handlers and blocked signals shared 419 CLONE_PTRACE = 0x00002000, // set if we want to let tracing continue on the child too 420 CLONE_VFORK = 0x00004000, // set if the parent wants the child to wake it up on mm_release 421 CLONE_PARENT = 0x00008000, // set if we want to have the same parent as the cloner 422 CLONE_THREAD = 0x00010000, // Same thread group? 423 CLONE_NEWNS = 0x00020000, // New namespace group? 424 CLONE_SYSVSEM = 0x00040000, // share system V SEM_UNDO semantics 425 CLONE_SETTLS = 0x00080000, // create a new TLS for the child 426 CLONE_PARENT_SETTID = 0x00100000, // set the TID in the parent 427 CLONE_CHILD_CLEARTID = 0x00200000, // clear the TID in the child 428 CLONE_DETACHED = 0x00400000, // Unused, ignored 429 CLONE_UNTRACED = 0x00800000, // set if the tracing process can't force CLONE_PTRACE on this clone 430 CLONE_CHILD_SETTID = 0x01000000, // set the TID in the child 431 CLONE_NEWUTS = 0x04000000, // New utsname group? 432 CLONE_NEWIPC = 0x08000000, // New ipcs 433 CLONE_NEWUSER = 0x10000000, // New user namespace 434 CLONE_NEWPID = 0x20000000, // New pid namespace 435 CLONE_NEWNET = 0x40000000, // New network namespace 436 CLONE_IO = 0x80000000, // Clone io context 437 } 438 439 public int mount(in char* __special_file, in char* __dir, in char* __fstype, ulong __rwflag, in void* __data); 440 public int umount(in char* target); 441 public int umount2(in char* target, int flags); 442 public enum MountOptions { 443 MS_RDONLY = 1, // Mount read-only. 444 MS_NOSUID = 2, // Ignore suid and sgid bits. 445 MS_NODEV = 4, // Disallow access to device special files. 446 MS_NOEXEC = 8, // Disallow program execution. 447 MS_SYNCHRONOUS = 16, // Writes are synced at once. 448 MS_REMOUNT = 32, // Alter flags of a mounted FS. 449 MS_MANDLOCK = 64, // Allow mandatory locks on an FS. 450 MS_DIRSYNC = 128, // Directory modifications are synchronous. 451 MS_NOATIME = 1024, // Do not update access times. 452 MS_NODIRATIME = 2048, // Do not update directory access times. 453 MS_BIND = 4096, // Bind directory at different place. 454 MS_MOVE = 8192, 455 MS_REC = 16384, 456 MS_SILENT = 32768, 457 MS_POSIXACL = 1 << 16, // VFS does not apply the umask. 458 MS_UNBINDABLE = 1 << 17, // Change to unbindable. 459 MS_PRIVATE = 1 << 18, // Change to private. 460 MS_SLAVE = 1 << 19, // Change to slave. 461 MS_SHARED = 1 << 20, // Change to shared. 462 MS_RELATIME = 1 << 21, // Update atime relative to mtime/ctime. 463 MS_KERNMOUNT = 1 << 22, // This is a kern_mount call. 464 MS_I_VERSION = 1 << 23, // Update inode I_version field. 465 MS_STRICTATIME = 1 << 24, // Always perform atime updates. 466 MS_ACTIVE = 1 << 30, 467 MS_NOUSER = 1 << 31 468 } 469 public enum { 470 MNT_FORCE = 1, /* Force unmounting. */ 471 MNT_DETACH = 2, /* Just detach from the tree. */ 472 MNT_EXPIRE = 4, /* Mark for expiry. */ 473 UMOUNT_NOFOLLOW = 8 /* Don't follow symlink on umount. */ 474 }; 475 } 476 477 /** Intercept a library of a system call 478 * 479 * To use: define a function (typically, with `extern(C)` linkage) that performs the alternative implementation of 480 * the library call. Then expand the template mixin here, giving it your function as a template argument. 481 * 482 * The template mixin will define a function called `next_` $(I yourfunction) 483 * 484 * Example: 485 * --- 486 * extern(C) int socket(int domain, int type, int protocol) { 487 * import std.stdio; 488 * int ret = next_socket(domain, type, protocol); 489 * 490 * writefln("socket(%s, %s, %s) = %s", domain, type, protocol, ret); 491 * 492 * return ret; 493 * } 494 * 495 * mixin InterceptCall!socket; 496 * --- 497 */ 498 mixin template InterceptCall(alias F) { 499 private: 500 import core.sys.posix.dlfcn: dlsym; 501 import core.sys.linux.dlfcn: RTLD_NEXT; 502 import std..string: format; 503 import mecca.lib.reflection: funcAttrToString; 504 505 mixin(q{ 506 typeof(F)* next_%1$s = &stub_%1$s; 507 508 extern(%2$s) ReturnType!F stub_%1$s(Parameters!F args) %3$s { 509 if( next_%1$s is &stub_%1$s ) { 510 next_%1$s = cast(typeof(F)*)dlsym(RTLD_NEXT, "%1$s"); 511 } 512 513 return next_%1$s(args); 514 } 515 }.format(mangledName!F, functionLinkage!F, funcAttrToString(functionAttributes!F))); 516 } 517 518 enum SyscallTracePoint { 519 PRE_SYSCALL, 520 POST_SYSCALL, 521 } 522 523 mixin template hookSyscall(alias F, Syscall nr, alias traceFunc, SyscallTracePoint tracePoint=SyscallTracePoint.PRE_SYSCALL, string file = __FILE_FULL_PATH__, size_t line = __LINE__, string _module_ = __MODULE__) { 524 import std.traits: Parameters, ReturnType; 525 import mecca.platform.linux: syscall; 526 enum name = __traits(identifier, F); 527 mixin("extern(C) pragma(mangle, \"" ~ name ~ "\") @system ReturnType!F " ~ name ~ "(Parameters!F args) { 528 static if (tracePoint == SyscallTracePoint.PRE_SYSCALL) { 529 traceFunc(args); 530 } 531 auto res = cast(ReturnType!F)syscall(nr, args); 532 static if (tracePoint == SyscallTracePoint.POST_SYSCALL) { 533 traceFunc(res, args); 534 } 535 return res; 536 }" 537 ); 538 import std.traits: fullyQualifiedName; 539 enum hookFunctionScope = fullyQualifiedName!(__traits(parent, name)); 540 static assert(_module_ == hookFunctionScope, 541 "syscall hook should be mixed into the global scope of a module in order for the linker to find it (instantiated on " ~ file ~ "(" ~ line.to!string ~ ")"); 542 } 543 544 /+version (unittest) { 545 __gshared bool hitPreFunc = false; 546 547 static import core.sys.posix.unistd; 548 mixin hookSyscall!(core.sys.posix.unistd.close, Syscall.NR_close, (int fd){hitPreFunc = true;}); 549 550 unittest { 551 import std.stdio; 552 auto f = File("/tmp/test", "w"); 553 f.close(); 554 assert (hitPreFunc); 555 } 556 }+/ 557 558 public import core.sys.linux.sys.mman : MAP_POPULATE, MREMAP_MAYMOVE; 559 import core.sys.posix.sys.types : pid_t; 560 import std.traits : ReturnType; 561 562 package(mecca): 563 564 /** 565 * Represents the ID of a thread. 566 * 567 * This type is platform dependent. 568 */ 569 alias ThreadId = ReturnType!gettid; 570 571 /** 572 * Represents the ID of a thread. 573 * 574 * This type is platform dependent. 575 */ 576 ThreadId currentThreadId() nothrow @system @nogc 577 { 578 return gettid(); 579 } 580 581 __gshared static immutable BLOCKED_SIGNALS = [ 582 OSSignal.SIGHUP, OSSignal.SIGINT, OSSignal.SIGQUIT, 583 //OSSignal.SIGILL, OSSignal.SIGTRAP, OSSignal.SIGABRT, 584 //OSSignal.SIGBUS, OSSignal.SIGFPE, OSSignal.SIGKILL, 585 //OSSignal.SIGUSR1, OSSignal.SIGSEGV, OSSignal.SIGUSR2, 586 OSSignal.SIGPIPE, OSSignal.SIGALRM, OSSignal.SIGTERM, 587 //OSSignal.SIGSTKFLT, OSSignal.SIGCONT, OSSignal.SIGSTOP, 588 OSSignal.SIGCHLD, OSSignal.SIGTSTP, OSSignal.SIGTTIN, 589 OSSignal.SIGTTOU, OSSignal.SIGURG, OSSignal.SIGXCPU, 590 OSSignal.SIGXFSZ, OSSignal.SIGVTALRM, OSSignal.SIGPROF, 591 OSSignal.SIGWINCH, OSSignal.SIGIO, OSSignal.SIGPWR, 592 //OSSignal.SIGSYS, 593 ]; 594 595 static if( __traits(compiles, O_CLOEXEC) ) { 596 enum O_CLOEXEC = core.sys.posix.fcntl.O_CLOEXEC; 597 } else { 598 enum O_CLOEXEC = 0x80000; 599 } 600 601 import fcntl = core.sys.posix.fcntl; 602 static if( __traits(compiles, fcntl.F_DUPFD_CLOEXEC) ) { 603 enum F_DUPFD_CLOEXEC = fcntl.F_DUPFD_CLOEXEC; 604 } else { 605 version(linux) { 606 enum F_DUPFD_CLOEXEC = 1030; 607 } 608 } 609 610 public import core.stdc.errno : EREMOTEIO; 611 public import core.sys.posix.sys.time : ITIMER_REAL; 612 613 import mecca.platform.os : MmapArguments; 614 615 // A wrapper that is compatible with the signature used for Darwin 616 void* mremap(Args...)(MmapArguments, void* oldAddress, 617 size_t oldSize, size_t newSize, int flags, Args args) 618 { 619 import core.sys.linux.sys.mman: mremap; 620 return mremap(oldAddress, oldSize, newSize, flags, args); 621 }