我试图让父母向孩子发送信息,并让孩子使用2个文件描述符将其发回。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define READ 0
#define WRITE 1
int main(void) {
int fdWrite[2];
int fdRead[2];
int pid, i, num;
FILE* output;
if (pipe(fdRead) == -1) {
perror("Can't create pipe");
exit(1);
}
if (pipe(fdWrite) == -1) {
perror("Can't create pipe");
exit(1);
}
char mystring[100] = { 0 };
char c;
pid = fork();
if (pid) {
FILE * read;
FILE * write;
close(fdRead[WRITE]);
close(fdWrite[READ]);
write = fdopen(fdWrite[WRITE], "w");
fprintf(write, "parent %s\n", "jeronimooo...");
read = fdopen(fdRead[READ], "r");
fgets(mystring, 100, read);
fprintf(stdout, "%s\n", mystring);
} else {
/* child */
dup2(fdRead[WRITE], STDOUT_FILENO);
close(fdRead[READ]);
close(fdRead[WRITE]);
dup2(fdWrite[READ], STDIN_FILENO);
close(fdWrite[READ]);
close(fdWrite[WRITE]);
fgets(mystring, 100, stdin);
fprintf(stdout, "child %s\n", mystring);
}
exit(0);
}
我正在尝试做什么:
目前暂停在线:fgets(mystring,100, read)
。
答案 0 :(得分:1)
C I / O流通常是缓冲的,这意味着当您执行此操作时fprintf
然后您打印到流中的内容实际上没有写入文件,而是写入内存缓冲区。当缓冲区已满时,其中的数据实际写入文件。 fflush
函数刷新缓冲区,即它占用缓冲区中的内容并立即将其写入文件。
这里的问题是当你执行fdopen
时,文件流是使用完全缓冲创建的(与例如stdout
的行缓冲不同)所以缓冲区真的必须填充它才能成为实际写的。通过明确强制写入它,管道的另一端可以读取它。
答案 1 :(得分:0)
the following is an excerpt for how to use a pipe,
extracted from a working system
where this pipe was used to kick a hardware watchdog
In general, this example only contains the code needed to :
create pipe, fork, write pipe, read pipe.
typedef struct
{
struct timespec time;
int tracking_number;
long magic;
} WatchdogRecord;
WatchdogRecord watchdog_record;
pid_t childpid;
int watchdog_pipe[2];
// open the pipe
pipe(watchdog_pipe);
// Set both ends of pipe to nonblocking
for(pipe_end=0; pipe_end<2; pipe_end++)
{
// Get previous flags
int f = fcntl(watchdog_pipe[pipe_end], F_GETFL, 0);
// Set bit for non-blocking flag
f |= O_NONBLOCK;
// Change flags on fd
fcntl(watchdog_pipe[pipe_end], F_SETFL, f);
} // for each pipe_end
// fork the child process
if ((childpid = fork()) == -1)
{ // then fork failed
perror("fork");
exit(1);
}
// implied else, fork successful
if (childpid == 0)
{ // then child process
// child closes up 'write' side of pipe
close(watchdog_pipe[1]);
// if any pipe input then store it
while (((readret = read(watchdog_pipe[0],
readbuffer+nbytes,
sizeof(readbuffer)-nbytes)) != -1)
&&
((nbytes+=readret) >= sizeof(WatchdogRecord)))
{
wdrec = (WatchdogRecord *)readbuffer;
// check magic number to make sure record is aligned properly in pipe
if (wdrec->magic == WD_MAGIC)
{
// read a full record, so reset nbytes to 0
nbytes = 0;
wd_syncerror = 0;
// and clear magic so it will have to be
// rewritten validly by the next read
wdrec->magic = 0L;
}
else // try to resynchronize
{
log_error("WDPipe Out Of Sync!, magic=0x%p\n", wdrec->magic);
//drop one of nbytes and wait for next try to resync
nbytes = 1;
// if this happens too many times, die
if (++wd_syncerror > sizeof(WatchdogRecord))
{
log_error("WDPipe Out Of Sync Too Long!\n");
watchdog_die();
} // ? too many sync errors
// fill in temporary info for wdrec so we don't use bad data
wdrec->time = curtime;
wdrec->tracking_number = -1;
} // pipe out of sync
}
else
{ // else parent process
// parent closes 'read' side of pipe
close(watchdog_pipe[0]);
// send message through pipe,
// remember pipe has no concept of record,
// so include a 'marker' so receiver can find edge of record
watchdog_record.time = curtime;
watchdog_record.tracking_number = tracking_number;
watchdog_record.magic = WD_MAGIC;
write(watchdog_pipe[1], &watchdog_record, sizeof(WatchdogRecord));