/* * Interpret * * arguments: * char *cmdLine: pointer to the command line string * * returns: none * * This is the high-level function called by tsh's main to interpret a * command line. */ void Interpret(char* cmdLine) { commandT* com = getCommand(cmdLine); RunCmd(com); freeCommand(com); } /* Interpret */
/*** * addCommand: * Add the given command to the statement list * stmt: REFERNCE is BORROWED * cmd: REFERENCE is STOLEN (added to end of stmt's list) ***/ void addCommand(Statement* stmt, Command* cmd) { // Allocate memory (be sure to check for Out-of-mem) CmdList* newCmd = malloc(sizeof(CmdList)); if (newCmd == NULL) { fprintf(stderr, ">> Error: Out of memory. Command not added.\n"); freeCommand(cmd); // Free command - since we STOLE it return; } // Store the contents (the new command) newCmd->cmd = cmd; newCmd->next = NULL; // Insert into the cmdList - at the tail if (stmt->head == NULL) { // First command stmt->head = stmt->tail = newCmd; } else { stmt->tail = stmt->tail->next = newCmd; } }
WekaClassifier::WekaClassifier(const std::vector<Feature> &features, bool caching, const std::string &opts) : Classifier(features,caching), dropFrac(0.0), trainAllowed(true) { classifierCount++; memSegName = "WEKA_BRIDGE_" + boost::lexical_cast<std::string>(getpid()) + "_" + boost::lexical_cast<std::string>(classifierCount); comm = boost::shared_ptr<Communicator>(new Communicator(memSegName,true,features.size(),numClasses)); // fork you pid = fork(); if (pid < 0) { // failed to fork std::cerr << "WekaClassifier: ERROR: failed in fork: " << pid << std::endl; exit(65); } else if (pid == 0) { //child std::string cmd = WEKA_CMD + " " + memSegName + " " + "data/dt/blank.arff" + " " + opts; char** cmdArr = splitCommand(cmd); execvp(cmdArr[0],cmdArr); freeCommand(cmdArr); exit(0); return; } else { //parent } *(comm->cmd) = '\0'; }
int main(int argc,char* argv[]) { int loop = 1; while(loop) { Command* com = makeCommand(); printCommand(com); loop = executeCommand(com); freeCommand(com); } return 0; }
/* * Interpret * * arguments: * char *cmdLine: pointer to the command line string * * returns: none * * This is the high-level function called by tsh's main to interpret a * command line. */ void Interpret(char* cmdLine) { //printf("interpret"); commandT* cmd = getCommand(cmdLine); //printf("before run cmd\n"); RunCmd(cmd); //printf("past run cmd\n"); freeCommand(cmd); //printf("seg here\n"); } /* Interpret */
/* * Interpret * * arguments: * char *cmdLine: pointer to the command line string * * returns: none * * This is the high-level function called by tsh's main to interpret a * command line. */ void Interpret(char* cmdLine) { commandT* cmd = getCommand(cmdLine); cmd->cmdline = (char *)malloc(sizeof(char) * (strlen(cmdLine) + 1)); strcpy(cmd->cmdline, cmdLine); RunCmd(cmd); freeCommand(cmd); } /* Interpret */
static void completeCommand(HelperCommand *command) { if (command->waiting) { debugMonitorEnter(commandCompleteLock); command->done = JNI_TRUE; log_debugee_location("completeCommand(): HelperCommand done waiting", NULL, NULL, 0); debugMonitorNotifyAll(commandCompleteLock); debugMonitorExit(commandCompleteLock); } else { freeCommand(command); } }
/* * RunCmdPipe * * arguments: * commandT *cmd1: the commandT struct for the left hand side of the pipe * commandT *cmd2: the commandT struct for the right hand side of the pipe * * returns: none * * Runs two commands, redirecting standard output from the first to * standard input on the second. */ void RunCmdPipe(commandT* cmd1, commandT* cmd2) { int pid, ppid, fd[2]; if (pipe(fd) < 0) { perror("pipe error"); } if ((pid = fork()) < 0) { perror("fork error"); } else if (pid == 0) { dup2(fd[1], 1); close(fd[0]); setpgid(0, fgpid(jobs)); RunExternalCmd(cmd1, 0); } else { if (fgpid(jobs) == 0) addjob(jobs, pid, FG, "nil"); if ((ppid = fork()) < 0) { perror("fork error"); } else if (ppid == 0) { dup2(fd[0], 0); close(fd[1]); setpgid(0, fgpid(jobs)); RunCmdFork(cmd2, 0); } else { close(fd[0]); close(fd[1]); waitpid(pid, NULL, 0); waitpid(ppid, NULL, 0); if (fgpid(jobs) == pid) deletejob(jobs, pid); } } freeCommand(cmd1); freeCommand(cmd2); } /* RunCmdPipe */
static void enqueueCommand(HelperCommand *command, jboolean wait, jboolean reportingVMDeath) { static jboolean vmDeathReported = JNI_FALSE; CommandQueue *queue = &commandQueue; jint size = commandSize(command); command->done = JNI_FALSE; command->waiting = wait; command->next = NULL; debugMonitorEnter(commandQueueLock); while (size + currentQueueSize > maxQueueSize) { debugMonitorWait(commandQueueLock); } log_debugee_location("enqueueCommand(): HelperCommand being processed", NULL, NULL, 0); if (vmDeathReported) { /* send no more events after VMDeath and don't wait */ wait = JNI_FALSE; } else { currentQueueSize += size; if (queue->head == NULL) { queue->head = command; } else { queue->tail->next = command; } queue->tail = command; if (reportingVMDeath) { vmDeathReported = JNI_TRUE; } } debugMonitorNotifyAll(commandQueueLock); debugMonitorExit(commandQueueLock); if (wait) { debugMonitorEnter(commandCompleteLock); while (!command->done) { log_debugee_location("enqueueCommand(): HelperCommand wait", NULL, NULL, 0); debugMonitorWait(commandCompleteLock); } freeCommand(command); debugMonitorExit(commandCompleteLock); } }
int main(int argc, char** argv) { if (argc == 1) { return 0; } // Check input for validity. if (!validateInput(argc - 1, &argv[1])) { return -1; } // Count number of processes on the pipeline. for (int i = 0; argv[i] != 0; ++i) { if (!strcmp(argv[i], "|")) { ++numProcesses; } } // Open files as needed for I/O redirection. int bound = argc - 1; for (int i = 0; i < bound; ++i) { int erase_redirect = 0; // Find output redirect if it exists and open the pipe. if (!strcmp(argv[i], ">")) { write_fd = open(argv[i+1], O_CREAT | O_WRONLY); if (write_fd < 0) { perror(argv[i+1]); exit(-1); } dup2(write_fd, 1); close(write_fd); erase_redirect = 1; } // Find input redirect if it exists and get the file descriptor for it. if (!strcmp(argv[i], "<")) { read_fd = open(argv[i+1], O_RDONLY); if (read_fd < 0) { perror(argv[i+1]); exit(-1); } erase_redirect = 1; } // If a redirect is detected, eliminate the arguments and continue // processing. if (erase_redirect) { for (int j = i; j < bound - 1; ++j) { argv[j] = argv[j+2]; } argc -= 2; bound -= 2; erase_redirect = 0; --i; } } // Get first command to execute. curIndex = argc - 1; prevIndex = curIndex; curIndex = nextSpecial(curIndex, argv); if (curIndex == -1) curIndex = 0; getNextCommand(curIndex + 1, prevIndex, argv); // If there are multiple processes, enter function to execute all processes. if (numProcesses > 1) { executeNext(argc, argv); } // Otherwise, redirect stdin if needed and execute the command. else { if (read_fd != -1) { dup2(read_fd, 0); close(read_fd); } execvp(command[0], command); } freeCommand(); }
/** * process * * Éxécution de la commande * * @param {char *} str La commande à exécuter * @param {int} fdInput File descriptot * @param {int} fdOutput File descriptot * * @return {int} Status de retour */ int process(char *str, int fdInput, int fdOutput) { DEBUG("process command (in:%d, out:%d): %s", fdInput, fdOutput, str); //Extraction des actions à effectuer de l'input Action **actions = NULL; int actc = 0; //nombre d'actions extractionActions(str, &actions, &actc); DEBUG("[parent]\t%d actions to do", actc); int status = 0; //status code of execution //let's create pipes to chain stdin and stdout int pstdin[2], pstdout[2]; pstdin[PIPE_READ] = fdInput; pstdin[PIPE_WRITE] = -1; pstdout[PIPE_READ] = -1; pstdout[PIPE_WRITE] = fdOutput; //On exécute et chaîne chaque action for (int i = 0; i < actc; i++) { FILE *file = NULL; //pour redirection Action *action = actions[i]; Command *cmd = lectureAction(action); DEBUG("[parent]\taction %d (%p): %s", i, action, action->cmd); DEBUG("[parent] cmd : %s", cmd->cmd); //On autorise l'utisateur à utiliser le caractère \n pour nettoyer //l'écran if (actc == 1 && cmd->cmd == NULL) { return 0; } // Gestion du chaînage d'entrée/sortie DEBUG("[parent]\tchaining type = %d", action->chainingType); if (action->chainingType == CHAINING_PIPE) { if (i > 0) { if (i > 1) { close(pstdin[0]); close(pstdin[1]); } pstdin[PIPE_READ] = pstdout[PIPE_READ]; pstdin[PIPE_WRITE] = pstdout[PIPE_WRITE]; close(pstdin[PIPE_WRITE]); } else { //la première action est branchée sur stdin pstdin[PIPE_READ] = fdInput; pstdin[PIPE_WRITE] = -1; } //si c'est la dernière action on redirige le flux vers stdout du shell //si prochaine action n'est pas pipée, idem if (i == actc - 1 || actions[i+1]->chainingType != CHAINING_PIPE) { //on attache just pstdout sur stdout pstdout[PIPE_WRITE] = fdOutput; pstdout[PIPE_READ] = -1; } else { //on crée un pipe pour le nouveau stdout if (pipe(pstdout) == -1) { perror("Error pipe creation"); exit(2); } } } else if (action->chainingType == CHAINING_AND && status != 0) { //(error) && action, on s'arrête break; } else if (action->chainingType == CHAINING_OR && status == 0) { //(pas d'error) || action, on s'arrête break; } //else action->chainingType == COMMA, on ne fait rien de spécial //Gestion des redirections d'entrées //cf. man bash, "Here Documents" DEBUG( "[parent]\tredirect input from file = %s", cmd->fromFile != NULL ? "true" : "false" ); //here documement if (cmd->fromFile != NULL && cmd->appendFile) { //cmd->fromFile n'est pas un fichier ici mais le code de stop int length = strlen(cmd->fromFile); DEBUG( "[parent]\there document, (stop=%s(%d))", cmd->fromFile, length ); //on modifie le stop pour le comparer avec une ligne de l'input char stop[length + 2]; strcpy(stop, cmd->fromFile); stop[length] = '\n'; stop[length + 1] = '\0'; DEBUG("stop word = %s", stop); //on crée un pipe pour stocker l'entrée int tmpPipe[2]; if (pipe(tmpPipe) == -1) { perror("Error pipe creation"); exit(EXIT_FAILURE); } size_t n; char *line = NULL; //on lit l'input tant qu'on ne reçoit pas le stop do { dprintf(fdOutput, YELLOW "➜ " END); if (line != NULL) { //pas le 1er getline write(tmpPipe[PIPE_WRITE], line, n); } n = 0; if (isSocket(fdInput)) { //c'est un socket n = getLineSocket(&line, &n, fdInput); } else { //c'est stdin n = getline(&line, &n, stdin); } DEBUG("get line = %s", line); } while (strlen(line) > 0 && strcmp(line, stop) != 0); close(tmpPipe[PIPE_WRITE]); pstdin[PIPE_READ] = tmpPipe[PIPE_READ]; } else if (cmd->fromFile != NULL) { char *mode = "r"; FILE *file = fopen(cmd->fromFile, mode); if (file == NULL) { perror("Redirection output : Not such file"); exit(EXIT_FAILURE); } pstdin[PIPE_READ] = fileno(file); } DEBUG( "[parent]\tredirect output to file = %s (apppend = %s)", cmd->toFile != NULL ? "true" : "false", cmd->appendFile ? "true" : "false" ); if (cmd->toFile != NULL) { //mode d'ouverture : append ou non char *mode = "w+"; if (cmd->appendFile) { mode = "a+"; } FILE *file = fopen(cmd->toFile, mode); if (file == NULL) { perror("Redirection output : Not such file"); exit(EXIT_FAILURE); } DEBUG("here %d", fileno(file)); pstdout[PIPE_WRITE] = fileno(file); DEBUG("here"); } //Création et éxécution du sous-processus //une commande built-in int e; if ((e = shellCommand(cmd)) != -1) { status = e; break; } //sinon, on lance un process fils int pid_child = fork(); if (pid_child == -1) { perror("Can't fork"); exit(3); } if (pid_child == 0) { //child DEBUG("[child %d] \t%d start",i, getpid()); DEBUG("[child %d] \tReplacing stdin (%d) with %d", i, fileno(stdin), pstdin[PIPE_READ]); DEBUG("[child %d] \tReplacing stdout (%d) with %d", i, fileno(stdout), pstdout[PIPE_WRITE]); //replace stdin if (pstdin[PIPE_READ] != fileno(stdin)) { close(fileno(stdin)); dup2(pstdin[PIPE_READ], fileno(stdin)); } //replace stdout if (pstdout[PIPE_WRITE] != fileno(stdout)) { close(fileno(stdout)); dup2(pstdout[PIPE_WRITE], fileno(stdout)); } //en mode socket on veut rediriger stderr sur le client if (isSocket(fdInput)) { dup2(pstdout[PIPE_WRITE], fileno(stderr)); } //Exécution de la commande //@see process.c#exec() exec(action, cmd); } else { //Fermeture des fichiers utilisés pour la redirection if (cmd->fromFile != NULL) { close(pstdin[PIPE_READ]); } if (cmd->toFile != NULL) { close(pstdout[PIPE_WRITE]); } //Si l'action doit s'effectuer en background //on n'attend pas et on met le status à 0 if (action->background) { //TODO : le child peut rester en zoombie dprintf(fdOutput, "Process %d in background\n", pid_child); status = 0; } else { //Attente de la terminaison du fils waitpid(pid_child, &status, 0); DEBUG("[parent]\tChild %s %d exited with code %d", action->cmd, pid_child, status); } } if (file != NULL) { fclose(file); } freeCommand(cmd); freeAction(action); } DEBUG("[parent] end"); free(actions); return status; }
int main(int argc, char *argv[], char *env[]) { //flag para laço principal int flag = 1; //comando lido de stdin char cmd[255]; //comando lido command app; initCommand(&app); //struct para manipulação de signals struct sigaction signals; struct jobs *j; struct job *jb; signals.sa_handler = &signalHandler; sigfillset(&signals.sa_mask); signals.sa_flags = 0; sigaction(SIGCHLD, &signals, NULL); sigaction(SIGTSTP, &signals, NULL); sigaction(SIGINT, &signals, NULL); sigaction(SIGTERM, &signals, NULL); //laço principal do { //inicialização do cmd strcpy(cmd, ""); //força a impressão do buffer de saída fflush(stdout); //impressão inicial do terminal printf("AB2> "); //limpeza do stdin __fpurge(stdin); //leitura do comando scanf("%[^\n]", cmd); //comando embutido "quit" ou "exit" if ((!strcmp(cmd, "quit")) || (!strcmp(cmd, "exit"))) { flag = 0; //comando embutido "pwd" } else if (!strcmp(cmd, "pwd")) { printf("%s\n", getcwd(NULL, 0)); //comando embutido "jobs" } else if (!strcmp(cmd, "jobs")) { //remove os 'jobs' terminados da lista cleanJobs(&jobs); if (jobs) { printf("Lista de 'jobs':\n"); j = jobs; while (j) { printf("\t[%d]", j->job.pid); printf("\t%s", (j->job.state == JOB_STOPPED ? "Parado" : (j->job.state == JOB_TERMINATED ? "Terminado" : (j->job.state == JOB_EXEC_FG ? "Executando" : "Executando em plano de fundo")))); printf("\t(%s)\n", j->job.application.input); j = j->next; } } else { printf("Nenhum 'job' na lista\n"); } //comando embutido "job" } else if (!strcmp(cmd, "job")) { printf("job_pid: %d\n", job_pid); //comando embutido "help" } else if (!strcmp(cmd, "help")) { printf("AB2 SHELL HELP\n\n"); printf("Comandos embutidos:\n"); printf(" help: exibe esta lista\n"); printf(" about: exibe o 'about' do shell\n"); printf(" pwd: mostra o diretório corrente\n"); printf(" cd: troca o diretório corrente\n"); printf(" quit: termina o shell\n"); printf(" jobs: lista todos os jobs em background\n"); printf(" bg <PID>: reinicia um job, passando sua execução para background\n"); printf(" fg <PID>: reinicia um job, passando sua execução para foreground\n"); //comando embutido "about" } else if (!strcmp(cmd, "about")) { printf("AB2 SHELL ABOUT\n\n"); printf("Shell criada por:\n"); printf(" André Vinícius Azevedo Aguilar NUSP: 5890160\n"); printf(" Eduardo de Freitas Alberice NUSP: 5890006\n"); printf(" Flávio Heleno Batista NUSP: 5890027\n"); //comandos embutidos com parâmetros ou comandos externos, não vazios } else if (strcmp(cmd, "")) { parseCommand(cmd, &app, env); //comando embutido "cd" if (!strcmp(app.argv[0], "cd")) { if (app.argc) { if (chdir(app.argv[1])) { printf("cd: %s: Diretório não encontrado\n", app.argv[1]); } } //comando embutido "bg" } else if (!strcmp(app.argv[0], "bg")) { if (app.argc == 2) { backgroundJob(atoi(app.argv[1]), &jobs); } else { if (!job_pid) { cleanJobs(&jobs); jb = lastJob(jobs); if (jb) { job_pid = jb->pid; } } if (job_pid) { backgroundJob(job_pid, &jobs); job_pid = 0; } else { printf("Nenhum 'job' ativo\n"); } } //comando embutido "fg" } else if (!strcmp(app.argv[0], "fg")) { if (app.argc == 2) { job_pid = atoi(app.argv[1]); foregroundJob(job_pid, &jobs); } else { if (!job_pid) { cleanJobs(&jobs); jb = lastJob(jobs); if (jb) { job_pid = jb->pid; } } if (job_pid) { foregroundJob(job_pid, &jobs); } else { printf("Nenhum 'job' ativo\n"); } } //comando embutido "kill" } else if (!strcmp(app.argv[0], "kill")) { if (app.argc == 2) { job_pid = atoi(app.argv[1]); terminateJob(job_pid, &jobs); printf("\n[%d]\tterminado\t%s\n", job_pid, ""); job_pid = 0; } else { if (!job_pid) { cleanJobs(&jobs); jb = lastJob(jobs); if (jb) { job_pid = jb->pid; } } if (job_pid) { terminateJob(job_pid, &jobs); printf("\n[%d]\tterminado\t%s\n", job_pid, ""); job_pid = 0; } else { printf("Nenhum 'job' ativo\n"); } } //comandos externos } else { //força a impressão do buffer de saída fflush(stdout); //cria o novo job job_pid = 0; job_pid = createJob(app, &jobs); if (stateJob(job_pid, jobs) == JOB_TERMINATED) { if (resultJob(job_pid, jobs) == JOB_FAILED) { printf("%s: comando não encontrado\n", app.argv[0]); } job_pid = 0; } } freeCommand(&app); } cleanJobs(&jobs); } while (flag); if (jobs) { killJobs(&jobs); cleanJobs(&jobs); } return 0; }