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