1 module runtime.system.posix.posix_; 2 3 ushort octal(int octal) nothrow @nogc 4 { 5 ushort result; 6 7 result += octal % 10; 8 octal /= 10; 9 result += 8 * (octal % 10); 10 octal /= 10; 11 result += (8 * 8) * (octal % 10); 12 octal /= 10; 13 result += (8 * 8 * 8) * (octal % 10); 14 octal /= 10; 15 result += (8 * 8 * 8 * 8) * (octal % 10); 16 octal /= 10; 17 result += (8 * 8 * 8 * 8 * 8) * (octal % 10); 18 octal /= 10; 19 result += (8 * 8 * 8 * 8 * 8 * 8) * (octal % 10); 20 octal /= 10; 21 result += (8 * 8 * 8 *8 * 8 * 8 * 8) * (octal % 10); 22 octal /= 10; 23 24 assert(octal == 0); 25 26 return result; 27 } 28 @("octal") 29 unittest 30 { 31 assert(octal(666) == 0x1B6); 32 } 33 34 version(Posix) extern(C) nothrow @nogc: 35 36 enum 37 { 38 PROT_NONE = 0, 39 PROT_READ = 1, 40 PROT_WRITE = 2, 41 PROT_EXEC = 4, 42 } 43 44 enum 45 { 46 MAP_FILE = 0, 47 MAP_SHARED = 1, 48 MAP_PRIVATE = 2, 49 MAP_TYPE = 0xF, 50 MAP_FIXED = 0x10, 51 MAP_ANONYMOUS = 0x20, 52 MAP_32BIT = 0x40, 53 MAP_GROWSDOWN = 0x00100, 54 MAP_DENYWRITE = 0x00800, 55 MAP_EXECUTABLE = 0x01000, 56 MAP_LOCKED = 0x02000, 57 MAP_NORESERVE = 0x04000, 58 MAP_POPULATE = 0x08000, 59 MAP_NONBLOCK = 0x10000, 60 MAP_STACK = 0x20000, 61 } 62 enum MAP_FAILED = cast(void*)-1; 63 64 enum 65 { 66 O_RDONLY = 0, 67 O_WRONLY = 1, 68 O_RDWR = 2, 69 O_CREAT = 100.octal, 70 O_EXCL = 200.octal, 71 O_NOCTTY = 400.octal, 72 O_TRUNC = 1000.octal, 73 O_APPEND = 2000.octal, 74 O_NONBLOCK = 4000.octal, 75 O_NDELAY = O_NONBLOCK, 76 O_SYNC = 4010000.octal, 77 O_FSYNC = O_SYNC, 78 O_ASYNC = 20000.octal, 79 O_LARGEFILE = 100000.octal, 80 O_DIRECTORY = 200000.octal, 81 O_NOFOLLOW = 400000.octal, 82 O_CLOEXEC = 2000000.octal, 83 O_DIRECT = 40000.octal, 84 O_NOATIME = 1000000.octal, 85 O_PATH = 10000000.octal, 86 O_DSYNC = 10000.octal, 87 O_TMPFILE = (20000000.octal | O_DIRECTORY), 88 } 89 90 enum 91 { 92 93 EPERM = 1, /* Operation not permitted */ 94 ENOENT = 2, /* No such file or directory */ 95 ESRCH = 3, /* No such process */ 96 EINTR = 4, /* Interrupted system call */ 97 EIO = 5, /* Input/output error */ 98 ENXIO = 6, /* Device not configured */ 99 E2BIG = 7, /* Argument list too long */ 100 ENOEXEC = 8, /* Exec format error */ 101 EBADF = 9, /* Bad file descriptor */ 102 ECHILD = 10, /* No child processes */ 103 EDEADLK = 11, /* Resource deadlock avoided */ 104 ENOMEM = 12, /* Cannot allocate memory */ 105 EACCES = 13, /* Permission denied */ 106 EFAULT = 14, /* Bad address */ 107 ENOTBLK = 15, /* Block device required */ 108 EBUSY = 16, /* Device busy */ 109 EEXIST = 17, /* File exists */ 110 EXDEV = 18, /* Cross-device link */ 111 ENODEV = 19, /* Operation not supported by device */ 112 ENOTDIR = 20, /* Not a directory */ 113 EISDIR = 21, /* Is a directory */ 114 EINVAL = 22, /* Invalid argument */ 115 ENFILE = 23, /* Too many open files in system */ 116 EMFILE = 24, /* Too many open files */ 117 ENOTTY = 25, /* Inappropriate ioctl for device */ 118 ETXTBSY = 26, /* Text file busy */ 119 EFBIG = 27, /* File too large */ 120 ENOSPC = 28, /* No space left on device */ 121 ESPIPE = 29, /* Illegal seek */ 122 EROFS = 30, /* Read-only file system */ 123 EMLINK = 31, /* Too many links */ 124 EPIPE = 32, /* Broken pipe */ 125 EDOM = 33, /* Numerical argument out of domain */ 126 ERANGE = 34, /* Result too large */ 127 EAGAIN = 35, /* Resource temporarily unavailable */ 128 EWOULDBLOCK = EAGAIN, /* Operation would block */ 129 EINPROGRESS = 36, /* Operation now in progress */ 130 EALREADY = 37, /* Operation already in progress */ 131 ENOTSOCK = 38, /* Socket operation on non-socket */ 132 EDESTADDRREQ = 39, /* Destination address required */ 133 EMSGSIZE = 40, /* Message too long */ 134 EPROTOTYPE = 41, /* Protocol wrong type for socket */ 135 ENOPROTOOPT = 42, /* Protocol not available */ 136 EPROTONOSUPPORT = 43, /* Protocol not supported */ 137 ESOCKTNOSUPPORT = 44, /* Socket type not supported */ 138 EOPNOTSUPP = 45, /* Operation not supported on socket */ 139 EPFNOSUPPORT = 46, /* Protocol family not supported */ 140 EAFNOSUPPORT = 47, /* Address family not supported by protocol family */ 141 EADDRINUSE = 48, /* Address already in use */ 142 EADDRNOTAVAIL = 49, /* Can't assign requested address */ 143 ENETDOWN = 50, /* Network is down */ 144 ENETUNREACH = 51, /* Network is unreachable */ 145 ENETRESET = 52, /* Network dropped connection on reset */ 146 ECONNABORTED = 53, /* Software caused connection abort */ 147 ECONNRESET = 54, /* Connection reset by peer */ 148 ENOBUFS = 55, /* No buffer space available */ 149 EISCONN = 56, /* Socket is already connected */ 150 ENOTCONN = 57, /* Socket is not connected */ 151 ESHUTDOWN = 58, /* Can't send after socket shutdown */ 152 ETOOMANYREFS = 59, /* Too many references: can't splice */ 153 ETIMEDOUT = 60, /* Connection timed out */ 154 ECONNREFUSED = 61, /* Connection refused */ 155 ELOOP = 62, /* Too many levels of symbolic links */ 156 ENAMETOOLONG = 63, /* File name too long */ 157 EHOSTDOWN = 64, /* Host is down */ 158 EHOSTUNREACH = 65, /* No route to host */ 159 ENOTEMPTY = 66, /* Directory not empty */ 160 EPROCLIM = 67, /* Too many processes */ 161 EUSERS = 68, /* Too many users */ 162 EDQUOT = 69, /* Disc quota exceeded */ 163 ESTALE = 70, /* Stale NFS file handle */ 164 EREMOTE = 71, /* Too many levels of remote in path */ 165 EBADRPC = 72, /* RPC struct is bad */ 166 ERPCMISMATCH = 73, /* RPC version wrong */ 167 EPROGUNAVAIL = 74, /* RPC prog. not avail */ 168 EPROGMISMATCH = 75, /* Program version wrong */ 169 EPROCUNAVAIL = 76, /* Bad procedure for program */ 170 ENOLCK = 77, /* No locks available */ 171 ENOSYS = 78, /* Function not implemented */ 172 EFTYPE = 79, /* Inappropriate file type or format */ 173 } 174 175 enum 176 { 177 SEEK_SET = 0, 178 SEEK_CUR = 1, 179 SEEK_END = 2, 180 } 181 182 enum 183 { 184 F_OK = 0 185 } 186 187 alias umode_t = ushort; 188 alias ssize_t = long; 189 alias uint dev_t; 190 alias ulong ino_t; 191 alias uint mode_t; 192 alias int pid_t; 193 alias uint uid_t; 194 alias uint gid_t; 195 alias ulong nlink_t; 196 alias long off_t; 197 alias long blksize_t; 198 alias long blkcnt_t; 199 alias long time_t; 200 201 __gshared int g_errno; 202 203 struct timespec { 204 time_t tv_sec; /* seconds */ 205 long tv_nsec; /* nanoseconds */ 206 }; 207 208 struct stat { 209 dev_t st_dev; /* ID of device containing file */ 210 ino_t st_ino; /* Inode number */ 211 mode_t st_mode; /* File type and mode */ 212 nlink_t st_nlink; /* Number of hard links */ 213 uid_t st_uid; /* User ID of owner */ 214 gid_t st_gid; /* Group ID of owner */ 215 dev_t st_rdev; /* Device ID (if special file) */ 216 off_t st_size; /* Total size, in bytes */ 217 blksize_t st_blksize; /* Block size for filesystem I/O */ 218 blkcnt_t st_blocks; /* Number of 512B blocks allocated */ 219 220 /* Since Linux 2.6, the kernel supports nanosecond 221 precision for the following timestamp fields. 222 For the details before Linux 2.6, see NOTES. */ 223 224 timespec st_atim; /* Time of last access */ 225 timespec st_mtim; /* Time of last modification */ 226 timespec st_ctim; /* Time of last status change */ 227 }; 228 229 private immutable setErrnoReturn = q{ 230 asm @nogc nothrow { 231 jnc RETURN; 232 neg RAX; 233 lea RCX, g_errno; 234 mov [RCX], RAX; 235 neg RAX; 236 RETURN: ret; 237 } 238 }; 239 240 void* mmap( 241 void* addr, 242 ulong len, 243 int prot = PROT_READ | PROT_WRITE, 244 int flags = MAP_PRIVATE | MAP_ANONYMOUS, 245 int fd = -1, 246 int off = 0 247 ) 248 { 249 asm @nogc nothrow 250 { 251 naked; 252 mov R10, RCX; 253 mov RAX, 9; 254 syscall; 255 } 256 mixin(setErrnoReturn); 257 } 258 259 int munmap(void* addr, ulong len) 260 { 261 asm @nogc nothrow 262 { 263 naked; 264 mov RAX, 11; 265 syscall; 266 } 267 mixin(setErrnoReturn); 268 } 269 270 int open(const char* filename, int flags, umode_t mode) 271 { 272 asm @nogc nothrow 273 { 274 naked; 275 mov RAX, 2; 276 syscall; 277 } 278 mixin(setErrnoReturn); 279 } 280 281 int close(uint fd) 282 { 283 asm @nogc nothrow 284 { 285 naked; 286 mov RAX, 3; 287 syscall; 288 } 289 mixin(setErrnoReturn); 290 } 291 292 ssize_t read(int fd, void* buf, size_t count) 293 { 294 asm @nogc nothrow 295 { 296 naked; 297 mov RAX, 0; 298 syscall; 299 } 300 mixin(setErrnoReturn); 301 } 302 303 ssize_t write(int fd, const void* buf, size_t count) 304 { 305 asm @nogc nothrow 306 { 307 naked; 308 mov RAX, 1; 309 syscall; 310 } 311 mixin(setErrnoReturn); 312 } 313 314 int fstat(int fd, stat* statbuf) 315 { 316 asm @nogc nothrow 317 { 318 naked; 319 mov RAX, 5; 320 syscall; 321 } 322 mixin(setErrnoReturn); 323 } 324 325 off_t lseek(int fd, off_t offset, int whence) 326 { 327 asm @nogc nothrow 328 { 329 naked; 330 mov RAX, 8; 331 syscall; 332 } 333 mixin(setErrnoReturn); 334 } 335 336 int access(const char* filename, int mode) 337 { 338 asm @nogc nothrow 339 { 340 naked; 341 mov RAX, 21; 342 syscall; 343 } 344 mixin(setErrnoReturn); 345 } 346 347 int unlink(const char* filename) 348 { 349 asm @nogc nothrow 350 { 351 naked; 352 mov RAX, 87; 353 syscall; 354 } 355 mixin(setErrnoReturn); 356 } 357 358 int rmdir(const char* filename) 359 { 360 asm @nogc nothrow 361 { 362 naked; 363 mov RAX, 84; 364 syscall; 365 } 366 mixin(setErrnoReturn); 367 }