1. Pipe => pipe[0], pipe[1]
2. FILE* stream = fdopen(fd, "x")
typedef struct __sFILE {
...
} FILE;
3. Stream is a struct in c99, it keeps offset pointer, seek pointer position
4. Stream is like a synchronized queue, consumer and producer
FILE* in C99 stdio.h
// Wed 9 Aug 10:50:47 2023
SEE: /Library/Developer/CommandLineTools/SDKs/MacOSX11.3.sdk/usr/include/_stdio.h
SEE: /Users/aaa/myfile/bitbucket/publicfile/c99_stdio.h
typedef struct __sFILE {
unsigned char *_p; /* current position in (some) buffer */
int _r; /* read space left for getc() */
int _w; /* write space left for putc() */
short _flags; /* flags, below; this FILE is free if 0 */
short _file; /* fileno, if Unix descriptor, else -1 */
struct __sbuf _bf; /* the buffer (at least 1 byte, if !NULL) */
int _lbfsize; /* 0 or -_bf._size, for inline putc */
/* operations */
void *_cookie; /* cookie passed to io functions */
int (* _Nullable _close)(void *);
int (* _Nullable _read) (void *, char *, int);
fpos_t (* _Nullable _seek) (void *, fpos_t, int);
int (* _Nullable _write)(void *, const char *, int);
/* separate buffer for long sequences of ungetc() */
struct __sbuf _ub; /* ungetc buffer */
struct __sFILEX *_extra; /* additions to FILE to not break ABI */
int _ur; /* saved _r when _r is counting ungetc data */
/* tricks to meet minimum requirements even when malloc() fails */
unsigned char _ubuf[3]; /* guarantee an ungetc() buffer */
unsigned char _nbuf[1]; /* guarantee a getc() buffer */
/* separate buffer for fgetln() when line crosses buffer boundary */
struct __sbuf _lb; /* buffer for fgetln() */
/* Unix stdio files get aligned to block boundaries on fseek() */
int _blksize; /* stat.st_blksize (may be != _bf._size) */
fpos_t _offset; /* current lseek offset (see WARNING) */
} FILE;
Create pipe in C
// $b/c99/pipe_sleep.c
// gcc myfile.c -o main
// cpp_compile.sh pipe_sleep.c
//
// +-> FILE* stream
// |
// Pipe associates with a stream which can be read or written
// |
// +-> like a buffer
// int mypipe[2];
// pipe(mypipe)
//
// mypipe[1] mypipe[0]
// | |
// v v
// write -> stdout [ ] -> read stdin
// | |
// v v
// mypipe[1] mypipe[0]
// | |
// v v
// write to stream read from stream
// | |
// v v
// like a buffer like a buffer
#include
#include
#include
#include
#include
// Read char from a pipe
void read_from_pipe(int file){
FILE *stream;
int c;
stream = fdopen(file, "r");
while((c = fgetc(stream)) != EOF){
putchar(c);
}
fclose(stream);
}
void write_to_pipe(int file){
FILE *stream;
int c;
stream = fdopen(file, "w");
fprintf(stream, "Hello World\n");
fprintf(stream, "Good Byte\n");
fclose(stream);
}
int main () {
pid_t pid;
int mypipe[2];
if(pipe(mypipe)){
fprintf(stderr, "Pipe failed.\n");
return EXIT_FAILURE;
}
pid = fork();
if(pid == (pid_t) 0){
// Child process
// close the write end
close(mypipe[1]);
read_from_pipe(mypipe[0]);
return EXIT_SUCCESS;
}else if(pid < (pid_t)0){
// fork() failed
fprintf(stderr, "fork() failed\n");
}else{
// This is parent process
close(mypipe[0]);
write_to_pipe(mypipe[1]);
return EXIT_SUCCESS;
}
return(0);
}