[dd74e612] | 1 | /* |
---|
| 2 | * |
---|
| 3 | * Instantatiate a new terminal shell. |
---|
| 4 | * |
---|
[aed742c] | 5 | * Author: |
---|
[dd74e612] | 6 | * |
---|
[aed742c] | 7 | * WORK: fernando.ruiz@ctv.es |
---|
[dd74e612] | 8 | * HOME: correo@fernando-ruiz.com |
---|
| 9 | * |
---|
[4e5299f] | 10 | * The license and distribution terms for this file may be |
---|
| 11 | * found in the file LICENSE in this distribution or at |
---|
| 12 | * http://www.rtems.com/license/LICENSE. |
---|
[dd74e612] | 13 | * |
---|
| 14 | * $Id$ |
---|
| 15 | */ |
---|
[814d9588] | 16 | |
---|
[b2712e3] | 17 | #ifdef HAVE_CONFIG_H |
---|
| 18 | #include "config.h" |
---|
| 19 | #endif |
---|
[dd74e612] | 20 | |
---|
| 21 | #include <stdio.h> |
---|
[84206479] | 22 | #include <time.h> |
---|
[dd74e612] | 23 | |
---|
| 24 | #include <rtems.h> |
---|
| 25 | #include <rtems/error.h> |
---|
| 26 | #include <rtems/libio.h> |
---|
[aed742c] | 27 | #include <rtems/libio_.h> |
---|
| 28 | #include <rtems/system.h> |
---|
[b2712e3] | 29 | #include <rtems/shell.h> |
---|
[4e5299f] | 30 | #include <rtems/shellconfig.h> |
---|
[06f8e558] | 31 | #include <rtems/console.h> |
---|
[4e5299f] | 32 | #include "internal.h" |
---|
[dd74e612] | 33 | |
---|
| 34 | #include <termios.h> |
---|
| 35 | #include <string.h> |
---|
| 36 | #include <stdlib.h> |
---|
| 37 | #include <ctype.h> |
---|
[70d689a] | 38 | #include <sys/stat.h> |
---|
[dd74e612] | 39 | #include <unistd.h> |
---|
| 40 | #include <errno.h> |
---|
[b2712e3] | 41 | #include <pwd.h> |
---|
[dd74e612] | 42 | |
---|
[8a775c27] | 43 | rtems_shell_env_t rtems_global_shell_env = { |
---|
[06f8e558] | 44 | .magic = rtems_build_name('S', 'E', 'N', 'V'), |
---|
| 45 | .devname = CONSOLE_DEVICE_NAME, |
---|
| 46 | .taskname = "SHGL", |
---|
| 47 | .exit_shell = false, |
---|
| 48 | .forever = true, |
---|
| 49 | .errorlevel = -1, |
---|
| 50 | .echo = false, |
---|
| 51 | .cwd = "/", |
---|
| 52 | .input = NULL, |
---|
| 53 | .output = NULL, |
---|
| 54 | .output_append = false, |
---|
| 55 | .wake_on_end = RTEMS_ID_NONE, |
---|
[8a775c27] | 56 | .login_check = NULL |
---|
[06f8e558] | 57 | }; |
---|
| 58 | |
---|
| 59 | rtems_shell_env_t *rtems_current_shell_env = &rtems_global_shell_env; |
---|
[4e5299f] | 60 | |
---|
| 61 | /* |
---|
[814d9588] | 62 | * Initialize the shell user/process environment information |
---|
[4e5299f] | 63 | */ |
---|
[2eeb648c] | 64 | rtems_shell_env_t *rtems_shell_init_env( |
---|
[06f8e558] | 65 | rtems_shell_env_t *shell_env |
---|
[4e5299f] | 66 | ) |
---|
| 67 | { |
---|
[814d9588] | 68 | if ( !shell_env ) { |
---|
[2eeb648c] | 69 | shell_env = malloc(sizeof(rtems_shell_env_t)); |
---|
[814d9588] | 70 | if ( !shell_env ) |
---|
[be8ab6a] | 71 | return NULL; |
---|
[1ff9922] | 72 | *shell_env = rtems_global_shell_env; |
---|
| 73 | shell_env->taskname = NULL; |
---|
[4e5299f] | 74 | } |
---|
| 75 | |
---|
[814d9588] | 76 | return shell_env; |
---|
[dd74e612] | 77 | } |
---|
[4e5299f] | 78 | |
---|
[798ff5a] | 79 | /* |
---|
| 80 | * Completely free a shell_env_t and all associated memory |
---|
| 81 | */ |
---|
| 82 | void rtems_shell_env_free( |
---|
| 83 | void *ptr |
---|
| 84 | ) |
---|
| 85 | { |
---|
| 86 | rtems_shell_env_t *shell_env; |
---|
| 87 | shell_env = (rtems_shell_env_t *) ptr; |
---|
| 88 | |
---|
| 89 | if ( !ptr ) |
---|
| 90 | return; |
---|
| 91 | |
---|
| 92 | if ( shell_env->input ) |
---|
| 93 | free((void *)shell_env->input); |
---|
| 94 | if ( shell_env->output ) |
---|
| 95 | free((void *)shell_env->output); |
---|
| 96 | free( ptr ); |
---|
| 97 | } |
---|
| 98 | |
---|
[814d9588] | 99 | /* |
---|
| 100 | * Get a line of user input with modest features |
---|
| 101 | */ |
---|
[ea90df23] | 102 | int rtems_shell_line_editor( |
---|
| 103 | char *cmds[], |
---|
| 104 | int count, |
---|
| 105 | int size, |
---|
| 106 | const char *prompt, |
---|
| 107 | FILE *in, |
---|
| 108 | FILE *out |
---|
| 109 | ) |
---|
| 110 | { |
---|
| 111 | unsigned int extended_key; |
---|
[7c4cdeb9] | 112 | int c; |
---|
[ea90df23] | 113 | int col; |
---|
| 114 | int last_col; |
---|
| 115 | int output; |
---|
| 116 | char line[size]; |
---|
| 117 | char new_line[size]; |
---|
| 118 | int up; |
---|
| 119 | int cmd = -1; |
---|
| 120 | int inserting = 1; |
---|
[8a775c27] | 121 | |
---|
[ea90df23] | 122 | output = (out && isatty(fileno(in))); |
---|
| 123 | |
---|
| 124 | col = last_col = 0; |
---|
[8a775c27] | 125 | |
---|
[ea90df23] | 126 | tcdrain(fileno(in)); |
---|
| 127 | if (out) |
---|
| 128 | tcdrain(fileno(out)); |
---|
| 129 | |
---|
| 130 | if (output && prompt) |
---|
| 131 | fprintf(out, "\r%s", prompt); |
---|
[8a775c27] | 132 | |
---|
[ea90df23] | 133 | line[0] = 0; |
---|
| 134 | new_line[0] = 0; |
---|
[8a775c27] | 135 | |
---|
[ea90df23] | 136 | for (;;) { |
---|
[8a775c27] | 137 | |
---|
[ea90df23] | 138 | if (output) |
---|
| 139 | fflush(out); |
---|
| 140 | |
---|
| 141 | extended_key = rtems_shell_getchar(in); |
---|
| 142 | |
---|
| 143 | if (extended_key == EOF) |
---|
| 144 | return -2; |
---|
[8a775c27] | 145 | |
---|
[ea90df23] | 146 | c = extended_key & RTEMS_SHELL_KEYS_NORMAL_MASK; |
---|
[8a775c27] | 147 | |
---|
[ea90df23] | 148 | /* |
---|
| 149 | * Make the extended_key usable as a boolean. |
---|
| 150 | */ |
---|
| 151 | extended_key &= ~RTEMS_SHELL_KEYS_NORMAL_MASK; |
---|
[8a775c27] | 152 | |
---|
[ea90df23] | 153 | up = 0; |
---|
[8a775c27] | 154 | |
---|
[ea90df23] | 155 | if (extended_key) |
---|
| 156 | { |
---|
| 157 | switch (c) |
---|
| 158 | { |
---|
| 159 | case RTEMS_SHELL_KEYS_END: |
---|
| 160 | if (output) |
---|
| 161 | fprintf(out,line + col); |
---|
| 162 | col = (int) strlen (line); |
---|
| 163 | break; |
---|
| 164 | |
---|
| 165 | case RTEMS_SHELL_KEYS_HOME: |
---|
| 166 | if (output) { |
---|
| 167 | if (prompt) |
---|
| 168 | fprintf(out,"\r%s", prompt); |
---|
| 169 | } |
---|
| 170 | col = 0; |
---|
| 171 | break; |
---|
| 172 | |
---|
| 173 | case RTEMS_SHELL_KEYS_LARROW: |
---|
| 174 | if (col > 0) |
---|
| 175 | { |
---|
| 176 | col--; |
---|
| 177 | if (output) |
---|
| 178 | fputc('\b', out); |
---|
| 179 | } |
---|
| 180 | break; |
---|
| 181 | |
---|
| 182 | case RTEMS_SHELL_KEYS_RARROW: |
---|
| 183 | if ((col < size) && (line[col] != '\0')) |
---|
| 184 | { |
---|
| 185 | if (output) |
---|
| 186 | fprintf(out, "%c", line[col]); |
---|
| 187 | col++; |
---|
| 188 | } |
---|
| 189 | break; |
---|
| 190 | |
---|
| 191 | case RTEMS_SHELL_KEYS_UARROW: |
---|
| 192 | if ((cmd >= (count - 1)) || (strlen(cmds[cmd + 1]) == 0)) { |
---|
| 193 | if (output) |
---|
| 194 | fputc('\x7', out); |
---|
| 195 | break; |
---|
| 196 | } |
---|
| 197 | |
---|
| 198 | up = 1; |
---|
| 199 | |
---|
| 200 | /* drop through */ |
---|
| 201 | case RTEMS_SHELL_KEYS_DARROW: |
---|
[8a775c27] | 202 | |
---|
[ea90df23] | 203 | { |
---|
| 204 | int last_cmd = cmd; |
---|
| 205 | int clen = strlen (line); |
---|
| 206 | |
---|
| 207 | if (prompt) |
---|
| 208 | clen += strlen(prompt); |
---|
[8a775c27] | 209 | |
---|
[ea90df23] | 210 | if (up) { |
---|
| 211 | cmd++; |
---|
| 212 | } else { |
---|
| 213 | if (cmd < 0) { |
---|
| 214 | if (output) |
---|
| 215 | fprintf(out, "\x7"); |
---|
| 216 | break; |
---|
| 217 | } |
---|
| 218 | else |
---|
| 219 | cmd--; |
---|
| 220 | } |
---|
| 221 | |
---|
| 222 | if ((last_cmd < 0) || (strcmp(cmds[last_cmd], line) != 0)) |
---|
| 223 | memcpy (new_line, line, size); |
---|
| 224 | |
---|
| 225 | if (cmd < 0) |
---|
| 226 | memcpy (line, new_line, size); |
---|
| 227 | else |
---|
| 228 | memcpy (line, cmds[cmd], size); |
---|
[8a775c27] | 229 | |
---|
[ea90df23] | 230 | col = strlen (line); |
---|
[8a775c27] | 231 | |
---|
[ea90df23] | 232 | if (output) { |
---|
| 233 | fprintf(out,"\r%*c", clen, ' '); |
---|
| 234 | fprintf(out,"\r%s%s", prompt, line); |
---|
| 235 | } |
---|
| 236 | else { |
---|
| 237 | if (output) |
---|
| 238 | fputc('\x7', out); |
---|
| 239 | } |
---|
| 240 | } |
---|
| 241 | break; |
---|
| 242 | |
---|
| 243 | case RTEMS_SHELL_KEYS_DEL: |
---|
| 244 | if (line[col] != '\0') |
---|
| 245 | { |
---|
| 246 | int end; |
---|
| 247 | int bs; |
---|
| 248 | strcpy (&line[col], &line[col + 1]); |
---|
| 249 | if (output) { |
---|
| 250 | fprintf(out,"\r%s%s ", prompt, line); |
---|
| 251 | end = (int) strlen (line); |
---|
| 252 | for (bs = 0; bs < ((end - col) + 1); bs++) |
---|
| 253 | fputc('\b', out); |
---|
| 254 | } |
---|
| 255 | } |
---|
| 256 | break; |
---|
| 257 | |
---|
| 258 | case RTEMS_SHELL_KEYS_INS: |
---|
| 259 | inserting = inserting ? 0 : 1; |
---|
| 260 | break; |
---|
| 261 | } |
---|
| 262 | } |
---|
| 263 | else |
---|
| 264 | { |
---|
| 265 | switch (c) |
---|
| 266 | { |
---|
| 267 | case 1:/*Control-a*/ |
---|
| 268 | if (output) { |
---|
| 269 | if (prompt) |
---|
| 270 | fprintf(out,"\r%s", prompt); |
---|
| 271 | } |
---|
| 272 | col = 0; |
---|
| 273 | break; |
---|
[8a775c27] | 274 | |
---|
[ea90df23] | 275 | case 5:/*Control-e*/ |
---|
| 276 | if (output) |
---|
| 277 | fprintf(out,line + col); |
---|
| 278 | col = (int) strlen (line); |
---|
| 279 | break; |
---|
| 280 | |
---|
| 281 | case 11:/*Control-k*/ |
---|
| 282 | if (line[col]) { |
---|
| 283 | if (output) { |
---|
| 284 | int end = strlen(line); |
---|
| 285 | int bs; |
---|
| 286 | fprintf(out,"%*c", end - col, ' '); |
---|
| 287 | for (bs = 0; bs < (end - col); bs++) |
---|
| 288 | fputc('\b', out); |
---|
| 289 | } |
---|
| 290 | line[col] = '\0'; |
---|
| 291 | } |
---|
| 292 | break; |
---|
[8a775c27] | 293 | |
---|
[ea90df23] | 294 | case 0x04:/*Control-d*/ |
---|
| 295 | if (strlen(line)) |
---|
| 296 | break; |
---|
| 297 | case EOF: |
---|
| 298 | if (output) |
---|
[8c422e2] | 299 | fputc('\n', out); |
---|
[ea90df23] | 300 | return -2; |
---|
[8a775c27] | 301 | |
---|
[ea90df23] | 302 | case '\f': |
---|
| 303 | if (output) { |
---|
| 304 | int end; |
---|
| 305 | int bs; |
---|
| 306 | fputc('\f',out); |
---|
| 307 | fprintf(out,"\r%s%s", prompt, line); |
---|
| 308 | end = (int) strlen (line); |
---|
| 309 | for (bs = 0; bs < (end - col); bs++) |
---|
| 310 | fputc('\b', out); |
---|
| 311 | } |
---|
| 312 | break; |
---|
| 313 | |
---|
| 314 | case '\b': |
---|
| 315 | case '\x7f': |
---|
| 316 | if (col > 0) |
---|
| 317 | { |
---|
| 318 | int bs; |
---|
| 319 | col--; |
---|
| 320 | strcpy (line + col, line + col + 1); |
---|
| 321 | if (output) { |
---|
| 322 | fprintf(out,"\b%s \b", line + col); |
---|
| 323 | for (bs = 0; bs < ((int) strlen (line) - col); bs++) |
---|
| 324 | fputc('\b', out); |
---|
| 325 | } |
---|
| 326 | } |
---|
| 327 | break; |
---|
| 328 | |
---|
| 329 | case '\n': |
---|
| 330 | case '\r': |
---|
| 331 | { |
---|
| 332 | /* |
---|
| 333 | * Process the command. |
---|
| 334 | */ |
---|
| 335 | if (output) |
---|
| 336 | fprintf(out,"\n"); |
---|
[8a775c27] | 337 | |
---|
[ea90df23] | 338 | /* |
---|
| 339 | * Only process the command if we have a command and it is not |
---|
| 340 | * repeated in the history. |
---|
| 341 | */ |
---|
| 342 | if (strlen(line) == 0) { |
---|
| 343 | cmd = -1; |
---|
| 344 | } else { |
---|
| 345 | if ((cmd < 0) || (strcmp(line, cmds[cmd]) != 0)) { |
---|
| 346 | if (count > 1) |
---|
| 347 | memmove(cmds[1], cmds[0], (count - 1) * size); |
---|
| 348 | memmove (cmds[0], line, size); |
---|
| 349 | cmd = 0; |
---|
| 350 | } |
---|
| 351 | } |
---|
| 352 | } |
---|
| 353 | return cmd; |
---|
| 354 | |
---|
| 355 | default: |
---|
[7311863] | 356 | if ((col < (size - 1)) && (c >= ' ') && (c <= '~')) { |
---|
[ea90df23] | 357 | int end = strlen (line); |
---|
| 358 | if (inserting && (col < end) && (end < size)) { |
---|
| 359 | int ch, bs; |
---|
| 360 | for (ch = end + 1; ch > col; ch--) |
---|
| 361 | line[ch] = line[ch - 1]; |
---|
| 362 | if (output) { |
---|
| 363 | fprintf(out, line + col); |
---|
| 364 | for (bs = 0; bs < (end - col + 1); bs++) |
---|
| 365 | fputc('\b', out); |
---|
| 366 | } |
---|
| 367 | } |
---|
| 368 | line[col++] = c; |
---|
| 369 | if (col > end) |
---|
| 370 | line[col] = '\0'; |
---|
| 371 | if (output) |
---|
| 372 | fputc(c, out); |
---|
| 373 | } |
---|
| 374 | break; |
---|
| 375 | } |
---|
| 376 | } |
---|
| 377 | } |
---|
| 378 | return -2; |
---|
| 379 | } |
---|
| 380 | |
---|
[dd74e612] | 381 | /* ----------------------------------------------- * |
---|
[aed742c] | 382 | * - The shell TASK |
---|
[dd74e612] | 383 | * Poor but enough.. |
---|
| 384 | * TODO: Redirection. Tty Signals. ENVVARs. Shell language. |
---|
| 385 | * ----------------------------------------------- */ |
---|
| 386 | |
---|
[1167235] | 387 | void rtems_shell_init_issue(void) |
---|
| 388 | { |
---|
| 389 | static bool issue_inited=false; |
---|
[814d9588] | 390 | struct stat buf; |
---|
[dd74e612] | 391 | |
---|
[814d9588] | 392 | if (issue_inited) |
---|
| 393 | return; |
---|
[1167235] | 394 | issue_inited = true; |
---|
[70d689a] | 395 | |
---|
[814d9588] | 396 | /* dummy call to init /etc dir */ |
---|
| 397 | getpwnam("root"); |
---|
| 398 | |
---|
| 399 | if (stat("/etc/issue",&buf)) { |
---|
[2eeb648c] | 400 | rtems_shell_write_file("/etc/issue", |
---|
[1fae7b43] | 401 | "\n" |
---|
[2eeb648c] | 402 | "Welcome to @V\\n" |
---|
| 403 | "Login into @S\\n"); |
---|
[814d9588] | 404 | } |
---|
| 405 | |
---|
| 406 | if (stat("/etc/issue.net",&buf)) { |
---|
[2eeb648c] | 407 | rtems_shell_write_file("/etc/issue.net", |
---|
[1fae7b43] | 408 | "\n" |
---|
[2eeb648c] | 409 | "Welcome to %v\n" |
---|
| 410 | "running on %m\n"); |
---|
[814d9588] | 411 | } |
---|
[70d689a] | 412 | } |
---|
| 413 | |
---|
[8a775c27] | 414 | static bool rtems_shell_login(FILE * in,FILE * out) { |
---|
[6dd411aa] | 415 | FILE *fd; |
---|
| 416 | int c; |
---|
| 417 | time_t t; |
---|
| 418 | int times; |
---|
| 419 | char name[128]; |
---|
| 420 | char pass[128]; |
---|
| 421 | struct passwd *passwd; |
---|
| 422 | |
---|
[2eeb648c] | 423 | rtems_shell_init_issue(); |
---|
[6dd411aa] | 424 | setuid(0); |
---|
| 425 | setgid(0); |
---|
| 426 | rtems_current_user_env->euid = |
---|
| 427 | rtems_current_user_env->egid =0; |
---|
| 428 | |
---|
| 429 | if (out) { |
---|
[2eeb648c] | 430 | if ((rtems_current_shell_env->devname[5]!='p')|| |
---|
| 431 | (rtems_current_shell_env->devname[6]!='t')|| |
---|
| 432 | (rtems_current_shell_env->devname[7]!='y')) { |
---|
[6dd411aa] | 433 | fd = fopen("/etc/issue","r"); |
---|
| 434 | if (fd) { |
---|
| 435 | while ((c=fgetc(fd))!=EOF) { |
---|
| 436 | if (c=='@') { |
---|
| 437 | switch(c=fgetc(fd)) { |
---|
| 438 | case 'L': |
---|
[2eeb648c] | 439 | fprintf(out,"%s",rtems_current_shell_env->devname); |
---|
[6dd411aa] | 440 | break; |
---|
| 441 | case 'B': |
---|
| 442 | fprintf(out,"0"); |
---|
| 443 | break; |
---|
[70d689a] | 444 | case 'T': |
---|
[6dd411aa] | 445 | case 'D': |
---|
| 446 | time(&t); |
---|
| 447 | fprintf(out,"%s",ctime(&t)); |
---|
| 448 | break; |
---|
| 449 | case 'S': |
---|
| 450 | fprintf(out,"RTEMS"); |
---|
| 451 | break; |
---|
| 452 | case 'V': |
---|
[a3ddb08b] | 453 | fprintf(out,"%s\n%s",_RTEMS_version, _Copyright_Notice); |
---|
[6dd411aa] | 454 | break; |
---|
| 455 | case '@': |
---|
| 456 | fprintf(out,"@"); |
---|
| 457 | break; |
---|
| 458 | default : |
---|
| 459 | fprintf(out,"@%c",c); |
---|
| 460 | break; |
---|
| 461 | } |
---|
| 462 | } else if (c=='\\') { |
---|
| 463 | switch(c=fgetc(fd)) { |
---|
| 464 | case '\\': fprintf(out,"\\"); break; |
---|
| 465 | case 'b': fprintf(out,"\b"); break; |
---|
| 466 | case 'f': fprintf(out,"\f"); break; |
---|
| 467 | case 'n': fprintf(out,"\n"); break; |
---|
| 468 | case 'r': fprintf(out,"\r"); break; |
---|
| 469 | case 's': fprintf(out," "); break; |
---|
| 470 | case 't': fprintf(out,"\t"); break; |
---|
| 471 | case '@': fprintf(out,"@"); break; |
---|
| 472 | } |
---|
| 473 | } else { |
---|
| 474 | fputc(c,out); |
---|
| 475 | } |
---|
| 476 | } |
---|
| 477 | fclose(fd); |
---|
| 478 | } |
---|
| 479 | } else { |
---|
| 480 | fd = fopen("/etc/issue.net","r"); |
---|
| 481 | if (fd) { |
---|
| 482 | while ((c=fgetc(fd))!=EOF) { |
---|
| 483 | if (c=='%') { |
---|
| 484 | switch(c=fgetc(fd)) { |
---|
| 485 | case 't': |
---|
[2eeb648c] | 486 | fprintf(out,"%s",rtems_current_shell_env->devname); |
---|
[6dd411aa] | 487 | break; |
---|
| 488 | case 'h': |
---|
| 489 | fprintf(out,"0"); |
---|
| 490 | break; |
---|
| 491 | case 'D': |
---|
| 492 | fprintf(out," "); |
---|
| 493 | break; |
---|
| 494 | case 'd': |
---|
| 495 | time(&t); |
---|
| 496 | fprintf(out,"%s",ctime(&t)); |
---|
| 497 | break; |
---|
| 498 | case 's': |
---|
| 499 | fprintf(out,"RTEMS"); |
---|
| 500 | break; |
---|
| 501 | case 'm': |
---|
| 502 | fprintf(out,"(" CPU_NAME "/" CPU_MODEL_NAME ")"); |
---|
| 503 | break; |
---|
| 504 | case 'r': |
---|
| 505 | fprintf(out,_RTEMS_version); |
---|
| 506 | break; |
---|
| 507 | case 'v': |
---|
| 508 | fprintf(out,"%s\n%s",_RTEMS_version,_Copyright_Notice); |
---|
| 509 | break; |
---|
| 510 | case '%':fprintf(out,"%%"); |
---|
| 511 | break; |
---|
| 512 | default: |
---|
| 513 | fprintf(out,"%%%c",c); |
---|
| 514 | break; |
---|
| 515 | } |
---|
| 516 | } else { |
---|
| 517 | fputc(c,out); |
---|
| 518 | } |
---|
| 519 | } |
---|
| 520 | fclose(fd); |
---|
| 521 | } |
---|
| 522 | } |
---|
| 523 | } |
---|
| 524 | |
---|
[8a775c27] | 525 | return rtems_shell_login_prompt( |
---|
| 526 | in, |
---|
| 527 | out, |
---|
| 528 | rtems_current_shell_env->devname, |
---|
| 529 | rtems_current_shell_env->login_check |
---|
| 530 | ); |
---|
[b2712e3] | 531 | } |
---|
| 532 | |
---|
[814d9588] | 533 | #if defined(SHELL_DEBUG) |
---|
[2eeb648c] | 534 | void rtems_shell_print_env( |
---|
| 535 | rtems_shell_env_t * shell_env |
---|
[6dd411aa] | 536 | ) |
---|
| 537 | { |
---|
| 538 | if ( !shell_env ) { |
---|
| 539 | printk( "shell_env is NULL\n" ); |
---|
| 540 | return; |
---|
| 541 | } |
---|
| 542 | printk( "shell_env=%p\n" |
---|
| 543 | "shell_env->magic=0x%08x\t" |
---|
| 544 | "shell_env->devname=%s\n" |
---|
| 545 | "shell_env->taskname=%s\t" |
---|
| 546 | "shell_env->exit_shell=%d\t" |
---|
| 547 | "shell_env->forever=%d\n", |
---|
| 548 | shell_env->magic, |
---|
| 549 | shell_env->devname, |
---|
| 550 | ((shell_env->taskname) ? shell_env->taskname : "NOT SET"), |
---|
| 551 | shell_env->exit_shell, |
---|
| 552 | shell_env->forever |
---|
| 553 | ); |
---|
| 554 | } |
---|
| 555 | #endif |
---|
[dd74e612] | 556 | |
---|
[8e30a269] | 557 | rtems_task rtems_shell_task(rtems_task_argument task_argument) |
---|
[6dd411aa] | 558 | { |
---|
[1ff9922] | 559 | rtems_shell_env_t *shell_env = (rtems_shell_env_t*) task_argument; |
---|
| 560 | rtems_id wake_on_end = shell_env->wake_on_end; |
---|
| 561 | rtems_shell_main_loop( shell_env ); |
---|
| 562 | if (wake_on_end != RTEMS_INVALID_ID) |
---|
| 563 | rtems_event_send (wake_on_end, RTEMS_EVENT_1); |
---|
| 564 | rtems_task_delete( RTEMS_SELF ); |
---|
[6dd411aa] | 565 | } |
---|
[dd74e612] | 566 | |
---|
[ea90df23] | 567 | #define RTEMS_SHELL_MAXIMUM_ARGUMENTS (128) |
---|
| 568 | #define RTEMS_SHELL_CMD_SIZE (128) |
---|
| 569 | #define RTEMS_SHELL_CMD_COUNT (32) |
---|
| 570 | #define RTEMS_SHELL_PROMPT_SIZE (128) |
---|
[aed742c] | 571 | |
---|
[1167235] | 572 | bool rtems_shell_main_loop( |
---|
[2eeb648c] | 573 | rtems_shell_env_t *shell_env_arg |
---|
[798ff5a] | 574 | ) |
---|
[6dd411aa] | 575 | { |
---|
[2eeb648c] | 576 | rtems_shell_env_t *shell_env; |
---|
| 577 | rtems_shell_cmd_t *shell_cmd; |
---|
[6dd411aa] | 578 | rtems_status_code sc; |
---|
| 579 | struct termios term; |
---|
[8084ce80] | 580 | struct termios previous_term; |
---|
[ea90df23] | 581 | char *prompt = NULL; |
---|
| 582 | int cmd; |
---|
| 583 | int cmd_count = 1; /* assume a script and so only 1 command line */ |
---|
| 584 | char *cmds[RTEMS_SHELL_CMD_COUNT]; |
---|
[8c422e2] | 585 | char *cmd_argv; |
---|
[6dd411aa] | 586 | int argc; |
---|
[2eeb648c] | 587 | char *argv[RTEMS_SHELL_MAXIMUM_ARGUMENTS]; |
---|
[1167235] | 588 | bool result = true; |
---|
[ff90595] | 589 | bool input_file = false; |
---|
[1ff9922] | 590 | int line = 0; |
---|
[a3ddb08b] | 591 | FILE *stdinToClose = NULL; |
---|
| 592 | FILE *stdoutToClose = NULL; |
---|
[2eeb648c] | 593 | |
---|
| 594 | rtems_shell_initialize_command_set(); |
---|
| 595 | |
---|
[798ff5a] | 596 | shell_env = |
---|
| 597 | rtems_current_shell_env = rtems_shell_init_env( shell_env_arg ); |
---|
[8a775c27] | 598 | |
---|
[2eeb648c] | 599 | /* |
---|
| 600 | * @todo chrisj |
---|
[1ff9922] | 601 | * Remove the use of task variables. Change to have a single |
---|
[2eeb648c] | 602 | * allocation per shell and then set into a notepad register |
---|
[1ff9922] | 603 | * in the TCB. Provide a function to return the pointer. |
---|
[2eeb648c] | 604 | * Task variables are a virus to embedded systems software. |
---|
| 605 | */ |
---|
[798ff5a] | 606 | sc = rtems_task_variable_add( |
---|
| 607 | RTEMS_SELF, |
---|
| 608 | (void*)&rtems_current_shell_env, |
---|
| 609 | rtems_shell_env_free |
---|
| 610 | ); |
---|
[6dd411aa] | 611 | if (sc != RTEMS_SUCCESSFUL) { |
---|
| 612 | rtems_error(sc,"rtems_task_variable_add(current_shell_env):"); |
---|
[1167235] | 613 | return false; |
---|
[814d9588] | 614 | } |
---|
[dd74e612] | 615 | |
---|
[b2712e3] | 616 | setuid(0); |
---|
| 617 | setgid(0); |
---|
[ea90df23] | 618 | |
---|
| 619 | rtems_current_user_env->euid = rtems_current_user_env->egid = 0; |
---|
[6dd411aa] | 620 | |
---|
[1ff9922] | 621 | fileno(stdout); |
---|
| 622 | |
---|
[8a775c27] | 623 | /* fprintf( stderr, |
---|
[a3ddb08b] | 624 | "-%s-%s-\n", shell_env->input, shell_env->output ); |
---|
[ea90df23] | 625 | */ |
---|
[be8ab6a] | 626 | |
---|
| 627 | if (shell_env->output && strcmp(shell_env->output, "stdout") != 0) { |
---|
[1ff9922] | 628 | if (strcmp(shell_env->output, "stderr") == 0) { |
---|
| 629 | stdout = stderr; |
---|
| 630 | } else if (strcmp(shell_env->output, "/dev/null") == 0) { |
---|
| 631 | fclose (stdout); |
---|
| 632 | } else { |
---|
| 633 | FILE *output = fopen(shell_env_arg->output, |
---|
| 634 | shell_env_arg->output_append ? "a" : "w"); |
---|
| 635 | if (!output) { |
---|
| 636 | fprintf(stderr, "shell: open output %s failed: %s\n", |
---|
| 637 | shell_env_arg->output, strerror(errno)); |
---|
[1167235] | 638 | return false; |
---|
[1ff9922] | 639 | } |
---|
| 640 | stdout = output; |
---|
[a3ddb08b] | 641 | stdoutToClose = output; |
---|
[1ff9922] | 642 | } |
---|
| 643 | } |
---|
[8a775c27] | 644 | |
---|
[be8ab6a] | 645 | if (shell_env->input && strcmp(shell_env_arg->input, "stdin") != 0) { |
---|
[1ff9922] | 646 | FILE *input = fopen(shell_env_arg->input, "r"); |
---|
| 647 | if (!input) { |
---|
| 648 | fprintf(stderr, "shell: open input %s failed: %s\n", |
---|
| 649 | shell_env_arg->input, strerror(errno)); |
---|
[1167235] | 650 | return false; |
---|
[1ff9922] | 651 | } |
---|
| 652 | stdin = input; |
---|
[a3ddb08b] | 653 | stdinToClose = input; |
---|
[1167235] | 654 | shell_env->forever = false; |
---|
| 655 | input_file =true; |
---|
[1ff9922] | 656 | } |
---|
| 657 | else { |
---|
| 658 | /* make a raw terminal,Linux Manuals */ |
---|
[8084ce80] | 659 | if (tcgetattr(fileno(stdin), &previous_term) >= 0) { |
---|
| 660 | term = previous_term; |
---|
[1ff9922] | 661 | term.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON); |
---|
| 662 | term.c_oflag &= ~OPOST; |
---|
| 663 | term.c_oflag |= (OPOST|ONLCR); /* But with cr+nl on output */ |
---|
| 664 | term.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN); |
---|
| 665 | term.c_cflag |= CLOCAL | CREAD; |
---|
| 666 | term.c_cc[VMIN] = 1; |
---|
| 667 | term.c_cc[VTIME] = 0; |
---|
| 668 | if (tcsetattr (fileno(stdin), TCSADRAIN, &term) < 0) { |
---|
| 669 | fprintf(stderr, |
---|
| 670 | "shell:cannot set terminal attributes(%s)\n",shell_env->devname); |
---|
| 671 | } |
---|
[814d9588] | 672 | } |
---|
[ea90df23] | 673 | cmd_count = RTEMS_SHELL_CMD_COUNT; |
---|
| 674 | prompt = malloc(RTEMS_SHELL_PROMPT_SIZE); |
---|
| 675 | if (!prompt) |
---|
| 676 | fprintf(stderr, |
---|
| 677 | "shell:cannot allocate prompt memory\n"); |
---|
[6dd411aa] | 678 | } |
---|
| 679 | |
---|
[1ff9922] | 680 | setvbuf(stdin,NULL,_IONBF,0); /* Not buffered*/ |
---|
| 681 | setvbuf(stdout,NULL,_IONBF,0); /* Not buffered*/ |
---|
| 682 | |
---|
[2eeb648c] | 683 | rtems_shell_initialize_command_set(); |
---|
[8a775c27] | 684 | |
---|
[ea90df23] | 685 | /* |
---|
| 686 | * Allocate the command line buffers. |
---|
| 687 | */ |
---|
[8c422e2] | 688 | cmd_argv = malloc (RTEMS_SHELL_CMD_SIZE); |
---|
| 689 | if (!cmd_argv) { |
---|
| 690 | fprintf(stderr, "no memory for command line buffers\n" ); |
---|
| 691 | } |
---|
[8a775c27] | 692 | |
---|
[ea90df23] | 693 | cmds[0] = calloc (cmd_count, RTEMS_SHELL_CMD_SIZE); |
---|
| 694 | if (!cmds[0]) { |
---|
| 695 | fprintf(stderr, "no memory for command line buffers\n" ); |
---|
| 696 | } |
---|
[8c422e2] | 697 | |
---|
| 698 | if (cmd_argv && cmds[0]) { |
---|
[ea90df23] | 699 | |
---|
| 700 | memset (cmds[0], 0, cmd_count * RTEMS_SHELL_CMD_SIZE); |
---|
| 701 | |
---|
| 702 | for (cmd = 1; cmd < cmd_count; cmd++) { |
---|
| 703 | cmds[cmd] = cmds[cmd - 1] + RTEMS_SHELL_CMD_SIZE; |
---|
[6dd411aa] | 704 | } |
---|
[8a775c27] | 705 | |
---|
[ea90df23] | 706 | do { |
---|
| 707 | /* Set again root user and root filesystem, side effect of set_priv..*/ |
---|
| 708 | sc = rtems_libio_set_private_env(); |
---|
| 709 | if (sc != RTEMS_SUCCESSFUL) { |
---|
| 710 | rtems_error(sc,"rtems_libio_set_private_env():"); |
---|
[1167235] | 711 | result = false; |
---|
[ea90df23] | 712 | break; |
---|
[1ff9922] | 713 | } |
---|
[7c4cdeb9] | 714 | |
---|
| 715 | /* |
---|
| 716 | * By using result here, we can fall to the bottom of the |
---|
| 717 | * loop when the connection is dropped during login and |
---|
| 718 | * keep on trucking. |
---|
| 719 | */ |
---|
[8a775c27] | 720 | if (shell_env->login_check != NULL) { |
---|
| 721 | result = rtems_shell_login(stdin,stdout); |
---|
[7c4cdeb9] | 722 | } else { |
---|
[06f8e558] | 723 | result = true; |
---|
[7c4cdeb9] | 724 | } |
---|
| 725 | |
---|
| 726 | if (result) { |
---|
[ea90df23] | 727 | const char *c; |
---|
| 728 | memset (cmds[0], 0, cmd_count * RTEMS_SHELL_CMD_SIZE); |
---|
[1ff9922] | 729 | if (!input_file) { |
---|
[ea90df23] | 730 | rtems_shell_cat_file(stdout,"/etc/motd"); |
---|
| 731 | fprintf(stdout, "\n" |
---|
| 732 | "RTEMS SHELL (Ver.1.0-FRC):%s. " \ |
---|
| 733 | __DATE__". 'help' to list commands.\n", |
---|
| 734 | shell_env->devname); |
---|
[1ff9922] | 735 | } |
---|
[55c64fc9] | 736 | |
---|
| 737 | if (input_file) |
---|
| 738 | chdir(shell_env->cwd); |
---|
| 739 | else |
---|
| 740 | chdir("/"); /* XXX: chdir to getpwent homedir */ |
---|
[8a775c27] | 741 | |
---|
[1167235] | 742 | shell_env->exit_shell = false; |
---|
[ea90df23] | 743 | |
---|
| 744 | for (;;) { |
---|
| 745 | int cmd; |
---|
[8a775c27] | 746 | |
---|
[ea90df23] | 747 | /* Prompt section */ |
---|
| 748 | if (prompt) { |
---|
| 749 | rtems_shell_get_prompt(shell_env, prompt, |
---|
| 750 | RTEMS_SHELL_PROMPT_SIZE); |
---|
| 751 | } |
---|
[8a775c27] | 752 | |
---|
[ea90df23] | 753 | /* getcmd section */ |
---|
| 754 | cmd = rtems_shell_line_editor(cmds, cmd_count, |
---|
| 755 | RTEMS_SHELL_CMD_SIZE, prompt, |
---|
| 756 | stdin, stdout); |
---|
| 757 | |
---|
| 758 | if (cmd == -1) |
---|
| 759 | continue; /* empty line */ |
---|
[8a775c27] | 760 | |
---|
[ea90df23] | 761 | if (cmd == -2) |
---|
| 762 | break; /*EOF*/ |
---|
| 763 | |
---|
| 764 | line++; |
---|
| 765 | |
---|
[55c64fc9] | 766 | if (shell_env->echo) |
---|
| 767 | fprintf(stdout, "%d: %s\n", line, cmds[cmd]); |
---|
[8a775c27] | 768 | |
---|
[ea90df23] | 769 | /* evaluate cmd section */ |
---|
| 770 | c = cmds[cmd]; |
---|
| 771 | while (*c) { |
---|
| 772 | if (!isblank(*c)) |
---|
| 773 | break; |
---|
| 774 | c++; |
---|
| 775 | } |
---|
[1ff9922] | 776 | |
---|
[ea90df23] | 777 | if (*c == '\0') /* empty line */ |
---|
| 778 | continue; |
---|
[a5de1ef] | 779 | |
---|
[ea90df23] | 780 | if (*c == '#') { /* comment character */ |
---|
| 781 | cmds[cmd][0] = 0; |
---|
| 782 | continue; |
---|
| 783 | } |
---|
[1ff9922] | 784 | |
---|
[ea90df23] | 785 | if (!strcmp(cmds[cmd],"bye") || !strcmp(cmds[cmd],"exit")) { |
---|
| 786 | fprintf(stdout, "Shell exiting\n" ); |
---|
| 787 | break; |
---|
| 788 | } else if (!strcmp(cmds[cmd],"shutdown")) { /* exit application */ |
---|
| 789 | fprintf(stdout, "System shutting down at user request\n" ); |
---|
| 790 | exit(0); |
---|
| 791 | } |
---|
[6dd411aa] | 792 | |
---|
[ea90df23] | 793 | /* exec cmd section */ |
---|
| 794 | /* TODO: |
---|
| 795 | * To avoid user crash catch the signals. |
---|
| 796 | * Open a new stdio files with posibility of redirection * |
---|
| 797 | * Run in a new shell task background. (unix &) |
---|
| 798 | * Resuming. A little bash. |
---|
| 799 | */ |
---|
[8c422e2] | 800 | memcpy (cmd_argv, cmds[cmd], RTEMS_SHELL_CMD_SIZE); |
---|
| 801 | if (!rtems_shell_make_args(cmd_argv, &argc, argv, |
---|
[ea90df23] | 802 | RTEMS_SHELL_MAXIMUM_ARGUMENTS)) { |
---|
| 803 | shell_cmd = rtems_shell_lookup_cmd(argv[0]); |
---|
| 804 | if ( argv[0] == NULL ) { |
---|
| 805 | shell_env->errorlevel = -1; |
---|
| 806 | } else if ( shell_cmd == NULL ) { |
---|
| 807 | shell_env->errorlevel = rtems_shell_script_file(argc, argv); |
---|
| 808 | } else { |
---|
| 809 | shell_env->errorlevel = shell_cmd->command(argc, argv); |
---|
| 810 | } |
---|
[6dd411aa] | 811 | } |
---|
[ea90df23] | 812 | |
---|
| 813 | /* end exec cmd section */ |
---|
| 814 | if (shell_env->exit_shell) |
---|
| 815 | break; |
---|
[6dd411aa] | 816 | } |
---|
| 817 | |
---|
[ea90df23] | 818 | fflush( stdout ); |
---|
| 819 | fflush( stderr ); |
---|
[6dd411aa] | 820 | } |
---|
[ea90df23] | 821 | } while (result && shell_env->forever); |
---|
| 822 | |
---|
| 823 | } |
---|
| 824 | |
---|
[8c422e2] | 825 | if (cmds[0]) |
---|
| 826 | free (cmds[0]); |
---|
| 827 | if (cmd_argv) |
---|
| 828 | free (cmd_argv); |
---|
[798ff5a] | 829 | if (prompt) |
---|
| 830 | free (prompt); |
---|
| 831 | |
---|
[8084ce80] | 832 | if (stdinToClose) { |
---|
[a3ddb08b] | 833 | fclose( stdinToClose ); |
---|
[8084ce80] | 834 | } else { |
---|
[798ff5a] | 835 | if (tcsetattr(fileno(stdin), TCSADRAIN, &previous_term) < 0) { |
---|
[8084ce80] | 836 | fprintf( |
---|
| 837 | stderr, |
---|
| 838 | "shell: cannot reset terminal attributes (%s)\n", |
---|
| 839 | shell_env->devname |
---|
| 840 | ); |
---|
| 841 | } |
---|
| 842 | } |
---|
[a3ddb08b] | 843 | if ( stdoutToClose ) |
---|
| 844 | fclose( stdoutToClose ); |
---|
[1ff9922] | 845 | return result; |
---|
[dd74e612] | 846 | } |
---|
[6dd411aa] | 847 | |
---|
[dd74e612] | 848 | /* ----------------------------------------------- */ |
---|
[cbd1e87] | 849 | static rtems_status_code rtems_shell_run ( |
---|
| 850 | const char *task_name, |
---|
| 851 | size_t task_stacksize, |
---|
| 852 | rtems_task_priority task_priority, |
---|
| 853 | const char *devname, |
---|
| 854 | bool forever, |
---|
| 855 | bool wait, |
---|
| 856 | const char *input, |
---|
| 857 | const char *output, |
---|
| 858 | bool output_append, |
---|
| 859 | rtems_id wake_on_end, |
---|
| 860 | bool echo, |
---|
| 861 | rtems_shell_login_check_t login_check |
---|
[6dd411aa] | 862 | ) |
---|
| 863 | { |
---|
| 864 | rtems_id task_id; |
---|
| 865 | rtems_status_code sc; |
---|
[2eeb648c] | 866 | rtems_shell_env_t *shell_env; |
---|
[4e5299f] | 867 | rtems_name name; |
---|
| 868 | |
---|
[e41eaa88] | 869 | if ( task_name && strlen(task_name) >= 4) |
---|
[814d9588] | 870 | name = rtems_build_name( |
---|
| 871 | task_name[0], task_name[1], task_name[2], task_name[3]); |
---|
[4e5299f] | 872 | else |
---|
| 873 | name = rtems_build_name( 'S', 'E', 'N', 'V' ); |
---|
[6dd411aa] | 874 | |
---|
| 875 | sc = rtems_task_create( |
---|
[4e5299f] | 876 | name, |
---|
[6dd411aa] | 877 | task_priority, |
---|
[4e5299f] | 878 | task_stacksize, |
---|
[3899a537] | 879 | RTEMS_PREEMPT | RTEMS_TIMESLICE | RTEMS_NO_ASR, |
---|
[6dd411aa] | 880 | RTEMS_LOCAL | RTEMS_FLOATING_POINT, |
---|
| 881 | &task_id |
---|
| 882 | ); |
---|
| 883 | if (sc != RTEMS_SUCCESSFUL) { |
---|
| 884 | rtems_error(sc,"creating task %s in shell_init()",task_name); |
---|
| 885 | return sc; |
---|
| 886 | } |
---|
| 887 | |
---|
[2eeb648c] | 888 | shell_env = rtems_shell_init_env( NULL ); |
---|
[6dd411aa] | 889 | if ( !shell_env ) { |
---|
[1ff9922] | 890 | rtems_error(RTEMS_NO_MEMORY, |
---|
| 891 | "allocating shell_env %s in shell_init()",task_name); |
---|
[6dd411aa] | 892 | return RTEMS_NO_MEMORY; |
---|
| 893 | } |
---|
[1ff9922] | 894 | shell_env->devname = devname; |
---|
| 895 | shell_env->taskname = task_name; |
---|
[1167235] | 896 | shell_env->exit_shell = false; |
---|
[1ff9922] | 897 | shell_env->forever = forever; |
---|
[55c64fc9] | 898 | shell_env->echo = echo; |
---|
[1ff9922] | 899 | shell_env->input = strdup (input); |
---|
| 900 | shell_env->output = strdup (output); |
---|
| 901 | shell_env->output_append = output_append; |
---|
| 902 | shell_env->wake_on_end = wake_on_end; |
---|
[8a775c27] | 903 | shell_env->login_check = login_check; |
---|
[6dd411aa] | 904 | |
---|
[55c64fc9] | 905 | getcwd(shell_env->cwd, sizeof(shell_env->cwd)); |
---|
| 906 | |
---|
[798ff5a] | 907 | sc = rtems_task_start(task_id, rtems_shell_task, |
---|
[2eeb648c] | 908 | (rtems_task_argument) shell_env); |
---|
[798ff5a] | 909 | if (sc != RTEMS_SUCCESSFUL) { |
---|
| 910 | rtems_error(sc,"starting task %s in shell_init()",task_name); |
---|
| 911 | return sc; |
---|
| 912 | } |
---|
| 913 | |
---|
| 914 | if (wait) { |
---|
| 915 | rtems_event_set out; |
---|
| 916 | sc = rtems_event_receive (RTEMS_EVENT_1, RTEMS_WAIT, 0, &out); |
---|
| 917 | } |
---|
| 918 | |
---|
| 919 | return 0; |
---|
[6dd411aa] | 920 | } |
---|
[1ff9922] | 921 | |
---|
[798ff5a] | 922 | rtems_status_code rtems_shell_init( |
---|
[cbd1e87] | 923 | const char *task_name, |
---|
| 924 | size_t task_stacksize, |
---|
| 925 | rtems_task_priority task_priority, |
---|
| 926 | const char *devname, |
---|
| 927 | bool forever, |
---|
| 928 | bool wait, |
---|
| 929 | rtems_shell_login_check_t login_check |
---|
[1ff9922] | 930 | ) |
---|
| 931 | { |
---|
[06f8e558] | 932 | rtems_id to_wake = RTEMS_ID_NONE; |
---|
[798ff5a] | 933 | |
---|
| 934 | if ( wait ) |
---|
| 935 | to_wake = rtems_task_self(); |
---|
| 936 | |
---|
| 937 | return rtems_shell_run( |
---|
| 938 | task_name, /* task_name */ |
---|
| 939 | task_stacksize, /* task_stacksize */ |
---|
| 940 | task_priority, /* task_priority */ |
---|
| 941 | devname, /* devname */ |
---|
| 942 | forever, /* forever */ |
---|
| 943 | wait, /* wait */ |
---|
| 944 | "stdin", /* input */ |
---|
| 945 | "stdout", /* output */ |
---|
[06f8e558] | 946 | false, /* output_append */ |
---|
[798ff5a] | 947 | to_wake, /* wake_on_end */ |
---|
[06f8e558] | 948 | false, /* echo */ |
---|
[8a775c27] | 949 | login_check /* login check */ |
---|
[798ff5a] | 950 | ); |
---|
[1ff9922] | 951 | } |
---|
| 952 | |
---|
| 953 | rtems_status_code rtems_shell_script ( |
---|
[e41eaa88] | 954 | const char *task_name, |
---|
[06f8e558] | 955 | size_t task_stacksize, |
---|
[1ff9922] | 956 | rtems_task_priority task_priority, |
---|
| 957 | const char* input, |
---|
| 958 | const char* output, |
---|
[06f8e558] | 959 | bool output_append, |
---|
| 960 | bool wait, |
---|
| 961 | bool echo |
---|
[1ff9922] | 962 | ) |
---|
| 963 | { |
---|
| 964 | rtems_id current_task = RTEMS_INVALID_ID; |
---|
| 965 | rtems_status_code sc; |
---|
| 966 | |
---|
| 967 | if (wait) { |
---|
| 968 | sc = rtems_task_ident (RTEMS_SELF, RTEMS_LOCAL, ¤t_task); |
---|
| 969 | if (sc != RTEMS_SUCCESSFUL) |
---|
| 970 | return sc; |
---|
| 971 | } |
---|
[8a775c27] | 972 | |
---|
[798ff5a] | 973 | sc = rtems_shell_run( |
---|
| 974 | task_name, /* task_name */ |
---|
| 975 | task_stacksize, /* task_stacksize */ |
---|
| 976 | task_priority, /* task_priority */ |
---|
| 977 | NULL, /* devname */ |
---|
| 978 | 0, /* forever */ |
---|
| 979 | wait, /* wait */ |
---|
| 980 | input, /* input */ |
---|
| 981 | output, /* output */ |
---|
| 982 | output_append, /* output_append */ |
---|
| 983 | current_task, /* wake_on_end */ |
---|
[06f8e558] | 984 | echo, /* echo */ |
---|
[8a775c27] | 985 | NULL /* login check */ |
---|
[798ff5a] | 986 | ); |
---|
[1ff9922] | 987 | if (sc != RTEMS_SUCCESSFUL) |
---|
| 988 | return sc; |
---|
| 989 | |
---|
| 990 | return sc; |
---|
| 991 | } |
---|