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 &params) {
   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