Closing open directories on exit() - c

I would like to know if there is a way to access a list of all open directories from the current process? I have a function that opens many directories recursively but exits the program as soon as something is wrong. Of course, I would like to close all directories before calling exit() without having to keep track of everything I open. Is this even possible?
Thanks!

I have a function that opens many directories recursively but exits the program as soon as something is wrong.
Of course, I would like to close all directories before calling exit() without having to keep track of everything I open.
I think your very approach is wrong. What is the point of opening the directories if you don't keep a handle on them?
You should keep a reference to the opened directory as long as you need it and discard it as soon as you can.
Keep in mind that normally, the nomber of open file descriptors is limited, e. g. to 1024.

You do not need to do this as exit() will (eventually) exit the process, which will close all open file descriptors whether for directories or real files.
However, you absolutely do need to worry about valgrind and friends reporting this, as this means fds are leaking in your program. But the solution is not to hunt around for open directories, but rather to simply ensure each opendir is matched by a closedir. That's what valgrind is prompting you to do.

When you exit(), file handles are close()d. This is good for one-time tools, but not good practice in the long run.
You should instead walk back up the recursion, close()ing as you go. Replace, for example:
exit(1);
for:
close(current_fd);
return NULL;
Change your recursive call for:
if (thisfunc(...) == NULL) {
close(current_fd);
return NULL;
}

Related

How to know the next available file descriptor in C?

Calling a function like open in C will return the next available file descriptor and use it up. Is there a way to simply ask my system what the next free fd will actually be instead? i.e not eating it up.
By the time you ask what the "next" one is, another component (library, thread, etc) may immediately grab it and use it, so it will no longer be free.
The information on what the next unused descriptor is, is completely worthless, so it is not available.

Accessing and running /usr/bin programs in C

What is the most efficient method for running programs from the /usr/bin directory in a C program? I am tasking with getting user input, and if the user input matches up with a program in bin, running the respective program.
I had the idea of throwing the names of all the bin's programs in a text file, and using a loop to iterate through each word in the file while comparing the word to the input. However, I figured that might be reinventing the wheel a bit. Are there any streamlined ways to do this?
The "classical" way of invoking a program from an existing process on any of the UNIX-like OS'es is to use one of the exec() functions. When you read about exec() most tutorials will start by explaining another function: fork(). These functions are very commonly used together, but don't get too caught up on that, because they are both useful in their own right.
To answer your question, a fairly efficient way of doing what you're after:
Take the user generated input from whatever your source happens to be
(Optionally, call fork())
Call the execvp() function
What you do here will depend on whether you called fork() in step (2), and what you intend to do (if anything) after performing the task you described.
execvp() will do the legwork for you, by automatically searching on your environment PATH for a filename matching the first argument. If the current environment does not have a PATH set, it will default to /bin:/usr/bin. Since the only way that a call to exec() can yield a return value is when that call failed, you might want to check the value of errno as part of step (4). In the event that the user input didn't match any executable in the environment PATH, errno will be set to ENOENT. Exactly how you do this and what additional steps might be worth taking will depend on whether or not you forked, along with any additional requirements for your program.
I would suggest looking if the name you get from the user matches a file in the /usr/bin directory and if it does use the system function to run this program.
https://linux.die.net/man/3/system
#include <stdlib.h>
int system(const char *command);
i.e
FILE *file;
if (file = fopen(userinput, "r")){
fclose(file);
system(userinput);
}

Is there a way to call fsync/flush the parent of a fd?

When you call fsync on a file, you flush its buffer and make sure it gets written to disk.
But if your program newly creates a file, then that needs to get recorded in the metadata of the parent directory. Thus, even if you fsync a file, it's not guaranteed to be persistent in the file system yet. You need to flush the parent directory's buffer as well.
Is there a simple call, such as fsync_parent(fd) that'll accomplish this? If?
(Looking at this question, it seems there's no C standard way to get the parent directory of a file)
There is no canonical "the parent directory" of a file. A file can have any number of links, or no links at all. If you need a particular directory containing (a link to) the file to be synchronized, you have to track that yourself.

Program restart self on update

I checked everywhere so I am hopefully not repeating a question.
I want to add a portable update feature to some C code I am writing. The program may not be in any specific location, and I would prefer to keep it to a single binary (No dynamic library loading)
Then after the update is complete, I want the program to be able to restart (not a loop, actually reload from the HDD)
Is there any way to do this in C on Linux?
If you know where the program is saved on disk, then you can exec() the program:
char args[] = { "/opt/somewhere/bin/program", 0 };
execv(args[0], args);
fprintf(stderr, "Failed to reexecute %s\n", args[0]);
exit(1);
If you don't know where the program is on disk, either use execvp() to search for it on $PATH, or find out. On Linux, use the /proc file system — and /proc/self/exe specifically; it is a symlink to the executable, so you would need to use readlink() to get the value. Beware: readlink() does not null terminate the string it reads.
If you want, you can arrange to pass an argument which indicates to the new process that it is being restarted after update; the bare minimum argument list I provided can be as complex as you need (a list of the files currently open for edit, perhaps, or any other appropriate information and options).
Also, don't forget to clean up before reexecuting — cleanly close any open files, for example. Remember, open file descriptors are inherited by the executed process (unless you mark them for closure on exec with FD_CLOEXEC or O_CLOEXEC), but the new process won't know what they're for unless you tell it (in the argument list) so it won't be able to use them. They'll just be cluttering up the process without helping in the least.
Yes, you need to call the proper exec() function. There might be some complications, it can be troublesome to find the absolute path name. You need to:
Store the current directory in main().
Store the argc and (all) argv[] values from main().
Since calling exec() replaces the current process, that should be all you need to do in order to restart yourself. You might also need to take care to close any opened files, since they might otherwise be "inherited" back to yourself, which is seldom what you want.

C get all open file descriptors

I want to implement behavior in my C program so that if a SIGINT happens, I close all open file descriptors. Is there a simple way to get a list of them?
I'd use brute force: for (i = 0; i < fd_max; ++i) close (i);. Quick and pretty portable.
Keep track of all of your open file descriptors and close them individually.
In the general case, a library you're using might have an open file, and closing it will cause that library to misbehave.
In fact, the same problem could exist in your own code, because if you close file descriptors indiscriminately but another part of your program still remembers the file descriptor and tries to use it, it will get an unexpected error or (if other files have been opened since) operate on the wrong file. It is much better for the component responsible for opening a file to also be responsible for closing it.
You could read out the content of /proc/<pid>/fd., if available.
But be aware of the potiential race, that might occur if your application closes some or opens new ones in between your read out /proc/<pid>/fd and you are going to close what you read.
So conculding I want to recommend Kevin Reid's approach to this.
My solution for POSIX systems:
All opened fd's are the lowest value possible.
Make a wrapper function upon open(2).
Your new function open (and return) the requested fd and pass his value to a function called define_if_is_the_higtest_fd_and_store_it().
You should have a int hightest_fd_saved accessible only for a singleton function (there is only 1 'descriptor table') named save_fd() (initial value is 3 (cuz stderr is 2)).
Configure SIGINT to your signal function. Inside, you do a loop from [3, return_fd()].
I think that's it...

Resources