Как запустить один и тот же файл JAR несколько раз, каждый раз разветвляя новый дочерний процесс? - PullRequest
3 голосов
/ 22 апреля 2011

Я пытаюсь написать программу на C ++. программа обязана запускать некоторые файлы jar, запускать каждый файл jar два раза. проблема в том, что программа запускает каждый файл только один раз правильно. во второй раз я получил сообщение об ошибке, как будто виртуальная машина получила неправильную команду. Однако это та же команда, которая запускает файлы jar в первый раз !!!

Это первые несколько строк красного сообщения об ошибке, которое я получил.

Usage: java [-options] class [args...]
       (to execute a class)
   or  java [-options] -jar jarfile [args...]
       (to execute a jar file)
where options include:
    -d32      use a 32-bit data model if available
    -d64      use a 64-bit data model if available
    -client   to select the "client" VM
    -server   to select the "server" VM

Это мой код. Это основной файл:

#include <iostream>
#include <fstream>
#include <signal.h>
#include <string.h>
#include <time.h>
#include "StringParser.h"
#include "ShellCore.h"
using namespace std;

int main() {

    while (1) {

    char checkers_command[] = "java -jar /home/samer/Downloads/chkr.jar";
    char castle_command[] = "java -jar /home/samer/Downloads/cas.jar";

        int child_status;
        bool wait_bool = true;
        cout << "Run Batch Shell> ";
        cin.getline(input_command_line, 256);

        if (strcasecmp("exit", input_command_line) == 0) {
            cout << "The shell program will terminate\n";
            exit(0);
        } else {
            char* commands;
            for (int var = 0; var < 4; ++var) {
                if (var % 2 == 0) {
                    commands = checkers_command;
                } else if (var % 2 == 1) {
                    commands = castle_command;
                } 

                char* arg_list_tokened[50];
                parse_command_line(arg_list_tokened, commands);
                spawn(arg_list_tokened[0], arg_list_tokened);

            if (wait_bool) {
                // The parent wait until the child finishes.
                cout << "The parent will wait for " << arg_list_tokened[0] << endl;
                wait(&child_status);
                if (WIFEXITED(child_status)) {
                    printf("The child process exited normally with exit code %d\n",
                            WEXITSTATUS(child_status));
                } else {
                    printf("The child process exited abnormally\n");
                }
            }
        }
        cout << "done\n";
    }
}
return 0;
}

Это метод spawn в файле Shellcore.cpp: Shellcore.h содержит необходимые включения для Shellcore.cpp.

#include "ShellCore.h"

pid_t child_pid;

int spawn(char* program_name, char** args) {
    child_pid = fork();

        if (child_pid != 0) {
        return child_pid;
    } else {
        execvp(program_name, args);
        // If the execvp return, this indicate that an error occurred.
        printf("From the spawn function in the parent process, execvp ERROR\n");
        abort();
    }
}

извините за длинный вопрос и длинный код. Спасибо заранее :))

Функция разбора:

void parse_command_line(char* output_list[], char* command_line) {
    char * pch;
    int i = 0;
    pch = strtok(command_line, " &\"");
    output_list[0] = pch;
    while (pch != NULL) {
        i++;
        pch = strtok(NULL, " &\"");
        output_list[i] = pch;
    }
    output_list[++i] = NULL;
}

1 Ответ

2 голосов
/ 22 апреля 2011

strtok () меняет вашу строку при вызове.Вы устанавливаете указатель «команды» на checkers_command или castle_command, но strtok просто перезапишет память, на которую указывает каждая из последних.Если вы копируете шашки / замок вместо того, чтобы просто указывать на них перед вызовом функции синтаксического анализа, у вас будет свежая копия шашки / замок каждый раз в цикле.

Есть гораздо лучшие способы сделать это, чем strdup, норади краткости вы можете просто сделать это.Если вы сохраняете этот метод копирования строки (не рекомендуется), не забывайте вызывать free () для возвращаемого указателя, когда закончите с ним, или у вас будет утечка памяти.

Изменитесь на что-то вроде этого:

for (int var = 0; var < 4; ++var)
{
    if (var % 2 == 0)
    {
        //commands = checkers_command;
        commands = strdup(checkers_command);
    }
    else
        if (var % 2 == 1)
        {
            //commands = castle_command;
            commands = strdup(castle_command);
        }

   char* arg_list_tokened[50];

   parse_command_line(arg_list_tokened, commands);

   spawn(arg_list_tokened[0], arg_list_tokened);

   //............

}
...