Передача стринга через pipe
pipe.c
#include<sys/types.h>
#include<unistd.h>
#include<stdio.h>
#include<string.h>
int main( int argc, char *argv[], char *envp)
{
int fd[2], result, result1;
char resstring[14];
if (pipe(fd)<0)
{
printf("Can't creat pipe\n");
exit(-1);
}
result=fork();
if (result<0)
{
printf("Can't fork child1\n");
exit(-1);
}
else if (result==0)
{
result1=fork();
if (results1<0)
{
printf("Can't fork child2\n");
exit(-1);
}
else if (result==0)
{
execle("root/child2","root/child2",0,envp);
}
else
{
printf("This is child1\n");
close(fd[1]);
size=read(fd[0],resstring,14);
if (size!=14)
{
printf("Can't read all string\n");
exit(-1);
}
close(fd[0]);
printf("%s",resstring);
}
}
else
{
printf("This is parent\n");
exit(-1);
}
return 0;
}
child2.c
#include<sys/types.h>
#include<unistd.h>
#include<stdio.h>
#include<string.h>
int main()
{
int fd[2];
size_t size;
char resstring[14]={"HELLO, WORLD!"};
close(fd[0]);
size=write(fd[1],resstring,14);
if (size!=14)
{
printf("Can't write all string\n");
exit(-1);
}
close(fd[1]);
return 0;
}
При запуске выдает сообщения:
This is child2
Can't write string
This is child1
This is parent
Can't read all string
Дочерний процесс должен знать те значения дескрипторов пайпа, которые создал родительский процесс.
В вашем случае вы в коде child2.c объявляете их, но не инициализируете никаким значением:
Код:
int fd[2];
В таком случае они содержат мусор, а не конкретные значения.
Один из способов это передавать их - с помощью параметров командной строки, например argv[1], argv[2], а затем использовать их.
Вот полный исправленый код:
pipe.c:
Код:
#include <stdlib.h>
#include<sys/types.h>
#include<unistd.h>
#include<stdio.h>
#include<string.h>
int main( int argc, char *argv[])
{
int fd[2], result, result1;
char fd0[8], fd1[8];
char resstring[14];
ssize_t size;
if (pipe(fd)<0)
{
printf("Can't create pipe\n");
exit(-1);
}
result=fork();
if (result<0)
{
printf("Can't fork child1\n");
exit(-1);
}
else if (result==0)
{
result1=fork();
if (result1 < 0)
{
printf("Can't fork child2\n");
exit(-1);
}
else if (result1==0)
{
snprintf(fd0, sizeof(fd0), "%d", fd[0]);
snprintf(fd1, sizeof(fd1), "%d", fd[1]);
execl("./child2", "child2", fd0, fd1, NULL);
}
else
{
printf("This is child1\n");
close(fd[1]);
size=read(fd[0],resstring,14);
if (size!=14)
{
printf("Can't read all string\n");
exit(-1);
}
close(fd[0]);
printf("%s", resstring);
waitpid(result1, NULL, 0); /* Wait for child process */
}
}
else
{
printf("This is parent\n");
waitpid(result, NULL, 0); /* Wait for child process */
exit(-1);
}
return 0;
}
#include<sys/types.h>
#include<unistd.h>
#include<stdio.h>
#include<string.h>
int main( int argc, char *argv[])
{
int fd[2], result, result1;
char fd0[8], fd1[8];
char resstring[14];
ssize_t size;
if (pipe(fd)<0)
{
printf("Can't create pipe\n");
exit(-1);
}
result=fork();
if (result<0)
{
printf("Can't fork child1\n");
exit(-1);
}
else if (result==0)
{
result1=fork();
if (result1 < 0)
{
printf("Can't fork child2\n");
exit(-1);
}
else if (result1==0)
{
snprintf(fd0, sizeof(fd0), "%d", fd[0]);
snprintf(fd1, sizeof(fd1), "%d", fd[1]);
execl("./child2", "child2", fd0, fd1, NULL);
}
else
{
printf("This is child1\n");
close(fd[1]);
size=read(fd[0],resstring,14);
if (size!=14)
{
printf("Can't read all string\n");
exit(-1);
}
close(fd[0]);
printf("%s", resstring);
waitpid(result1, NULL, 0); /* Wait for child process */
}
}
else
{
printf("This is parent\n");
waitpid(result, NULL, 0); /* Wait for child process */
exit(-1);
}
return 0;
}
child2.c:
Код:
#include <stdlib.h>
#include<sys/types.h>
#include<unistd.h>
#include<stdio.h>
#include<string.h>
int main(int argc, char* argv[])
{
int fd[2];
ssize_t size;
char resstring[14]={"HELLO, WORLD!"};
if(argc < 3)
{
fprintf(stderr, "Usage: %s fd[0] fd[1]\n", argv[0]);
exit(1);
}
fd[0] = atoi(argv[1]);
fd[1] = atoi(argv[2]);
close(fd[0]);
size=write(fd[1],resstring,14);
if (size!=14)
{
printf("Can't write all string\n");
exit(-1);
}
close(fd[1]);
return 0;
}
#include<sys/types.h>
#include<unistd.h>
#include<stdio.h>
#include<string.h>
int main(int argc, char* argv[])
{
int fd[2];
ssize_t size;
char resstring[14]={"HELLO, WORLD!"};
if(argc < 3)
{
fprintf(stderr, "Usage: %s fd[0] fd[1]\n", argv[0]);
exit(1);
}
fd[0] = atoi(argv[1]);
fd[1] = atoi(argv[2]);
close(fd[0]);
size=write(fd[1],resstring,14);
if (size!=14)
{
printf("Can't write all string\n");
exit(-1);
}
close(fd[1]);
return 0;
}
Сюда же я добавил к родительским потокам ожидание их потомков, чтобы они не переходили в постояние "Зомби":
Код:
waitpid(result, NULL, 0);
И еще у вас была опечатка в 34 строке, при проверке родитель это или потомок, после второго fork'а: там не result, а result1 (child2 выполнялся два раза).
добрый какой :)
Большое спасибо. Теперь стало понятно.