Problems with system() in C - c

I'm quite new at C programming. Im using a Mac and I just created this app program with Matlab. This app what it does is, that creates a .txt based on some data. When I run it directly from the terminal it creates my .txt file, but when I try to execute this app using the following code (First test code) :
int main(int argc, const char * argv[])
{
char test_Exe[BUFSIZ];
// Build a buffer, and execute the commands within it
strcpy (test_Exe, "/Users/pepe1503/Documents/Pepe/Stage_Bruker/HS_Conversion_Topspin_Bucket_Matlab/matlab/MP_ToolBox/small_toolbox/test_Exe_D2O/distrib/run_test_Exe_D2O.sh");
strcat (test_Exe, " /Applications/MATLAB/MATLAB_Compiler_Runtime/v715 /Users/pepe1503/Documents/Pepe/Stage_Bruker/HS_Conversion_Topspin_Bucket_Matlab/matlab/MP_ToolBox/small_toolbox/D20/nmr/Agrifood_Caviar_Sturgeon_D2O/4/pdata");
printf ("Executing your Matlab program: %s\n", test_Exe);
system (test_Exe);
return 0;
}
I got the same printed output as the terminal but it doesn't build my .txt file.
Does anyone know the reason?
TY!
Following your suggestions I recently changed my code to (keeping my last program in another code just in case) :
int main(int argc, const char * argv[])
{
char* arg_list[] = {
"run_test_Exe_D2O.sh",
"/Applications/MATLAB/MATLAB_Compiler_Runtime/v715",
"/Users/pepe1503/Documents/Pepe/Stage_Bruker/HS_Conversion_Topspin_Bucket_Matlab/matlab/MP_ToolBox/small_toolbox/D20/nmr/Agrifood_Caviar_Sturgeon_D2O/4/pdata",
NULL
};
pid_t child_pid;
child_pid = fork();
if ( child_pid != 0 ) {
// This is the parent process.
return child_pid;
}
else {
// Now execute PROGRAM, searching for it in the path.
fprintf(stdout, "\n");
fprintf(stdout, "Executing your Matlab program:\n");
execvp("/Users/pepe1503/Documents/Pepe/Stage_Bruker/HS_Conversion_Topspin_Bucket_Matlab/matlab/MP_ToolBox/small_toolbox/test_Exe_D2O/distrib/run_test_Exe_D2O.sh", arg_list);
// The execvp function returns only if an error occurs.
fprintf (stderr, "an error occurred in execvp\n");
abort ();
}
return 0;
}
It still executes the application, now not printing the messages of the application as with system(), but it stills not create my .txt that I can obtain by executing it from my terminal. To be more precise with system() it does create my .txt but it erase it after the program execution.
Any sugestions of why it doesn't print my app messages and why it does create it but erase it ?

You are trying to execute the following program:
"/Users/pepe1503/Documents/Pepe/Stage_Bruker/HS_Conversion_Topspin_Bucket_Matlab/matlab/MP_ToolBox/small_toolbox/test_Exe_D2O/distrib"
Are you sure this is what you intended?

Try to use "bash run_test_Exe_D2O.sh" or "sh run_test_Exe_D2O.sh" instead raw script filename. Also, are you sure that whitespaces in script file name are OK?

Ok I found the answer. The problem was with system that it creates I think a temporary file each time Xcode is lunched. In which it was storing my .txt files.

Related

Why isn't redirected input considered a command line argument?

I'm trying to read command line arguments that have been redirected from a file. The command I'm using is ./a.out < test.txt
And the contents of test.txt is: Hello world.
But the output of my program below isn't printing Hello
world. Instead it is only showing ./a.out. Why is this?
int main(int argc, char* argv[], char* envp[]) {
for (int i = 1; i < argc; i++) {
printf("%s\n", argv[i]);
}
}
The shell intercepts the redirection commands before preparing the command line for the program:
myProg <infile -t >outfile
will pass to the program
myProg -t
with stdin and stdout already rerouted before the pogram starts. So the program never sees the rediretion.
There a lot of cases, besides simple derirection:
dir > myfile.txt
Especially you can pipe output from one program to another:
dir | more
It will send output if dir command to more command. Since program launch handled by OS shell, it handles a redirection too.
Because the language is defined that way. Suppose what you say is true —
All the user input will have to come from command line arguments, but text redirected from a file can satisfy input required in different functions. This can be achieved if the input appears as command line arguments.
Consider this program:
#include <stdio.h>
int is_dict(char *word)
{
/* code to look up a dictionary */
int result = 1;
return result;
}
int main(int argc, char *argv[])
{
if(argc == 2 && is_dict(argv[1]))
printf("%s found", argv[1]);
return 0;
}
If the program is written that way to accommodate it, then the input would have to come from the command line arguments. How would you take input when it is not redirected? It would require more program overhead to detect the missing inputs.
Moreover, imagine a text file containing a million words: it is unfeasible to expect each word to arrive as an argv[n].
There are other objections too. Suppose the program prints a series of prompts for responses. The user would have to know in advance what the prompts are, to supply the answers before the prompts appear.
Lastly, if the program is run from a GUI, then all the program's input will have to be edited into its properties before it is run.

basic CLI program in C

Okay so overall im trying to complete a basic CLI C program which will complete functions such as clear, quit, cd, ls, help (bring up the unix man) etc.. i altered my code and so far i have this, im getting segmination error when trying to execute the cd command part of the program, (im very new to c btw);
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
int main (int argc, char *argv[])
{
char input[] = " ";
char *argument;
while(strcmp(input, "quit")!= 0)
{
printf("$");
scanf ("%s", input);
if(strcmp(input,"clear") == 0)
{
printf("\e[1;1H\e[2J");
}
else if(strcmp(argv[1],"cd") == 0)
{
if(chdir(argv[2]) == -1)
{
printf("\n directory does not exists");
}
}
else if(strcmp(input, "echo") == 0)
{
char str[50];
scanf("%[^\n]+", str);
printf(" %s", str);
}
}
}
input is declared as a ' ' (space) character. It will never match 'cd'.
This is probably more along the lines of what you want to achieve, where the first parameter is the command (cd), and the second will be the directory:
int main (int argc, char *argv[])
{
char *argument;
if(strcmp(argv[1],"cd") == 0)
{
if(chdir(argv[2]) == -1)
{
printf("\n directory does not exists");
}
}
Edit Also please note that there is no need for the else satement. If chdir does not return an error, it will change the directory, thus no need to call it again in an else.
Additionally, another tip for using system calls in general, it would be of great help if you print the error number returned by the system upon a failure in system call. This will make things easier when things start going wrong. To do this simply include <errno.h>' and modify the printf to printerrno` which gives specific details about the error:
printf("Chdir error: %d", errno);
For instance chdir() does not only return an error when the directory does not exist, but also for example if you do not have permissions to view the contents of the directory. See the man page for a list of possible errors.
To implement your own shell, you need to take input directly from stdin, not from command-line arguments (argv) from another shell. The basic pattern is like this:
Read input
Execute command
Print results
Loop back to step 1

How many ways are there to execute system command in C program for windows

I am using MS visual studio 2008, for C coding.
I know we can use
"int system(const char *command)" to execute commands.
Is there any other method to execute system commands in C program.
Also I need to store output of executed command in a variable.
system() function execute command and send output to stdout , is there any way to read from stdout and store in variable.
So my ultimate goal is to execute system command in C program for windows (using visual studio) and store output of that command in a variable.
Any suggestions ?
Standard C libraries give you only one way to execute external command in OS, so use int system(const char *command).
You can save output of this command to text file, and then read this file from you program.
For example:
#include <stdio.h>
#include <stdlib.h>
#define TMP_FILE_NAME "TMP_FOLDER_CONTENT.txt"
int main(int argc, char *argv[])
{
system("dir C:\* > "TMP_FILE_NAME);
FILE * fdir = fopen(TMP_FILE_NAME, "r");
char buff[100];
if (fdir)
{
while (1) {
if (fgets(buff, 100, fdir) == NULL) break;
printf("%s", buff);
}
}
fclose(fdir);
remove(TMP_FILE_NAME);
return 0;
}
Where dir is a program to be executed, C:\* - argument of the program, and > - redirection of standard output for that command after which filename TMP_FOLDER_CONTENT.txt will be substituted.
Also you can check returned value, as:
int errorcode = system("dir C:\* > "TMP_FILE_NAME);
printf("Command executed and returned a value %d\n", errorcode);
or taking into account command you use, change the logic of your program, e.g.:
int errorcode = system("dir C:\* > "TMP_FILE_NAME);
if( errorcode )
{
return errorcode;
}
UPDATE:
Alternatively, you could use pipes in C++, for example as shown in the answer to question How to execute a command and get output of command within C++ using POSIX?
you can do as #VolAnd said or also if you don't care about/don't want the output of the command to be in stdout and you also don't want anything else to be printed to stdout you can use freopen to set stdout to a file of your choice.

Load script from memory in C

I have a script starting with a shebang stored in a string. I would like to execute this script without writing it in a temporary file.
I saw that execve takes a filename as argument. Is it possible to do the same with a script in memory.
A script is not directly executable, when executing a script, the kernel identify which interpreter to launch then pass the file name as an argument to the interpreter, in your case a shell.
Should you want to execute a script stored in a string, you might directly launch the shell of your choice and pass your string as its standard input through a pipe.
Here is way to do it using popen:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[])
{
FILE *fp;
char *prefix="/bin/bash <<'%EOF%'\n";
char *script="#!/bin/bash\necho foo\ndate\n";
char *suffix="%EOF%\n";
char *command;
char buf[1024];
command=malloc(strlen(prefix)+strlen(script)+strlen(suffix)+1);
sprintf(command,"%s%s%s",prefix,script,suffix);
fp=popen(command, "r");
if(fp == NULL) {
perror("Error\n");
exit(1);
}
while(fgets(buf, sizeof(buf), fp) != NULL) {
printf("%s", buf);
}
pclose(fp);
return 0;
}
As you say that the script starts with a shebang string, you cannot directly pipe it into the standard input of a shell. But you can mimic what a shell would have done:
extract the shell command from the shebang line
start it with a pipe as standard input
pipe the remaining of the script into that shell command
A more generalist version would control whether the script string starts with a #!. If it does, use the above way, else just pipe the whole string into an instance of /bin/sh (or whatever shell you are used to)

use diskpart in c program

Automating diskpart commands in windows requires pointing to a .txt file that contains the sequence of commands you want to execute. I am writing a C program that needs to use this automated feature. I want to have it run completely independent of the working directory. How would I do this?
Either use a fully qualified name for the file, or, with a bit more work, pass the commands from the C program to diskpart through an anonymous pipe using popen.
Example added:
#include <stdio.h>
int main ( int argc, char *argv[] )
{
char buffer[MAXBUF];
FILE *fp = popen("gzip -dc data.gz","r");
while (fgets(buffer,MAXBUF,fp)) {
/* Process line of data, here just print it out… */
fputs(buffer,stdout);
}
printf ("Command exit status %d\n", pclose(fp));
}

Resources