В данный момент я запускаю веб-сервер HTML, который может выполнять команды, данные ему через текстовое поле и кнопку отправки, но мне нужно преобразовать execlp
в execv
, и я не понимаю часть массива execv
.Я попытался просто сделать это execv(command, command);
, но он дает мне проходной аргумент несовместимой проблемы типа указателя.Кроме того, по какой-то причине мое выполнение будет запускать только одно слово команды, такие как ls
, и не будет принимать флаги, и я не совсем уверен, почему это так.Раздел выполнения и синтаксического анализа кода ниже, может предоставить полный код, если это необходимо.
Exection.c
char *parse(char *command){
char * newCommand = (char *) malloc(sizeof(char)*50);
int tgt = 0;
newCommand = strstr(command, "/run?command=");
newCommand = strtok(newCommand, " ");
newCommand = newCommand + 13;
for(int src = 0; src< strlen(newCommand); src++){
if(newCommand[src] == '+')
{
newCommand[src] = ' ';
}
else if(newCommand[src] == '%')
{
newCommand[src] = ' ';
}
else if(newCommand[src] == '7')
{
newCommand[src] = ' ';
}
else if(newCommand[src] == 'C')
{
newCommand[src] = '|';
}
}
return newCommand;
}
char * execution(char *command){
int piper[2];
size_t len = 0;
pipe(piper);
char* output = malloc(1000 * sizeof(char));
memset(output, '\0', 1000* sizeof(char));
pid_t pid = fork();
if(pid != 0)// parent
{
wait(NULL);
close(piper[1]);
int n = sizeof(output);
struct pollfd * poll_fd = malloc(sizeof(struct pollfd));
poll_fd->fd = piper[0];
poll_fd->events = POLLIN;
if(poll(poll_fd, 1, 0) == 1){ // pipe data check
read(piper[0], output, 1000);
}
}
else{
close(1);
dup(piper[1]);
execlp(command, command, NULL);
exit(1);
}
return output;
}
int main (void){
int sockfd;
int new_fd;
struct addrinfo hints;
struct addrinfo *serverinfo;
struct addrinfo *p;
struct sockaddr_storage client_addr;
socklen_t addrsize;
struct sigaction sa;
int yes = 1;
char s[INET6_ADDRSTRLEN];
int status;
memset(&hints, 0, sizeof hints); //makes struct empty
hints.ai_family = AF_UNSPEC; //IPv4 or v6
hints.ai_socktype = SOCK_STREAM; //TCP type need
hints.ai_flags = AI_PASSIVE; //Fill in IP for us
//if can't get address info print error
if((status = getaddrinfo(NULL, PORT, &hints, &serverinfo)) != 0){
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(status));
return 1;
}
for(p = serverinfo; p != NULL; p = p->ai_next){
if((sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1){
perror("server: socket");
continue;
}
if(setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1){
perror("setsockopt");
exit(1);
}
if(bind(sockfd, p->ai_addr, p->ai_addrlen) == -1){
close(sockfd);
perror("server: bind");
continue;
}
break;
}
freeaddrinfo(serverinfo);
if(p == NULL){
fprintf(stderr, "server: failed to bind\n");
exit(1);
}
if(listen(sockfd, BACKLOG) == -1){
perror("listen");
exit(1);
}
sa.sa_handler = sigchld_handler; // reap all dead processes
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_RESTART;
if (sigaction(SIGCHLD, &sa, NULL) == -1) {
perror("sigaction");
exit(1);
}
printf("server: waiting for connections....\n");
while(1){
addrsize = sizeof client_addr;
new_fd = accept(sockfd, (struct sockaddr *)&client_addr, &addrsize);
if(new_fd == -1){
perror("Did not accept");
continue;
}
inet_ntop(client_addr.ss_family, get_in_addr((struct sockaddr *)&client_addr), s, sizeof s);
printf("server: got connection from %s\n", s);
if(!fork()){
close(sockfd);
int bufsize = 1024;
char *buffer = malloc(bufsize);
recv(new_fd, buffer, bufsize, 0);
send(new_fd, header, bufsize, 0);
if(send(new_fd, execution(parse(buffer)), 1000, 0) == -1)
perror("send");
close(new_fd);
exit(0);
}
close(new_fd);
}
return 0;
}