[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 | |
---|
[06f8e558] | 43 | rtems_shell_env_t rtems_global_shell_env = { |
---|
| 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, |
---|
| 56 | .login = true |
---|
| 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; |
---|
| 121 | |
---|
| 122 | output = (out && isatty(fileno(in))); |
---|
| 123 | |
---|
| 124 | col = last_col = 0; |
---|
| 125 | |
---|
| 126 | tcdrain(fileno(in)); |
---|
| 127 | if (out) |
---|
| 128 | tcdrain(fileno(out)); |
---|
| 129 | |
---|
| 130 | if (output && prompt) |
---|
| 131 | fprintf(out, "\r%s", prompt); |
---|
| 132 | |
---|
| 133 | line[0] = 0; |
---|
| 134 | new_line[0] = 0; |
---|
| 135 | |
---|
| 136 | for (;;) { |
---|
| 137 | |
---|
| 138 | if (output) |
---|
| 139 | fflush(out); |
---|
| 140 | |
---|
| 141 | extended_key = rtems_shell_getchar(in); |
---|
| 142 | |
---|
| 143 | if (extended_key == EOF) |
---|
| 144 | return -2; |
---|
| 145 | |
---|
| 146 | c = extended_key & RTEMS_SHELL_KEYS_NORMAL_MASK; |
---|
| 147 | |
---|
| 148 | /* |
---|
| 149 | * Make the extended_key usable as a boolean. |
---|
| 150 | */ |
---|
| 151 | extended_key &= ~RTEMS_SHELL_KEYS_NORMAL_MASK; |
---|
| 152 | |
---|
| 153 | up = 0; |
---|
| 154 | |
---|
| 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: |
---|
| 202 | |
---|
| 203 | { |
---|
| 204 | int last_cmd = cmd; |
---|
| 205 | int clen = strlen (line); |
---|
| 206 | |
---|
| 207 | if (prompt) |
---|
| 208 | clen += strlen(prompt); |
---|
| 209 | |
---|
| 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); |
---|
| 229 | |
---|
| 230 | col = strlen (line); |
---|
| 231 | |
---|
| 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; |
---|
| 274 | |
---|
| 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; |
---|
| 293 | |
---|
| 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; |
---|
| 301 | |
---|
| 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"); |
---|
| 337 | |
---|
| 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 | |
---|
[85659ee] | 381 | int rtems_shell_scanline( |
---|
[ea90df23] | 382 | char *line, |
---|
| 383 | int size, |
---|
| 384 | FILE *in, |
---|
| 385 | FILE *out |
---|
[85659ee] | 386 | ) |
---|
| 387 | { |
---|
| 388 | int c; |
---|
| 389 | int col; |
---|
| 390 | int doEcho; |
---|
| 391 | |
---|
| 392 | doEcho = (out && isatty(fileno(in))); |
---|
[814d9588] | 393 | |
---|
| 394 | col = 0; |
---|
[70d689a] | 395 | if (*line) { |
---|
[814d9588] | 396 | col = strlen(line); |
---|
[85659ee] | 397 | if (doEcho) fprintf(out,"%s",line); |
---|
[814d9588] | 398 | } |
---|
[6dd411aa] | 399 | tcdrain(fileno(in)); |
---|
[814d9588] | 400 | if (out) |
---|
| 401 | tcdrain(fileno(out)); |
---|
[dd74e612] | 402 | for (;;) { |
---|
[814d9588] | 403 | line[col] = 0; |
---|
[4e5299f] | 404 | c = fgetc(in); |
---|
| 405 | switch (c) { |
---|
| 406 | case EOF: |
---|
| 407 | return 0; |
---|
| 408 | case '\n': |
---|
| 409 | case '\r': |
---|
[85659ee] | 410 | if (doEcho) |
---|
[4e5299f] | 411 | fputc('\n',out); |
---|
[6dd411aa] | 412 | return 1; |
---|
[4e5299f] | 413 | case 127: |
---|
| 414 | case '\b': |
---|
| 415 | if (col) { |
---|
[85659ee] | 416 | if (doEcho) { |
---|
[4e5299f] | 417 | fputc('\b',out); |
---|
| 418 | fputc(' ',out); |
---|
| 419 | fputc('\b',out); |
---|
| 420 | } |
---|
| 421 | col--; |
---|
[6dd411aa] | 422 | } else { |
---|
[85659ee] | 423 | if (doEcho) fputc('\a',out); |
---|
[4e5299f] | 424 | } |
---|
[6dd411aa] | 425 | break; |
---|
[4e5299f] | 426 | default: |
---|
| 427 | if (!iscntrl(c)) { |
---|
| 428 | if (col<size-1) { |
---|
[814d9588] | 429 | line[col++] = c; |
---|
[85659ee] | 430 | if (doEcho) fputc(c,out); |
---|
[4e5299f] | 431 | } else { |
---|
[85659ee] | 432 | if (doEcho) fputc('\a',out); |
---|
[4e5299f] | 433 | } |
---|
| 434 | } else { |
---|
[85659ee] | 435 | if (doEcho) |
---|
[4e5299f] | 436 | if (c=='\a') fputc('\a',out); |
---|
| 437 | } |
---|
| 438 | break; |
---|
| 439 | } |
---|
| 440 | } |
---|
[dd74e612] | 441 | } |
---|
[ea90df23] | 442 | |
---|
[dd74e612] | 443 | /* ----------------------------------------------- * |
---|
[aed742c] | 444 | * - The shell TASK |
---|
[dd74e612] | 445 | * Poor but enough.. |
---|
| 446 | * TODO: Redirection. Tty Signals. ENVVARs. Shell language. |
---|
| 447 | * ----------------------------------------------- */ |
---|
| 448 | |
---|
[1167235] | 449 | void rtems_shell_init_issue(void) |
---|
| 450 | { |
---|
| 451 | static bool issue_inited=false; |
---|
[814d9588] | 452 | struct stat buf; |
---|
[dd74e612] | 453 | |
---|
[814d9588] | 454 | if (issue_inited) |
---|
| 455 | return; |
---|
[1167235] | 456 | issue_inited = true; |
---|
[70d689a] | 457 | |
---|
[814d9588] | 458 | /* dummy call to init /etc dir */ |
---|
| 459 | getpwnam("root"); |
---|
| 460 | |
---|
| 461 | if (stat("/etc/issue",&buf)) { |
---|
[2eeb648c] | 462 | rtems_shell_write_file("/etc/issue", |
---|
[1fae7b43] | 463 | "\n" |
---|
[2eeb648c] | 464 | "Welcome to @V\\n" |
---|
| 465 | "Login into @S\\n"); |
---|
[814d9588] | 466 | } |
---|
| 467 | |
---|
| 468 | if (stat("/etc/issue.net",&buf)) { |
---|
[2eeb648c] | 469 | rtems_shell_write_file("/etc/issue.net", |
---|
[1fae7b43] | 470 | "\n" |
---|
[2eeb648c] | 471 | "Welcome to %v\n" |
---|
| 472 | "running on %m\n"); |
---|
[814d9588] | 473 | } |
---|
[70d689a] | 474 | } |
---|
| 475 | |
---|
[2eeb648c] | 476 | int rtems_shell_login(FILE * in,FILE * out) { |
---|
[6dd411aa] | 477 | FILE *fd; |
---|
| 478 | int c; |
---|
| 479 | time_t t; |
---|
| 480 | int times; |
---|
| 481 | char name[128]; |
---|
| 482 | char pass[128]; |
---|
| 483 | struct passwd *passwd; |
---|
| 484 | |
---|
[2eeb648c] | 485 | rtems_shell_init_issue(); |
---|
[6dd411aa] | 486 | setuid(0); |
---|
| 487 | setgid(0); |
---|
| 488 | rtems_current_user_env->euid = |
---|
| 489 | rtems_current_user_env->egid =0; |
---|
| 490 | |
---|
| 491 | if (out) { |
---|
[2eeb648c] | 492 | if ((rtems_current_shell_env->devname[5]!='p')|| |
---|
| 493 | (rtems_current_shell_env->devname[6]!='t')|| |
---|
| 494 | (rtems_current_shell_env->devname[7]!='y')) { |
---|
[6dd411aa] | 495 | fd = fopen("/etc/issue","r"); |
---|
| 496 | if (fd) { |
---|
| 497 | while ((c=fgetc(fd))!=EOF) { |
---|
| 498 | if (c=='@') { |
---|
| 499 | switch(c=fgetc(fd)) { |
---|
| 500 | case 'L': |
---|
[2eeb648c] | 501 | fprintf(out,"%s",rtems_current_shell_env->devname); |
---|
[6dd411aa] | 502 | break; |
---|
| 503 | case 'B': |
---|
| 504 | fprintf(out,"0"); |
---|
| 505 | break; |
---|
[70d689a] | 506 | case 'T': |
---|
[6dd411aa] | 507 | case 'D': |
---|
| 508 | time(&t); |
---|
| 509 | fprintf(out,"%s",ctime(&t)); |
---|
| 510 | break; |
---|
| 511 | case 'S': |
---|
| 512 | fprintf(out,"RTEMS"); |
---|
| 513 | break; |
---|
| 514 | case 'V': |
---|
[a3ddb08b] | 515 | fprintf(out,"%s\n%s",_RTEMS_version, _Copyright_Notice); |
---|
[6dd411aa] | 516 | break; |
---|
| 517 | case '@': |
---|
| 518 | fprintf(out,"@"); |
---|
| 519 | break; |
---|
| 520 | default : |
---|
| 521 | fprintf(out,"@%c",c); |
---|
| 522 | break; |
---|
| 523 | } |
---|
| 524 | } else if (c=='\\') { |
---|
| 525 | switch(c=fgetc(fd)) { |
---|
| 526 | case '\\': fprintf(out,"\\"); break; |
---|
| 527 | case 'b': fprintf(out,"\b"); break; |
---|
| 528 | case 'f': fprintf(out,"\f"); break; |
---|
| 529 | case 'n': fprintf(out,"\n"); break; |
---|
| 530 | case 'r': fprintf(out,"\r"); break; |
---|
| 531 | case 's': fprintf(out," "); break; |
---|
| 532 | case 't': fprintf(out,"\t"); break; |
---|
| 533 | case '@': fprintf(out,"@"); break; |
---|
| 534 | } |
---|
| 535 | } else { |
---|
| 536 | fputc(c,out); |
---|
| 537 | } |
---|
| 538 | } |
---|
| 539 | fclose(fd); |
---|
| 540 | } |
---|
| 541 | } else { |
---|
| 542 | fd = fopen("/etc/issue.net","r"); |
---|
| 543 | if (fd) { |
---|
| 544 | while ((c=fgetc(fd))!=EOF) { |
---|
| 545 | if (c=='%') { |
---|
| 546 | switch(c=fgetc(fd)) { |
---|
| 547 | case 't': |
---|
[2eeb648c] | 548 | fprintf(out,"%s",rtems_current_shell_env->devname); |
---|
[6dd411aa] | 549 | break; |
---|
| 550 | case 'h': |
---|
| 551 | fprintf(out,"0"); |
---|
| 552 | break; |
---|
| 553 | case 'D': |
---|
| 554 | fprintf(out," "); |
---|
| 555 | break; |
---|
| 556 | case 'd': |
---|
| 557 | time(&t); |
---|
| 558 | fprintf(out,"%s",ctime(&t)); |
---|
| 559 | break; |
---|
| 560 | case 's': |
---|
| 561 | fprintf(out,"RTEMS"); |
---|
| 562 | break; |
---|
| 563 | case 'm': |
---|
| 564 | fprintf(out,"(" CPU_NAME "/" CPU_MODEL_NAME ")"); |
---|
| 565 | break; |
---|
| 566 | case 'r': |
---|
| 567 | fprintf(out,_RTEMS_version); |
---|
| 568 | break; |
---|
| 569 | case 'v': |
---|
| 570 | fprintf(out,"%s\n%s",_RTEMS_version,_Copyright_Notice); |
---|
| 571 | break; |
---|
| 572 | case '%':fprintf(out,"%%"); |
---|
| 573 | break; |
---|
| 574 | default: |
---|
| 575 | fprintf(out,"%%%c",c); |
---|
| 576 | break; |
---|
| 577 | } |
---|
| 578 | } else { |
---|
| 579 | fputc(c,out); |
---|
| 580 | } |
---|
| 581 | } |
---|
| 582 | fclose(fd); |
---|
| 583 | } |
---|
| 584 | } |
---|
| 585 | } |
---|
| 586 | |
---|
| 587 | times=0; |
---|
| 588 | strcpy(name,""); |
---|
| 589 | strcpy(pass,""); |
---|
| 590 | for (;;) { |
---|
| 591 | times++; |
---|
| 592 | if (times>3) break; |
---|
| 593 | if (out) fprintf(out,"\nlogin: "); |
---|
[2eeb648c] | 594 | if (!rtems_shell_scanline(name,sizeof(name),in,out )) break; |
---|
[6dd411aa] | 595 | if (out) fprintf(out,"Password: "); |
---|
[2eeb648c] | 596 | if (!rtems_shell_scanline(pass,sizeof(pass),in,NULL)) break; |
---|
[6dd411aa] | 597 | if (out) fprintf(out,"\n"); |
---|
| 598 | if ((passwd=getpwnam(name))) { |
---|
| 599 | if (strcmp(passwd->pw_passwd,"!")) { /* valid user */ |
---|
| 600 | setuid(passwd->pw_uid); |
---|
| 601 | setgid(passwd->pw_gid); |
---|
| 602 | rtems_current_user_env->euid = |
---|
[814d9588] | 603 | rtems_current_user_env->egid = 0; |
---|
[2eeb648c] | 604 | chown(rtems_current_shell_env->devname,passwd->pw_uid,0); |
---|
[6dd411aa] | 605 | rtems_current_user_env->euid = passwd->pw_uid; |
---|
| 606 | rtems_current_user_env->egid = passwd->pw_gid; |
---|
| 607 | if (!strcmp(passwd->pw_passwd,"*")) { |
---|
[814d9588] | 608 | /* /etc/shadow */ |
---|
| 609 | return 0; |
---|
[6dd411aa] | 610 | } else { |
---|
[814d9588] | 611 | /* crypt() */ |
---|
| 612 | return 0; |
---|
[6dd411aa] | 613 | } |
---|
| 614 | } |
---|
| 615 | } |
---|
| 616 | if (out) |
---|
| 617 | fprintf(out,"Login incorrect\n"); |
---|
| 618 | strcpy(name,""); |
---|
| 619 | strcpy(pass,""); |
---|
| 620 | } |
---|
| 621 | return -1; |
---|
[b2712e3] | 622 | } |
---|
| 623 | |
---|
[814d9588] | 624 | #if defined(SHELL_DEBUG) |
---|
[2eeb648c] | 625 | void rtems_shell_print_env( |
---|
| 626 | rtems_shell_env_t * shell_env |
---|
[6dd411aa] | 627 | ) |
---|
| 628 | { |
---|
| 629 | if ( !shell_env ) { |
---|
| 630 | printk( "shell_env is NULL\n" ); |
---|
| 631 | return; |
---|
| 632 | } |
---|
| 633 | printk( "shell_env=%p\n" |
---|
| 634 | "shell_env->magic=0x%08x\t" |
---|
| 635 | "shell_env->devname=%s\n" |
---|
| 636 | "shell_env->taskname=%s\t" |
---|
| 637 | "shell_env->exit_shell=%d\t" |
---|
| 638 | "shell_env->forever=%d\n", |
---|
| 639 | shell_env->magic, |
---|
| 640 | shell_env->devname, |
---|
| 641 | ((shell_env->taskname) ? shell_env->taskname : "NOT SET"), |
---|
| 642 | shell_env->exit_shell, |
---|
| 643 | shell_env->forever |
---|
| 644 | ); |
---|
| 645 | } |
---|
| 646 | #endif |
---|
[dd74e612] | 647 | |
---|
[8e30a269] | 648 | rtems_task rtems_shell_task(rtems_task_argument task_argument) |
---|
[6dd411aa] | 649 | { |
---|
[1ff9922] | 650 | rtems_shell_env_t *shell_env = (rtems_shell_env_t*) task_argument; |
---|
| 651 | rtems_id wake_on_end = shell_env->wake_on_end; |
---|
| 652 | rtems_shell_main_loop( shell_env ); |
---|
| 653 | if (wake_on_end != RTEMS_INVALID_ID) |
---|
| 654 | rtems_event_send (wake_on_end, RTEMS_EVENT_1); |
---|
| 655 | rtems_task_delete( RTEMS_SELF ); |
---|
[6dd411aa] | 656 | } |
---|
[dd74e612] | 657 | |
---|
[ea90df23] | 658 | #define RTEMS_SHELL_MAXIMUM_ARGUMENTS (128) |
---|
| 659 | #define RTEMS_SHELL_CMD_SIZE (128) |
---|
| 660 | #define RTEMS_SHELL_CMD_COUNT (32) |
---|
| 661 | #define RTEMS_SHELL_PROMPT_SIZE (128) |
---|
[aed742c] | 662 | |
---|
[1167235] | 663 | bool rtems_shell_main_loop( |
---|
[2eeb648c] | 664 | rtems_shell_env_t *shell_env_arg |
---|
[798ff5a] | 665 | ) |
---|
[6dd411aa] | 666 | { |
---|
[2eeb648c] | 667 | rtems_shell_env_t *shell_env; |
---|
| 668 | rtems_shell_cmd_t *shell_cmd; |
---|
[6dd411aa] | 669 | rtems_status_code sc; |
---|
| 670 | struct termios term; |
---|
[8084ce80] | 671 | struct termios previous_term; |
---|
[ea90df23] | 672 | char *prompt = NULL; |
---|
| 673 | int cmd; |
---|
| 674 | int cmd_count = 1; /* assume a script and so only 1 command line */ |
---|
| 675 | char *cmds[RTEMS_SHELL_CMD_COUNT]; |
---|
[8c422e2] | 676 | char *cmd_argv; |
---|
[6dd411aa] | 677 | int argc; |
---|
[2eeb648c] | 678 | char *argv[RTEMS_SHELL_MAXIMUM_ARGUMENTS]; |
---|
[1167235] | 679 | bool result = true; |
---|
[ff90595] | 680 | bool input_file = false; |
---|
[1ff9922] | 681 | int line = 0; |
---|
[a3ddb08b] | 682 | FILE *stdinToClose = NULL; |
---|
| 683 | FILE *stdoutToClose = NULL; |
---|
[2eeb648c] | 684 | |
---|
| 685 | rtems_shell_initialize_command_set(); |
---|
| 686 | |
---|
[798ff5a] | 687 | shell_env = |
---|
| 688 | rtems_current_shell_env = rtems_shell_init_env( shell_env_arg ); |
---|
[1ff9922] | 689 | |
---|
[2eeb648c] | 690 | /* |
---|
| 691 | * @todo chrisj |
---|
[1ff9922] | 692 | * Remove the use of task variables. Change to have a single |
---|
[2eeb648c] | 693 | * allocation per shell and then set into a notepad register |
---|
[1ff9922] | 694 | * in the TCB. Provide a function to return the pointer. |
---|
[2eeb648c] | 695 | * Task variables are a virus to embedded systems software. |
---|
| 696 | */ |
---|
[798ff5a] | 697 | sc = rtems_task_variable_add( |
---|
| 698 | RTEMS_SELF, |
---|
| 699 | (void*)&rtems_current_shell_env, |
---|
| 700 | rtems_shell_env_free |
---|
| 701 | ); |
---|
[6dd411aa] | 702 | if (sc != RTEMS_SUCCESSFUL) { |
---|
| 703 | rtems_error(sc,"rtems_task_variable_add(current_shell_env):"); |
---|
[1167235] | 704 | return false; |
---|
[814d9588] | 705 | } |
---|
[dd74e612] | 706 | |
---|
[b2712e3] | 707 | setuid(0); |
---|
| 708 | setgid(0); |
---|
[ea90df23] | 709 | |
---|
| 710 | rtems_current_user_env->euid = rtems_current_user_env->egid = 0; |
---|
[6dd411aa] | 711 | |
---|
[1ff9922] | 712 | fileno(stdout); |
---|
| 713 | |
---|
[a3ddb08b] | 714 | /* fprintf( stderr, |
---|
| 715 | "-%s-%s-\n", shell_env->input, shell_env->output ); |
---|
[ea90df23] | 716 | */ |
---|
[be8ab6a] | 717 | |
---|
| 718 | if (shell_env->output && strcmp(shell_env->output, "stdout") != 0) { |
---|
[1ff9922] | 719 | if (strcmp(shell_env->output, "stderr") == 0) { |
---|
| 720 | stdout = stderr; |
---|
| 721 | } else if (strcmp(shell_env->output, "/dev/null") == 0) { |
---|
| 722 | fclose (stdout); |
---|
| 723 | } else { |
---|
| 724 | FILE *output = fopen(shell_env_arg->output, |
---|
| 725 | shell_env_arg->output_append ? "a" : "w"); |
---|
| 726 | if (!output) { |
---|
| 727 | fprintf(stderr, "shell: open output %s failed: %s\n", |
---|
| 728 | shell_env_arg->output, strerror(errno)); |
---|
[1167235] | 729 | return false; |
---|
[1ff9922] | 730 | } |
---|
| 731 | stdout = output; |
---|
[a3ddb08b] | 732 | stdoutToClose = output; |
---|
[1ff9922] | 733 | } |
---|
| 734 | } |
---|
| 735 | |
---|
[be8ab6a] | 736 | if (shell_env->input && strcmp(shell_env_arg->input, "stdin") != 0) { |
---|
[1ff9922] | 737 | FILE *input = fopen(shell_env_arg->input, "r"); |
---|
| 738 | if (!input) { |
---|
| 739 | fprintf(stderr, "shell: open input %s failed: %s\n", |
---|
| 740 | shell_env_arg->input, strerror(errno)); |
---|
[1167235] | 741 | return false; |
---|
[1ff9922] | 742 | } |
---|
| 743 | stdin = input; |
---|
[a3ddb08b] | 744 | stdinToClose = input; |
---|
[1167235] | 745 | shell_env->forever = false; |
---|
| 746 | input_file =true; |
---|
[1ff9922] | 747 | } |
---|
| 748 | else { |
---|
| 749 | /* make a raw terminal,Linux Manuals */ |
---|
[8084ce80] | 750 | if (tcgetattr(fileno(stdin), &previous_term) >= 0) { |
---|
| 751 | term = previous_term; |
---|
[1ff9922] | 752 | term.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON); |
---|
| 753 | term.c_oflag &= ~OPOST; |
---|
| 754 | term.c_oflag |= (OPOST|ONLCR); /* But with cr+nl on output */ |
---|
| 755 | term.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN); |
---|
| 756 | term.c_cflag |= CLOCAL | CREAD; |
---|
| 757 | term.c_cc[VMIN] = 1; |
---|
| 758 | term.c_cc[VTIME] = 0; |
---|
| 759 | if (tcsetattr (fileno(stdin), TCSADRAIN, &term) < 0) { |
---|
| 760 | fprintf(stderr, |
---|
| 761 | "shell:cannot set terminal attributes(%s)\n",shell_env->devname); |
---|
| 762 | } |
---|
[814d9588] | 763 | } |
---|
[ea90df23] | 764 | cmd_count = RTEMS_SHELL_CMD_COUNT; |
---|
| 765 | prompt = malloc(RTEMS_SHELL_PROMPT_SIZE); |
---|
| 766 | if (!prompt) |
---|
| 767 | fprintf(stderr, |
---|
| 768 | "shell:cannot allocate prompt memory\n"); |
---|
[6dd411aa] | 769 | } |
---|
| 770 | |
---|
[1ff9922] | 771 | setvbuf(stdin,NULL,_IONBF,0); /* Not buffered*/ |
---|
| 772 | setvbuf(stdout,NULL,_IONBF,0); /* Not buffered*/ |
---|
| 773 | |
---|
[2eeb648c] | 774 | rtems_shell_initialize_command_set(); |
---|
[ea90df23] | 775 | |
---|
| 776 | /* |
---|
| 777 | * Allocate the command line buffers. |
---|
| 778 | */ |
---|
[8c422e2] | 779 | cmd_argv = malloc (RTEMS_SHELL_CMD_SIZE); |
---|
| 780 | if (!cmd_argv) { |
---|
| 781 | fprintf(stderr, "no memory for command line buffers\n" ); |
---|
| 782 | } |
---|
| 783 | |
---|
[ea90df23] | 784 | cmds[0] = calloc (cmd_count, RTEMS_SHELL_CMD_SIZE); |
---|
| 785 | if (!cmds[0]) { |
---|
| 786 | fprintf(stderr, "no memory for command line buffers\n" ); |
---|
| 787 | } |
---|
[8c422e2] | 788 | |
---|
| 789 | if (cmd_argv && cmds[0]) { |
---|
[ea90df23] | 790 | |
---|
| 791 | memset (cmds[0], 0, cmd_count * RTEMS_SHELL_CMD_SIZE); |
---|
| 792 | |
---|
| 793 | for (cmd = 1; cmd < cmd_count; cmd++) { |
---|
| 794 | cmds[cmd] = cmds[cmd - 1] + RTEMS_SHELL_CMD_SIZE; |
---|
[6dd411aa] | 795 | } |
---|
[ea90df23] | 796 | |
---|
| 797 | do { |
---|
| 798 | /* Set again root user and root filesystem, side effect of set_priv..*/ |
---|
| 799 | sc = rtems_libio_set_private_env(); |
---|
| 800 | if (sc != RTEMS_SUCCESSFUL) { |
---|
| 801 | rtems_error(sc,"rtems_libio_set_private_env():"); |
---|
[1167235] | 802 | result = false; |
---|
[ea90df23] | 803 | break; |
---|
[1ff9922] | 804 | } |
---|
[7c4cdeb9] | 805 | |
---|
| 806 | /* |
---|
| 807 | * By using result here, we can fall to the bottom of the |
---|
| 808 | * loop when the connection is dropped during login and |
---|
| 809 | * keep on trucking. |
---|
| 810 | */ |
---|
[06f8e558] | 811 | if (shell_env->login) { |
---|
| 812 | result = rtems_shell_login(stdin,stdout) == 0; |
---|
[7c4cdeb9] | 813 | } else { |
---|
[06f8e558] | 814 | result = true; |
---|
[7c4cdeb9] | 815 | } |
---|
| 816 | |
---|
| 817 | if (result) { |
---|
[ea90df23] | 818 | const char *c; |
---|
| 819 | memset (cmds[0], 0, cmd_count * RTEMS_SHELL_CMD_SIZE); |
---|
[1ff9922] | 820 | if (!input_file) { |
---|
[ea90df23] | 821 | rtems_shell_cat_file(stdout,"/etc/motd"); |
---|
| 822 | fprintf(stdout, "\n" |
---|
| 823 | "RTEMS SHELL (Ver.1.0-FRC):%s. " \ |
---|
| 824 | __DATE__". 'help' to list commands.\n", |
---|
| 825 | shell_env->devname); |
---|
[1ff9922] | 826 | } |
---|
[55c64fc9] | 827 | |
---|
| 828 | if (input_file) |
---|
| 829 | chdir(shell_env->cwd); |
---|
| 830 | else |
---|
| 831 | chdir("/"); /* XXX: chdir to getpwent homedir */ |
---|
[1ff9922] | 832 | |
---|
[1167235] | 833 | shell_env->exit_shell = false; |
---|
[ea90df23] | 834 | |
---|
| 835 | for (;;) { |
---|
| 836 | int cmd; |
---|
| 837 | |
---|
| 838 | /* Prompt section */ |
---|
| 839 | if (prompt) { |
---|
| 840 | rtems_shell_get_prompt(shell_env, prompt, |
---|
| 841 | RTEMS_SHELL_PROMPT_SIZE); |
---|
| 842 | } |
---|
| 843 | |
---|
| 844 | /* getcmd section */ |
---|
| 845 | cmd = rtems_shell_line_editor(cmds, cmd_count, |
---|
| 846 | RTEMS_SHELL_CMD_SIZE, prompt, |
---|
| 847 | stdin, stdout); |
---|
| 848 | |
---|
| 849 | if (cmd == -1) |
---|
| 850 | continue; /* empty line */ |
---|
| 851 | |
---|
| 852 | if (cmd == -2) |
---|
| 853 | break; /*EOF*/ |
---|
| 854 | |
---|
| 855 | line++; |
---|
| 856 | |
---|
[55c64fc9] | 857 | if (shell_env->echo) |
---|
| 858 | fprintf(stdout, "%d: %s\n", line, cmds[cmd]); |
---|
| 859 | |
---|
[ea90df23] | 860 | /* evaluate cmd section */ |
---|
| 861 | c = cmds[cmd]; |
---|
| 862 | while (*c) { |
---|
| 863 | if (!isblank(*c)) |
---|
| 864 | break; |
---|
| 865 | c++; |
---|
| 866 | } |
---|
[1ff9922] | 867 | |
---|
[ea90df23] | 868 | if (*c == '\0') /* empty line */ |
---|
| 869 | continue; |
---|
[a5de1ef] | 870 | |
---|
[ea90df23] | 871 | if (*c == '#') { /* comment character */ |
---|
| 872 | cmds[cmd][0] = 0; |
---|
| 873 | continue; |
---|
| 874 | } |
---|
[1ff9922] | 875 | |
---|
[ea90df23] | 876 | if (!strcmp(cmds[cmd],"bye") || !strcmp(cmds[cmd],"exit")) { |
---|
| 877 | fprintf(stdout, "Shell exiting\n" ); |
---|
| 878 | break; |
---|
| 879 | } else if (!strcmp(cmds[cmd],"shutdown")) { /* exit application */ |
---|
| 880 | fprintf(stdout, "System shutting down at user request\n" ); |
---|
| 881 | exit(0); |
---|
| 882 | } |
---|
[6dd411aa] | 883 | |
---|
[ea90df23] | 884 | /* exec cmd section */ |
---|
| 885 | /* TODO: |
---|
| 886 | * To avoid user crash catch the signals. |
---|
| 887 | * Open a new stdio files with posibility of redirection * |
---|
| 888 | * Run in a new shell task background. (unix &) |
---|
| 889 | * Resuming. A little bash. |
---|
| 890 | */ |
---|
[8c422e2] | 891 | memcpy (cmd_argv, cmds[cmd], RTEMS_SHELL_CMD_SIZE); |
---|
| 892 | if (!rtems_shell_make_args(cmd_argv, &argc, argv, |
---|
[ea90df23] | 893 | RTEMS_SHELL_MAXIMUM_ARGUMENTS)) { |
---|
| 894 | shell_cmd = rtems_shell_lookup_cmd(argv[0]); |
---|
| 895 | if ( argv[0] == NULL ) { |
---|
| 896 | shell_env->errorlevel = -1; |
---|
| 897 | } else if ( shell_cmd == NULL ) { |
---|
| 898 | shell_env->errorlevel = rtems_shell_script_file(argc, argv); |
---|
| 899 | } else { |
---|
| 900 | shell_env->errorlevel = shell_cmd->command(argc, argv); |
---|
| 901 | } |
---|
[6dd411aa] | 902 | } |
---|
[ea90df23] | 903 | |
---|
| 904 | /* end exec cmd section */ |
---|
| 905 | if (shell_env->exit_shell) |
---|
| 906 | break; |
---|
[6dd411aa] | 907 | } |
---|
| 908 | |
---|
[ea90df23] | 909 | fflush( stdout ); |
---|
| 910 | fflush( stderr ); |
---|
[6dd411aa] | 911 | } |
---|
[ea90df23] | 912 | } while (result && shell_env->forever); |
---|
| 913 | |
---|
| 914 | } |
---|
| 915 | |
---|
[8c422e2] | 916 | if (cmds[0]) |
---|
| 917 | free (cmds[0]); |
---|
| 918 | if (cmd_argv) |
---|
| 919 | free (cmd_argv); |
---|
[798ff5a] | 920 | if (prompt) |
---|
| 921 | free (prompt); |
---|
| 922 | |
---|
[8084ce80] | 923 | if (stdinToClose) { |
---|
[a3ddb08b] | 924 | fclose( stdinToClose ); |
---|
[8084ce80] | 925 | } else { |
---|
[798ff5a] | 926 | if (tcsetattr(fileno(stdin), TCSADRAIN, &previous_term) < 0) { |
---|
[8084ce80] | 927 | fprintf( |
---|
| 928 | stderr, |
---|
| 929 | "shell: cannot reset terminal attributes (%s)\n", |
---|
| 930 | shell_env->devname |
---|
| 931 | ); |
---|
| 932 | } |
---|
| 933 | } |
---|
[a3ddb08b] | 934 | if ( stdoutToClose ) |
---|
| 935 | fclose( stdoutToClose ); |
---|
[1ff9922] | 936 | return result; |
---|
[dd74e612] | 937 | } |
---|
[6dd411aa] | 938 | |
---|
[dd74e612] | 939 | /* ----------------------------------------------- */ |
---|
[1ff9922] | 940 | static rtems_status_code rtems_shell_run ( |
---|
[e41eaa88] | 941 | const char *task_name, |
---|
[06f8e558] | 942 | size_t task_stacksize, |
---|
[6dd411aa] | 943 | rtems_task_priority task_priority, |
---|
[e41eaa88] | 944 | const char *devname, |
---|
[06f8e558] | 945 | bool forever, |
---|
| 946 | bool wait, |
---|
[1ff9922] | 947 | const char* input, |
---|
| 948 | const char* output, |
---|
[06f8e558] | 949 | bool output_append, |
---|
[55c64fc9] | 950 | rtems_id wake_on_end, |
---|
[06f8e558] | 951 | bool echo, |
---|
| 952 | bool login |
---|
[6dd411aa] | 953 | ) |
---|
| 954 | { |
---|
| 955 | rtems_id task_id; |
---|
| 956 | rtems_status_code sc; |
---|
[2eeb648c] | 957 | rtems_shell_env_t *shell_env; |
---|
[4e5299f] | 958 | rtems_name name; |
---|
| 959 | |
---|
[e41eaa88] | 960 | if ( task_name && strlen(task_name) >= 4) |
---|
[814d9588] | 961 | name = rtems_build_name( |
---|
| 962 | task_name[0], task_name[1], task_name[2], task_name[3]); |
---|
[4e5299f] | 963 | else |
---|
| 964 | name = rtems_build_name( 'S', 'E', 'N', 'V' ); |
---|
[6dd411aa] | 965 | |
---|
| 966 | sc = rtems_task_create( |
---|
[4e5299f] | 967 | name, |
---|
[6dd411aa] | 968 | task_priority, |
---|
[4e5299f] | 969 | task_stacksize, |
---|
[3899a537] | 970 | RTEMS_PREEMPT | RTEMS_TIMESLICE | RTEMS_NO_ASR, |
---|
[6dd411aa] | 971 | RTEMS_LOCAL | RTEMS_FLOATING_POINT, |
---|
| 972 | &task_id |
---|
| 973 | ); |
---|
| 974 | if (sc != RTEMS_SUCCESSFUL) { |
---|
| 975 | rtems_error(sc,"creating task %s in shell_init()",task_name); |
---|
| 976 | return sc; |
---|
| 977 | } |
---|
| 978 | |
---|
[2eeb648c] | 979 | shell_env = rtems_shell_init_env( NULL ); |
---|
[6dd411aa] | 980 | if ( !shell_env ) { |
---|
[1ff9922] | 981 | rtems_error(RTEMS_NO_MEMORY, |
---|
| 982 | "allocating shell_env %s in shell_init()",task_name); |
---|
[6dd411aa] | 983 | return RTEMS_NO_MEMORY; |
---|
| 984 | } |
---|
[1ff9922] | 985 | shell_env->devname = devname; |
---|
| 986 | shell_env->taskname = task_name; |
---|
[1167235] | 987 | shell_env->exit_shell = false; |
---|
[1ff9922] | 988 | shell_env->forever = forever; |
---|
[55c64fc9] | 989 | shell_env->echo = echo; |
---|
[1ff9922] | 990 | shell_env->input = strdup (input); |
---|
| 991 | shell_env->output = strdup (output); |
---|
| 992 | shell_env->output_append = output_append; |
---|
| 993 | shell_env->wake_on_end = wake_on_end; |
---|
[06f8e558] | 994 | shell_env->login = login; |
---|
[6dd411aa] | 995 | |
---|
[55c64fc9] | 996 | getcwd(shell_env->cwd, sizeof(shell_env->cwd)); |
---|
| 997 | |
---|
[798ff5a] | 998 | sc = rtems_task_start(task_id, rtems_shell_task, |
---|
[2eeb648c] | 999 | (rtems_task_argument) shell_env); |
---|
[798ff5a] | 1000 | if (sc != RTEMS_SUCCESSFUL) { |
---|
| 1001 | rtems_error(sc,"starting task %s in shell_init()",task_name); |
---|
| 1002 | return sc; |
---|
| 1003 | } |
---|
| 1004 | |
---|
| 1005 | if (wait) { |
---|
| 1006 | rtems_event_set out; |
---|
| 1007 | sc = rtems_event_receive (RTEMS_EVENT_1, RTEMS_WAIT, 0, &out); |
---|
| 1008 | } |
---|
| 1009 | |
---|
| 1010 | return 0; |
---|
[6dd411aa] | 1011 | } |
---|
[1ff9922] | 1012 | |
---|
[798ff5a] | 1013 | rtems_status_code rtems_shell_init( |
---|
[e41eaa88] | 1014 | const char *task_name, |
---|
[06f8e558] | 1015 | size_t task_stacksize, |
---|
[1ff9922] | 1016 | rtems_task_priority task_priority, |
---|
[e41eaa88] | 1017 | const char *devname, |
---|
[06f8e558] | 1018 | bool forever, |
---|
| 1019 | bool wait, |
---|
| 1020 | bool login |
---|
[1ff9922] | 1021 | ) |
---|
| 1022 | { |
---|
[06f8e558] | 1023 | rtems_id to_wake = RTEMS_ID_NONE; |
---|
[798ff5a] | 1024 | |
---|
| 1025 | if ( wait ) |
---|
| 1026 | to_wake = rtems_task_self(); |
---|
| 1027 | |
---|
| 1028 | return rtems_shell_run( |
---|
| 1029 | task_name, /* task_name */ |
---|
| 1030 | task_stacksize, /* task_stacksize */ |
---|
| 1031 | task_priority, /* task_priority */ |
---|
| 1032 | devname, /* devname */ |
---|
| 1033 | forever, /* forever */ |
---|
| 1034 | wait, /* wait */ |
---|
| 1035 | "stdin", /* input */ |
---|
| 1036 | "stdout", /* output */ |
---|
[06f8e558] | 1037 | false, /* output_append */ |
---|
[798ff5a] | 1038 | to_wake, /* wake_on_end */ |
---|
[06f8e558] | 1039 | false, /* echo */ |
---|
| 1040 | login /* login */ |
---|
[798ff5a] | 1041 | ); |
---|
[1ff9922] | 1042 | } |
---|
| 1043 | |
---|
| 1044 | rtems_status_code rtems_shell_script ( |
---|
[e41eaa88] | 1045 | const char *task_name, |
---|
[06f8e558] | 1046 | size_t task_stacksize, |
---|
[1ff9922] | 1047 | rtems_task_priority task_priority, |
---|
| 1048 | const char* input, |
---|
| 1049 | const char* output, |
---|
[06f8e558] | 1050 | bool output_append, |
---|
| 1051 | bool wait, |
---|
| 1052 | bool echo |
---|
[1ff9922] | 1053 | ) |
---|
| 1054 | { |
---|
| 1055 | rtems_id current_task = RTEMS_INVALID_ID; |
---|
| 1056 | rtems_status_code sc; |
---|
| 1057 | |
---|
| 1058 | if (wait) { |
---|
| 1059 | sc = rtems_task_ident (RTEMS_SELF, RTEMS_LOCAL, ¤t_task); |
---|
| 1060 | if (sc != RTEMS_SUCCESSFUL) |
---|
| 1061 | return sc; |
---|
| 1062 | } |
---|
| 1063 | |
---|
[798ff5a] | 1064 | sc = rtems_shell_run( |
---|
| 1065 | task_name, /* task_name */ |
---|
| 1066 | task_stacksize, /* task_stacksize */ |
---|
| 1067 | task_priority, /* task_priority */ |
---|
| 1068 | NULL, /* devname */ |
---|
| 1069 | 0, /* forever */ |
---|
| 1070 | wait, /* wait */ |
---|
| 1071 | input, /* input */ |
---|
| 1072 | output, /* output */ |
---|
| 1073 | output_append, /* output_append */ |
---|
| 1074 | current_task, /* wake_on_end */ |
---|
[06f8e558] | 1075 | echo, /* echo */ |
---|
| 1076 | false /* login */ |
---|
[798ff5a] | 1077 | ); |
---|
[1ff9922] | 1078 | if (sc != RTEMS_SUCCESSFUL) |
---|
| 1079 | return sc; |
---|
| 1080 | |
---|
| 1081 | return sc; |
---|
| 1082 | } |
---|