I am writing code for simple shell in C, and for some unknown reason I am getting error when trying to execute man command, while commands like ls, cat or other works fine. I want to have function for searching path of command.
This is error:
man: can't execute cat: No such file or directory
man: command exited with status 255: (cd /usr/share/man && /usr/lib/man-db/zsoelim) | (cd /usr/share/man && /usr/lib/man-db/manconv -f UTF-8:ISO-8859-1 -t ISO-8859-1//IGNORE) | (cd /usr/share/man && tbl) | (cd /usr/share/man && nroff -mandoc -rLL=88n -rLT=88n -Tutf8)
#include<string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <stdio.h>
char *searchPath(char *cmd) {
int poljelen = 2;
char **stringovi = malloc(poljelen * sizeof(char*));
char *path = getenv("PATH");
int i = 0;
while((stringovi[i] = strsep(&path, ":")) != NULL) {
i ;
if (i >= poljelen) {
poljelen = poljelen i;
stringovi = realloc(stringovi, poljelen * sizeof(char*));
if (stringovi == NULL) {
fprintf(stderr, "%s", "Alloc error\n");
exit(0);
}
}
}
stringovi[i] = '\0';
i = 0;
while(*stringovi[i] != '\0') {
int pathlen = strlen(stringovi[i]);
int cmdlen = strlen(cmd);
char path[pathlen cmdlen 2];
strcpy(path, stringovi[i]);
strcat(path, "/");
strcat(path, cmd);
if (access(path, F_OK) == 0) {
char *pathname = malloc(sizeof(char) * (pathlen cmdlen 2));
if (!pathname) {
return NULL;
}
strcpy(pathname, path);
pathname[strlen(pathname)] = '\0';
return pathname;
}
else {
i ;
continue;
}
}
return NULL;
}
int main() {
char *tokens[3];
tokens[0] = "man"; //if you put here "ls"
tokens[1] = "ls"; // and here "-al" its working
tokens[2] = NULL;
char *pathh = searchPath(tokens[0]);
if (pathh == NULL) {
fprintf(stderr, "Error: command not found\n");
return 1;
}
char stringg[strlen(pathh) 1];
strcpy(stringg, pathh);
pid_t childP;
int status = 0;
childP = fork();
if (childP == 0) {
if (execv(stringg, tokens) == -1) {
fprintf(stderr, "Error: execv failed: %s\n", strerror(errno));
exit(1);
}
}
else if (childP == -1) {
fprintf(stderr, "Error: fork failed: %s\n", strerror(errno));
return 1;
}
else {
waitpid(childP, &status, WUNTRACED);
}
}
CodePudding user response:
Your use of strsep()
corrupts your PATH
environment variable.
Per the Linux strsep()
man page:
... this function finds the first token in the string
*stringp
, that is delimited by one of the bytes in the stringdelim
. This token is terminated by overwriting the delimiter with a null byte ('\0'
) ...
By calling strsep()
with the value returned from getenv("PATH")
you corrupt your PATH
environment variable, leaving it as only the first component of the original value.
You should make a copy of the value returned from getenv("PATH")
and split that into tokens.