~galfy/helenos/bird-port-coastline

« back to all changes in this revision

Viewing changes to gcc/pex-helenos.c

  • Committer: Vojtech Horky
  • Date: 2014-08-29 08:13:57 UTC
  • Revision ID: vojtechhorky@users.sourceforge.net-20140829081357-7lfwgbe7plvgat81
libiberty: update pex implementation

There is new task_spawn() and task_wait() semantics that has to
be reflected in iberty libraray (process execution module).

Now, binutils and GCC shall be buildable again.

Show diffs side-by-side

added added

removed removed

Lines of Context:
35
35
#include "pex-common.h"
36
36
 
37
37
#include <libc/task.h>
 
38
#include <assert.h>
38
39
#include <string.h>
39
40
#include <fcntl.h>
40
41
#include <unistd.h>
41
42
#include <stdio.h>
 
43
#include <stdlib.h>
42
44
#include <limits.h>
43
45
 
 
46
struct pex_task_wait {
 
47
        task_wait_t task_wait;
 
48
        task_id_t task_id;
 
49
};
 
50
 
 
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;
 
55
};
 
56
 
44
57
/*
45
58
 * Implementation of the individual operations.
46
59
 */
62
75
        return close(fd);
63
76
}
64
77
 
65
 
static pid_t pex_helenos_exec_child(struct pex_obj *obj ATTRIBUTE_UNUSED,
 
78
static pid_t pex_helenos_exec_child(struct pex_obj *obj,
66
79
    int flags ATTRIBUTE_UNUSED,
67
80
    const char *executable, char * const * argv,
68
81
    char * const * env ATTRIBUTE_UNUSED,
76
89
        files[2] = &errdes;
77
90
        files[3] = NULL;
78
91
        
79
 
        task_id_t task_id = 0;
80
 
        char  full_path[1024];
 
92
        struct pex_helenos *pex_helenos = (struct pex_helenos *) obj->sysdep;
 
93
 
 
94
        /* Prepare space for the task_wait structure. */
 
95
        pex_helenos->tasks = XRESIZEVEC(struct pex_task_wait,
 
96
                pex_helenos->tasks, pex_helenos->task_count + 1);
 
97
 
 
98
 
 
99
        struct pex_task_wait *this_task = &pex_helenos->tasks[pex_helenos->task_count];
 
100
 
 
101
        char full_path[1024];
81
102
        // FIXME: decide on paths
82
103
        snprintf(full_path, 1023, "/app/%s", executable);
83
 
        int rc = task_spawnvf(&task_id, full_path, argv, files);
 
104
        int rc = task_spawnvf(&this_task->task_id, &this_task->task_wait,
 
105
                full_path, argv, files);
84
106
        
85
107
        if (rc != 0) {
86
108
                *err = rc;
87
109
                *errmsg = "task_spawnvf";
 
110
                pex_helenos->tasks = XRESIZEVEC(struct pex_task_wait,
 
111
                        pex_helenos->tasks, pex_helenos->task_count);
88
112
                return (pid_t) -1;
89
113
        }
90
114
        
91
 
        return (pid_t) task_id;
 
115
        pex_helenos->task_count++;
 
116
 
 
117
        return (pid_t) this_task->task_id;
92
118
}
93
119
 
94
 
static int pex_helenos_wait(struct pex_obj *obj ATTRIBUTE_UNUSED,
 
120
static int pex_helenos_wait(struct pex_obj *obj,
95
121
    pid_t pid, int *status,
96
122
    struct pex_time *time, int done,
97
123
    const char **errmsg, int *err)
98
124
{
 
125
        struct pex_helenos *pex_helenos = (struct pex_helenos *) obj->sysdep;
 
126
        task_id_t task_id = (task_id_t) pid;
 
127
 
 
128
        /* Find the task in the list of known ones. */
 
129
        struct pex_task_wait *this_task = NULL;
 
130
        for (size_t i = 0; i < pex_helenos->task_count; i++) {
 
131
                if (pex_helenos->tasks[i].task_id == task_id) {
 
132
                        this_task = &pex_helenos->tasks[i];
 
133
                        break;
 
134
                }
 
135
        }
 
136
 
 
137
        if (this_task == NULL) {
 
138
                *err = -ENOENT;
 
139
                *errmsg = "no such task registered";
 
140
                *status = *err;
 
141
                return -1;
 
142
        }
 
143
 
99
144
        /*
100
145
         * If @c done is set, we are cleaning-up. Kill the process
101
146
         * mercilessly.
102
147
         */
103
148
        if (done) {
104
 
                task_kill( (task_id_t) pid);
 
149
                task_kill(this_task->task_id);
105
150
        }
106
151
        
107
152
        if (time != NULL) {
110
155
        
111
156
        task_exit_t task_exit;
112
157
        int task_retval;
113
 
        int rc = task_wait((task_id_t) pid, &task_exit, &task_retval);
 
158
        int rc = task_wait(&this_task->task_wait, &task_exit, &task_retval);
 
159
 
114
160
        if (rc != 0) {
115
161
                *err = -rc;
116
162
                *errmsg = "task_wait";
127
173
        }
128
174
}
129
175
 
 
176
static void pex_helenos_cleanup(struct pex_obj  *obj)
 
177
{
 
178
        struct pex_helenos *pex_helenos = (struct pex_helenos *) obj->sysdep;
 
179
 
 
180
        free(pex_helenos->tasks);
 
181
        free(pex_helenos);
 
182
 
 
183
        obj->sysdep = NULL;
 
184
}
 
185
 
130
186
 
131
187
/*
132
188
 * PEX initialization.
141
197
        NULL,
142
198
        NULL,
143
199
        NULL,
144
 
        NULL
 
200
        pex_helenos_cleanup
145
201
};
146
202
 
147
203
struct pex_obj *pex_init(int flags, const char *pname, const char *tempbase)
148
204
{
149
 
        return pex_init_common(flags, pname, tempbase, &funcs);
 
205
        /* Common initialization. */
 
206
        struct pex_obj *obj = pex_init_common(flags, pname, tempbase, &funcs);
 
207
 
 
208
        /* Prepare the HelenOS specific data. */
 
209
        struct pex_helenos *pex_helenos = XNEW(struct pex_helenos);
 
210
        pex_helenos->tasks = NULL;
 
211
        pex_helenos->task_count = 0;
 
212
 
 
213
        obj->sysdep = pex_helenos;
 
214
 
 
215
        return obj;
150
216
}
151
217
 
152
218
#endif