如何通过每次分叉新的子进程来多次运行同一个jar文件?
我正在尝试编写一个 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;
}
这是 Shellcore.cpp 文件中的“spawn”方法: 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;
}
i am trying to write a c++ program.
the program is required to run some jar files, run every jar file two times.
the problem is that the program runs every file just one time correctly.
at the second time i got an error message, as if the VM got a wrong command. However, it is the same command that run the jar files the first time !!!
This is the first few lines of the red-colored error message that i got.
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
This is my code.
This is the main file:
#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;
}
This is the "spawn" method in the Shellcore.cpp file:
The Shellcore.h contains the required includes for the 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();
}
}
sorry for the long question and long code.
Thanks is advance :)
The parse function:
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;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
strtok() 在调用时会更改您的字符串。您将指针“commands”设置为 checkers_command 或 castle_command,但 strtok 只会覆盖后者指向的内存。如果您在调用解析函数之前复制跳棋/城堡而不是仅仅指向它,那么每次循环都会有一个跳棋/城堡的新副本。
有比 strdup 更好的方法来做到这一点,但为了简洁起见,您可以简单地这样做。如果保留这种复制字符串的方法(不建议),请记住在完成后对返回的指针调用 free(),否则会出现内存泄漏。
改成这样:
strtok() changes your string when you call it. You set the pointer "commands" to either checkers_command or castle_command but strtok is just going to overwrite the memory pointed to at each of the latter. If you copy checkers/castle rather than just point to it before calling your parse function you will have a fresh copy of checkers/castle each time through the loop.
There are much better ways to do this than strdup but for brevity sake you can simply do this. If you keep this method of copying the string (unadvisable) remember to call free() on the returned pointer when you are done with it or you will have a memory leak.
Change to something like this: