fix from trunk for assert(ptproc == newptproc) without vm_stop on shutdown.
[minix.git] / lib / libhgfs / file.c
blob24bdbd1571d32146aceca836dab281f07de9f67a
1 /* Part of libhgfs - (c) 2009, D.C. van Moolenbroek */
3 #include "inc.h"
5 #include <fcntl.h>
6 #include <sys/stat.h>
8 /*===========================================================================*
9 * hgfs_open *
10 *===========================================================================*/
11 PUBLIC int hgfs_open(path, flags, mode, handle)
12 char *path; /* path name to open */
13 int flags; /* open flags to use */
14 int mode; /* mode to create (user bits only) */
15 hgfs_file_t *handle; /* place to store resulting handle */
17 /* Open a file. Store a file handle upon success.
19 int r, type;
21 /* We could implement this, but that means we would have to start tracking
22 * open files in order to associate data with them. Rather not.
24 if (flags & O_APPEND) return EINVAL;
26 if (flags & O_CREAT) {
27 if (flags & O_EXCL) type = HGFS_OPEN_TYPE_C;
28 else if (flags & O_TRUNC) type = HGFS_OPEN_TYPE_COT;
29 else type = HGFS_OPEN_TYPE_CO;
30 } else {
31 if (flags & O_TRUNC) type = HGFS_OPEN_TYPE_OT;
32 else type = HGFS_OPEN_TYPE_O;
35 RPC_REQUEST(HGFS_REQ_OPEN);
36 RPC_NEXT32 = (flags & O_ACCMODE);
37 RPC_NEXT32 = type;
38 RPC_NEXT8 = HGFS_MODE_TO_PERM(mode);
40 path_put(path);
42 if ((r = rpc_query()) != OK)
43 return r;
45 *handle = (hgfs_file_t)RPC_NEXT32;
47 return OK;
50 /*===========================================================================*
51 * hgfs_read *
52 *===========================================================================*/
53 PUBLIC int hgfs_read(handle, buf, size, off)
54 hgfs_file_t handle; /* handle to open file */
55 char *buf; /* data buffer or NULL */
56 size_t size; /* maximum number of bytes to read */
57 u64_t off; /* file offset */
59 /* Read from an open file. Upon success, return the number of bytes read.
61 int r, len, max;
63 RPC_REQUEST(HGFS_REQ_READ);
64 RPC_NEXT32 = (u32_t)handle;
65 RPC_NEXT32 = ex64lo(off);
66 RPC_NEXT32 = ex64hi(off);
68 max = RPC_BUF_SIZE - RPC_LEN - sizeof(u32_t);
69 RPC_NEXT32 = (size < max) ? size : max;
71 if ((r = rpc_query()) != OK)
72 return r;
74 len = RPC_NEXT32;
75 if (len > max) len = max; /* sanity check */
77 /* Only copy out data if we're requested to do so. */
78 if (buf != NULL)
79 memcpy(buf, RPC_PTR, len);
81 return len;
84 /*===========================================================================*
85 * hgfs_write *
86 *===========================================================================*/
87 PUBLIC int hgfs_write(handle, buf, len, off, append)
88 hgfs_file_t handle; /* handle to open file */
89 const char *buf; /* data buffer or NULL */
90 size_t len; /* number of bytes to write */
91 u64_t off; /* file offset */
92 int append; /* if set, append to file (ignore offset) */
94 /* Write to an open file. Upon success, return the number of bytes written.
96 int r;
98 RPC_REQUEST(HGFS_REQ_WRITE);
99 RPC_NEXT32 = (u32_t)handle;
101 if (append) {
102 RPC_NEXT8 = 1;
103 RPC_NEXT32 = 0;
104 RPC_NEXT32 = 0;
106 else {
107 RPC_NEXT8 = 0;
108 RPC_NEXT32 = ex64lo(off);
109 RPC_NEXT32 = ex64hi(off);
112 RPC_NEXT32 = len;
114 /* Only copy in data if we're requested to do so. */
115 if (buf != NULL)
116 memcpy(RPC_PTR, buf, len);
117 RPC_ADVANCE(len);
119 if ((r = rpc_query()) != OK)
120 return r;
122 return RPC_NEXT32;
125 /*===========================================================================*
126 * hgfs_close *
127 *===========================================================================*/
128 PUBLIC int hgfs_close(handle)
129 hgfs_file_t handle; /* handle to open file */
131 /* Close an open file.
134 RPC_REQUEST(HGFS_REQ_CLOSE);
135 RPC_NEXT32 = (u32_t)handle;
137 return rpc_query();
140 /*===========================================================================*
141 * hgfs_readbuf *
142 *===========================================================================*/
143 PUBLIC size_t hgfs_readbuf(ptr)
144 char **ptr;
146 /* Return information about the read buffer, for zero-copy purposes. Store a
147 * pointer to the first byte of the read buffer, and return the maximum data
148 * size. The results are static, but must only be used directly prior to a
149 * hgfs_read() call (with a NULL data buffer address).
151 u32_t off;
153 off = RPC_HDR_SIZE + sizeof(u32_t);
155 RPC_RESET;
156 RPC_ADVANCE(off);
157 *ptr = RPC_PTR;
159 return RPC_BUF_SIZE - off;
162 /*===========================================================================*
163 * hgfs_writebuf *
164 *===========================================================================*/
165 PUBLIC size_t hgfs_writebuf(ptr)
166 char **ptr;
168 /* Return information about the write buffer, for zero-copy purposes. Store a
169 * pointer to the first byte of the write buffer, and return the maximum data
170 * size. The results are static, but must only be used immediately after a
171 * hgfs_write() call (with a NULL data buffer address).
173 u32_t off;
175 off = RPC_HDR_SIZE + sizeof(u32_t) + sizeof(u8_t) + sizeof(u32_t) * 3;
177 RPC_RESET;
178 RPC_ADVANCE(off);
179 *ptr = RPC_PTR;
181 return RPC_BUF_SIZE - off;