/** * Redirección de la E/S estándar. * Esta función se llama por el BSP antes de llamar a main, y una vez que se * han inicializado los dispositivos, para fijar la E/S estándar del sistema, * que por defecto está asignada a /dev/null. * @param stdin_dev Nombre del dispositivo que se usará para la entrada estándar * @param stdout_dev Nombre del dispositivo que se usará para la salida estándar * @param stderr_dev Nombre del dispositivo que se usará para el error estándar */ static void bsp_io_redirect(const char* stdin_dev, const char* stdout_dev, const char* stderr_dev) { /* Redireccionamos la E/S estándar */ redirect_fd (STDIN_FILENO, stdin_dev, O_RDONLY, 0777); redirect_fd (STDOUT_FILENO, stdout_dev, O_WRONLY, 0777); redirect_fd (STDERR_FILENO, stderr_dev, O_WRONLY, 0777); }
int daemonize() { pid_t pid; /* Fork once to ensure we aren't the process group leader */ pid = fork(); if (pid < 0) { guacd_log_error("Could not fork() parent: %s", strerror(errno)); return 1; } /* Exit if we are the parent */ if (pid > 0) { guacd_log_info("Exiting and passing control to PID %i", pid); _exit(0); } /* Start a new session (if not already group leader) */ setsid(); /* Fork again so the session group leader exits */ pid = fork(); if (pid < 0) { guacd_log_error("Could not fork() group leader: %s", strerror(errno)); return 1; } /* Exit if we are the parent */ if (pid > 0) { guacd_log_info("Exiting and passing control to PID %i", pid); _exit(0); } /* Change to root directory */ if (chdir(GUACD_ROOT) < 0) { guacd_log_error( "Unable to change working directory to " GUACD_ROOT); return 1; } /* Reopen the 3 stdxxx to /dev/null */ if (redirect_fd(STDIN_FILENO, O_RDONLY) || redirect_fd(STDOUT_FILENO, O_WRONLY) || redirect_fd(STDERR_FILENO, O_WRONLY)) { guacd_log_error( "Unable to redirect standard file descriptors to " GUACD_DEV_NULL); return 1; } /* Success */ return 0; }
// Execute cmd. Never returns. void runcmd(struct cmd *cmd) { int p[2], r, old_fd; struct execcmd *ecmd; struct pipecmd *pcmd; struct redircmd *rcmd; if(cmd == 0) exit(0); switch(cmd->type){ default: fprintf(stderr, "unknown runcmd\n"); exit(-1); case ' ': ecmd = (struct execcmd*)cmd; if(ecmd->argv[0] == 0) exit(0); // fprintf(stderr, "exec not implemented\n"); // Your code here ... // yeli: print all arguments #if 0 int idx = 0; for (idx = 0; idx < MAXARGS; ++idx) { if (0 == ecmd->argv[idx]) break; fprintf(stdout,"argv %d: %s\n", idx, ecmd->argv[idx]); } #endif if (-1 == execvp(ecmd->argv[0], ecmd->argv)) fprintf(stderr, "failed to exec %s\n", ecmd->argv[0]); break; case '>': case '<': rcmd = (struct redircmd*)cmd; // fprintf(stderr, "redir not implemented\n"); // Your code here ... int file_fd = open(rcmd->file, rcmd->mode);//open file if (-1 == file_fd) { fprintf(stderr, "fail to open file %s\n", rcmd->file); break; } old_fd = redirect_fd(file_fd, rcmd->fd);//old_fd point to stdin file if (-1 == old_fd) { fprintf(stderr, "fail to redirect %d to file %s\n", rcmd->fd, rcmd->file); } else { runcmd(rcmd->cmd); file_fd = redirect_fd(old_fd, rcmd->fd); } close(file_fd); break; case '|': pcmd = (struct pipecmd*)cmd; // fprintf(stderr, "pipe not implemented\n"); // Your code here ... int fds[2]; pipe(fds); int pid = fork(); if (0 < pid) { //child, fds[0] for read, redirect it to stdin close(fds[1]); old_fd = redirect_fd(fds[0], STDIN_FILENO); runcmd(pcmd->right); fds[0] = redirect_fd(old_fd, STDIN_FILENO); close(fds[0]); } else { //father, fds[1] for write, redirect it to stdout close(fds[0]); redirect_fd(fds[1], STDOUT_FILENO); runcmd(pcmd->left); fds[1] = redirect_fd(old_fd, STDOUT_FILENO); close(fds[1]); } break; } exit(0); }