summaryrefslogtreecommitdiffstats
path: root/skia/ext/SkFontHost_fontconfig_ipc.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'skia/ext/SkFontHost_fontconfig_ipc.cpp')
-rw-r--r--skia/ext/SkFontHost_fontconfig_ipc.cpp144
1 files changed, 144 insertions, 0 deletions
diff --git a/skia/ext/SkFontHost_fontconfig_ipc.cpp b/skia/ext/SkFontHost_fontconfig_ipc.cpp
new file mode 100644
index 0000000..1705aed
--- /dev/null
+++ b/skia/ext/SkFontHost_fontconfig_ipc.cpp
@@ -0,0 +1,144 @@
+/* libs/graphics/ports/SkFontHost_fontconfig_direct.cpp
+**
+** Copyright 2009, Google Inc.
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+// http://code.google.com/p/chromium/wiki/LinuxSandboxIPC
+
+#include "SkFontHost_fontconfig_ipc.h"
+
+#include <errno.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+
+#include "base/pickle.h"
+#include "base/unix_domain_socket_posix.h"
+
+FontConfigIPC::FontConfigIPC(int fd)
+ : fd_(fd) {
+}
+
+FontConfigIPC::~FontConfigIPC() {
+ close(fd_);
+}
+
+static ssize_t SyncIPC(int fd, uint8_t* reply, unsigned reply_len, int* result_fd,
+ const Pickle& request) {
+ int fds[2];
+ if (socketpair(AF_UNIX, SOCK_DGRAM, 0, fds) == -1)
+ return false;
+
+ std::vector<int> fd_vector;
+ fd_vector.push_back(fds[1]);
+ if (!base::SendMsg(fd, request.data(), request.size(), fd_vector)) {
+ close(fds[0]);
+ close(fds[1]);
+ return -1;
+ }
+ close(fds[1]);
+
+ fd_vector.clear();
+ const ssize_t r = base::RecvMsg(fds[0], reply, reply_len, &fd_vector);
+ close(fds[0]);
+ if (r == -1)
+ return -1;
+
+ if ((fd_vector.size() > 0 && result_fd == NULL) || fd_vector.size() > 1) {
+ for (std::vector<int>::const_iterator
+ i = fd_vector.begin(); i != fd_vector.end(); ++i) {
+ close(*i);
+ }
+
+ return -1;
+ }
+
+ if (result_fd) {
+ if (fd_vector.size() == 0) {
+ *result_fd = -1;
+ } else {
+ *result_fd = fd_vector[0];
+ }
+ }
+
+ return r;
+}
+
+bool FontConfigIPC::Match(std::string* result_family,
+ unsigned* result_fileid,
+ bool fileid_valid, unsigned fileid,
+ const std::string& family, int is_bold,
+ int is_italic) {
+ Pickle request;
+ request.WriteInt(METHOD_MATCH);
+ request.WriteBool(fileid_valid);
+ if (fileid_valid)
+ request.WriteUInt32(fileid);
+ request.WriteBool(is_bold);
+ request.WriteBool(is_italic);
+ request.WriteString(family);
+
+ uint8_t reply_buf[512];
+ const ssize_t r = SyncIPC(fd_, reply_buf, sizeof(reply_buf), NULL, request);
+ if (r == -1)
+ return false;
+
+ Pickle reply(reinterpret_cast<char*>(reply_buf), r);
+ void* iter = NULL;
+ bool result;
+ if (!reply.ReadBool(&iter, &result))
+ return false;
+ if (!result)
+ return false;
+
+ uint32_t reply_fileid;
+ std::string reply_family;
+ if (!reply.ReadUInt32(&iter, &reply_fileid) ||
+ !reply.ReadString(&iter, &reply_family)) {
+ return false;
+ }
+
+ *result_fileid = reply_fileid;
+ if (result_family)
+ *result_family = reply_family;
+
+ return true;
+}
+
+int FontConfigIPC::Open(unsigned fileid) {
+ Pickle request;
+ request.WriteInt(METHOD_OPEN);
+ request.WriteUInt32(fileid);
+
+ int result_fd = -1;
+ uint8_t reply_buf[256];
+ const ssize_t r = SyncIPC(fd_, reply_buf, sizeof(reply_buf), &result_fd, request);
+
+ if (r == -1)
+ return -1;
+
+ Pickle reply(reinterpret_cast<char*>(reply_buf), r);
+ bool result;
+ void* iter = NULL;
+ if (!reply.ReadBool(&iter, &result) ||
+ !result) {
+ if (result_fd)
+ close(result_fd);
+ return -1;
+ }
+
+ return result_fd;
+}