Change Ubuntu version
[harbours.git] / gcc / pex-helenos.c
blob7387c72427a43205a16631deb136f0116edacc95
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 #define _HELENOS_SOURCE
35 #include "config.h"
36 #include "libiberty.h"
37 #include "pex-common.h"
39 #include <libc/task.h>
40 #include <assert.h>
41 #include <errno.h>
42 #include <string.h>
43 #include <fcntl.h>
44 #include <unistd.h>
45 #include <stdio.h>
46 #include <stdlib.h>
47 #include <limits.h>
49 struct pex_task_wait {
50 task_wait_t task_wait;
51 task_id_t task_id;
54 /* Helen-OS specific information stored in each pex_obj. */
55 struct pex_helenos {
56 struct pex_task_wait *tasks;
57 size_t task_count;
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)
78 return close(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];
98 char full_path[1024];
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);
104 if (rc != 0) {
105 *err = rc;
106 *errmsg = "task_spawnvf";
107 pex_helenos->tasks = XRESIZEVEC(struct pex_task_wait,
108 pex_helenos->tasks, pex_helenos->task_count);
109 return (pid_t) -1;
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];
130 break;
134 if (this_task == NULL) {
135 *err = -ENOENT;
136 *errmsg = "no such task registered";
137 *status = *err;
138 return -1;
142 * If @c done is set, we are cleaning-up. Kill the process
143 * mercilessly.
145 if (done) {
146 task_kill(this_task->task_id);
149 if (time != NULL) {
150 memset(time, 0, sizeof(*time));
153 task_exit_t task_exit;
154 int task_retval;
155 int rc = task_wait(&this_task->task_wait, &task_exit, &task_retval);
157 if (rc != 0) {
158 *err = -rc;
159 *errmsg = "task_wait";
160 *status = -rc;
161 return -1;
162 } else {
163 if (task_exit == TASK_EXIT_UNEXPECTED) {
164 *status = INT_MIN;
165 return -1;
166 } else {
167 *status = task_retval;
168 return 0;
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);
178 free(pex_helenos);
180 obj->sysdep = NULL;
185 * PEX initialization.
188 const struct pex_funcs funcs = {
189 pex_helenos_open_read,
190 pex_helenos_open_write,
191 pex_helenos_exec_child,
192 pex_helenos_close,
193 pex_helenos_wait,
194 NULL,
195 NULL,
196 NULL,
197 pex_helenos_cleanup
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;
212 return obj;
215 #endif