How to use execl as replacement for system - c++

int main(void)
{
execl("echo", "test");
return 0;
}
I want to execute command echo test with execl
Why ? Because i can't use system() i have some reasons
What is wrong ?

The execl function does not look up commands on your PATH like a shell would, so you need to provide the full path to echo (or else provide a relative path from your current working directory, I think). Also, the first arg in the args list should be the filename of the executable, and the last arg should be NULL so that execl can figure out how many args you are trying to pass.
This works for me:
#include <unistd.h>
int main(void)
{
execl("/bin/echo", "/bin/echo", "test", NULL);
return 0;
}
You can run which echo to find out where echo is located on your system; it might be different from mine and you would have to edit the code.

Related

.exe does not run with more than one instance of "../" in the path

Issue
I have a Release-compiled MSVC C++17 "server" application. I usually make a child process from the client application to run a local server, so I use a relative directory path for the command line to execute as the child process. I am emulating that call here by typing in the relative path manually in powershell from where the client application executable runs.
It seems running run_Server.exe works with a command line like:
(Case 1)
PS C:\Users\me\Documents\MyProjectRelease1.0\Client_App_Folder> ../Server_App_Folder/run_Server.exe -help
(Proceeds to print out help)
But not with a command line like:
(Case 2)
PS C:\Users\me\Documents\MyProjectRelease1.0\Client_App_Folder\Client_App_Subfolder> ../../Server_App_Folder/run_Server.exe -help
(Waits a second then exits the program without any output)
Note: Client_App_Subfolder has an identical name as Client_App_Folder due to unimportant reasons.
Why is this happening? I may be mistaken, but I thought this did not happen under the exact same circumstances previously. I'm not finding much in the way of documentation about this phenomenon yet. I think this might have something to do with the up-directory ..\s in the command. Slash direction seems to not alter the results in this case in powershell.
Attempted Troubleshooting
Here's the first portion of main.cpp:
// Other #includes above.
#include <filesystem>
#include <iostream>
int main(int argc, char* argv[])
{
std::filesystem::path cwd = std::filesystem::current_path() / "filename.txt";
std::ofstream file(cwd.string());
file.close();
// ...proceed to parse command line arguments, etc.
}
This code results in outputting filename.txt in the MyProject\Client_App_Folder directory for the first case, but nothing for the second case.

Spawning a new terminal and opening vim

What I'm trying to achieve is to open a new terminal from a C/C++ program and run vim. I'm doing this by forking and execing "xterm -e vim [fname]". Try as I might, I can't seem to get xterm to understand what it is I want it to do.
Below is the relevant code segment:
int pid = fork();
if (pid){
//parent
int retstat;
waitpid (pid, &retstat, 0);
}else{
//child
char* ifname_cchararr = (char*)malloc(ifname.length() + 1);
strcpy (ifname_cchararr, ifname.c_str());
char* const argv[4] = {"-e", "vim", ifname_cchararr, NULL};
// std::cout << ifname_cchararr<<std::endl;
execvp ("xterm", argv);
}
Running the program results in xterm complaining:
-e : Explicit shell already was /usr/bin/vim
-e : bad command line option "testfile"
I get the feeling I've messed up argc somehow, but I'm confused, because running the following in an xterm window:
xterm -e vim testfile
works perfectly fine.
Please enlighten me!
You forgot to add xterm as first argument in argv. It may seems a bit weird, that you have to add the program-name to argv, since you already tell execvp which program you're calling, but thats how it is. For more information to why, see this recently asked question on Unix & Linux: Why does argv include the program name

C++ running grep in execv searches for executable path

argv = {'/usr/bin/grep', '/usr/bin/grep', '-ri', 'test', '.', 0}
pid_t pid = fork();
if (pid == 0) {
execv(argv[0], argv);
exit(0);
}
else {
wait(NULL);
}
This is what I have for my code. I am simply trying to get the grep command to run. The problem I run into is that it thinks the second /usr/bin/grep is the search pattern.
I have tried to change the argv array to only contain one /usr/bin/grep, but that errors out and does not run the grep. Any help?
execv takes the command as the first parameter so you want "usr/bin/grep" not argv[0] which is the program you are running. Also remove the first parameter from argv.
I would also check that grep is in /usr/bin it's often in /bin.

C++ Save console output to a text file before quit WINAPI ( No MFC )

I am trying to get my program to log the output of a console application to a text file before it quits. This is a GUI program which launches the console application (tool.exe). The problem is that I am using CTRL + C to quit the console application. This console application cant be altered either. I have tried a few ways of doing this but none have seemed to work ( tool.exe > output.txt ).
Can anyone point me in the right direction of which approach to take ? It would be greatly appreciated.
EDIT:
The file is created but it is empty and does not receive any data. The thing I am after noticing though is if I run the tool from the command line myself, it will work. Eg. c:\>tool.exe > output.txt However this is not working when its executed from my GUI application.
Here is the code I am using to execute the tool:
strcpy (tool, "\" start /D \"");
strcat (tool, toolLocation);
strcat (tool, "\" tool.exe > output.txt\"");
system (tool);
This will run tool.exe and create output.txt fine but will not output anything to the file.
EDIT2:
I think what is actually happening is that because I am using start , the >output.txt is outputing start instead of tool.exe. This would explain why it creates the empty file. Start is just running a fresh command line which is then running tool.exe. The problem is, how do I get around this issue now ?
Try:
#include <signal.h>
void signal_handlerkill(int sig)
{
//Do Soemthing
exit(1);
}
int main()
{
signal(SIGINT, signal_handlerkill); //Connect the interrupt signal (^C) to the function
//Do your code here
return 0;
}
And if that doesn't work, I'd suggest looking here. Specifically:
// crt_signal.c
// compile with: /c
// Use signal to attach a signal handler to the abort routine
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <tchar.h>
void SignalHandler(int signal)
{
printf("Application aborting...\n");
}
int main()
{
typedef void (*SignalHandlerPointer)(int);
SignalHandlerPointer previousHandler;
previousHandler = signal(SIGABRT, SignalHandler);
abort();
}
If you run the application without redirecting to a file, do you see the output you need on the console when you press ctrl+c?
If you don't then there is nothing you can do since you cannot change the application.
Update
What you need is to redirect stdout and stderr to the file. I have never done that but jamesdlin seems to have done that. Take a look at his comment.
What you could try is instead of using start try using cmd.exe directly.
This is the code which managed to solve the problem for me:
char path[500]; //Create character array
strcpy (path, "cd "); //Copy 'cd' into the array
strcat (path, toolLocation); //Copy the path of the tool into the array
strcat (path, " & ip.exe > output.txt"); //Append on the name of the exe and output to a file
system (path); //Run the built array
I am creating a character array and then appending to it. The vital bit here was the & being used in the system call. This is working as an and and first cd'ing to the firectory before executing the .exe.

usage of system function in cpp program

Please explain the syntax of:
system(const char *command);
I want to use this function for running the command on unix sytem.
I need to execute(automate) several test cases with the same command but,they also have other input values which are different.how do I reuse this code for all the test-cases.
int main()
{
char *base = "./your_testcase " ;
char aux[50] = "./your_testcase " ;
char *args[] = {"arg1" ,"arg2" ,"arg3"};
int nargs = 3;
for(i=0;i < nargs;i++)
{
/* Add arg to the end of the command */
strcat(aux,args[i]) ;
/* Call command with parameter */
system(aux);
/* Reset aux to just the system call with no parameters */
strcpy(aux,base);
}
}
Keep in mind that calling system is the same as calling fork and execl. That mean you need to be aware of things like open socket descriptors and file descriptors. I once had a problem with a TCP/IP socket dying on a server because a client was calling system which created a new socket connection to the server that was not being serviced.
I don't see how the syntax can be a problem:
system( "foo" );
executes the program called foo, via your preferred shell.
Generate a command line for each invokation, then pass those command lines into system() one a time.
See also the question:
'How to call an external program with parameters?;
How to call an external program with parameters?
I would avoid use of the system() function, here is a link to why this might be a bad idea
Here is the code, how to implement system() command in c++
#include <cstdlib>
 
int main()
{
    system("pause");
    return 0;
}
system(const char *command)
Is used to execute a command on the command line of the current operating system. It is generally not the best idea to use this because the commands are platform specific. Keep in mind that const char *command is a string and you can pass any string value as a parameter and it will be sent to the command line.
i think Anter is interested in a example:
for instance to remove a file in a directory:
system("/bin/rm -rf /home/ederek/file.txt");