/************************************************************************* * * FUNCTION * * _open * * DESCRIPTION * * Open a file. Minimal implementation * *************************************************************************/ int _open(const char * filename, int flags, int mode) { int filename_len = strlen(filename) + 1; int payload_size = sizeof(struct _sys_rpc) + filename_len; int retval = -1; if ((!filename) || (filename_len > FILE_NAME_LEN)) { return -1; } /* Construct rpc payload */ rpc_data->rpc->id = OPEN_SYSCALL_ID; rpc_data->rpc->sys_call_args.int_field1 = flags; rpc_data->rpc->sys_call_args.int_field2 = mode; rpc_data->rpc->sys_call_args.data_len = filename_len; memcpy(&rpc_data->rpc->sys_call_args.data, filename, filename_len); /* Transmit rpc request */ env_lock_mutex(rpc_data->rpc_lock); send_rpc((void*) rpc_data->rpc, payload_size); env_unlock_mutex(rpc_data->rpc_lock); /* Wait for response from proxy on master */ env_acquire_sync_lock(rpc_data->sync_lock); /* Obtain return args and return to caller */ if (rpc_data->rpc_response->id == OPEN_SYSCALL_ID) { retval = rpc_data->rpc_response->sys_call_args.int_field1; } return retval; }
/************************************************************************* * * FUNCTION * * _write * * DESCRIPTION * * Low level function to redirect IO to serial. * *************************************************************************/ int _write(int fd, const char * ptr, int len) { int retval = -1; int payload_size = sizeof(struct _sys_rpc) + len; int null_term = 0; if (fd == 1) { null_term = 1; } rpc_data->rpc->id = WRITE_SYSCALL_ID; rpc_data->rpc->sys_call_args.int_field1 = fd; rpc_data->rpc->sys_call_args.int_field2 = len; rpc_data->rpc->sys_call_args.data_len = len + null_term; memcpy(rpc_data->rpc->sys_call_args.data, ptr, len); if (null_term) { *(char*) (rpc_data->rpc->sys_call_args.data + len + null_term) = 0; } env_lock_mutex(rpc_data->rpc_lock); send_rpc((void*) rpc_data->rpc, payload_size); env_unlock_mutex(rpc_data->rpc_lock); env_acquire_sync_lock(rpc_data->sync_lock); if (rpc_data->rpc_response->id == WRITE_SYSCALL_ID) { retval = rpc_data->rpc_response->sys_call_args.int_field1; } return retval; }
/************************************************************************* * * FUNCTION * * _read * * DESCRIPTION * * Low level function to redirect IO to serial. * *************************************************************************/ int _read(int fd, char * buffer, int buflen) { int payload_size = sizeof(struct _sys_rpc); int retval = -1; if (!buffer || !buflen) return retval; /* Construct rpc payload */ rpc_data->rpc->id = READ_SYSCALL_ID; rpc_data->rpc->sys_call_args.int_field1 = fd; rpc_data->rpc->sys_call_args.int_field2 = buflen; rpc_data->rpc->sys_call_args.data_len = 0; /*not used*/ /* Transmit rpc request */ env_lock_mutex(rpc_data->rpc_lock); get_response=0; send_rpc((void*) rpc_data->rpc, payload_size); env_unlock_mutex(rpc_data->rpc_lock); /* Wait for response from proxy on master */ env_acquire_sync_lock(rpc_data->sync_lock); /* Obtain return args and return to caller */ if (rpc_data->rpc_response->id == READ_SYSCALL_ID) { if (rpc_data->rpc_response->sys_call_args.int_field1 > 0) { memcpy(buffer, rpc_data->rpc_response->sys_call_args.data, rpc_data->rpc_response->sys_call_args.data_len); } retval = rpc_data->rpc_response->sys_call_args.int_field1; } return retval; }
/* read and broadcast the file */ static void _bcast_file(void) { int buf_size; ssize_t size_read = 0; file_bcast_msg_t bcast_msg; char *buffer; if (params.block_size) buf_size = MIN(params.block_size, f_stat.st_size); else buf_size = MIN((512 * 1024), f_stat.st_size); bcast_msg.fname = params.dst_fname; bcast_msg.block_no = 1; bcast_msg.last_block = 0; bcast_msg.force = params.force; bcast_msg.modes = f_stat.st_mode; bcast_msg.uid = f_stat.st_uid; bcast_msg.user_name = uid_to_string(f_stat.st_uid); bcast_msg.gid = f_stat.st_gid; buffer = xmalloc(buf_size); bcast_msg.block = buffer; bcast_msg.block_len = 0; bcast_msg.cred = sbcast_cred->sbcast_cred; if (params.preserve) { bcast_msg.atime = f_stat.st_atime; bcast_msg.mtime = f_stat.st_mtime; } else { bcast_msg.atime = 0; bcast_msg.mtime = 0; } while (1) { bcast_msg.block_len = _get_block(buffer, buf_size); debug("block %d, size %u", bcast_msg.block_no, bcast_msg.block_len); size_read += bcast_msg.block_len; if (size_read >= f_stat.st_size) bcast_msg.last_block = 1; send_rpc(&bcast_msg, sbcast_cred); if (bcast_msg.last_block) break; /* end of file */ bcast_msg.block_no++; } xfree(bcast_msg.user_name); xfree(buffer); }
/************************************************************************* * * FUNCTION * * _close * * DESCRIPTION * * Close a file. Minimal implementation * *************************************************************************/ int _close(int fd) { int payload_size = sizeof(struct _sys_rpc); int retval = -1; rpc_data->rpc->id = CLOSE_SYSCALL_ID; rpc_data->rpc->sys_call_args.int_field1 = fd; rpc_data->rpc->sys_call_args.int_field2 = 0; /*not used*/ rpc_data->rpc->sys_call_args.data_len = 0; /*not used*/ env_lock_mutex(rpc_data->rpc_lock); send_rpc((void*) rpc_data->rpc, payload_size); env_unlock_mutex(rpc_data->rpc_lock); /* Wait for response from proxy on master */ env_acquire_sync_lock(rpc_data->sync_lock); if (rpc_data->rpc_response->id == CLOSE_SYSCALL_ID) { retval = rpc_data->rpc_response->sys_call_args.int_field1; } return retval; }
int rpmsg_retarget_send(void *data, int len) { return send_rpc(data, len); }