Node.js get fd file descriptor - node.js

Is fs.open/close the only way to get the file descriptor or is there a faster/efficient way?
The reason I close the file is cause I assume I should otherwise I'd end up leaving tones of files open.
fs.open('/my/file.txt','r',function(e,fd){
console.log(fd);//12
fs.close(fd,function(){
fs.fsync(fd,function(){// more code ...
It seems a bit silly to open an close the file just to get an fd but fs.sync requires an fd (a number) instead of string.

I can call close and don't wait for the callback
This way is Asynchronous (non-blocking)
fs.open('/my/file.txt','r',function(e,fd){
console.log(fd);//12
fs.close(fd,function(){});
fs.fsync(fd,function(){// more code ...

Related

fs.createReadStream() at specific position of file

Is it possible to create a stream that reads from a specific position of file in node.js?
I know that I could use a more traditional fs.open / seek / read API, but in that case I need to somehow wrap them in a stream for underlying layers of my application.
fs.createReadStream() has an option you can pass it to specify the start position for the stream.
let f = fs.createReadStream("myfile.txt", {start: 1000});
You could also open a normal file descriptor with fs.open(), then fs.read() one byte from a position right before where you want the stream to be positioned using the position argument to fs.read() and then you can pass that file descriptor into fs.createReadStream() as an option and the stream will start with that file descriptor and position (though obviously the start option to fs.createReadStream() is a bit simpler).

Duplicating the file descriptor with dup2 and then closing it with close

I have one file descriptor(basically socket descriptor) example sockfd. I use dup2 to command
(void) dup2(sockfd,0);
then i close the descriptor close(sockfd);
Now i try to receive message on receive recv(0,buf,sizeof(buf),0);
But it is not working whats wrong with it?
dup2 doesn't return void, it returns int, so you should check its return code. If dup2 were failing for some reason and that was the problem then you wouldn't know about it. That being said, dup2 normally always works.
There is one corner case that could cause what you are seeing: if sockfd is already 0. Then you'd be dup2ing 0 to 0 and then closing 0, leaving you with no file descriptor at all. Therefore it's good practice before using dup2 to check whether or not the file descriptor you are trying to renumber is already numbered correctly. But again, this is not likely in your case than sockfd is 0 to begin with.
That being also said, what you are trying to do should work. If it is not, then nobody can answer your question unless you clarify what you mean by "it is not working".

Why epoll_wait() doesn't react on dup2(writable_fd, non_writable_fd)?

Let's imagine I added non writable fd to epoll watcher to wait when it will become writable.
epoll_ctl(epollfd, EPOLL_CTL_ADD, non_writable_fd, {EPOLLOUT})
non_writable_fd still non writable and epoll_wait will return 0 ready fds
Then I'll make this
dup2(writable_fd, non_writable_fd)
Where writable_fd is a file descriptor which is writable. Now I am expecting that epoll_wait will return 1 fd immediately. But unfortunetly it still timeouts with 0 fd returned.
Why this technique doesn't work with epoll when it works with select and poll?
The problem is that epoll cares about "open file descriptions", not about file descriptors. The answer is hidden in a few layers of man pages. First, epoll_wait:
Will closing a file descriptor cause it to be removed from all epoll
sets automatically?
Yes, but be aware of the following point. A file
descriptor is a reference to an open file description (see
open(2))[...]
Back to your dup2 call:
dup2(writable_fd, non_writable_fd)
dup2 call atomically first closes non_writable_fd and then makes it point to the same file description as writable_fd. Consider 2 cases:
You didn't do anything special so your dup2 ends up closing the open file description associated with non_writable_fd. In this case epoll simply removes it from the set and that's that
You had beforehand dup'd non_writable_fd into something else. In this case dup2 simply severs the association between non_writable_fd and its OFD, which lives on, watched by epoll
In both situations your dup call doesn't achieve what you want: you need to explicitly call epoll_ctl again.

Finding Socket Options set for a FD

I need to find the socket options set for a File descriptor.
For example, the accept call returns a FD. I set a number of socket options. Then I need to find if the socket options are actually set for the FD.
P.S: setsockopt is not returning an error, but behavior of fd is not in line with the option. Hence I need to verify this.
You can simply call getsockopt().

How can I detect that a file descriptor was redefined to a new filehandle?

In this code:
open my $fh1,'>','file1';
my $fh1_desc=fileno $fh1;
close $fh1;
open my $fh2,'>','file2';
open my $fh1_,'>&=',$fh1_desc;
if (fileno $fh1_ == fileno $fh2 ) {
print "\$fh1_ and \$fh2 are dups\n";
}
After that $fh1_ and $fh2 point to the same file. How can I detect that the redefinition of file descriptor?
This is "dummy code"! The real case is:
When I pass the file descriptor to a different thread how can I know that it wasn't redefined?
Once you've closed a file handle, the numerical descriptor is meaningless, and will usually just be re-used by the next open, as you've shown. My suggestion is that when you close a file, you make sure to set any handles you may have to 'undef' so you don't fool yourself into thinking they are still valid.
But I may have misunderstood your problem - you didn't supply very much detail.

Resources