Issuing system commands in Linux from C, C++ - c++

I know that in a DOS/Windows application, you can issue system commands from code using lines like:
system("pause");
or
system("myProgram.exe");
...from stdlib.h. Is there a similar Linux command, and if so which header file would I find it in?
Also, is this considered bad programming practice? I am considering trying to get a list of loaded kernal modules using the lsmod command. Is that a good idea or bad idea? I found some websites that seemed to view system calls (at least system("pause");) in a negative light.

system is a bad idea for several reasons:
Your program is suspended until the command finishes.
It runs the command through a shell, which means you have to worry about making sure the string you pass is safe for the shell to evaluate.
If you try to run a backgrounded command with &, it ends up being a grandchild process and gets orphaned and taken in by the init process (pid 1), and you have no way of checking its status after that.
There's no way to read the command's output back into your program.
For the first and final issues, popen is one solution, but it doesn't address the other issues. You should really use fork and exec (or posix_spawn) yourself for running any external command/program.

Not surprisingly, the command is still
system("whatever");
and the header is still stdlib.h. That header file's name means "standard library", which means it's on every standard platform that supports C.
And yes, calling system() is often a bad idea. There are usually more programmatic ways of doing things.
If you want to see how lsmod works, you can always look-up its source code and see what the major system calls are that it makes. Then use those calls yourself.
A quick Google search turns up this link, which indicates that lsmod is reading the contents of /proc/modules.

Well, lsmod does it by parsing the /proc/modules file. That would be my preferred method.

I think what you are looking for are fork and exec.

Related

How to make a gui for command-line program?

Recently, i've got interested in making a front-end for command-line program.
I guess there's two way to do it.
First one is just including source code and calling main proc with arguments
(Of course, there should be some changes in source code).
Second one, which is there's no source code and just program, is just executing program internally then reading the command line with APIs.
Though I well know about the first solution, i don't know what APIs is needed to do the second solution.
I'm talking about the APIs that get a command-line string or something like that.
See this question for information on how to run an external application; basically, you need to call CreateProcess function. I'm not sure what you mean by "reading the command line", I suppose you mean reading the output of an executed program? As for capturing an external application's output, there's already another question asking for that, you will probably find this answer most helpful.
here is a codeProject project that I have used and can handle command line arguments for you (in the setup you describe). If you are not happy with it, you can use the direct WinApi calls using CommandLineToArgvW.
Enjoy!

C++, linux: how to limit function access to file system?

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.

Will execv run this in the foreground or background?

I have this in my program:
execv (programname, (char **)argv);
I'm not sure if the command is actually being executed correctly. How can I find out? Is this being run in the background?
I highly recommend getting a book that relates to the task you're trying to do. It's going to be a really long road if you ask a new question on SO on every step of the way. We love to help, but sometimes books are better.
Advanced UNIX Programming is an excellent one that contains a full sample of a shell, including pipelines. In fact, the example programs are available for download for free (but I recommend picking up a copy of the book anyway).
Since execv replace the current process, the command will be run on the same state as the parent process.
One way to know if your command is executed is to make the command print something on the console, if it is possible.
I believe execv() is supposed to overlay the current process with "programname". If you want to run a program in a separate process, you want fork() or system() -- I don't believe the latter is "standard" but it seems to be fairly ubiquitous.
From man page of execv.
RETURN VALUE
If any of the exec() functions returns, an error will have occurred. The return value is -1, and errno will be set to indicate the error.
So, if you get a return value, something went wrong.

Communication with a script from a C++ program

I have a c++ program (very complicated, and lengthy both in code and execution time).
Once in a while this program stops and calls a user-specified shell script.
Before calling the script, my program creates a .out file with current data. I call the script via system() command. The script then reads the .out file, and creates its own script.out file and exits.
Then the system() function call ends, and my program reads and parses the script.out file.
Question: is there a better way to execute communication between my c++ program and a random shell script?
My intent is to have full communication between the two. Script could virtually "ask" the program "What data do you have right now?" and the program would reply with some strict convention. Then the script could say "Add this data...", or "delete all your previous data" etc.etc.
The reason I need this is because the shell script tells the program to modify its data. The exact data that was put in the original .out file. So after the modification is done -- the actual data held by the program does not correspond to the data written in the .out file.
Thanks!
P.S.
I swear I've searched around, but everyone suggests an intermediate file.
There are certainly ways to do that without intermediate files. The most common approach is to use command line arguments for input, and pipes for standard output; others also use pipes for input. The most straight-forward alternative to system then is to use popen.
On a unix-like system? Perhaps pipe (2) will work for you?
From the man page (Mac OS X 10.5 version):
SYNOPSIS
#include <unistd.h>
int pipe(int fildes[2]);
DESCRIPTION
The pipe() function creates a pipe (an object that allows unidirectional
data flow) and allocates a pair of file descriptors. The first descrip-
tor connects to the read end of the pipe; the second connects to the
write end.
You will, of course, have to follow the creation of the pipes with a fork and exec pair. Probably this has already been answered in detail, and now you know what to search on...
It's been a while since I did this, but:
In the main process, before forking the sub-process you call pipe twice. Now you have two pipes and control both ends of both of them.
You fork.
The main process will read from one pipe and write from the other. It doesn't matter which is which, but you need to be clear about this.
The child process will call one of the exec family of function to replace it's image with that of the shell you want to run but first you will use dup2 to replace it's standard input and output with the ends of the two pipes (again, this is where you need to be clear about which pipe is which).
At his point you have two processes, the main process can send things into one pipe ad they will be received on the standard input of the script, and anything the script writes to it's standard output will be sent up the other pipe to the controlling process. So they take turns, just like interacting with the shell.
You can use pipes or (maybe more convenient) sockets - for example frontends to gdb, or expect do that. It would require changes to your shell scripts, and switching from system() to more low-level fork() and exec().
It's rather complicated so please, be more specific about your environment and what you need to clarify.
You are asking the question on Interprocess Communication (IPC).
There are a lot of ways to do that. You can do a simply search and Internet will return you most answers.
If I am not wrong, Google chrome uses a technique called Named Pipe.
Anyway, I think the most "portable way" is probably a file. But if you know you are working on which operating system, you can definitely use most of the IPC techniques.

Is there a better way to shell out a command in C++ than system()?

I have a C++ windows service that sometimes crashes when I call the system() function to shell out a command. I've run the exact text of the command in the windows command-line, and it runs just fine, but for some reason it fails when system() is run.
To make matters worse, I can't seem to get any information as to why system() is failing. There doesn't seem to be an exception raised, because I'm doing a catch(...) and nothing's getting caught. My service just stops running. I know that it's the call to system() that is failing because I've put logging information before and after the call, and anything after just doesn't log anything.
So, is there a different way that I can shell out my command? At the very least, something that will give me some information if things go wrong, or at least let me handle an exception or something.
I belive system() is technically part of the C standard library, and therefore wouldn't throw exceptions. You should be able to check the return code or the ERRNO variable to get some information about what happened. This MSDN link has some information about the possible return codes on Windows.
I've also seen system() fail for other external reasons, such as virus scanners, so you might investigate that as well.
I don't know of a better way to run shell commands, but I could be wrong.
EDIT: If it still just seems to crash for no reason, you might try using process monitor to see what is going on at a lower level. Since the output from process monitor can be kind of overwhelming, a trick I like to use is to add a statement right before the call to system() to your program to open a nonexistent file like "C:\MARKER.TXT" or something, then you can search the process monitor output for the name of the file and look at the entries right afterward that may have something to do with the problem.
Ordinary catch() will not catch fatal exceptions (e.g. segmentation fault). You have to use structured exception handling. Better yet, enable post-mortem debugging; this article explains how you can enable post-mortem debugging of services.
You could use fork/exec, but I think that is what the system is doing.
I think your problem could be the user account associated on your service.
Either there's an environment problem (missing entry in path) or the account the service is using to run doesn't have the rights to exec whatever you're trying to run.
Run services.msc and look at the properties for your service.
On the logon page, as a test, change the setup so it uses your account to run the service. If it succeeds, you know what the problem is.
Another thing to look at is the path while inside the service. Use getenv( "PATH" ) and see if a path you might be reliant on is missing.
Hope this helps...
I ended up using CreateProcess. It's been working out so far.