2 * Copyright (c) 2013 Vojtech Horky
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 #include "libiberty.h"
35 #include "pex-common.h"
37 #include <libc/task.h>
46 struct pex_task_wait
{
47 task_wait_t task_wait
;
51 /* Helen-OS specific information stored in each pex_obj. */
53 struct pex_task_wait
*tasks
;
58 * Implementation of the individual operations.
61 static int pex_helenos_open_read(struct pex_obj
*obj ATTRIBUTE_UNUSED
,
62 const char *name
, int binary ATTRIBUTE_UNUSED
)
64 return open(name
, O_RDONLY
);
67 static int pex_helenos_open_write(struct pex_obj
*obj ATTRIBUTE_UNUSED
,
68 const char *name
, int binary ATTRIBUTE_UNUSED
)
70 return open(name
, O_WRONLY
| O_CREAT
| O_TRUNC
);
73 static int pex_helenos_close(struct pex_obj
*obj ATTRIBUTE_UNUSED
, int fd
)
78 static pid_t
pex_helenos_exec_child(struct pex_obj
*obj
,
79 int flags ATTRIBUTE_UNUSED
,
80 const char *executable
, char * const * argv
,
81 char * const * env ATTRIBUTE_UNUSED
,
82 int in
, int out
, int errdes
,
83 int toclose ATTRIBUTE_UNUSED
,
84 const char **errmsg
, int *err
)
86 struct pex_helenos
*pex_helenos
= (struct pex_helenos
*) obj
->sysdep
;
88 /* Prepare space for the task_wait structure. */
89 pex_helenos
->tasks
= XRESIZEVEC(struct pex_task_wait
,
90 pex_helenos
->tasks
, pex_helenos
->task_count
+ 1);
93 struct pex_task_wait
*this_task
= &pex_helenos
->tasks
[pex_helenos
->task_count
];
96 // FIXME: decide on paths
97 snprintf(full_path
, 1023, "/app/%s", executable
);
98 int rc
= task_spawnvf(&this_task
->task_id
, &this_task
->task_wait
,
99 full_path
, argv
, in
, out
, errdes
);
103 *errmsg
= "task_spawnvf";
104 pex_helenos
->tasks
= XRESIZEVEC(struct pex_task_wait
,
105 pex_helenos
->tasks
, pex_helenos
->task_count
);
109 pex_helenos
->task_count
++;
111 return (pid_t
) this_task
->task_id
;
114 static int pex_helenos_wait(struct pex_obj
*obj
,
115 pid_t pid
, int *status
,
116 struct pex_time
*time
, int done
,
117 const char **errmsg
, int *err
)
119 struct pex_helenos
*pex_helenos
= (struct pex_helenos
*) obj
->sysdep
;
120 task_id_t task_id
= (task_id_t
) pid
;
122 /* Find the task in the list of known ones. */
123 struct pex_task_wait
*this_task
= NULL
;
124 for (size_t i
= 0; i
< pex_helenos
->task_count
; i
++) {
125 if (pex_helenos
->tasks
[i
].task_id
== task_id
) {
126 this_task
= &pex_helenos
->tasks
[i
];
131 if (this_task
== NULL
) {
133 *errmsg
= "no such task registered";
139 * If @c done is set, we are cleaning-up. Kill the process
143 task_kill(this_task
->task_id
);
147 memset(time
, 0, sizeof(*time
));
150 task_exit_t task_exit
;
152 int rc
= task_wait(&this_task
->task_wait
, &task_exit
, &task_retval
);
156 *errmsg
= "task_wait";
160 if (task_exit
== TASK_EXIT_UNEXPECTED
) {
164 *status
= task_retval
;
170 static void pex_helenos_cleanup(struct pex_obj
*obj
)
172 struct pex_helenos
*pex_helenos
= (struct pex_helenos
*) obj
->sysdep
;
174 free(pex_helenos
->tasks
);
182 * PEX initialization.
185 const struct pex_funcs funcs
= {
186 pex_helenos_open_read
,
187 pex_helenos_open_write
,
188 pex_helenos_exec_child
,
197 struct pex_obj
*pex_init(int flags
, const char *pname
, const char *tempbase
)
199 /* Common initialization. */
200 struct pex_obj
*obj
= pex_init_common(flags
, pname
, tempbase
, &funcs
);
202 /* Prepare the HelenOS specific data. */
203 struct pex_helenos
*pex_helenos
= XNEW(struct pex_helenos
);
204 pex_helenos
->tasks
= NULL
;
205 pex_helenos
->task_count
= 0;
207 obj
->sysdep
= pex_helenos
;