1 module more.os.posix.core;
2 
3 import more.types : passfail;
4 import more.c : cint;
5 
6 /**
7 Common return value for os functions.
8 */
9 struct SysResult
10 {
11     private cint value;
12     @property bool failed() const { return value != 0; }
13     @property bool passed() const { return value == 0; }
14 }
15 
16 /**
17 The generic type that represents a system error code as returned
18 by the `lastError` function.
19 */
20 alias SysErrorCode = cint;
21 SysErrorCode lastError()
22 {
23     import core.stdc.errno : errno;
24     return errno;
25 }
26 
27 
28 /**
29 Represents a file handle
30 */
31 struct FileHandle
32 {
33     @property static FileHandle invalidValue()
34     {
35         return FileHandle(-1);
36     }
37     private cint _value;
38     @property bool isInvalid() const
39     {
40         return _value < 0;
41     }
42     @property auto val() const { return cast(cint)_value; }
43 }
44 
45 alias sysresult_t = cint;
46 pragma(inline)
47 @property bool failed(sysresult_t result)
48 {
49     return result != 0;
50 }
51 pragma(inline)
52 @property bool success(sysresult_t result)
53 {
54     return result == 0;
55 }
56 
57 extern(C) nothrow @nogc
58 {
59     cint fcntl(FileHandle file, cint command, ...);
60     // TODO: probably split this into seperate function depending
61     //       on the command, like this one
62     import core.sys.posix.fcntl :
63         F_DUPFD,
64         F_GETFL,
65         F_SETFL;
66     public import core.sys.posix.fcntl :
67         O_NONBLOCK;
68     pragma(inline)
69     FileHandle fcntlDupFD(FileHandle file)
70     {
71         return cast(FileHandle)fcntl(file, F_DUPFD);
72     }
73     struct FDFlags
74     {
75         cint flags;
76         @property bool isInvalid() const pure @nogc { return flags == -1; }
77         FDFlags opBinary(string op)(cint right)
78         {
79             mixin("return FDFlags(flags " ~ op ~ " right);");
80         }
81         FDFlags opBinaryRight(string op)(cint left)
82         {
83             mixin("return FDFlags(left " ~ op ~ " flags);");
84         }
85     }
86     FDFlags fcntlGetFlags(FileHandle file)
87     {
88         return cast(FDFlags)fcntl(file, F_GETFL);
89     }
90     passfail fcntlSetFlags(FileHandle file, FDFlags flags)
91         in { assert(!flags.isInvalid); } do
92     {
93         return (-1 == fcntl(file, F_SETFL, flags)) ? passfail.fail : passfail.pass;
94     }
95     sysresult_t close(FileHandle);
96 }
97