source: mainline/uspace/app/sbi/src/os/helenos.c@ 1c635d6

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 1c635d6 was 1c635d6, checked in by Martin Sucha <sucha14@…>, 11 years ago

Do not hold a task's return value after it has disconnected.

Holding the task's return value meant that if nobody waited
for task's result, it polluted NS's memory. This was apparently
done because of a race between spawning a task and waiting for it.

We solve this problem in another way: ns discards the return value
as soon as the task disconnects from it. This typically happens
when the task finishes its execution. In order to avoid the race,
we send the wait request to ns while spawning the task (i.e. when
we talk to the loader), but before we allow the loaded program
to run.

Fixes #132

  • Property mode set to 100644
File size: 6.3 KB
RevLine 
[94d484a]1/*
2 * Copyright (c) 2010 Jiri Svoboda
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
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.
16 *
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.
27 */
28
29/** @file HelenOS-specific code. */
30
[051bc69a]31#include <assert.h>
[94d484a]32#include <errno.h>
33#include <stdio.h>
34#include <stdlib.h>
[1faa995]35#include <str.h>
[94d484a]36#include <task.h>
[1ebc1a62]37#include <tinput.h>
[d9fae235]38#include <str_error.h>
[94d484a]39
40#include "os.h"
41
[074444f]42/** Path to executable file via which we have been invoked. */
43static char *ef_path;
44
[94d484a]45/*
46 * Using HelenOS-specific string API.
47 */
48
[1ebc1a62]49static tinput_t *tinput = NULL;
50
[38aaacc2]51/** Concatenate two strings.
52 *
53 * @param a First string
54 * @param b Second string
55 * @return New string, concatenation of @a a and @a b.
56 */
[94d484a]57char *os_str_acat(const char *a, const char *b)
58{
59 int a_size, b_size;
60 char *str;
61
62 a_size = str_size(a);
63 b_size = str_size(b);
64
65 str = malloc(a_size + b_size + 1);
66 if (str == NULL) {
67 printf("Memory allocation error.\n");
68 exit(1);
69 }
70
71 memcpy(str, a, a_size);
72 memcpy(str + a_size, b, b_size);
73 str[a_size + b_size] = '\0';
74
75 return str;
76}
77
[051bc69a]78/** Return slice (substring) of a string.
79 *
80 * Copies the specified range of characters from @a str and returns it
81 * as a newly allocated string. @a start + @a length must be less than
82 * or equal to the length of @a str.
83 *
84 * @param str String
85 * @param start Index of first character (starting from zero).
86 * @param length Number of characters to copy.
87 *
88 * @return Newly allocated string holding the slice.
89 */
90char *os_str_aslice(const char *str, size_t start, size_t length)
91{
92 char *slice;
93 size_t offset;
94 size_t i;
95 size_t size;
96 wchar_t c;
97
98 assert(start + length <= str_length(str));
99
100 offset = 0;
101 for (i = 0; i < start; ++i) {
102 c = str_decode(str, &offset, STR_NO_LIMIT);
103 assert(c != '\0');
104 assert(c != U_SPECIAL);
105 (void) c;
106 }
107
108 size = str_lsize(str, length);
109 slice = str_ndup(str + offset, size);
110
111 return slice;
112}
113
[38aaacc2]114/** Compare two strings.
115 *
116 * @param a First string
117 * @param b Second string
118 * @return Zero if equal, nonzero if not equal
119 */
[94d484a]120int os_str_cmp(const char *a, const char *b)
121{
122 return str_cmp(a, b);
123}
124
[38aaacc2]125/** Return number of characters in string.
126 *
127 * @param str String
128 * @return Number of characters in @a str.
129 */
[074444f]130size_t os_str_length(const char *str)
131{
132 return str_length(str);
133}
134
[38aaacc2]135/** Duplicate string.
136 *
137 * @param str String
138 * @return New string, duplicate of @a str.
139 */
[94d484a]140char *os_str_dup(const char *str)
141{
142 return str_dup(str);
143}
144
[38aaacc2]145/** Get character from string at the given index.
146 *
147 * @param str String
148 * @param index Character index (starting from zero).
149 * @param out_char Place to store character.
150 * @return EOK on success, EINVAL if index is out of bounds,
151 * EIO on decoding error.
152 */
[d0febca]153int os_str_get_char(const char *str, int index, int *out_char)
154{
155 size_t offset;
156 int i;
157 wchar_t c;
158
159 if (index < 0)
160 return EINVAL;
161
162 offset = 0;
163 for (i = 0; i <= index; ++i) {
164 c = str_decode(str, &offset, STR_NO_LIMIT);
165 if (c == '\0')
166 return EINVAL;
167 if (c == U_SPECIAL)
168 return EIO;
169 }
170
171 *out_char = (int) c;
172 return EOK;
173}
174
[c5cb943d]175/** Convert character to new string.
176 *
177 * @param chr Character
178 * @return Newly allocated string.
179 */
180char *os_chr_to_astr(wchar_t chr)
181{
182 char *str;
183 size_t offset;
184
185 str = malloc(STR_BOUNDS(1) + 1);
186 if (str == NULL) {
187 printf("Memory allocation error.\n");
188 exit(1);
189 }
190
191 offset = 0;
192 if (chr_encode(chr, str, &offset, STR_BOUNDS(1)) != EOK) {
193 /* XXX Should handle gracefully */
194 printf("String conversion error.\n");
195 exit(1);
196 }
197
198 str[offset] = '\0';
199 return str;
200}
201
[23de644]202/** Display survival help message. */
203void os_input_disp_help(void)
204{
205 printf("Press Ctrl-Q to quit.\n");
206}
207
[38aaacc2]208/** Read one line of input from the user.
209 *
210 * @param ptr Place to store pointer to new string.
211 */
[9be9c4d]212int os_input_line(const char *prompt, char **ptr)
[1ebc1a62]213{
214 char *line;
[5db9084]215 int rc;
[1ebc1a62]216
217 if (tinput == NULL) {
218 tinput = tinput_new();
219 if (tinput == NULL)
220 return EIO;
[9be9c4d]221
222 tinput_set_prompt(tinput, prompt);
[1ebc1a62]223 }
224
[5db9084]225 rc = tinput_read(tinput, &line);
226 if (rc == ENOENT) {
227 /* User-requested abort */
228 *ptr = os_str_dup("");
229 return EOK;
230 }
231
232 if (rc != EOK) {
233 /* Error in communication with console */
[1ebc1a62]234 return EIO;
[5db9084]235 }
[1ebc1a62]236
237 /* XXX Input module needs trailing newline to keep going. */
238 *ptr = os_str_acat(line, "\n");
239 free(line);
240
241 return EOK;
242}
243
[38aaacc2]244/** Simple command execution.
245 *
246 * @param cmd Command and arguments (NULL-terminated list of strings.)
247 * Command is present just one, not duplicated.
248 */
[94d484a]249int os_exec(char *const cmd[])
250{
251 task_id_t tid;
[1c635d6]252 task_wait_t twait;
[94d484a]253 task_exit_t texit;
[0485135]254 int rc, retval;
[94d484a]255
[1c635d6]256 rc = task_spawnv(&tid, &twait, cmd[0], (char const * const *) cmd);
[0485135]257 if (rc != EOK) {
[d9fae235]258 printf("Error: Failed spawning '%s' (%s).\n", cmd[0],
[0485135]259 str_error(rc));
[94d484a]260 exit(1);
261 }
262
263 /* XXX Handle exit status and return value. */
[1c635d6]264 rc = task_wait(&twait, &texit, &retval);
[0485135]265 (void) rc;
[94d484a]266
267 return EOK;
268}
[074444f]269
[38aaacc2]270/** Store the executable file path via which we were executed.
271 *
272 * @param path Executable path via which we were executed.
273 */
[074444f]274void os_store_ef_path(char *path)
275{
276 ef_path = path;
277}
278
279/** Return path to the Sysel library
280 *
281 * @return New string. Caller should deallocate it using @c free().
282 */
283char *os_get_lib_path(void)
284{
285 return os_str_dup("/src/sysel/lib");
286}
Note: See TracBrowser for help on using the repository browser.