Я пытаюсь реализовать execvp () с помощью execv (). Я не знаю, является ли код лучшей реализацией.
мой код:
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <stdio.h>
extern char **environ;
int my_execvp(char *file, char *argv[])
{
char *p, *colon, *pathseq = getenv("PATH");
size_t len;
if(strchr (file, "https://codereview.stackexchange.com/"))
return execv(file, argv);
if (pathseq == NULL) {
len = confstr(_CS_PATH, (char *) NULL, 0);
pathseq = (char *) alloca(1 + len);
pathseq[0] = ':';
(void) confstr (_CS_PATH, pathseq + 1, len);
}
len = strlen(file) + strlen(pathseq) + 2;
for(p = pathseq; p && *p; p = colon)
{
char b[len];
colon = strchr(p, ':');
if(colon)
{
memcpy(b, p, (size_t) (colon - p));
b[colon++-p] = 0;
}
else
strcpy(b, p);
strcat (b, "/");
strcat (b, file);
if(!access(b, F_OK)) {
execv(b, argv);
fprintf(stderr, "an error occurred in execvn");
abort();
}
}
errno = ENOENT;
return -1;
}
int main()
{
/* "ls / -l" */
char *arg[] = {"ls", "/", "-l", NULL};
my_execvp (arg[0], arg);
return 0;
}
И вопрос, который у меня есть, хорошая ли это реализация? Как это можно улучшить или написать лучшую реализацию?
1 ответ
Реализация не соответствует требованиям.
- Нет обработки undefined
PATH
. Цитированиеman execp
:
путь поиска — это путь, указанный в окружении переменной PATH. Если эта переменная не указана, путь по умолчанию устанавливается в соответствии с
_PATH_DEFPATH
определение в
Один раз confstr
возвращается 0
, проверить errno
, и действовать соответственно.
Звонок
abort
наexecv
неудача — это просто неправильно. По крайней мере, верни то, чтоexecv
возвращается.Звонок
access
тоже неверно. Если файл существует, но не имеет правильных разрешений,execvp
продолжим поиски.
В качестве примечания, access
очень редко бывает полезным. Рассмотрите возможность звонка execvp
вслепую и испытания errno
по возвращении.
Финал
errno = ENOENT;
также не соответствует требованиям.execvp
наборыENOENT
если файл не существует ни по одному пути. Если он был найден хотя бы один раз и не выполняется,errno
должен бытьEACCES
.execvp
не предполагаетсяfprintf
что-либо.