libuv / help

Need help with libuv? Post your question here.
28 stars 7 forks source link

How to get errno directly? #165

Open Meigyoku-Thmn opened 4 years ago

Meigyoku-Thmn commented 4 years ago

My question refers to NodeJS addon development. Many libuv functions return negated errno when an error occurs, that's good, but some functions just don't. An example is the uv_get_osfhandle function: https://github.com/libuv/libuv/blob/619937c783a05b51fba95cc9a62543deeffe5fa7/src/win/handle-inl.h#L166 On Windows, this function only return the result from _get_osfhandle, and if an error occurs, _get_osfhandle returns -1 and set the errno. But on Windows, it seems that I have no way to know what the specific error is, if uv_get_osfhandle fails (in NodeJS addon). It's true that in addon I can actually "get" the errno value, but addon and NodeJS use separate C runtimes (libuv shares C runtime with NodeJS). So the errno in addon is not the same errno in NodeJS. My question is "how to", but apparently there is really no way to do this, so I think libuv should re-export important C runtime symbols for who want to extend the file system of NodeJS/libuv.

bnoordhuis commented 4 years ago

I think it'd be okay to change uv_get_osfhandle() to return -errno as the status code on failure. I'm fairly sure that UV_EBADF is the only possible error, but that aside. Are there other API functions where you run into this issue?

Apropos this:

I think libuv should re-export important C runtime symbols

That's pretty much off the table. I recognize the problem of co-existing CRTs but I don't feel it's libuv's responsibility to fix (or rather: work around) that, that's the responsibility of Node.js or your add-on.

Meigyoku-Thmn commented 4 years ago

Ok I realized, that's the responsibility of Node.js, or me :) Actually I want to take the fd from NodeJS/libuv, then pass it to fdopen, and at there, the problem of separate CRTs emerges (I program on Windows). Sorry because I'm not very clear in my issue. This is more like a suggestion than a question. Thanks for answering me 👍

bnoordhuis commented 4 years ago

I think I understand what you mean. What you can do is export the the HANDLE from one CRT to another:

// error handling elided for brevity
int export(int fd) {
  HANDLE h = uv_get_osfhandle(fd);
  return _open_osfhandle((intptr_t) h, 0);
}

I'm not 100% sure but I think you need to keep the fd open in the first CRT, otherwise it'll call CloseHandle() on the underlying HANDLE object.

vtjnash commented 4 years ago

FWIW, libuv v2 will remove this issue https://github.com/libuv/leps/blob/master/005-windows-handles-not-fd.md. You also likely need to call DuplicateHandle, such that ownership is properly reference counted, instead of keeping it open in the first CRT.