对 FIFO 的轮询立即在 HP-UX 中返回
poll on FIFO returns immediately in HP-UX
我正在尝试在各种平台上的FIFO上使用poll(2(,但是(与Linux,Solaris,AIX相比(,HP-UX的行为与其他平台有些不同。
下面的代码创建一个 FIFO(命名管道(并以 3 秒超时轮询它。由于此代码不会写入 FIFO,因此我希望轮询结果为 0。
#include <fcntl.h>
#include <poll.h>
#include <signal.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <errno.h>
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#if defined(CLOCK_MONOTONIC)
#define MY_CLOCK_TIME CLOCK_MONOTONIC
#elif defined(CLOCK_REALTIME)
#define MY_CLOCK_TIME CLOCK_REALTIME
#else
#error neither CLOCK_REALTIME nor CLOCK_MONOTONIC defined.
#endif
#define HANDLE_ERROR(expr, msg)
do
{
if ((expr) < 0)
{
perror(msg);
exit(EXIT_FAILURE);
}
} while (0);
namespace {
const char pipename[] = "pipe";
template <size_t N>
struct type_of_size
{
typedef char type[N];
};
template <typename T, size_t Size>
typename type_of_size<Size>::type& sizeof_array_helper(T (&)[Size]);
#define SIZE_OF_ARR(pArray) sizeof(sizeof_array_helper(pArray))
int my_unlink(const char* name)
{
int result = unlink(name);
if (result < 0)
{
if (errno == ENOENT)
{
result = 0;
errno = 0;
}
}
return result;
}
double timediff(const struct timespec& t1, const struct timespec& t2)
{
return static_cast<double>(static_cast<int64_t>(
(t1.tv_sec - t2.tv_sec) * 1000000000LL + (t1.tv_nsec - t2.tv_nsec))) /
1000000000LL;
}
} // namespace
int main()
{
HANDLE_ERROR(my_unlink(pipename), "unlink");
HANDLE_ERROR(mkfifo(pipename, 0600), "mkfifo");
int result = 0;
int poll_timeout = 3000; // 3s
struct timespec before;
memset(&before, 0, sizeof(struct timespec));
struct timespec after;
memset(&after, 0, sizeof(struct timespec));
int fd = open(pipename, O_RDONLY | O_NONBLOCK);
HANDLE_ERROR((fd < 0), "open");
pollfd fds[1];
memset(fds, 0, sizeof(pollfd) * SIZE_OF_ARR(fds));
fds[0].fd = fd;
fds[0].events = POLLIN;
HANDLE_ERROR(clock_gettime(MY_CLOCK_TIME, &before), "clock_gettime");
#ifdef USE_FAKE_OPEN
int fakeopen_fd = open(pipename, O_WRONLY | O_NONBLOCK);
HANDLE_ERROR((fakeopen_fd < 0), "open");
#endif
result = poll(fds, SIZE_OF_ARR(fds), poll_timeout);
memset(&after, 0, sizeof(struct timespec));
HANDLE_ERROR(clock_gettime(MY_CLOCK_TIME, &after), "clock_gettime");
double interval = timediff(after, before);
printf("call interval: %.3f, poll result: %d, errr: %sn", interval, result, strerror(errno));
#ifdef USE_FAKE_OPEN
close(fakeopen_fd);
#endif
close(fd);
return (interval > 2.0) ? EXIT_SUCCESS : EXIT_FAILURE;
}
在Linux,Solaris 10,AIX 7.1上,它按预期工作(call interval: 3.000, poll result: 0, errr: Error 0
(,但HP-UX(11.31(不遵守超时参数并立即返回(call interval: 0.000, poll result: 1, errr: Error 0
(。
如果我在轮询读取之前打开 FIFO 进行写入,(定义USE_FAKE_OPEN
(即使对于 HP-UX,它也能按预期工作。
是什么导致了这种行为?
HP-UX 的民意调查是否符合 POSIX 标准?
好的,有一条编程规则是"这总是你的错(选择没有损坏(",但惠普表示,他们在 HP-UX 补丁PHKL_41419文档中对 FIFO 的民意调查被打破了:
poll(2( 设置 POLLIN(数据准备读取(事件偶数 如果打开 FIFO 时另一端没有写入器 O_RDONLY处于非阻塞模式(O_NONBLOCK设置(。
案件已结案。
相关文章:
- 来自 std::list 的迭代器 .end() 按预期返回"0xcdcdcdcdcdcdcdcd"但 .begin()
- 什么时候在C++中返回常量引用是个好主意
- 你能重载对象变量名本身返回的内容吗
- 为什么 Serial.println(<char[]>);返回随机字符?
- C++映射:具有自定义类的运算符[]不起作用(总是返回0)
- 如何获取std::result_of函数的返回类型
- QueryWorkingSet总是返回false
- (C++)分析树以计算返回错误值的简单算术表达式
- 访问者访问变体并返回不同类型时出错
- 如何返回一个类的两个对象相加的结果
- OpenInventor从9.8升级到10.4.2后,GLSL纹理返回零
- lower_bound()返回最后一个元素
- Boost 1.64 是否支持 HP-UX?
- 对 FIFO 的轮询立即在 HP-UX 中返回
- 如何在HP-UX中使用GCC创建共享库
- HP-UX、Solaris或AIX上是否有getifaddrs()替代方案
- HP-UX C/aC++编译器错误,使用纯虚拟方法的语句
- HP-UX Itanium比较和交换
- gdb、hp ux:获取消息找不到虚拟表 -- 对象可能尚未构造
- hp ux - C++ std::string Constructor