rtems_task Init( rtems_task_argument argument ) { puts( "\n\n*** TEST Tests for error reporting routines - 01 ***" ); errno = -1; rtems_error(RTEMS_ERROR_ERRNO, "Dummy: Resources unavailable"); errno = ENOMEM; rtems_error( RTEMS_NO_MEMORY | RTEMS_ERROR_ERRNO, "Dummy: Resources unavailable" ); puts( "Dummy: causing panic.. will print test end message, then..." ); puts( " print various error messages" ); rtems_error( RTEMS_NO_MEMORY | RTEMS_ERROR_PANIC, "Dummy: Resources unavailable\n" "*** END OF TEST Tests for error reporting routines - 01 ***\n" ); rtems_test_exit(0); }
rtems_id telnetd_dflt_spawn(const char *name, unsigned int priority, unsigned int stackSize, void (*fn)(void *), void* fnarg) { rtems_status_code sc; rtems_id task_id = RTEMS_ID_NONE; char nm[4] = {'X','X','X','X' }; struct wrap_delete_args *pwa = malloc(sizeof(*pwa)); strncpy(nm, name, 4); if ( !pwa ) { perror("Telnetd: no memory\n"); return RTEMS_ID_NONE; } pwa->t = fn; pwa->a = fnarg; if ((sc=rtems_task_create( rtems_build_name(nm[0], nm[1], nm[2], nm[3]), (rtems_task_priority)priority, stackSize, RTEMS_DEFAULT_MODES, RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT, &task_id)) || (sc=rtems_task_start( task_id, wrap_delete, (rtems_task_argument)pwa))) { free(pwa); rtems_error(sc,"Telnetd: spawning task failed"); return RTEMS_ID_NONE; } return task_id; }
void rtems_monitor_init( uint32_t monitor_flags ) { rtems_status_code status; rtems_monitor_kill(); status = rtems_task_create(RTEMS_MONITOR_NAME, 1, RTEMS_MINIMUM_STACK_SIZE * 2, RTEMS_INTERRUPT_LEVEL(0), RTEMS_DEFAULT_ATTRIBUTES, &rtems_monitor_task_id); if (status != RTEMS_SUCCESSFUL) { rtems_error(status, "could not create monitor task"); return; } rtems_monitor_node = rtems_object_id_get_node(rtems_monitor_task_id); rtems_monitor_default_node = rtems_monitor_node; rtems_monitor_server_init(monitor_flags); if (!(monitor_flags & RTEMS_MONITOR_NOTASK)) { /* * Start the monitor task itself */ status = rtems_task_start( rtems_monitor_task_id, rtems_monitor_task, monitor_flags); if (status != RTEMS_SUCCESSFUL) { rtems_error(status, "could not start monitor"); return; } } }
void rtems_panic( const char *printf_format, ... ) { va_list arglist; va_start(arglist, printf_format); (void) rtems_verror(RTEMS_ERROR_PANIC, printf_format, arglist); va_end(arglist); rtems_error(0, "fatal error, exiting"); _exit(errno); }
rtems_task Init( rtems_task_argument argument ) { TEST_BEGIN(); errno = -1; rtems_error(RTEMS_ERROR_ERRNO, "Dummy: Resources unavailable"); errno = ENOMEM; rtems_error( RTEMS_NO_MEMORY | RTEMS_ERROR_ERRNO, "Dummy: Resources unavailable" ); puts( "Dummy: causing panic.. will print test end message, then..." ); puts( " print various error messages" ); rtems_error( RTEMS_NO_MEMORY | RTEMS_ERROR_PANIC, "Dummy: Resources unavailable\n" ); rtems_test_assert(0); }
int rtems_error( rtems_error_code_t error_flag, const char *printf_format, ... ) { va_list arglist; int chars_written; va_start(arglist, printf_format); chars_written = rtems_verror(error_flag, printf_format, arglist); va_end(arglist); if (error_flag & RTEMS_ERROR_PANIC) { rtems_error(0, "fatal error, exiting"); _exit(errno); } if (error_flag & RTEMS_ERROR_ABORT) { rtems_error(0, "fatal error, aborting"); abort(); } return chars_written; }
rtems_task Init( rtems_task_argument argument ) { puts( "\n\n*** TEST Tests for error reporting routines - 02 ***" ); errno = ENOMEM; rtems_error( RTEMS_NO_MEMORY | RTEMS_ERROR_ABORT, "Dummy: Resources unavailable\n" "*** END OF TEST Tests for error reporting routines - 02 ***\n" ); rtems_test_exit(0); }
/* ----------------------------------------------- */ static rtems_status_code rtems_shell_run ( const char *task_name, size_t task_stacksize, rtems_task_priority task_priority, const char *devname, bool forever, bool wait, const char *input, const char *output, bool output_append, rtems_id wake_on_end, bool echo, rtems_shell_login_check_t login_check ) { rtems_id task_id; rtems_status_code sc; rtems_shell_env_t *shell_env; rtems_name name; if ( task_name && strlen(task_name) >= 4) name = rtems_build_name( task_name[0], task_name[1], task_name[2], task_name[3]); else name = rtems_build_name( 'S', 'E', 'N', 'V' ); sc = rtems_task_create( name, task_priority, task_stacksize, RTEMS_PREEMPT | RTEMS_TIMESLICE | RTEMS_NO_ASR, RTEMS_LOCAL | RTEMS_FLOATING_POINT, &task_id ); if (sc != RTEMS_SUCCESSFUL) { rtems_error(sc,"creating task %s in shell_init()",task_name); return sc; } shell_env = rtems_shell_init_env( NULL ); if ( !shell_env ) { rtems_error(RTEMS_NO_MEMORY, "allocating shell_env %s in shell_init()",task_name); return RTEMS_NO_MEMORY; } shell_env->devname = devname; shell_env->taskname = task_name; shell_env->exit_shell = false; shell_env->forever = forever; shell_env->echo = echo; shell_env->input = strdup (input); shell_env->output = strdup (output); shell_env->output_append = output_append; shell_env->wake_on_end = wake_on_end; shell_env->login_check = login_check; getcwd(shell_env->cwd, sizeof(shell_env->cwd)); sc = rtems_task_start(task_id, rtems_shell_task, (rtems_task_argument) shell_env); if (sc != RTEMS_SUCCESSFUL) { rtems_error(sc,"starting task %s in shell_init()",task_name); return sc; } if (wait) { rtems_event_set out; sc = rtems_event_receive (RTEMS_EVENT_1, RTEMS_WAIT, 0, &out); } return 0; }
bool rtems_shell_main_loop( rtems_shell_env_t *shell_env_arg ) { rtems_shell_env_t *shell_env; rtems_shell_cmd_t *shell_cmd; rtems_status_code sc; struct termios term; struct termios previous_term; char *prompt = NULL; int cmd; int cmd_count = 1; /* assume a script and so only 1 command line */ char *cmds[RTEMS_SHELL_CMD_COUNT]; char *cmd_argv; int argc; char *argv[RTEMS_SHELL_MAXIMUM_ARGUMENTS]; bool result = true; bool input_file = false; int line = 0; FILE *stdinToClose = NULL; FILE *stdoutToClose = NULL; rtems_shell_initialize_command_set(); shell_env = rtems_current_shell_env = rtems_shell_init_env( shell_env_arg ); /* * @todo chrisj * Remove the use of task variables. Change to have a single * allocation per shell and then set into a notepad register * in the TCB. Provide a function to return the pointer. * Task variables are a virus to embedded systems software. */ sc = rtems_task_variable_add( RTEMS_SELF, (void*)&rtems_current_shell_env, rtems_shell_env_free ); if (sc != RTEMS_SUCCESSFUL) { rtems_error(sc,"rtems_task_variable_add(current_shell_env):"); return false; } setuid(0); setgid(0); rtems_current_user_env->euid = rtems_current_user_env->egid = 0; fileno(stdout); /* fprintf( stderr, "-%s-%s-\n", shell_env->input, shell_env->output ); */ if (shell_env->output && strcmp(shell_env->output, "stdout") != 0) { if (strcmp(shell_env->output, "stderr") == 0) { stdout = stderr; } else if (strcmp(shell_env->output, "/dev/null") == 0) { fclose (stdout); } else { FILE *output = fopen(shell_env_arg->output, shell_env_arg->output_append ? "a" : "w"); if (!output) { fprintf(stderr, "shell: open output %s failed: %s\n", shell_env_arg->output, strerror(errno)); return false; } stdout = output; stdoutToClose = output; } } if (shell_env->input && strcmp(shell_env_arg->input, "stdin") != 0) { FILE *input = fopen(shell_env_arg->input, "r"); if (!input) { fprintf(stderr, "shell: open input %s failed: %s\n", shell_env_arg->input, strerror(errno)); return false; } stdin = input; stdinToClose = input; shell_env->forever = false; input_file =true; } else { /* make a raw terminal,Linux Manuals */ if (tcgetattr(fileno(stdin), &previous_term) >= 0) { term = previous_term; term.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON); term.c_oflag &= ~OPOST; term.c_oflag |= (OPOST|ONLCR); /* But with cr+nl on output */ term.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN); term.c_cflag |= CLOCAL | CREAD; term.c_cc[VMIN] = 1; term.c_cc[VTIME] = 0; if (tcsetattr (fileno(stdin), TCSADRAIN, &term) < 0) { fprintf(stderr, "shell:cannot set terminal attributes(%s)\n",shell_env->devname); } } cmd_count = RTEMS_SHELL_CMD_COUNT; prompt = malloc(RTEMS_SHELL_PROMPT_SIZE); if (!prompt) fprintf(stderr, "shell:cannot allocate prompt memory\n"); } setvbuf(stdin,NULL,_IONBF,0); /* Not buffered*/ setvbuf(stdout,NULL,_IONBF,0); /* Not buffered*/ rtems_shell_initialize_command_set(); /* * Allocate the command line buffers. */ cmd_argv = malloc (RTEMS_SHELL_CMD_SIZE); if (!cmd_argv) { fprintf(stderr, "no memory for command line buffers\n" ); } cmds[0] = calloc (cmd_count, RTEMS_SHELL_CMD_SIZE); if (!cmds[0]) { fprintf(stderr, "no memory for command line buffers\n" ); } if (cmd_argv && cmds[0]) { memset (cmds[0], 0, cmd_count * RTEMS_SHELL_CMD_SIZE); for (cmd = 1; cmd < cmd_count; cmd++) { cmds[cmd] = cmds[cmd - 1] + RTEMS_SHELL_CMD_SIZE; } do { /* Set again root user and root filesystem, side effect of set_priv..*/ sc = rtems_libio_set_private_env(); if (sc != RTEMS_SUCCESSFUL) { rtems_error(sc,"rtems_libio_set_private_env():"); result = false; break; } /* * By using result here, we can fall to the bottom of the * loop when the connection is dropped during login and * keep on trucking. */ if (shell_env->login_check != NULL) { result = rtems_shell_login(stdin,stdout); } else { result = true; } if (result) { const char *c; memset (cmds[0], 0, cmd_count * RTEMS_SHELL_CMD_SIZE); if (!input_file) { rtems_shell_cat_file(stdout,"/etc/motd"); fprintf(stdout, "\n" "RTEMS SHELL (Ver.1.0-FRC):%s. " \ __DATE__". 'help' to list commands.\n", shell_env->devname); } if (input_file) chdir(shell_env->cwd); else chdir("/"); /* XXX: chdir to getpwent homedir */ shell_env->exit_shell = false; for (;;) { int cmd; /* Prompt section */ if (prompt) { rtems_shell_get_prompt(shell_env, prompt, RTEMS_SHELL_PROMPT_SIZE); } /* getcmd section */ cmd = rtems_shell_line_editor(cmds, cmd_count, RTEMS_SHELL_CMD_SIZE, prompt, stdin, stdout); if (cmd == -1) continue; /* empty line */ if (cmd == -2) break; /*EOF*/ line++; if (shell_env->echo) fprintf(stdout, "%d: %s\n", line, cmds[cmd]); /* evaluate cmd section */ c = cmds[cmd]; while (*c) { if (!isblank((unsigned char)*c)) break; c++; } if (*c == '\0') /* empty line */ continue; if (*c == '#') { /* comment character */ cmds[cmd][0] = 0; continue; } if (!strcmp(cmds[cmd],"bye") || !strcmp(cmds[cmd],"exit")) { fprintf(stdout, "Shell exiting\n" ); break; } else if (!strcmp(cmds[cmd],"shutdown")) { /* exit application */ fprintf(stdout, "System shutting down at user request\n" ); exit(0); } /* exec cmd section */ /* TODO: * To avoid user crash catch the signals. * Open a new stdio files with posibility of redirection * * Run in a new shell task background. (unix &) * Resuming. A little bash. */ memcpy (cmd_argv, cmds[cmd], RTEMS_SHELL_CMD_SIZE); if (!rtems_shell_make_args(cmd_argv, &argc, argv, RTEMS_SHELL_MAXIMUM_ARGUMENTS)) { shell_cmd = rtems_shell_lookup_cmd(argv[0]); if ( argv[0] == NULL ) { shell_env->errorlevel = -1; } else if ( shell_cmd == NULL ) { shell_env->errorlevel = rtems_shell_script_file(argc, argv); } else { shell_env->errorlevel = shell_cmd->command(argc, argv); } } /* end exec cmd section */ if (shell_env->exit_shell) break; } fflush( stdout ); fflush( stderr ); } } while (result && shell_env->forever); } if (cmds[0]) free (cmds[0]); if (cmd_argv) free (cmd_argv); if (prompt) free (prompt); if (stdinToClose) { fclose( stdinToClose ); } else { if (tcsetattr(fileno(stdin), TCSADRAIN, &previous_term) < 0) { fprintf( stderr, "shell: cannot reset terminal attributes (%s)\n", shell_env->devname ); } } if ( stdoutToClose ) fclose( stdoutToClose ); return result; }
rtems_status_code rtems_monitor_server_request( uint32_t server_node, rtems_monitor_server_request_t *request, rtems_monitor_server_response_t *response ) { rtems_id server_id; rtems_status_code status; size_t size; /* * What is id of monitor on target node? * Look it up if we don't know it yet. */ server_id = rtems_monitor_server_request_queue_ids[server_node]; if (server_id == 0) { status = rtems_message_queue_ident(RTEMS_MONITOR_QUEUE_NAME, server_node, &server_id); if (status != RTEMS_SUCCESSFUL) { rtems_error(status, "ident of remote server failed"); goto done; } rtems_monitor_server_request_queue_ids[server_node] = server_id; } request->return_id = rtems_monitor_server_response_queue_id; status = rtems_message_queue_send(server_id, request, sizeof(*request)); if (status != RTEMS_SUCCESSFUL) { rtems_error(status, "monitor server request send failed"); goto done; } /* * Await response, if requested */ if (response) { status = rtems_message_queue_receive(rtems_monitor_server_response_queue_id, response, &size, RTEMS_WAIT, 100); if (status != RTEMS_SUCCESSFUL) { rtems_error(status, "server did not respond"); /* maybe server task was restarted; look it up again next time */ rtems_monitor_server_request_queue_ids[server_node] = 0; goto done; } if (response->command != RTEMS_MONITOR_SERVER_RESPONSE) { status = RTEMS_INCORRECT_STATE; goto done; } } done: return status; }
void rtems_monitor_server_init( uint32_t monitor_flags __attribute__((unused)) ) { #if defined(RTEMS_MULTIPROCESSING) rtems_status_code status; if (_System_state_Is_multiprocessing && (_Configuration_MP_table->maximum_nodes > 1)) { uint32_t maximum_nodes = _Configuration_MP_table->maximum_nodes; /* * create the msg que our server will listen * Since we only get msgs from other RTEMS monitors, we just * need reserve space for 1 msg from each node. */ status = rtems_message_queue_create( RTEMS_MONITOR_QUEUE_NAME, maximum_nodes, sizeof(rtems_monitor_server_request_t), RTEMS_GLOBAL, &rtems_monitor_server_request_queue_id); if (status != RTEMS_SUCCESSFUL) { rtems_error(status, "could not create monitor server message queue"); goto done; } /* * create the msg que our responses will come on * Since monitor just does one thing at a time, we only need 1 item * message queue. */ status = rtems_message_queue_create( RTEMS_MONITOR_RESPONSE_QUEUE_NAME, 1, /* depth */ sizeof(rtems_monitor_server_response_t), RTEMS_GLOBAL, &rtems_monitor_server_response_queue_id); if (status != RTEMS_SUCCESSFUL) { rtems_error(status, "could not create monitor response message queue"); goto done; } /* need an id for queue of each other server we might talk to */ /* indexed by node, so add 1 to maximum_nodes */ rtems_monitor_server_request_queue_ids = (rtems_id *) malloc((maximum_nodes + 1) * sizeof(rtems_id)); (void) memset(rtems_monitor_server_request_queue_ids, 0, (maximum_nodes + 1) * sizeof(rtems_id)); rtems_monitor_server_request_queue_ids[rtems_monitor_node] = rtems_monitor_server_request_queue_id; /* * create the server task */ status = rtems_task_create(RTEMS_MONITOR_SERVER_NAME, 1, 0 /* default stack */, RTEMS_INTERRUPT_LEVEL(0), RTEMS_DEFAULT_ATTRIBUTES, &rtems_monitor_server_task_id); if (status != RTEMS_SUCCESSFUL) { rtems_error(status, "could not create monitor server task"); goto done; } /* * Start the server task */ status = rtems_task_start(rtems_monitor_server_task_id, rtems_monitor_server_task, monitor_flags); if (status != RTEMS_SUCCESSFUL) { rtems_error(status, "could not start monitor server"); goto done; } } done: #endif return; }
void rtems_monitor_server_task( rtems_task_argument monitor_flags __attribute__((unused)) ) { rtems_monitor_server_request_t request; rtems_monitor_server_response_t response; rtems_status_code status; size_t size; for (;;) { status = rtems_message_queue_receive( rtems_monitor_server_request_queue_id, &request, &size, RTEMS_WAIT, (rtems_interval) 0); if (status != RTEMS_SUCCESSFUL) { rtems_error(status, "monitor server msg queue receive error"); goto failed; } if (size != sizeof(request)) { rtems_error(0, "monitor server bad size on receive"); goto failed; } switch (request.command) { case RTEMS_MONITOR_SERVER_CANONICAL: { rtems_monitor_object_type_t object_type; rtems_id id; rtems_id next_id; object_type = (rtems_monitor_object_type_t) request.argument0; id = (rtems_id) request.argument1; next_id = rtems_monitor_object_canonical_get(object_type, id, &response.payload, &size); response.command = RTEMS_MONITOR_SERVER_RESPONSE; response.result0 = next_id; response.result1 = size; #define SERVER_OVERHEAD (offsetof(rtems_monitor_server_response_t, \ payload)) status = rtems_message_queue_send(request.return_id, &response, size + SERVER_OVERHEAD); if (status != RTEMS_SUCCESSFUL) { rtems_error(status, "response send failed"); goto failed; } break; } default: { rtems_error(0, "invalid command to monitor server: %d", request.command); goto failed; } } } failed: rtems_task_delete(RTEMS_SELF); }
/* utility wrapper */ static void spawned_shell(void *targ) { rtems_status_code sc; FILE *nstd[3]={0}; FILE *ostd[3]={ stdin, stdout, stderr }; int i=0; struct shell_args *arg = targ; bool login_failed = false; bool start = true; sc=rtems_libio_set_private_env(); /* newlib hack/workaround. Before we change stdin/out/err we must make * sure the internal data are initialized (fileno(stdout) has this sideeffect). * This should probably be done from RTEMS' libc support layer... * (T.S., newlibc-1.13; 2005/10) */ fileno(stdout); if (RTEMS_SUCCESSFUL != sc) { rtems_error(sc,"rtems_libio_set_private_env"); goto cleanup; } /* redirect stdio */ for (i=0; i<3; i++) { if ( !(nstd[i]=fopen(arg->devname,"r+")) ) { perror("unable to open stdio"); goto cleanup; } } stdin = nstd[0]; stdout = nstd[1]; stderr = nstd[2]; #if 0 printk("STDOUT is now %x (%x) (FD %i/%i)\n", stdout,nstd[1],fileno(stdout),fileno(nstd[1])); printf("hello\n"); write(fileno(stdout),"hellofd\n",8); #endif /* call their routine */ if (rtems_telnetd_config.login_check != NULL) { start = rtems_shell_login_prompt( stdin, stderr, arg->devname, rtems_telnetd_config.login_check ); login_failed = !start; } if (start) { rtems_telnetd_config.command( arg->devname, arg->arg); } stdin = ostd[0]; stdout = ostd[1]; stderr = ostd[2]; if (login_failed) { syslog( LOG_AUTHPRIV | LOG_WARNING, "telnetd: to many wrong passwords entered from %s", arg->peername ); } cleanup: release_a_Connection(arg->devname, arg->peername, nstd, i); free(arg); }
static int rtems_verror( uint32_t error_flag, const char *printf_format, va_list arglist ) { int local_errno = 0; int chars_written = 0; rtems_status_code status; if (error_flag & RTEMS_ERROR_PANIC) { if (rtems_panic_in_progress++) _Thread_Disable_dispatch(); /* disable task switches */ /* don't aggravate things */ if (rtems_panic_in_progress > 2) return 0; } (void) fflush(stdout); /* in case stdout/stderr same */ status = error_flag & ~RTEMS_ERROR_MASK; if (error_flag & RTEMS_ERROR_ERRNO) /* include errno? */ local_errno = errno; #if defined(RTEMS_MULTIPROCESSING) if (_System_state_Is_multiprocessing) fprintf(stderr, "[%" PRIu32 "] ", _Configuration_MP_table->node); #endif chars_written += vfprintf(stderr, printf_format, arglist); if (status) chars_written += fprintf(stderr, " (status: %s)", rtems_status_text(status)); if (local_errno) { if ((local_errno > 0) && *strerror(local_errno)) chars_written += fprintf(stderr, " (errno: %s)", strerror(local_errno)); else chars_written += fprintf(stderr, " (unknown errno=%d)", local_errno); } chars_written += fprintf(stderr, "\n"); (void) fflush(stderr); if (error_flag & (RTEMS_ERROR_PANIC | RTEMS_ERROR_ABORT)) { if (error_flag & RTEMS_ERROR_PANIC) { rtems_error(0, "fatal error, exiting"); _exit(local_errno); } else { rtems_error(0, "fatal error, aborting"); abort(); } } return chars_written; }