1 # SYS/FD.D - File descriptor / File System support
6 # The Fs class handles most basic filesystem calls that manipulate
7 # file paths or descriptors. A descriptor can be set in Fs.fd to enable
8 # descriptor-based system calls such as read(). Errors are typically
9 # returned (not always), and will always be recorded in the error field.
11 # The API explicitly allows the programmer to pull out descriptors and
12 # replicate Fs objects in order to e.g. separately track error conditions.
14 # All calls which create a new descriptor automatically set the descriptor
15 # O_CLOEXEC. We do not expose OS-specific descriptor operations with flags
16 # for the same, on purpose. e.g. open(), pipe(), socketpair(), dup(),
17 # dup2() all automatically set O_CLOEXEC. The caller should use the
18 # setcloexec(TRUE/FALSE) call to change it. All systems this language runs
19 # on are required to implement appropriate system calls to allow this.
21 # File descriptors can be passed around discretely without using the
22 # Fs class, as evidenced by some of the other structures in this module.
23 # Fs objects are needed as a container for method calls and error codes.
25 # Note that there is no auto-close destructor for this class. Fs is
26 # meant to be used this way. The programmer is responsible for
27 # closing file descriptors, or for embedding Fs into a larger class
28 # (such as our File or Stream class) which DOES close the underlying
31 # read - read the full request or until EOF.
32 # read1 - read at least 1 byte plus whatever else is available.
33 # readn - non-blocking read can return on EINTR or EAGAIN.
34 # write - write the full request or until an error.
35 # write1- write at least 1 byte plus whatever else it can.
36 # writen- non-blocking write can return on EINTR or EAGAIN.
37 # importdesc - adjust imported descriptor for rune operation
40 public int fd = -1; # field must match libruntime
41 public int error; # field must match libruntime
45 # NOTE: These functions always set error, so if an operation has
46 # no error, the error field will be set to 0.
48 public internal method size_t read(void *buf, size_t bytes,
50 public internal method size_t read1(void *buf, size_t bytes,
52 public internal method size_t readn(void *buf, size_t bytes,
54 public internal method size_t write(void *buf, size_t bytes,
56 public internal method size_t write1(void *buf, size_t bytes,
58 public internal method size_t writen(void *buf, size_t bytes,
60 public internal method int open(const char *path, int flags,
62 public internal method int close();
66 # dup dups sfd and sets object->fd to the result. Result is
67 # automatically O_CLOEXEC.
69 # dup2 dups sfd and sets object->fd to the result, using dfd.
70 # Result is automatically O_CLOEXEC.
72 public internal method int flock(int op);
73 public internal method int dup(int sfd);
74 public internal method int dup2(int sfd, int dfd);
75 public internal mode_t umask(mode_t mode);
76 public internal method off_t lseek(off_t off, int how);
77 public internal method int setcloexec(bool enable);
78 public internal method int setappend(bool enable);
79 public internal method int setnonblock(bool enable);
80 public internal method int setdirect(bool enable);
81 public internal method void importdesc();
82 public internal method void iowait_rd();
83 public internal method void iowait_wr();
87 # These path based methods do not need an operational descriptor
88 # but are still method calls for error setting.
90 # (if I decide to add the 'at*' calls, those will).
92 public internal method int symlink(const char *buf, const char *nfile);
93 public internal method int link(const char *ofile, const char *nfile);
94 public internal method int readlink(const char *target, char *buf);
95 public internal method int unlink(const char *target);
99 # pipe creates a one-way pipe with a read descriptor and a write
100 # descriptor. The descriptors are O_CLOEXEC on return.
102 # socketpair creates a full-duplex socket (or pipe). The descriptors
103 # are O_CLOEXEC on return.
105 public internal int pipe(lvalue Fs fdr, lvalue Fs fdw);
106 public internal int socketpair(int d, int type, int proto,
107 lvalue Fs fdr, lvalue Fs fdw);
120 # The FdLock class manages fcntl-based locking operations. Fields
121 # basically work the same as you'd expect in C. The structure is
122 # not field-for-field compatible (the rune pid_t might be a different size),
123 # but the system interface will translate.
125 # This class has an auto-unlock destructor.
127 public class FdLock {
128 off_t start; # all fields must match libruntime
132 int whence = SEEK_SET;
136 public internal method int fgetlk();
137 public internal method int fsetlk();
138 public internal method int fsetlkw();
141 public destructor method
145 if (this.active && this.type != F_UNLCK) {
154 # The FdMap class manages memory maps. Note that this class has an
155 # auto-unmap destructor.
157 # NOTE: You may assign the base pointer to any structural pointer you
158 # desire as long as the structure contains no lvalues, pointers, or
159 # references, and the target structure is an integral multiple of
160 # the number of bytes mapped.
163 public constant char *base; # all fields must match libruntime
164 public constant size_t bytes;
168 public internal method int mmap(size_t bytes, int prot, int flags,
169 int fd = -1, off_t offset = 0);
170 public internal method int munmap();
171 public internal method int mprotect(int prot, size_t off = 0,
172 size_t bytes = this.bytes);
173 public internal method int madvise(int behav, size_t off = 0,
174 size_t bytes = this.bytes);
175 public internal method int msync(size_t off = 0,
176 size_t bytes = this.bytes,
177 int flags = MS_ASYNC);
180 public destructor method