github.com/jlmucb/cloudproxy@v0.0.0-20170830161738-b5aa0b619bc4/src/tao/fd_message_channel.cc (about) 1 // File: fd_message_channel.cc 2 // Author: Tom Roeder <tmroeder@google.com> 3 // 4 // Description: A MessageChannel that communicates over Unix file descriptors. 5 // 6 // Copyright (c) 2013, Google Inc. All rights reserved. 7 // 8 // Licensed under the Apache License, Version 2.0 (the "License"); 9 // you may not use this file except in compliance with the License. 10 // You may obtain a copy of the License at 11 // 12 // http://www.apache.org/licenses/LICENSE-2.0 13 // 14 // Unless required by applicable law or agreed to in writing, software 15 // distributed under the License is distributed on an "AS IS" BASIS, 16 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 // See the License for the specific language governing permissions and 18 // limitations under the License. 19 #include "tao/fd_message_channel.h" 20 21 #include <arpa/inet.h> 22 #include <unistd.h> 23 24 #include <list> 25 #include <string> 26 27 #include <glog/logging.h> 28 29 #include "tao/util.h" 30 31 namespace tao { 32 33 void FDMessageChannel::FDClose() { 34 if (readfd_ != -1) { 35 close(readfd_); 36 } 37 if (writefd_ != -1 && writefd_ != readfd_) { 38 close(writefd_); 39 } 40 readfd_ = writefd_ = -1; 41 } 42 43 bool FDMessageChannel::SendData(const void *buffer, size_t buffer_len) { 44 if (IsClosed()) { 45 LOG(ERROR) << "Could not send data, channel already closed"; 46 return false; 47 } 48 int bytes_written = write(writefd_, buffer, buffer_len); 49 if (bytes_written < 0) { 50 PLOG(ERROR) << "Could not send data"; 51 Close(); 52 return false; 53 } 54 if (static_cast<size_t>(bytes_written) != buffer_len) { 55 LOG(ERROR) << "Could not send complete data"; 56 Close(); 57 return false; 58 } 59 return true; 60 } 61 62 bool FDMessageChannel::ReceivePartialData(void *buffer, size_t max_recv_len, 63 size_t *recv_len, bool *eof) { 64 if (IsClosed()) { 65 LOG(ERROR) << "Can't receive data, channel is already closed"; 66 *eof = true; 67 return true; 68 } else { 69 *eof = false; 70 } 71 int in_len = 72 read(readfd_, reinterpret_cast<unsigned char *>(buffer), max_recv_len); 73 if (in_len == 0) { 74 *eof = true; 75 Close(); 76 return true; 77 } else if (in_len < 0) { 78 PLOG(ERROR) << "Failed to read data from file descriptor"; 79 Close(); 80 return false; 81 } 82 *recv_len = in_len; 83 return true; 84 } 85 86 bool FDMessageChannel::GetFileDescriptors(list<int> *keep_open) const { 87 if (readfd_ != -1) { 88 keep_open->push_back(readfd_); 89 } 90 if (writefd_ != -1 && writefd_ != readfd_) { 91 keep_open->push_back(writefd_); 92 } 93 return true; 94 } 95 96 bool FDMessageChannel::SerializeToString(string *params) const { 97 stringstream out; 98 out << "tao::FDMessageChannel(" << readfd_ << ", " << writefd_ << ")"; 99 params->assign(out.str()); 100 return true; 101 } 102 103 FDMessageChannel *FDMessageChannel::DeserializeFromString( 104 const string ¶ms) { 105 stringstream in(params); 106 skip(in, "tao::FDMessageChannel("); 107 if (!in) return nullptr; // not for us 108 int rfd, wfd; 109 in >> rfd; 110 skip(in, ", "); 111 in >> wfd; 112 skip(in, ")"); 113 if (!in || (in.get() && !in.eof())) { 114 LOG(ERROR) << "Could not deserialize FDMessageChannel"; 115 return nullptr; 116 } 117 return new FDMessageChannel(rfd, wfd); 118 } 119 120 } // namespace tao