Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

errno portability #3941

Closed
Miosss opened this issue May 29, 2020 · 7 comments
Closed

errno portability #3941

Miosss opened this issue May 29, 2020 · 7 comments

Comments

@Miosss
Copy link

Miosss commented May 29, 2020

Hello,

Issue description

I am using cppzmq. In socket_t.recv(...) there is this if:
if (zmq_errno() == EAGAIN) return {};
which returns optional<>{} (no value) when EAGAIN is encountered. And it is, because I call recv with ZMQ_DONTWAIT flag. The problem is, that this condition is false (!) but the zmq_errno() returns correctly EAGAIN (11).

Though this may seem bizarre, I debuged it and the problem is in the left part of the equality test: == EAGAIN. Because EAGAIN is 42, instead of 11.

Environment

  • libzmq version (commit hash if unreleased): 4.3.2
  • cppzmq: 4.6.0
  • OS: Windows

I am preety sure what is the cause of the problem, though I do not have idea how to solve it. But it all comes down to the setup I believe.

I use libzmq in C++ Builder 10.3 (old Borland). But building CMake with bcc32c was impossible for me. so I took the shortcut. I built the libzmq.dll with MSVC 2019 and generated libzmq.lib using Borland's implib tool.
Thanks to that, I can link with the dll.

But there is the problem - errno. I already have problem with the same dll used from go: pebbe/zmq4 repo. I found out, that zmq_errno() was deliberatly created to solve any problems with application linking to other runtime that the libzmq, but here it is worse.
It turns out, that EAGAIN in errno.h for msvc is 11, but in errno.h for Borland it is 42. They have completely different errno.h!

So, libzmq for me is built with msvc and EAGAIN = 11, but EAGAIN in Borland's crt is 42!
And since I include headers in my app, they get included from Borlands libraries.

What's the expected result?

I would hope, that zmq_errno() -> EAGAIN is equal to EAGAIN in different compiler... Can it be done?

The more serious problem is that integer values for errors from errno.,h are not truly standard. and since the 'names' are just macros, and there can be multiple implementations of errno.h ...

@bluca
Copy link
Member

bluca commented May 29, 2020

cppzmq's repository is https://github.com/zeromq/cppzmq

@bluca bluca closed this as completed May 29, 2020
@Miosss
Copy link
Author

Miosss commented May 29, 2020

@bluca While your post is entirely correct it does not change the matter at hand.

Which is that zmq_errno() in this case returns different integer value than is expected, ergo any comparing to for example EAGAIN is pointless. It is not specific to cppzmq.

@Miosss
Copy link
Author

Miosss commented Jun 1, 2020

@bluca
Can you reopen and comment on the issue?

@bluca
Copy link
Member

bluca commented Jun 1, 2020

zmq_errno is a stable API, and thus its return values cannot be changed. If in your environment the return codes are not useful, simply don't use it. It is not a mandatory API call.

@Miosss
Copy link
Author

Miosss commented Jun 1, 2020

It may be stable, but is designed not to pe portable.

C++ comittee understood, that errno.h which contains standard NAMES for errors, but completely arbitraty VALUES for them is not portable. It just happens to be most of the time, because POSIX systems do have the same values. They even have a solution for it now:
https://en.cppreference.com/w/cpp/error/errc

But since I can compile libzmq.dll with EAGAIN constant set to 11, but then use that dll (and include the zmq.h header!) with EAGAIN set to 42 then any comparison of errno to EAGAIN is pointless.

You writing that error codes returned from zmq functions are not to be used (?) is strange. Why are there error codes at all then?

@bluca
Copy link
Member

bluca commented Jun 1, 2020

You writing that error codes returned from zmq functions are not to be used (?) is strange. Why are there error codes at all then?

Because in most cases it's fine. If you have some specific use case in which the return value of zmq_errno() is not useful, then simply don't use it. Changing return values of existing stable API is not going to happen - sorry.

@Miosss
Copy link
Author

Miosss commented Jun 1, 2020

Its not just about zmq_errno(). It is about every occurence of errno that is propagated outside of the library. And since this is the only way in which zmq shows exact error code - then it is broken.

I do not ask you to change existing values (most of the time). I am talking about specyfing them in ZMQ explicitly, not in external header (with nonstandard content).
Do you understand the case?
Do you agree that errno.h values are not standard?
Do you agree that there is a problem?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants