static void task_delete_hook(WIND_TCB * tcb) { int i; ChildProcess * prs; semTake(prs_list_lock, WAIT_FOREVER); prs = find_process((UINT32)tcb); if (prs != NULL) { close(ioTaskStdGet(prs->pid, 1)); close(ioTaskStdGet(prs->pid, 2)); for (i = 0; i < 2; i++) { char pnm[32]; snprintf(pnm, sizeof(pnm), "/pty/tcf-%0*lx-%d", sizeof(prs->pid) * 2, prs->pid, i); ptyDevRemove(pnm); } } semGive(prs_list_lock); }
int sal_console_info_get(sal_console_info_t *info) { #if defined(TIOCGWINSZ) struct winsize W; #endif /* defined(TIOCGWINSZ) */ if (!isatty(ioTaskStdGet(0,STD_IN))) { return -1; } if (info == NULL) { return 0; } memset(info, 0, sizeof(*info)); #if defined(TIOCGWINSZ) if (ioctl(ioTaskStdGet(0,STD_IN), TIOCGWINSZ, &W) >= 0) { info->cols = (int)W.ws_col; info->rows = (int)W.ws_row; } #endif /* defined(TIOCGWINSZ) */ return 0; }
int sal_console_read(void *buf, int count) { int n; /* * VxWorks read does not abort with EINTR if a SIGINT is received, * so a signal handler and setjmp are used to emulate it. */ TTYget_orig_sigint = signal(SIGINT, TTYget_sighandler); if (setjmp(TTYget_jb)) { /* Stuff Ctrl-C in buffer to make readline happy */ ((char*)buf)[0] = 'C' & 0x1f; n = 1; } else { n = read(ioTaskStdGet(0,STD_IN), buf, count); } signal(SIGINT, TTYget_orig_sigint); return n; }
/* N.B.!! We do *not* execute in the context of the dying task here, but rather that of tExcTask - we do get a pointer to the task's TCB though - this pointer is in fact also the task's ID. */ static void save_reclaim(WIND_TCB *tcbp) { int i, var, oldfd; struct task_data *tdp; struct mall_data *mdp, *mdnextp; if ((var = taskVarGet((int)tcbp, (int *)&task_data)) != ERROR && var != 0) { tdp = (struct task_data *)var; if (tdp->version == (FUNCPTR)save_reclaim) { /* Only handle our own */ #ifdef DEBUG fdprintf(2, "Reclaiming for task id 0x%x:\nFiles: ", (int)tcbp); #endif /* Ugh! VxWorks doesn't even flush stdout/err - we need to get at those (which are task-private of course, i.e. we can't just do fflush(stdout) here) - we could be really pedantic and try to redefine stdout/err (which "are" function calls) too, snarfing the values when they are used - but besides the overhead this is problematic since they are actually #defines already... We'll peek in the TCB instead (no documentation of course). And of course, we must also meddle with the *file descriptor* indirections, or we'll just flush out on tExcTask's descriptors... */ for (i = 1; i <= 2; i++) { if (tcbp->taskStdFp[i] != NULL) { #ifdef DEBUG fdprintf(2, "fflush(%s) ", i == 1 ? "stdout" : "stderr"); #endif oldfd = ioTaskStdGet(0, i); ioTaskStdSet(0, i, tcbp->taskStd[i]); fflush(tcbp->taskStdFp[i]); ioTaskStdSet(0, i, oldfd); } } for (i = 3; i < tdp->max_files; i++) { if (FD_ISSET(i, &tdp->open_fds)) { #ifdef DEBUG fdprintf(2, "close(%d) ", i); #endif (void) close(i); } if (tdp->open_fps[i] != NULL) { #ifdef DEBUG fdprintf(2, "fclose(%0x%x) ", (int)tdp->open_fps[i]); #endif (void) fclose(tdp->open_fps[i]); } } i = 0; mdp = tdp->mall_data; while (mdp != NULL) { mdnextp = mdp->next; if(reclaim_free_function != NULL) (*reclaim_free_function)(mdp->self); else free(mdp->self); i++; mdp = mdnextp; } #ifdef DEBUG fdprintf(2, "\nFreeing memory: total %d mallocs\n", i); #endif if (tdp->delete_hook != NULL) { #ifdef DEBUG fdprintf(2, "Calling delete hook at 0x%08x\n", tdp->delete_hook); #endif (*tdp->delete_hook)(tdp->hook_data); #ifdef DEBUG fdprintf(2, "Called delete hook at 0x%08x\n", tdp->delete_hook); #endif } #ifdef DEBUG fdprintf(2, "Freeing own mem at 0x%08x\n", tdp); #endif (void) free((char *)tdp); #ifdef DEBUG fdprintf(2, "Freed own mem at 0x%08x, done (0x%08x)\n**********\n", tdp, taskIdSelf()); checkStack(0); #endif } } #ifdef DEBUG else fdprintf(2, "No task data found for id 0x%x, var = %d\n", (int)tcbp, var); #endif }
int sal_console_write(const void *buf, int count) { return write(ioTaskStdGet(0,STD_OUT), (void *)buf, count); }