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 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 int r, len, max; 64 65 RPC_REQUEST(HGFS_REQ_READ); 66 RPC_NEXT32 = (u32_t)handle; 67 RPC_NEXT32 = ex64lo(off); 68 RPC_NEXT32 = ex64hi(off); 69 70 max = RPC_BUF_SIZE - RPC_LEN - sizeof(u32_t); 71 RPC_NEXT32 = (size < max) ? size : max; 72 73 if ((r = rpc_query()) != OK) 74 return r; 75 76 len = RPC_NEXT32; 77 if (len > max) len = max; /* sanity check */ 78 79 /* Only copy out data if we're not operating directly on the RPC buffer. */ 80 if (buf != RPC_PTR) 81 memcpy(buf, RPC_PTR, len); 82 83 return len; 84 } 85 86 /*===========================================================================* 87 * hgfs_write * 88 *===========================================================================*/ 89 ssize_t hgfs_write( 90 sffs_file_t handle, /* handle to open file */ 91 char *buf, /* data buffer or NULL */ 92 size_t len, /* number of bytes to write */ 93 u64_t off /* file offset */ 94 ) 95 { 96 /* Write to an open file. Upon success, return the number of bytes written. 97 */ 98 int r; 99 100 RPC_REQUEST(HGFS_REQ_WRITE); 101 RPC_NEXT32 = (u32_t)handle; 102 RPC_NEXT8 = 0; /* append flag */ 103 RPC_NEXT32 = ex64lo(off); 104 RPC_NEXT32 = ex64hi(off); 105 RPC_NEXT32 = len; 106 107 /* Only copy in data if we're not operating directly on the RPC buffer. */ 108 if (RPC_PTR != buf) 109 memcpy(RPC_PTR, buf, len); 110 RPC_ADVANCE(len); 111 112 if ((r = rpc_query()) != OK) 113 return r; 114 115 return RPC_NEXT32; 116 } 117 118 /*===========================================================================* 119 * hgfs_close * 120 *===========================================================================*/ 121 int hgfs_close( 122 sffs_file_t handle /* handle to open file */ 123 ) 124 { 125 /* Close an open file. 126 */ 127 128 RPC_REQUEST(HGFS_REQ_CLOSE); 129 RPC_NEXT32 = (u32_t)handle; 130 131 return rpc_query(); 132 } 133 134 /*===========================================================================* 135 * hgfs_readbuf * 136 *===========================================================================*/ 137 size_t hgfs_readbuf(char **ptr) 138 { 139 /* Return information about the read buffer, for zero-copy purposes. Store a 140 * pointer to the first byte of the read buffer, and return the maximum data 141 * size. The results are static, but must only be used directly prior to a 142 * hgfs_read() call (with a NULL data buffer address). 143 */ 144 u32_t off; 145 146 off = RPC_HDR_SIZE + sizeof(u32_t); 147 148 RPC_RESET; 149 RPC_ADVANCE(off); 150 *ptr = RPC_PTR; 151 152 return RPC_BUF_SIZE - off; 153 } 154 155 /*===========================================================================* 156 * hgfs_writebuf * 157 *===========================================================================*/ 158 size_t hgfs_writebuf(char **ptr) 159 { 160 /* Return information about the write buffer, for zero-copy purposes. Store a 161 * pointer to the first byte of the write buffer, and return the maximum data 162 * size. The results are static, but must only be used immediately after a 163 * hgfs_write() call (with a NULL data buffer address). 164 */ 165 u32_t off; 166 167 off = RPC_HDR_SIZE + sizeof(u32_t) + sizeof(u8_t) + sizeof(u32_t) * 3; 168 169 RPC_RESET; 170 RPC_ADVANCE(off); 171 *ptr = RPC_PTR; 172 173 return RPC_BUF_SIZE - off; 174 } 175