#c #linux #jvm #executable-jar #fork
#c #linux #jvm #исполняемый файл-jar #fork
Вопрос:
я пытаюсь написать программу на 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 terminaten";
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(amp;child_status);
if (WIFEXITED(child_status)) {
printf("The child process exited normally with exit code %dn",
WEXITSTATUS(child_status));
} else {
printf("The child process exited abnormallyn");
}
}
}
cout << "donen";
}
}
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 ERRORn");
abort();
}
}
извините за длинный вопрос и длинный код.
Заранее спасибо 🙂
Функция синтаксического анализа:
void parse_command_line(char* output_list[], char* command_line) {
char * pch;
int i = 0;
pch = strtok(command_line, " amp;"");
output_list[0] = pch;
while (pch != NULL) {
i ;
pch = strtok(NULL, " amp;"");
output_list[i] = pch;
}
output_list[ i] = NULL;
}
Комментарии:
1. Я думаю, что проблема в parse_command_line или в том, как вы ее используете. Можете ли вы вставить исходный код для этой функции?
2. я так не думаю, поскольку функция parse работает впервые с каждым файлом jar.
3. Да, я хочу сказать, что во второй раз это не сработает! C — это не Haskell — функции не обязательно каждый раз выполняют одно и то же, как в Haskell!
Ответ №1:
strtok() изменяет вашу строку при ее вызове. Вы устанавливаете указатель «commands» либо на checkers_command, либо на castle_command, но strtok просто перезапишет память, на которую указано в каждом из последних. Если вы копируете checkers / castle, а не просто указываете на него перед вызовом своей функции синтаксического анализа, у вас будет новая копия checkers / castle каждый раз в цикле.
Есть гораздо лучшие способы сделать это, чем 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);
//............
}
Комментарии:
1. Большое спасибо, я забыл проблему со strtok.