Дескриптор файла передачи - Execve (typecast) - PullRequest
0 голосов
/ 12 сентября 2011

Мне интересно, как я могу передать дескриптор файла с помощью команды execve() и затем получить к нему доступ с другой стороны.Я знаю, что могу использовать dup2 для перенаправления файлового дескриптора, но я не могу этого сделать.Я должен передать дескриптор файла потомку и использовать его в потомке.

Что я сделал до сих пор:

Родитель делает pipe + аргументы, подобные следующим:

int pfd[2];
if(pipe(pfd) == -1)
    exitWithError("PIPE FAILED", 1);
char *args_1[] = {"reader", argv[1], (char*) pfd, (char *) 0};

Затем дочерний элемент вызывает execve после fork(), как показано ниже:

close(pfd[1]);
execve("./reader", args_1, NULL);

Затем в программе чтения я пытаюсь получить доступ к дескриптору канала, который был передан:

int main(int argc, char* argv[]){
    ...
    write(argv[2][1], buf, read_test);

argv[2] должен ссылаться на дескриптор канала, тогда argv[1] должен идти к концу записи канала.Я почти уверен, что мне нужно выполнить некоторое приведение типов по-другому, но все, что я пытаюсь, не совсем получается.

ПРИМЕЧАНИЕ : у меня есть рабочая версия этой программы, использующаяdup2 для перенаправления на stdin и stdout для детей, но я должен фактически передать дескриптор канала ребенку в соответствии с инструкциями проекта.

Любая помощь приветствуется.

1 Ответ

2 голосов
/ 12 сентября 2011

Просто приведение файлового дескриптора к char* не очень хорошая идея. Это может привести к потере данных, если ОС выберет копирование строк и остановится на 0 байтах, поэтому данные копируются не полностью. Было бы безопаснее создать строку, содержащую дескриптор файла.

int pfd[2];
if(pipe(pfd) == -1)
    exitWithError("PIPE FAILED", 1);
char string1[12]; // A 32 bit number can't take more than 11 characters, + a terminating 0
snprintf(string1,12,"%i",pfd[1]); // Copy the file descriptor into a string
char *args_1[] = {"reader", argv[1], &string1[0], (char *) 0};

Программа чтения затем использует atoi, чтобы преобразовать это обратно в int.

int fd = atoi(argv[2]);
write(fd,buf,read_test);

Если вы действительно хотите использовать приведение, то вам нужно разыграть argv[2] как int* в вашем считывателе.

write(((int*)argv[2])[1],buf,read_test);
...