void fgCommand(int index) { int size = list_size(lista_trabajos); // Guardamos el tamaño de la lista if(empty_list(lista_trabajos)) { printf("La lista está vacía\n"); } else if(index > size || index <= 0) { printf("El argumento indicado está fuera del rango de la lista\n"); printf("La lista sólo contiene {%d} elementos\n", size); } else { // Extraemos el trabajo de la lista de trabajos job *trabajo = get_item_bypos(lista_trabajos, index); // Información sobre el proceso actual printf("Tarea: %d, pid: %d, comando: %s, estado anterior: %s. \n", index, trabajo->pgid, trabajo->command, state_strings[trabajo->state]); // Si la tarea está parada es que la hemos suspendido if(trabajo->state == STOPPED) { printf("Reanudando la tarea... \n"); killpg(trabajo->pgid, SIGCONT); // Enviamos al proceso la señal para reanudarlo } if(trabajo->state != FOREGROUND) { int status; int pgid; int info; pgid = trabajo->pgid; trabajo->state = FOREGROUND; printf("Tarea: %d, pid: %d, comando: %s, estado actual: %s. \n", index, trabajo->pgid, trabajo->command, state_strings[trabajo->state]); printf("Asignándole el terminal...\n"); set_terminal(pgid); // Esperamos que el proceso siga haciendo su ejecución en primer plano pid_t wpid = waitpid(pgid, &status, WUNTRACED); // Vemos su nuevo estado y damos el mensaje enum status st = analyze_status(status, &info); printf("Background pid: %d, command: %s, %s, info: %d \n", wpid, trabajo->command, status_strings[st], info); block_SIGCHLD(); if(st == SUSPENDED) { // Actualizamos su estado en la lista trabajo->state = STOPPED; // Si no, es que ha terminado y por tanto lo eliminamos de la lista } else { // Lo eliminamos de la lista delete_job(lista_trabajos, trabajo); } unblock_SIGCHLD(); // Le devolvemos al terminal al proceso principal set_terminal(getpid()); } } }
int main(int ac, char **av, char **env) { t_sh *sh; int stop; create_env(env); env = add_builtin_pid(env); set_signal(); if (ac > 1) (void)av; else { stop = 0; sh = get_sh(&stop); set_terminal(sh); while (!stop) { sh->ft_stdin = dup(STDIN_FILENO); sh->ft_stdout = dup(STDOUT_FILENO); start_sh(sh); ft_putenv("PID_EXECV", NULL); } } return (0); }
void tty_reset(void) { set_terminal(1, 0, 0); tty_esc("?25h"); tty_esc("0m"); tty_jump(0, 999); tty_esc("K"); }
WIOUnix::~WIOUnix() { int f = fileno(ttyf); ioctl(f, TCSETS, &ttysav); if (ttyf != stdin) { fclose(ttyf); } set_terminal(false); }
void kbopen(VOID) { kbinitmap(); if ((fptty = tfopen("/dev/tty","r")) != (FILE*)NULL) { set_terminal(); screen_lines = get_screen_lines(); } }
kmain() { /* Inicializa */ init_interrupts(); init_video(); init_stdio(); keyboard_queue_initialize(); set_language(ENGLISH); set_terminal(0); loop(); }
WIOUnix::WIOUnix() : tty_open(0), ttyf(nullptr) { if ((ttyf = fdopen(::open(TTY, O_RDWR), "r")) == nullptr) { ttyf = stdin; } else { setbuf(ttyf, NULL); } int f = fileno(ttyf); set_terminal(true); struct termios ttyb; ioctl(f, TCGETS, &ttysav); ioctl(f, TCGETS, &ttyb); ttyb.c_lflag &= ~(ECHO | ISIG); ioctl(f, TCSETS, &ttyb); }
void kbhit(int fd) { struct termios termios; char kb[32]; int rc; set_terminal(fd, &termios); do { rc = read(fd, kb, sizeof(kb)); if (rc > 0) break; usleep(100); } while (1); reset_terminal(fd, &termios); }
int main(int argc, char *argv[]) { FILE *f; char c = 0, buf[512]; int d; if (argc < 2) { fprintf(stderr, "needed a file name\n"); exit(0); } f = fopen(argv[1], "r"); if (!f) { fprintf(stderr, "unable to open %s\n", argv[1]); exit(0); } set_terminal(); while(c!=0x1b) { read(0, &c, 1); if (c == 0x0a || c == 0x0d) { if (fgets(buf, 512, f)) fputs(buf, stdout); else break; } else { if ((d = fgetc(f)) != EOF) putchar(d); else break; } fflush(stdout); } reset_terminal(); fputs("\033[0m\n", stdout); return 0; }
void xset_terminal(int fd, int raw, struct termios *old) { if (-1 == set_terminal(fd, raw, old)) perror_exit("bad tty fd#%d", fd); }
/* ** Animates a game until it is finished, and then cleans up allocated stuff. ** Returns final status of the game. */ int play_game() { unsigned int status; int i; Boolean newgame; if (num_combatants == 0) return GAME_FAILED; /* In an ultimate game, only reset at the beginning, since we want don't want scores to reset after every goal. */ if (settings.si.game == ULTIMATE_GAME) { init_combatants(); newgame = TRUE; } do { #ifdef X11 button_up(ANIM_WIN, FALSE); follow_mouse(ANIM_WIN, FALSE); #endif if (settings.si.game != ULTIMATE_GAME) { init_combatants(); newgame = TRUE; } if (setup_game(newgame) == GAME_FAILED) return GAME_FAILED; newgame = FALSE; game_running = True; #ifdef SOUND play_all(START_SOUND); #endif /*SOUND*/ do { status = animate(); } while (status == GAME_RUNNING); #ifdef SOUND play_all(END_SOUND); #endif /*SOUND*/ game_running = False; status = display_game_stats(status); game_cleanup(); /* nuking all the vehicles here is overkill */ } while (status == GAME_RESET); /* Unmap battle windows and clear all other windows on all the terminals */ for (i = 0; i < num_terminals; i++) { set_terminal(i); unmap_battle_windows(); clear_windows(); } /* Return to terminal 0 for the user interface */ set_terminal(0); #ifdef X11 button_up(ANIM_WIN, TRUE); follow_mouse(ANIM_WIN, TRUE); #endif return status; }
int main(void) { char inputBuffer[MAX_LINE]; /** buffer to hold the command entered **/ int background; /** equals 1 if a command is followed by '&' **/ int respawnable; /** igual a 1 si al comando le sigue '#' **/ char *args[MAX_LINE / 2]; /** command line (of 256) has max of 128 arguments **/ // probably useful variables: int pid_fork, pid_wait; /** pid for created and waited process **/ int status; /** status returned by wait **/ enum status status_res; /** status processed by analyze_status() **/ int info; /** info processed by analyze_status() **/ ignore_terminal_signals(); /** Ignora las señales del terminal **/ /** Asociamos el manejador a la señal SIGCHLD y creamos la lista de trabajos **/ signal(SIGCHLD, manejador); lista_trabajos = new_list("Lista trabajos"); /** Program terminates normally inside get_command() after ^D is typed **/ while(1) { printf("\nCOMMAND->"); fflush(stdout); /** get next command **/ get_command(inputBuffer, MAX_LINE, args, &background, &respawnable); // if empty command if(args[0] == NULL) { continue; } /** Comando interno CD **/ if(strcmp(args[0], "cd") == 0 && args[1] != NULL) { chdir(args[1]); continue; } /** Comando interno historial **/ if(strcmp(args[0], "historial") == 0) { continue; } /** Comando interno JOBS (HECHO) **/ if(strcmp(args[0], "jobs") == 0) { if(empty_list(lista_trabajos)) { printf("La lista de tareas está vacía\n"); } else { print_job_list(lista_trabajos); } continue; } /** Comando interno BG (HECHO) **/ if(strcmp(args[0], "bg") == 0) { if(args[1] == NULL) { printf("No le has pasado ningún argumento al comando \n"); } else { int index = atoi(args[1]); // Convertimos el indice pasado a un entero bgCommand(index); // Invocamos al comando FG } continue; } /** Comando interno FG (HECHO) **/ if(strcmp(args[0], "fg") == 0) { int index = 1; // Por defecto a la primera tarea de la lista if(args[1] != NULL) { index = atoi(args[1]); // Si no es nulo, lo aplicaremos al correspondiente } fgCommand(index); // Invocamos al comando FG continue; } // the steps are: // (1) fork a child process using fork() pid_fork = fork(); if(pid_fork < 0) { // Caso de error printf("Error. The system wasn able to spawn a new process. Exiting...\n"); exit(-1); } else if(pid_fork == 0) { // Proceso hijo /** Nuevo identificador de grupo de procesos para el hijo, asociacion del terminal y señales a default **/ pid_t mypid = getpid(); new_process_group(mypid); // Metemos al hijo en un nuevo grupo if(!background && !respawnable) { // Le asignamos el terminal set_terminal(mypid); } // Restauramos las señales que reciben del terminal restore_terminal_signals(); // (2) the child process will invoke execvp() execvp(args[0], args); // Solo llegará aquí si no se ha producido el cambio de imagen printf("Error. Command not found: %s\n", args[0]); exit(-1); // Padre } else { /** Nuevo identificador de grupo de procesos para el hijo **/ new_process_group(pid_fork); // El padre se va a un nuevo grupo de trabajo /** Si el programa está en background o es respawnable **/ if(background || respawnable) { /** BLoqueamos la señal SIGCHLD, añadimos el trabajo a la lista(background) y desbloqueamos la señal **/ block_SIGCHLD(); job *aux; // Creamos un nuevo nodo para agregarlo a la lista if(background) { aux = new_job(pid_fork, args[0], args, BACKGROUND); } else if(respawnable) { aux = new_job(pid_fork, args[0], args, RESPAWNABLE); } // Añadimos ese nodo a la lista creada anteriormente add_job(lista_trabajos, aux); unblock_SIGCHLD(); printf("Background job running... pid: %d, command: %s. \n", pid_fork, args[0]); /** Si no, es por que está en foreground **/ } else { /** * Wait con detección de suspension y recuperación del terminal * Con el WUNTRACED se comprueba también si el hijo se suspende **/ set_terminal(pid_fork); // Redundante pid_t wait_pid = waitpid(pid_fork, &status, WUNTRACED); set_terminal(getpid()); /** * pid_fork = waitpid(pid_fork, &status, 0); * esta instruccion ya no es necesaria porque hacemos el wait_pid **/ int info; // Le pasamos la variable "status" que nos acaba de pasar el wait enum status st = analyze_status(status, &info); /** * Si sale del bloqueo debido a la suspensión del estado * lo metemos en la lista de tareas para poder llevar un * seguimiento de los procesos suspendidos **/ if(st == SUSPENDED) { /** BLoqueamos la señal SIGCHLD, añadimos el trabajo a la lista (suspendido) y desbloqueamos la señal **/ block_SIGCHLD(); // Creamos un nuevo nodo para agregarlo a la lista job *aux = new_job(pid_fork, args[0], args, STOPPED); // Añadimos ese nodo a la lista creada anteriormente add_job(lista_trabajos, aux); unblock_SIGCHLD(); } // (4) Shell shows a status message for processed command printf("Foreground pid: %d, command: %s, status: %s, info: %d. \n", wait_pid, args[0], status_strings[st], info); } } // (5) loop returns to get_commnad() function } // end while }
int main(int argc, char *argv[]) { if (argc < 3) { fprintf(stderr, "%s [server name] [log file] ([config file]...)\n", argv[0]); return 1; } set_initial_id(); /*NOTE: must be before log file for su servers*/ set_log_file(argv[2]); /*setup~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ if (!set_program_name(argv[0])) return 1; if (!change_server_name(argv[1])) { fprintf(stderr, "%s: invalid server name '%s'\n", argv[0], argv[1]); return 1; } /*use 'clean_server_exit' below here (after initialization)*/ if (!initialize_server()) { fprintf(stderr, "%s: couldn't initialize server (check log file)\n", argv[0]); clean_server_exit(1); } /*NOTE: stop using standard error here and use logging only because of daemonizing*/ start_server(); int current_pid = getpid(); #ifndef PARAM_NO_DAEMON if (getsid(0) != getpid()) { notify_parent = current_pid; pid_t daemon = fork(); if (daemon < 0) { log_server_daemon_error(strerror(errno)); fprintf(stderr, "%s: daemon error (check log file)\n", argv[0]); clean_server_exit(1); } if (daemon == 0) { log_server_daemon(current_pid, getpid()); #ifndef PARAM_NO_SESSION if (getpid() == setsid()) /*NOTE: leave 'getpid' first here in case of error*/ log_server_session_set(); else { log_server_session_error(strerror(errno)); fprintf(stderr, "%s: session error (check log file)\n", argv[0]); clean_server_exit(1); } #else setpgid(0, 0); #endif raise(SIGSTOP); } else { setpgid(0, 0); signal(SIGUSR1, &parent_signal); signal(SIGUSR2, &parent_signal); int error = 0, status = 0; while ( ((error = waitpid(daemon, &status, WUNTRACED)) < 0 && errno == EINTR) || (!WIFSTOPPED(status) && !WIFEXITED(status)) ); if (error < 0 || WIFEXITED(status)) { fprintf(stderr, "%s: internal error: %s\n", argv[0], (error < 0)? strerror(errno) : "unknown error"); partial_server_exit(1); } kill(daemon, SIGCONT); struct timespec register_wait = server_register_all_wait(); nanosleep(®ister_wait, NULL); partial_server_exit(1); } } else log_server_session_leader(); #endif set_env_pid(); if (set_terminal()) log_server_terminal(); set_controlling_pid(getpid()); /*END setup~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ /*scheduling setup~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ struct sched_param parameters = { sched_priority: sched_get_priority_max(SCHED_RR) };
int _readline(struct rls *rls) { int flags; struct termios termios; int i, j; int fkey; char *kb; int ihist; int rc; char **tab; char *p; int off = 0; if (isatty(rls->fdin)) set_terminal(rls->fdin, &termios); memset(rls->kbuffer, 0, rls->maxbuflen); rls->pos = 0; /* flags = fcntl(0, F_GETFL); fcntl(0, F_SETFL, flags); */ flags = 0; ihist = 0; kb = rls->kb; rc = 0; do { if (off >= rc) { memset(kb, 0, sizeof(rls->kb)); rc = read(rls->fdin, kb, sizeof(rls->kb)); if (rc <= 0) { //usleep(1); continue; } off = 0; } else { memmove(kb, kb + off, rc - off); rc -= off; } #if 0 printf("\n%2.2x - %2.2x - %2.2x - %2.2x - %2.2x - %2.2x - %2.2x - %2.2x\n", kb[0], kb[1], kb[2], kb[3], kb[4], kb[5], kb[6], kb[6]); fflush(stdout); #endif if (kb[0] == ESC && kb[1] == ESC_PAD) { fkey = kb[2] | (kb[3] << 8); if (kb[2] == KEY_UP) { off = 3; if (flags == 0) { /* set history-mode */ flags = 1; ihist = rls->hist_total; if (rls->pos != 0) strcpy(rls->history[rls->maxhistnum], rls->kbuffer); else rls->history[rls->maxhistnum][0] = '\0'; } if (ihist == 0) continue; i = findhistory(rls, 0 - ihist); if (i == -1) continue; ihist = i; /* while (rls->pos-- > 0) */ i = strlen(rls->kbuffer); while (rls->pos++ < i) vprint(rls->fdout, " ", 1); while (i-- > 0) vprint(rls->fdout, "\b \b", 3); memset(rls->kbuffer, 0, rls->maxbuflen); strcpy(rls->kbuffer, rls->history[ihist]); rls->pos = strlen(rls->kbuffer); vprint(rls->fdout, rls->kbuffer, rls->pos); continue; } if (kb[2] == KEY_DOWN){ off = 3; if (flags == 0) continue; if ((ihist + 1) >= rls->hist_total) { i = strlen(rls->kbuffer); while (rls->pos++ < i) vprint(rls->fdout, " ", 1); while (i-- > 0) vprint(rls->fdout, "\b \b", 3); memset(rls->kbuffer, 0, rls->maxbuflen); rls->pos = 0; flags = 0; continue; } //printf("ihist = %d, rls->hist_total = %d\n", // ihist, rls->hist_total); i = findhistory(rls, ihist); if (i == -1) continue; ihist = i; i = strlen(rls->kbuffer); while (rls->pos++ < i) vprint(rls->fdout, " ", 1); while (i-- > 0) vprint(rls->fdout, "\b \b", 3); memset(rls->kbuffer, 0, rls->maxbuflen); strcpy(rls->kbuffer, rls->history[ihist]); rls->pos = strlen(rls->kbuffer); vprint(rls->fdout, rls->kbuffer, rls->pos); continue; } if (kb[2] == KEY_RIGHT) { off = 3; if (rls->pos < strlen(rls->kbuffer)) vprint(rls->fdout, &(rls->kbuffer[rls->pos++]), 1); continue; } if (kb[2] == KEY_LEFT) { off = 3; if (rls->pos > 0) { vprint(rls->fdout, "\b", 1); rls->pos --; } continue; } if (fkey == KEY_HOME) { off = 4; while (rls->pos > 0) { vprint(rls->fdout, "\b", 1); rls->pos --; } continue; } if (fkey == KEY_END) { off = 4; while (rls->pos < strlen(rls->kbuffer)) { vprint(rls->fdout, &(rls->kbuffer[rls->pos++]), 1); } continue; } } flags = 0; /* 'enter' */ if (kb[0] == LF || kb[0] == CR) { off = 1; trimspace(rls->kbuffer); rls->pos = strlen(rls->kbuffer); if (rls->pos == 0) break; if (rls->hist_total == rls->maxhistnum) { memmove(rls->history[0], rls->history[1], rls->maxbuflen * (rls->maxhistnum - 1)); rls->hist_total--; } strcpy(rls->history[rls->hist_total++], rls->kbuffer); break; } if (kb[0] == CTRLC) { off = 1; rls->pos = 0; rls->kbuffer[0] = '\0'; break; } if (kb[0] == '\t') { off = 1; if (rls->tab_callback == NULL) continue; p= NULL; if (rls->pos != 0) { p = rls->kbuffer + rls->pos; while (p > rls->kbuffer) { if (*(p - 1) == ' ') break; p--; } } tab = rls->tab_callback(rls->kbuffer, p); if (tab == NULL) continue; /* only one */ if (*tab != NULL && *(tab + 1) == NULL) { for (i = 0; i < strlen(p); i++) vprint(rls->fdout, "\b \b", 3); i = strlen(*tab); vprint(rls->fdout, *tab, i); if (p - rls->kbuffer + i < rls->maxbuflen) { strcpy(p, *tab); rls->pos = strlen(rls->kbuffer); } free(*tab); free(tab); continue; } /* more than one */ vprint(rls->fdout, "\n", 1); i = 0; while (*(tab + i)) { vprint(rls->fdout, *(tab + i), strlen(*(tab + i))); vprint(rls->fdout, " ", 1); free(*(tab + i)); i++; } vprint(rls->fdout, "\n", 1); free(tab); vprint(rls->fdout, rls->prompt, strlen(rls->prompt)); vprint(rls->fdout, rls->kbuffer, rls->pos); continue; } /* backspace */ if ((kb[0] == BACKSP0)|| (kb[0] == BACKSP1)) { off = 1; if (rls->pos > 0) { i = strlen(rls->kbuffer); j = rls->pos; while (j < i) { rls->kbuffer[j - 1] = rls->kbuffer[j]; j++; } rls->kbuffer[j - 1] = '\0'; rls->pos--; vprint(rls->fdout, "\b", 1); vprint(rls->fdout, &rls->kbuffer[rls->pos], strlen(&rls->kbuffer[rls->pos])); vprint(rls->fdout, " \b", 2); for (i = 0; i < strlen(rls->kbuffer) - rls->pos; i++) vprint(rls->fdout, "\b", 1); } continue; } /* normal key */ off = 1; i = kb[0]; if (isprint(i)) { if (rls->pos < strlen(rls->kbuffer) - 1) { j = strlen(rls->kbuffer); /* avoid overflow */ if (j < rls->maxbuflen - 1) { while (j > rls->pos) { rls->kbuffer[j] = rls->kbuffer[j-1]; j--; } rls->kbuffer[rls->pos] = kb[0]; //rls->kbuffer[rls->pos + 1] = '\0'; vprint(rls->fdout, &rls->kbuffer[rls->pos], strlen(&rls->kbuffer[rls->pos])); for (j = 0; j < strlen(rls->kbuffer) - rls->pos - 1; j++) vprint(rls->fdout, "\b", 1); } } else { rls->kbuffer[rls->pos] = kb[0]; rls->kbuffer[rls->pos + 1] = '\0'; vprint(rls->fdout, &kb[0], 1); } rls->pos++; } } while (kb[0] != CTRLP); if (isatty(rls->fdin)) reset_terminal(rls->fdin, &termios); return (rls->pos > 0 ? 1 : 0); }