xref: /minix/minix/lib/libhgfs/file.c (revision 0a6a1f1d)
1 /* Part of libhgfs - (c) 2009, D.C. van Moolenbroek */
2 
3 #include "inc.h"
4 
5 #include <fcntl.h>
6 #include <sys/stat.h>
7 
8 /*===========================================================================*
9  *				hgfs_open				     *
10  *===========================================================================*/
11 int hgfs_open(
12 	const 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 */
16 )
17 {
18 /* Open a file. Store a file handle upon success.
19  */
20   int r, type;
21 
22   /* We could implement this, but that means we would have to start tracking
23    * open files in order to associate data with them. Rather not.
24    */
25   if (flags & O_APPEND) return EINVAL;
26 
27   if (flags & O_CREAT) {
28     if (flags & O_EXCL) type = HGFS_OPEN_TYPE_C;
29     else if (flags & O_TRUNC) type = HGFS_OPEN_TYPE_COT;
30     else type = HGFS_OPEN_TYPE_CO;
31   } else {
32     if (flags & O_TRUNC) type = HGFS_OPEN_TYPE_OT;
33     else type = HGFS_OPEN_TYPE_O;
34   }
35 
36   RPC_REQUEST(HGFS_REQ_OPEN);
37   RPC_NEXT32 = (flags & O_ACCMODE);
38   RPC_NEXT32 = type;
39   RPC_NEXT8 = HGFS_MODE_TO_PERM(mode);
40 
41   path_put(path);
42 
43   if ((r = rpc_query()) != OK)
44 	return r;
45 
46   *handle = (sffs_file_t)RPC_NEXT32;
47 
48   return OK;
49 }
50 
51 /*===========================================================================*
52  *				hgfs_read				     *
53  *===========================================================================*/
54 ssize_t hgfs_read(
55 	sffs_file_t handle,	/* handle to open file */
56 	char *buf,         	/* data buffer or NULL */
57 	size_t size,       	/* maximum number of bytes to read */
58 	u64_t off          	/* file offset */
59 )
60 {
61 /* Read from an open file. Upon success, return the number of bytes read.
62  */
63   size_t len, max;
64   int r;
65 
66   RPC_REQUEST(HGFS_REQ_READ);
67   RPC_NEXT32 = (u32_t)handle;
68   RPC_NEXT32 = ex64lo(off);
69   RPC_NEXT32 = ex64hi(off);
70 
71   max = RPC_BUF_SIZE - RPC_LEN - sizeof(u32_t);
72   RPC_NEXT32 = (size < max) ? size : max;
73 
74   if ((r = rpc_query()) != OK)
75 	return r;
76 
77   len = RPC_NEXT32;
78   if (len > max) len = max; /* sanity check */
79 
80   /* Only copy out data if we're not operating directly on the RPC buffer. */
81   if (buf != RPC_PTR)
82 	memcpy(buf, RPC_PTR, len);
83 
84   return len;
85 }
86 
87 /*===========================================================================*
88  *				hgfs_write				     *
89  *===========================================================================*/
90 ssize_t hgfs_write(
91 	sffs_file_t handle,	/* handle to open file */
92 	char *buf,         	/* data buffer or NULL */
93 	size_t len,        	/* number of bytes to write */
94 	u64_t off          	/* file offset */
95 )
96 {
97 /* Write to an open file. Upon success, return the number of bytes written.
98  */
99   int r;
100 
101   RPC_REQUEST(HGFS_REQ_WRITE);
102   RPC_NEXT32 = (u32_t)handle;
103   RPC_NEXT8 = 0;		/* append flag */
104   RPC_NEXT32 = ex64lo(off);
105   RPC_NEXT32 = ex64hi(off);
106   RPC_NEXT32 = len;
107 
108   /* Only copy in data if we're not operating directly on the RPC buffer. */
109   if (RPC_PTR != buf)
110 	memcpy(RPC_PTR, buf, len);
111   RPC_ADVANCE(len);
112 
113   if ((r = rpc_query()) != OK)
114 	return r;
115 
116   return RPC_NEXT32;
117 }
118 
119 /*===========================================================================*
120  *				hgfs_close				     *
121  *===========================================================================*/
122 int hgfs_close(
123 	sffs_file_t handle		/* handle to open file */
124 )
125 {
126 /* Close an open file.
127  */
128 
129   RPC_REQUEST(HGFS_REQ_CLOSE);
130   RPC_NEXT32 = (u32_t)handle;
131 
132   return rpc_query();
133 }
134 
135 /*===========================================================================*
136  *				hgfs_readbuf				     *
137  *===========================================================================*/
138 size_t hgfs_readbuf(char **ptr)
139 {
140 /* Return information about the read buffer, for zero-copy purposes. Store a
141  * pointer to the first byte of the read buffer, and return the maximum data
142  * size. The results are static, but must only be used directly prior to a
143  * hgfs_read() call (with a NULL data buffer address).
144  */
145   u32_t off;
146 
147   off = RPC_HDR_SIZE + sizeof(u32_t);
148 
149   RPC_RESET;
150   RPC_ADVANCE(off);
151   *ptr = RPC_PTR;
152 
153   return RPC_BUF_SIZE - off;
154 }
155 
156 /*===========================================================================*
157  *				hgfs_writebuf				     *
158  *===========================================================================*/
159 size_t hgfs_writebuf(char **ptr)
160 {
161 /* Return information about the write buffer, for zero-copy purposes. Store a
162  * pointer to the first byte of the write buffer, and return the maximum data
163  * size. The results are static, but must only be used immediately after a
164  * hgfs_write() call (with a NULL data buffer address).
165  */
166   u32_t off;
167 
168   off = RPC_HDR_SIZE + sizeof(u32_t) + sizeof(u8_t) + sizeof(u32_t) * 3;
169 
170   RPC_RESET;
171   RPC_ADVANCE(off);
172   *ptr = RPC_PTR;
173 
174   return RPC_BUF_SIZE - off;
175 }
176