I recently wrote a daemon in c++ that backs up certain folders by periodically copying a directory (and its contents) on my computer to an external flash drive. So far I can only back up one directory with a specific fixed path that I set in my source code. I would like to be able to pass an argument from another process to the daemon, while it is running, to change the path of the directory I want to backup. I have done research on signals like kill(), but I do not think that they are the correct kind of inter-process communication for my specific application.
Any help or direction as to how I should accomplish this task is greatly appreciated.
You need to use pipes or shared memory see poping 2 processes
Related
So I have an idea that I would like to implement and it's as follows:
Monitor a specific directory.
once a sub-directory is not only created but completed (i.e. a folder that's being downloaded or copied has just completed) the code calls a procedure or a scheme to compress the folder.
I have a sort of an idea of implementing this using ReadDirectoryChangesW. However my question is how to wait for changes, but when a change happens, it waits for its completeness. The second question would be how to identify the subfolder that's completed so I can call the compression scheme and supply it as an argument.
Thank you.
Since it's labelled "winapi", just set the NTFS compression attribute on the subdirectory as soon as you see it. Any new files in that directory will be automatically compressed as they're created.
Is it possible to run a c++ application from a terminal and on certain conditions return a command back into the terminal from which it was called from? For instance, if I were to run an application within my terminal and after my selections; my application needs to change my PATH by running an export command such as:
(USING BASH)
export PATH=.:/home/User/application/bin:$PATH
After I'm done and before my application completely closes can I make the application change my terminals local environment variables with the above command? Does Qt offer a way of doing this? Thanks in advance for any help!
No, you cannot change parent application environment.
Why? When your parent app started yours (probably using system()), it actually fork()ed - child process was born as to be almost exact replica of parent, and then that child used execve() call, which completely replaced executable image of that process with executable image of your application (for scripts it would be image of interpreter like bash).
In addition to that, that process also prepared few more things. One is list of open files, starting with file handles 0,1,2 (stdin, stdout, stderr). Also, it created memory block (which belongs to child process address space) which contains environment variables (as key=value pairs).
Because environment block belongs to your process, you can change your own environment as you please. But, it is impossible for your process to change environment memory block of parent (or any other process for that matter). The only way to possibly achieve this would be to use IPC (inter-process communication) and gently ask parent to do this task inside of it, but parent must be actively listening (on local or network socket) and be willing to fulfill such request from somebody, and child is not any special compared to any other process in that regard.
This also reason why you can change environment in bash using some shell script, but ONLY using source or . bash macro - because it is processed by bash itself, without starting any external process.
However, you cannot change environment by executing any other program or script for reasons stated above.
The common solution is to have your application print the result to standard output, then have the invoker pass it to its environment. A textbook example is ssh-agent which prints an environment variable assigment; you usually invoke it with eval $(ssh-agent)
Our app is ran from SU or normal user. We have a library we have connected to our project. In that library there is a function we want to call. We have a folder called notRestricted in the directory where we run application from. We have created a new thread. We want to limit access of the thread to file system. What we want to do is simple - call that function but limit its access to write only to that folder (we prefer to let it read from anywhere app can read from).
Update:
So I see that there is no way to disable only one thread from all FS but one folder...
I read your propositions dear SO users and posted some kind of analog to this question here so in there thay gave us a link to sandbox with not a bad api, but I do not really know if it would work on anething but GentOS (but any way such script looks quite intresting in case of using Boost.Process command line to run it and than run desired ex-thread (which migrated to seprate application=)).
There isn't really any way you can prevent a single thread, because its in the same process space as you are, except for hacking methods like function hooking to detect any kind of file system access.
Perhaps you might like to rethink how you're implementing your application - having native untrusted code run as su isn't exactly a good idea. Perhaps use another process and communicate via. RPC, or use a interpreted language that you can check against at run time.
In my opinion, the best strategy would be:
Don't run this code in a different thread, but run it in a different process.
When you create this process (after the fork but before any call to execve), use chroot to change the root of the filesystem.
This will give you some good isolation... However doing so will make your code require root... Don't run the child process as root since root can trivially work around this.
Inject a replacement for open(2) that checks the arguments and returns -EACCES as appropriate.
This doesn't sound like the right thing to do. If you think about it, what you are trying to prevent is a problem well known to the computer games industry. The most common approach to deal with this problem is simply encoding or encrypting the data you don't want others to have access to, in such a way that only you know how to read/understand it.
Alright so to start this is strictly for Windows and I'd prefer to use C++ over .NET but I'm not opposed to boost::filesystem although if it can be avoided in favor of straight Windows API I'd prefer that.
Now the scenario is an application on another machine I can't change is going to create files in a particular directory on the machine that I need to make backups of and do some extra processing. Currently I've made a little application which will sit and listen for change notifications in a target directory using FindFirstChangeNotification and FindNextChangeNotification windows APIs.
The problem is that while I can get notified when new files are created in the directory, modified, size changes, etc it only notifies once and does not specifically tell me which files. I've looked at ReadDirectoryChangesW as well but it's the same story there except that I can get slightly more specific information.
Now I can scan the directory and try to acquire locks or open the files to determine what specifically changed from the last notification and whether they are available for further use but in the case of copying a large file I've found this isn't good enough as the file won't be ready to be manipulated and I won't get any other notifications after the first so there is no way to tell when it's actually done copying unless after the first notification I continually try to acquire locks until it succeeds.
The only other thing I can think of that would be less hackish would be to have some kind of end token file but since I don't have control over the application creating the files in the first place I don't see how I'd go about doing that and it's still not ideal.
Any suggestions?
This is a fairly common problem and one that doesn't have an easy answer. Acquiring locks is one of the best options when you cannot change the thing at the remote end. Another I have seen is to watch the file at intervals until the size doesn't change for an interval or two.
Other strategies include writing a no-byte file as a trigger when the main file is complete and writing to a temp directory then moving the complete file to the real destination. But to be reliable, it must be the sender who controls this. As the receiver, you are constrained to watching the directory and waiting for the file to settle.
It looks like ReadDirectoryChangesW is going to be your best bet. For each file copy operation, you should be receiving FILE_ACTION_ADDED followed by a bunch of FILE_ACTION_MODIFIED notifications. On the last FILE_ACTION_MODIFIED notification, the file should no longer be locked by the copying process. So, if you try to acquire a lock after each FILE_ACTION_MODIFIED of the copy, it should fail until the copy completes. It's not a particularly elegant solution, but there doesn't seem to be any notifications available for when a file copy completes.
You can process the data once the file is closed, right? So the task is to track when the file is closed. This can be done using file system filter driver. You can write your own or you can use our CallbackFilter product.
I must write a program that must be aware of another instance of itself running on that machine, and communicate with it, then die. I want to know if there is a canonical way of doing that in Linux.
My first thought was to write a file containing the PID of the process somewere, and look for that file every time the program executes, but where is the "right" place and name for that file? Is there a better, or more "correct" way?
Then I must communicate, saying the user tried to run it, but since there is another instance it will hand over the job and exit. I thought of just sending a signal, like SIGUSR1, but that would not allow me to send more information, like the X11 display from where the user executed the second process. How to send this info?
The program is linked against Gtk, so a solution that uses the glib is OK.
Putting the pid in a file is a common way of achieving this. For daemons ("system programs"), the common place to put such a file is /var/run/PROGRAM.pid. For user programs, put the pid file hidden in the user's homedir (if the program also has configuration files, then put both config files and the pid file in a subdir of the home dir).
Sending information to the "master" instance is most commonly achieved using Unix domain sockets, also known as local sockets. With a socket, you won't need a pid file (if no-one listens on the socket, the process knows it's master).
Unix domain sockets. Have the first instance create one in a temporary directory, then have other instances communicate with it via that.
Writing a PID file is a common approach. Check the pidfile(3) library.
Does linux have the equivalent of a named mutex or semaphore? So you can check to see if it's 'locked' and then warn the user they already have one out there and close it out?
does this make sense from this link?
http://www.linuxquestions.org/questions/programming-9/named-mutex-in-linux-296816/
There are many ways to do this. The way you proposed (using a file containing the PID) is a valid one and is used by many applications.
Some times the application's configuration file contains the path for the PID file, other times a hardcoded path is used. Usually application put the PID file in /tmp, in /var (if they run with uid 0) or in their local directory (~/.application/).
Wouldn't have a general suggestion on where to put your PID file, just choose the place you prefer.
You can certainly use a Unix domain socket; I think most applications (which don't use a higher-level system like DCOP or DBUS) use these.
If you're happy for it to be Linux-specific, you can use an "abstract namespace" unix socket; these are rather nice because they don't need to exist in the filesystem.
If your program is user-oriented, it should probably be multiuser aware; one user should not be able to trigger behaviour in another user's copy of the app, and security needs to be in place to ensure that users cannot DoS each other easily either (Example: if user A's copy of the program hangs, does it stop user B's from starting?).