4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
8 http://www.apache.org/licenses/LICENSE-2.0
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
28 #include <sys/types.h>
30 extern char **environ;
33 #include "af-launch.h"
34 #include "secmgr-wrap.h"
41 static int launch_html(struct af_launch_desc *desc, struct launchparam *params);
42 static int launch_bin(struct af_launch_desc *desc, struct launchparam *params);
43 static int launch_qml(struct af_launch_desc *desc, struct launchparam *params);
45 static int launch_master(struct af_launch_desc *desc, struct launchparam *params, int fd, pid_t child);
49 int (*launcher)(struct af_launch_desc *desc, struct launchparam *params);
52 { "text/html", launch_html },
53 { "application/x-executable", launch_bin },
54 { "application/octet-stream", launch_bin },
55 { "text/vnd.qt.qml", launch_qml }
58 static void mksecret(char buffer[9])
60 snprintf(buffer, 9, "%08lX", (0xffffffff & random()));
65 static int port_ring = 12345;
67 if (port < 12345 || port > 15432)
73 int af_launch(struct af_launch_desc *desc, pid_t children[2])
75 char datadir[PATH_MAX];
82 struct launchparam params;
86 if (desc->type != NULL && *desc->type) {
87 nkl = sizeof known_launchers / sizeof * known_launchers;
88 while (ikl < nkl && strcmp(desc->type, known_launchers[ikl].type))
91 ERROR("type %s not found!", desc->type);
98 rc = snprintf(datadir, sizeof datadir, "%s/%s", desc->home, desc->tag);
99 if (rc < 0 || rc >= sizeof datadir) {
100 ERROR("overflow for datadir");
105 /* make the secret and port */
110 params.secret = secret;
112 /* prepare the pipes */
113 rc = pipe2(mpipe, O_CLOEXEC);
115 ERROR("error while calling pipe2: %m");
118 rc = pipe2(spipe, O_CLOEXEC);
120 ERROR("error while calling pipe2: %m");
126 /* fork the master child */
127 children[0] = fork();
128 if (children[0] < 0) {
129 ERROR("master fork failed: %m");
137 /********* in the parent process ************/
140 /* wait the ready signal (that transmit the slave pid) */
141 rc = read(mpipe[0], &children[1], sizeof children[1]);
143 ERROR("reading master pipe failed: %m");
149 assert(rc == sizeof children[1]);
150 /* start the child */
151 rc = write(spipe[1], "start", 5);
153 ERROR("writing slave pipe failed: %m");
161 /********* in the master child ************/
165 /* enter the process group */
168 ERROR("setpgid failed");
172 /* enter security mode */
173 rc = secmgr_prepare_exec(desc->tag);
175 ERROR("call to secmgr_prepare_exec failed: %m");
179 /* enter the datadirectory */
180 rc = mkdir(datadir, 0755);
181 if (rc && errno != EEXIST) {
182 ERROR("creation of datadir %s failed: %m", datadir);
187 ERROR("can't enter the datadir %s: %m", datadir);
191 /* fork the slave child */
192 children[1] = fork();
193 if (children[1] < 0) {
194 ERROR("slave fork failed: %m");
197 if (children[1] == 0) {
198 /********* in the slave child ************/
200 rc = read(spipe[0], message, sizeof message);
202 ERROR("reading slave pipe failed: %m");
205 rc = known_launchers[ikl].launcher(desc, ¶ms);
206 ERROR("slave launch failed: %m");
210 /********* still in the master child ************/
212 rc = launch_master(desc, ¶ms, mpipe[1], children[1]);
213 ERROR("master launch failed: %m");
217 static int launch_master(struct af_launch_desc *desc, struct launchparam *params, int fd, pid_t child)
221 argv[0] = "/bin/echo";
222 (void)asprintf(&argv[1], "--alias=/icons:%s", FWK_ICON_DIR);
223 (void)asprintf(&argv[2], "--port=%d", params->port);
224 (void)asprintf(&argv[3], "--rootdir=%s", desc->path);
225 (void)asprintf(&argv[4], "--token=%", desc->path);
228 rc = write(fd, &child, sizeof child);
230 ERROR("can't write master pipe: %m");
234 rc = execve(argv[0], argv, environ);
235 ERROR("failed to exec master %s: %m", argv[0]);
239 static int launch_html(struct af_launch_desc *desc, struct launchparam *params)
242 char *url = asprintf("http://localhost:%d/", params->port);
246 argv[0] = "/usr/bin/chromium";
247 (void)asprintf(&argv[1], "file://%s/%s", desc->path, desc->content);
249 rc = execve(argv[0], argv, environ);
250 ERROR("failed to exec slave %s: %m", argv[0]);
254 static int launch_bin(struct af_launch_desc *desc, struct launchparam *params)
256 ERROR("unimplemented launch_bin");
260 static int launch_qml(struct af_launch_desc *desc, struct launchparam *params)
262 ERROR("unimplemented launch_qml");