Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 /* libs/graphics/ports/SkFontHost_fontconfig_direct.cpp | |
| 2 ** | |
| 3 ** Copyright 2009, Google Inc. | |
| 4 ** | |
| 5 ** Licensed under the Apache License, Version 2.0 (the "License"); | |
| 6 ** you may not use this file except in compliance with the License. | |
| 7 ** You may obtain a copy of the License at | |
| 8 ** | |
| 9 ** http://www.apache.org/licenses/LICENSE-2.0 | |
| 10 ** | |
| 11 ** Unless required by applicable law or agreed to in writing, software | |
| 12 ** distributed under the License is distributed on an "AS IS" BASIS, | |
| 13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| 14 ** See the License for the specific language governing permissions and | |
| 15 ** limitations under the License. | |
| 16 */ | |
| 17 | |
| 18 // http://code.google.com/p/chromium/wiki/LinuxSandboxIPC | |
| 19 | |
| 20 #include "SkFontHost_fontconfig_ipc.h" | |
| 21 | |
| 22 #include <errno.h> | |
| 23 #include <unistd.h> | |
| 24 #include <fcntl.h> | |
| 25 #include <sys/socket.h> | |
| 26 #include <sys/uio.h> | |
| 27 | |
| 28 FontConfigIPC::FontConfigIPC(int fd) | |
| 29 : fd_(fd) { | |
| 30 } | |
| 31 | |
| 32 FontConfigIPC::~FontConfigIPC() { | |
| 33 close(fd_); | |
| 34 } | |
| 35 | |
| 36 static ssize_t SyncIPC(int fd, const struct iovec* output, unsigned output_len, | |
| 37 int* result_fd, const struct iovec* input, | |
| 38 unsigned input_len) { | |
| 39 char cmsg_buf[CMSG_SPACE(sizeof(int))]; | |
| 40 | |
| 41 int fds[2]; | |
| 42 if (socketpair(AF_UNIX, SOCK_DGRAM, 0, fds) == -1) | |
| 43 return false; | |
| 44 | |
| 45 struct msghdr msg = {0}; | |
| 46 msg.msg_iov = const_cast<struct iovec*>(input); | |
| 47 msg.msg_iovlen = input_len; | |
| 48 msg.msg_control = cmsg_buf; | |
| 49 msg.msg_controllen = sizeof(cmsg_buf); | |
| 50 | |
| 51 struct cmsghdr* cmsg = CMSG_FIRSTHDR(&msg); | |
| 52 cmsg->cmsg_level = SOL_SOCKET; | |
| 53 cmsg->cmsg_type = SCM_RIGHTS; | |
| 54 cmsg->cmsg_len = CMSG_LEN(sizeof(int)); | |
| 55 *(int *) CMSG_DATA(cmsg) = fds[1]; | |
| 56 msg.msg_controllen = cmsg->cmsg_len; | |
| 57 | |
| 58 ssize_t r; | |
| 59 do { | |
| 60 r = sendmsg(fd, &msg, 0); | |
| 61 } while (r == -1 && errno == EINTR); | |
| 62 close(fds[1]); | |
| 63 | |
| 64 if (r == -1) { | |
| 65 close(fds[0]); | |
| 66 return -1; | |
| 67 } | |
| 68 | |
| 69 memset(&msg, 0, sizeof(msg)); | |
|
Lei Zhang
2009/06/04 01:30:43
fta reports compile failure. http://paste.ubuntu.c
| |
| 70 | |
| 71 msg.msg_iov = const_cast<struct iovec*>(output); | |
| 72 msg.msg_iovlen = output_len; | |
| 73 msg.msg_control = cmsg_buf; | |
| 74 msg.msg_controllen = sizeof(cmsg_buf); | |
| 75 | |
| 76 do { | |
| 77 r = recvmsg(fds[0], &msg, 0); | |
| 78 } while (r == -1 && errno == EINTR); | |
| 79 close(fds[0]); | |
| 80 | |
| 81 if (r == -1 || msg.msg_flags & (MSG_TRUNC | MSG_CTRUNC)) | |
| 82 return -1; | |
| 83 | |
| 84 cmsg = CMSG_FIRSTHDR(&msg); | |
| 85 if (cmsg && cmsg->cmsg_level == SOL_SOCKET && | |
| 86 cmsg->cmsg_type == SCM_RIGHTS) { | |
| 87 const int fd = *(int*) CMSG_DATA(cmsg); | |
| 88 if (!result_fd) | |
| 89 close(fd); | |
| 90 *result_fd = fd; | |
| 91 } | |
| 92 | |
| 93 return r; | |
| 94 } | |
| 95 | |
| 96 bool FontConfigIPC::Match(std::string* result_family, | |
| 97 unsigned* result_fileid, | |
| 98 bool fileid_valid, unsigned fileid, | |
| 99 const std::string& family, int is_bold, | |
| 100 int is_italic) { | |
| 101 MatchRequest request; | |
| 102 request.method = METHOD_MATCH; | |
| 103 request.fileid_valid = fileid_valid; | |
| 104 request.fileid = fileid; | |
| 105 request.is_bold = is_bold; | |
| 106 request.is_italic = is_italic; | |
| 107 | |
| 108 if (family.size() > 255) | |
| 109 return false; | |
| 110 request.family_len = family.size(); | |
| 111 | |
| 112 struct iovec out_iov[2]; | |
| 113 out_iov[0].iov_base = &request; | |
| 114 out_iov[0].iov_len = sizeof(request); | |
| 115 if (family.size()) { | |
| 116 out_iov[1].iov_base = const_cast<char*>(family.data()); | |
| 117 out_iov[1].iov_len = family.size(); | |
| 118 } | |
| 119 | |
| 120 MatchReply reply; | |
| 121 char filename_buf[PATH_MAX]; | |
|
Lei Zhang
2009/06/04 01:30:43
and limits.h
| |
| 122 | |
| 123 struct iovec in_iov[2]; | |
| 124 in_iov[0].iov_base = &reply; | |
| 125 in_iov[0].iov_len = sizeof(reply); | |
| 126 in_iov[1].iov_base = filename_buf; | |
| 127 in_iov[1].iov_len = sizeof(filename_buf); | |
| 128 | |
| 129 const ssize_t r = SyncIPC(fd_, in_iov, 2, NULL, out_iov, | |
| 130 family.size() ? 2 : 1); | |
| 131 | |
| 132 if (r == -1 || r < sizeof(reply)) | |
| 133 return false; | |
| 134 | |
| 135 if (reply.result == 0) | |
| 136 return false; | |
| 137 | |
| 138 *result_fileid = reply.result_fileid; | |
| 139 if (r != sizeof(reply) + reply.filename_len) | |
| 140 return false; | |
| 141 if (result_family) | |
| 142 *result_family = std::string(filename_buf, reply.filename_len); | |
| 143 | |
| 144 return true; | |
| 145 } | |
| 146 | |
| 147 int FontConfigIPC::Open(unsigned fileid) { | |
| 148 OpenRequest request; | |
| 149 OpenReply reply; | |
| 150 const struct iovec out_iov = {&request, sizeof(request)}; | |
| 151 const struct iovec in_iov = {&reply, sizeof(reply)}; | |
| 152 int result_fd = -1; | |
| 153 | |
| 154 request.method = METHOD_OPEN; | |
| 155 request.fileid = fileid; | |
| 156 const ssize_t r = SyncIPC(fd_, &in_iov, 1, &result_fd, &out_iov, 1); | |
| 157 if (r == -1 || r != sizeof(reply) || reply.result == 0) { | |
| 158 if (result_fd >= 0) | |
| 159 close(result_fd); | |
| 160 return -1; | |
| 161 } | |
| 162 | |
| 163 return result_fd; | |
| 164 } | |
| OLD | NEW |