Reputation: 95
I'm planing to monitor the fifo and stdin with select function, but it always block the code flow even though O_NONBLOCK
is configured, would anyone help check about it please ?
I'm not sure it's the code issue or solution is not a right direction to try, thanks in advance.
There are 2 problems :
stdin
is not able to read when the program start.FD_ISSET(pipe_fd, &fds)
will continuously be true, if do not close pipe_fd
manually.
if (FD_ISSET(pipe_fd, &fds)) {
read_pipe(pipe_fd);
close_pipe(pipe_fd); // continously triggered if not close here
}
Here is the full code.
#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#define BUF_SZ 128
#define FIFO_BUF_SZ 128
#define PIPE_PATH "./test_fifo"
int create_pipe_fd()
{
char *f_path = PIPE_PATH;
int ret;
// creating the named file(FIFO)
// mkfifo(<pathname>, <permission>)
//ret = mkfifo(f_path, 0666);
ret = mkfifo(f_path, 0666);
if (ret < 0) {
printf("create fifo file failed, err = %s\n", strerror(errno));
}
}
int open_pipe()
{
char *f_path = PIPE_PATH;
int fd;
// open fifo for read only
fd = open(f_path, O_RDONLY);
// non blocking mode
if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0) {
printf("mode set failed, err = %s\n", strerror(errno));
}
return fd;
}
int read_pipe(int fd)
{
uint8_t buf[FIFO_BUF_SZ];
ssize_t cnt;
size_t end;
size_t sz = sizeof(buf);
cnt = read(fd, buf, sz);
end = (cnt > (sz - 1)) ? (sz - 1) : cnt;
buf[end] = '\0';
printf("read pipe = %s\n", buf);
}
void close_pipe(int fd)
{
close(fd);
//printf("pipe closed.\n");
}
uint16_t read_stdin()
{
char *line = NULL;
size_t len = 0;
ssize_t lineSize = 0;
uint8_t stdin_buf[BUF_SZ];
lineSize = getline(&line, &len, stdin);
printf("[stdin %zu bytes] : %s", lineSize, line);
if (0 == strncmp("stop", line, strlen("stop"))) {
return 0;
}
free(line);
return (int)lineSize;
}
int main()
{
fd_set fds;
int max_fd = 0;
int pipe_fd = -1;
uint16_t bytes;
printf("start.\n");
// get pipe file descriptor
//pipe_fd = create_pipe_fd();
create_pipe_fd();
pipe_fd = open_pipe();
//max_fd = pipe_fd > max_fd ? pipe_fd : max_fd;
while (1) {
FD_ZERO(&fds);
// stdin
FD_SET(0, &fds);
//pipe_fd = open_pipe();
if (pipe_fd > 0) {
FD_SET(pipe_fd, &fds);
}
max_fd = pipe_fd > max_fd ? pipe_fd : max_fd;
select(max_fd + 1, &fds, NULL, NULL, NULL);
if (FD_ISSET(0, &fds)) {
bytes = read_stdin();
if (0 == bytes) {
break;
}
}
if (FD_ISSET(pipe_fd, &fds)) {
read_pipe(pipe_fd);
close_pipe(pipe_fd);
}
}
_EXIT:
if (pipe_fd) {
close_pipe(pipe_fd);
}
printf("exit.\n");
}
Upvotes: 0
Views: 441