I want to make a small application that runs another application multiple times for different input parameters.
Is this already done?
Is it wrong to use system("myAp param"), for each call (of course with different param value)?
I am using kdevelop on Linux-Ubuntu.
From your comments, I understand that instead of:
system("path/to/just_testing p1 p2");
I shall use:
execl("path/to/just_testing", "path/to/just_testing", "p1", "p2", (char *) 0);
Is it true? You are saying that execl is safer than system and it is better to use?
In the non-professional field, using system() is perfectly acceptable, but be warned, people will always tell you that it's "wrong." It's not wrong, it's a way of solving your problem without getting too complicated. It's a bit sloppy, yes, but certainly is still a usable (if a bit less portable) option. The data returned by the system() call will be the return value of the application you're calling. Based on the limited information in your post, I assume that's all you're really wanting to know.
DIFFERENCES BETWEEN SYSTEM AND EXEC
system() will invoke the default command shell, which will execute the command passed as argument.
Your program will stop until the command is executed, then it'll continue.
The value you get back is not about the success of the command itself, but regards the correct opening of command shell.
A plus of system() is that it's part of the standard library.
With exec(), your process (the calling process) is replaced. Moreover you cannot invoke a script or an internal command. You could follow a commonly used technique: Differences between fork and exec
So they are quite different (for further details you could see: Difference between "system" and "exec" in Linux?).
A correct comparison is between POSIX spawn() and system(). spawn() is more complex but it allows to read the external command's return code.
SECURITY
system() (or popen()) can be a security risk since certain environment variables (like $IFS / $PATH) can be modified so that your program will execute external programs you never intended it to (i.e. a command is specified without a path name and the command processor path name resolution mechanism is accessible to an attacker).
Also the system() function can result in exploitable vulnerabilities:
when passing an unsanitized or improperly sanitized command string originating from a tainted source;
if a relative path to an executable is specified and control over the current working directory is accessible to an attacker;
if the specified executable program can be spoofed by an attacker.
For further details: ENV33-C. Do not call system()
Anyway... I like Somberdon's answer.
Related
Is there a way I could access program's args outside of main() without storing references to them?
Program arguments are stored within preserved space of the program, so I see no reason for not being able to access them. Maybe there is something like const char** get_program_arguments() and int get_program_arguments_count() but I cannot find it...
My problem comes from the fact that I am rewriting a library that is used now in many programs within the company, and I need to access these programs common arguments without changing them. For example I need program name, but I cannot use ::getenv("_") as they can be executed from various shells. I cannot use GNU extension because this needs to work on Linux, AIX, SunOS using gcc, CC and so on.
Some systems do provide access to the argument list, or at least argv[0]. But it’s common practice for main to mutate argc and argv during option processing, so there is no reliably correct answer as to what a global interface for them should return.
Add to that the general undesirability of global state, and the fact that it harms debugging to have whatever low-level functions attempt to analyze the arguments to a program they might know nothing about, and you end up with don’t do that. It’s not hard to pass arguments (or, better, meaningful flags that result from decoding them) to a library.
Look at the code below! You will understand what I want:
#include <iostream>
#include <windows.h>
using namespace std;
int main()
{
system("set plock=24865");
system("echo %plock%"); // I know this will not work.But How to make it work?
return 0;
}
Each system() invocation creates a separate environment then destroys it when it returns to your program. This is why they can not pass information between each other.
To set an environment variable for the environment of your program use the putenv() call and later read it with the getenv() call.
The system() call inherits a copy of the environment of the program which invokes it , so at least you can set variables using putenv() and have a program invoked by system() read them.
If you expect to invoke an external program using system() and get information back from it via environment variables you can not do this easily. If this is your goal consider using fork().
Well, as you say, that won't work. What's important to understand is why: The system call spawns a child process to run the shell, and then you're setting an environment variable in that child process, which promptly terminates.
So perhaps your question is over-specific in that it asks how to do this "using system()"; short answer is you can't. (Long answer is you could set the environment variable in the registry, but that's only sensible if you intend this to be a permanent configuration change to the computer. It's not the best idea if you just mean to set a variable for use in subsequent system() calls from the same program..)
So instead you could use the SetEnvironmentVariable() function, which will set the environment variable in your current process (instead of in a child that's about to go away).
UPDATE - There is one other option, alluded to in the question's comment thread; but it assumes that you can set the variable and immediately run any/all commands that depend on it right after. In the case where you can do that, you could pack all the commands into one system call, most simply with a batch script...
Passing command-line arguments to an application in Linux just works fine with the exec* commands where you clearly pass each argument on its own. Doing so on Windows using the same functions is not an option if one wants to control the standard pipes. As those functions are based on CreateProcess() there are some clear rules on how to escape special characters like double quotes.
Sadly, this only works correctly as long as the called application retrieves its command-line arguments via main(), wmain() or CommandLineToArgvW(). However, if the called application gets those arguments via WinMain(), wWinMain(), GetCommandLineA() or GetCommandLineW() it is up to the application how to parse the command-line arguments as it gets the whole command-line rather than argument by argument.
That means a simple application named test using main() as entry point gets "abc" if called as test.exe \"abc\". Calling cmd.exe as cmd.exe /c "echo \"abc\"" will not output "abc" as expected but \"abc\".
This leads to my question:How it possible to pass command-line arguments to Windows applications in a generic way despite these quirks?
In Windows, you need to think about the command as a whole, not as a list of individual arguments. Applications are not obliged to parse the command into arguments in any particular way, or indeed at all; consider the example of the echo command, which treats the command line as a single string.
This can be a problem for runtime library developers, because it means there is no reliable way to implement a POSIX-like exec function. Some library developers take the straightforward approach, and require the programmer to provide quote marks as necessary, and some attempt to quote the arguments automatically. In the latter case it is essential to provide some method for the programmer to specify the command line as a whole, disabling any automatic quotation, even if that means a Windows-specific extension.
However, in your scenario (as described in the comments) there shouldn't be a problem. All you have to do is make sure you ask the user for a command, not for a list of arguments. Your program simply doesn't need to know how the command will be split up into arguments, if at all; understanding the command's syntax is the user's job. [NB: if you don't think this is true, you need to explain your scenario much more clearly. Provide an example of what the user might enter and how you think your application would need to process it.]
PS: since you mentioned the C library _exec functions, note that they don't work as you might be expecting. The arguments are not passed individually to the child, since that's impossible; in the Microsoft C runtime, if I remember correctly, the arguments are simply combined together into a single string, with a single space as the delimiter, so ("hello there") will be indistinguishable from ("hello", "there").
PPS: note that calling cmd.exe to parse the command introduces an additional (and much more complicated) layer of processing. Generally speaking taking that into account would still be the user's job, but you may want to be aware of it. The escape character for cmd.exe processing is the caret.
It is the C language that makes you need to use a backslash before a double quote in C code. There is no such rule for shell processing. So if you writing code to call CreateProcess and passing the literal string "abc" then you need to use backslashes because you are writing in C. But if are writing a shell script to pass invoke your app to pass "abc", e.g. the Echo example, then you don't use backslashes because there is no C code involved.
My problem is pretty simple, but I can't seem to find anything straightforward or specific to what I am trying to do. I'm simply using execl to list the files in the current folder that follow the same pattern (ie, execl("ls nameOfFile*.txt")). What I want to do now is grab those file names so that I can loop through and get the data out of them. Is there a simple way of doing this? Am I using the correct exec?
Thanks for any help or tips.
The signature of execl is
int execl(const char *path, const char *arg, ...);
You're supposed to pass the path to the executable as the first argument, and arguments for the executable as the subsequent arguments, so your calling syntax is wrong. Even if you fix that, it still won't do what you want. The only way execl and friends ever return control to the calling program is if an error occurs. This answer contains an excellent explanation of what execl does.
You were probably thinking of std::system, which you can pass an arbitrary string to, and have the OS execute that command. While that'll print the filenames to stdout, it's still not what you want, because system returns an error code resulting from executing the command line you specified, it has no way of capturing and returning whatever may be written to stdout by the command.
Unfortunately, there is nothing in the C++ standard library (yet) that allows you to list and iterate files from the filesystem. The preferred cross platform approach is to use Boost.Filesystem. Otherwise, there are platform specific APIs available, which are listed in this answer, along with a Boost usage example.
I need some help with external program call from c++ code.
I have to call javap.exe (from JDK package) from my program many times (probably more than 100), but call system("javap.exe some_parameters") is extremely slow. It's work so good for one set of parameters but repeated calls of system() not acceptable. I think it is only because of costs to access the hard disk and application run (but I'm not sure).
What can I do for better performance? Can I "save javap.exe in RAM" and call it "directly".
Or may be somebody knows how can I get java-class description and methods signature without javap.exe?
The Java VM is not cheap to start running, and it's likely that its initialization is eating up the lion's share of your time. Luckily, the functionality of javap is available directly through Java code. I suggest that you write a small Java application which, while similar to javap, does with one invocation what you would otherwise need thousands for. (Though... maybe you could already use just one? javap will take multiple class files, after all...)
Calling system() is easy, but very inefficient, primarily because you are not just launching whatever program you specify. Rather, you are launching one process (a shell), and that shell will examine your parameter and launch a second process.
If you're on a system that supports fork() and exec*(), you're going to improve performance by using them instead. As a pseudo-code example, consider:
void replace_system(const char *command)
{
pid_t child = fork();
if (child < 0) {
perror("fork:");
return;
}
if (child) {
/* this is the parent, wait for the child to finish */
while (waitpid(child, &status, options) <= 0);
return;
}
/* this is the new process */
exec*(...);
perror("failed to start the child");
exit(-1);
}
Choose one of the exec* functions based on how you want to arrange the parameters. You'll need to break your string of arguments into components, and possibly provide an environment of your liking. Once you call the exec* function, that function will never return (unless there is an error starting the command you've defined for it).
Beyond performance considerations, another reason to use this is, if desired, it allows you to modify the child's standard paths. For example, you might be interested in the output of a child; if you modify its stdout to be a pipe available to you, you can simply read what it prints. Research source code for the standard popen() call to find an example of this.