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 |