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.
33 #define _HELENOS_SOURCE
36 #include "libiberty.h"
37 #include "pex-common.h"
39 #include <libc/task.h>
49 struct pex_task_wait
{
50 task_wait_t task_wait
;
54 /* Helen-OS specific information stored in each pex_obj. */
56 struct pex_task_wait
*tasks
;
61 * Implementation of the individual operations.
64 static int pex_helenos_open_read(struct pex_obj
*obj ATTRIBUTE_UNUSED
,
65 const char *name
, int binary ATTRIBUTE_UNUSED
)
67 return open(name
, O_RDONLY
);
70 static int pex_helenos_open_write(struct pex_obj
*obj ATTRIBUTE_UNUSED
,
71 const char *name
, int binary ATTRIBUTE_UNUSED
)
73 return open(name
, O_WRONLY
| O_CREAT
| O_TRUNC
);
76 static int pex_helenos_close(struct pex_obj
*obj ATTRIBUTE_UNUSED
, int fd
)
81 static pid_t
pex_helenos_exec_child(struct pex_obj
*obj
,
82 int flags ATTRIBUTE_UNUSED
,
83 const char *executable
, char * const * argv
,
84 char * const * env ATTRIBUTE_UNUSED
,
85 int in
, int out
, int errdes
,
86 int toclose ATTRIBUTE_UNUSED
,
87 const char **errmsg
, int *err
)
89 struct pex_helenos
*pex_helenos
= (struct pex_helenos
*) obj
->sysdep
;
91 /* Prepare space for the task_wait structure. */
92 pex_helenos
->tasks
= XRESIZEVEC(struct pex_task_wait
,
93 pex_helenos
->tasks
, pex_helenos
->task_count
+ 1);
96 struct pex_task_wait
*this_task
= &pex_helenos
->tasks
[pex_helenos
->task_count
];
99 // FIXME: decide on paths
100 snprintf(full_path
, 1023, "/app/%s", executable
);
101 int rc
= task_spawnvf(&this_task
->task_id
, &this_task
->task_wait
,
102 full_path
, argv
, in
, out
, errdes
);
106 *errmsg
= "task_spawnvf";
107 pex_helenos
->tasks
= XRESIZEVEC(struct pex_task_wait
,
108 pex_helenos
->tasks
, pex_helenos
->task_count
);
112 pex_helenos
->task_count
++;
114 return (pid_t
) this_task
->task_id
;
117 static int pex_helenos_wait(struct pex_obj
*obj
,
118 pid_t pid
, int *status
,
119 struct pex_time
*time
, int done
,
120 const char **errmsg
, int *err
)
122 struct pex_helenos
*pex_helenos
= (struct pex_helenos
*) obj
->sysdep
;
123 task_id_t task_id
= (task_id_t
) pid
;
125 /* Find the task in the list of known ones. */
126 struct pex_task_wait
*this_task
= NULL
;
127 for (size_t i
= 0; i
< pex_helenos
->task_count
; i
++) {
128 if (pex_helenos
->tasks
[i
].task_id
== task_id
) {
129 this_task
= &pex_helenos
->tasks
[i
];
134 if (this_task
== NULL
) {
136 *errmsg
= "no such task registered";
142 * If @c done is set, we are cleaning-up. Kill the process
146 task_kill(this_task
->task_id
);
150 memset(time
, 0, sizeof(*time
));
153 task_exit_t task_exit
;
155 int rc
= task_wait(&this_task
->task_wait
, &task_exit
, &task_retval
);
159 *errmsg
= "task_wait";
163 if (task_exit
== TASK_EXIT_UNEXPECTED
) {
167 *status
= task_retval
;
173 static void pex_helenos_cleanup(struct pex_obj
*obj
)
175 struct pex_helenos
*pex_helenos
= (struct pex_helenos
*) obj
->sysdep
;
177 free(pex_helenos
->tasks
);
185 * PEX initialization.
188 const struct pex_funcs funcs
= {
189 pex_helenos_open_read
,
190 pex_helenos_open_write
,
191 pex_helenos_exec_child
,
200 struct pex_obj
*pex_init(int flags
, const char *pname
, const char *tempbase
)
202 /* Common initialization. */
203 struct pex_obj
*obj
= pex_init_common(flags
, pname
, tempbase
, &funcs
);
205 /* Prepare the HelenOS specific data. */
206 struct pex_helenos
*pex_helenos
= XNEW(struct pex_helenos
);
207 pex_helenos
->tasks
= NULL
;
208 pex_helenos
->task_count
= 0;
210 obj
->sysdep
= pex_helenos
;