Attempt to fix cross-compilers.
[harbours.git] / gcc / pex-helenos.c
blob5d71cfde8443dd2129b1d63019a8a5c981d51705
1 /*
2 * Copyright (c) 2013 Vojtech Horky
3 * All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
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.
29 #ifndef __helenos__
30 #include "pex-unix.c"
31 #else
33 #include "config.h"
34 #include "libiberty.h"
35 #include "pex-common.h"
37 #include <libc/task.h>
38 #include <assert.h>
39 #include <string.h>
40 #include <fcntl.h>
41 #include <unistd.h>
42 #include <stdio.h>
43 #include <stdlib.h>
44 #include <limits.h>
46 struct pex_task_wait {
47 task_wait_t task_wait;
48 task_id_t task_id;
51 /* Helen-OS specific information stored in each pex_obj. */
52 struct pex_helenos {
53 struct pex_task_wait *tasks;
54 size_t task_count;
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)
75 return close(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];
95 char full_path[1024];
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);
101 if (rc != 0) {
102 *err = rc;
103 *errmsg = "task_spawnvf";
104 pex_helenos->tasks = XRESIZEVEC(struct pex_task_wait,
105 pex_helenos->tasks, pex_helenos->task_count);
106 return (pid_t) -1;
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];
127 break;
131 if (this_task == NULL) {
132 *err = -ENOENT;
133 *errmsg = "no such task registered";
134 *status = *err;
135 return -1;
139 * If @c done is set, we are cleaning-up. Kill the process
140 * mercilessly.
142 if (done) {
143 task_kill(this_task->task_id);
146 if (time != NULL) {
147 memset(time, 0, sizeof(*time));
150 task_exit_t task_exit;
151 int task_retval;
152 int rc = task_wait(&this_task->task_wait, &task_exit, &task_retval);
154 if (rc != 0) {
155 *err = -rc;
156 *errmsg = "task_wait";
157 *status = -rc;
158 return -1;
159 } else {
160 if (task_exit == TASK_EXIT_UNEXPECTED) {
161 *status = INT_MIN;
162 return -1;
163 } else {
164 *status = task_retval;
165 return 0;
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);
175 free(pex_helenos);
177 obj->sysdep = NULL;
182 * PEX initialization.
185 const struct pex_funcs funcs = {
186 pex_helenos_open_read,
187 pex_helenos_open_write,
188 pex_helenos_exec_child,
189 pex_helenos_close,
190 pex_helenos_wait,
191 NULL,
192 NULL,
193 NULL,
194 pex_helenos_cleanup
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;
209 return obj;
212 #endif