minor fixes for safecopy & safemap tests
[minix.git] / lib / libhgfs / file.c
blob12f21c692798bbdc1316917b9d9465a6a63e143d
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 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 sffs_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 = (sffs_file_t)RPC_NEXT32;
47 return OK;
50 /*===========================================================================*
51 * hgfs_read *
52 *===========================================================================*/
53 ssize_t hgfs_read(handle, buf, size, off)
54 sffs_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 not operating directly on the RPC buffer. */
78 if (buf != RPC_PTR)
79 memcpy(buf, RPC_PTR, len);
81 return len;
84 /*===========================================================================*
85 * hgfs_write *
86 *===========================================================================*/
87 ssize_t hgfs_write(handle, buf, len, off)
88 sffs_file_t handle; /* handle to open file */
89 char *buf; /* data buffer or NULL */
90 size_t len; /* number of bytes to write */
91 u64_t off; /* file offset */
93 /* Write to an open file. Upon success, return the number of bytes written.
95 int r;
97 RPC_REQUEST(HGFS_REQ_WRITE);
98 RPC_NEXT32 = (u32_t)handle;
99 RPC_NEXT8 = 0; /* append flag */
100 RPC_NEXT32 = ex64lo(off);
101 RPC_NEXT32 = ex64hi(off);
102 RPC_NEXT32 = len;
104 /* Only copy in data if we're not operating directly on the RPC buffer. */
105 if (RPC_PTR != buf)
106 memcpy(RPC_PTR, buf, len);
107 RPC_ADVANCE(len);
109 if ((r = rpc_query()) != OK)
110 return r;
112 return RPC_NEXT32;
115 /*===========================================================================*
116 * hgfs_close *
117 *===========================================================================*/
118 int hgfs_close(handle)
119 sffs_file_t handle; /* handle to open file */
121 /* Close an open file.
124 RPC_REQUEST(HGFS_REQ_CLOSE);
125 RPC_NEXT32 = (u32_t)handle;
127 return rpc_query();
130 /*===========================================================================*
131 * hgfs_readbuf *
132 *===========================================================================*/
133 size_t hgfs_readbuf(ptr)
134 char **ptr;
136 /* Return information about the read buffer, for zero-copy purposes. Store a
137 * pointer to the first byte of the read buffer, and return the maximum data
138 * size. The results are static, but must only be used directly prior to a
139 * hgfs_read() call (with a NULL data buffer address).
141 u32_t off;
143 off = RPC_HDR_SIZE + sizeof(u32_t);
145 RPC_RESET;
146 RPC_ADVANCE(off);
147 *ptr = RPC_PTR;
149 return RPC_BUF_SIZE - off;
152 /*===========================================================================*
153 * hgfs_writebuf *
154 *===========================================================================*/
155 size_t hgfs_writebuf(ptr)
156 char **ptr;
158 /* Return information about the write buffer, for zero-copy purposes. Store a
159 * pointer to the first byte of the write buffer, and return the maximum data
160 * size. The results are static, but must only be used immediately after a
161 * hgfs_write() call (with a NULL data buffer address).
163 u32_t off;
165 off = RPC_HDR_SIZE + sizeof(u32_t) + sizeof(u8_t) + sizeof(u32_t) * 3;
167 RPC_RESET;
168 RPC_ADVANCE(off);
169 *ptr = RPC_PTR;
171 return RPC_BUF_SIZE - off;