C programm: execute bash script several times [duplicate] - c

This question already has answers here:
Closed 11 years ago.
Similar to:
program not executing anything after a call to system()
I am fairly new to using C but basically, I want to execute the following line:
int a = system("python -m plotter");
which will launch a python module I developed. However, I want the rest of my c program to keep running instead of waiting for the command to finish executing (the python app is on an infinite loop so it wont close automatically). Is there any way to do this using C/C++?
Update:
the solution was:
int a = system("start python -m plotter &");

system() simply passes its argument to the shell (on Unix-like systems, usually /bin/sh).
Try this:
int a = system("python -m plotter &");
Of course the value returned by system() won't be the exit status of the python script, since it won't have finished yet.
This is likely to work only on Unix-like systems (probably including MacOS); in particular, it probably won't work on MS Windows, unless you're running under Cygwin.
On Windows, system() probably invokes cmd.exe, which doesn't accept commands with the same syntax used on Unix-like systems. But the Windows start command should do the job:
int a = system("start python -m plotter");
As long as you're writing Windows-specific code (start won't work on Unix unless you happen to have a start command in your $PATH), you might consider using some lower-level Windows feature, perhaps by calling StartProcess. That's more complicated, but it's likely to give you more control over how the process executes. On the other hand, if system() meets your requirements, you might as well use it.

I believe if you add a '&' to the end of the command it will work. '&' tells the command to run in the background
int a = system("python -m plotter &");

There's no way in the standard library, but you can fork out or create a separate thread that would run it on the background, if your OS supports it.

"System" command on Linux will let the rest of code execute only when it has done executing itself.
You should use fork() if you want simultaneous processing.

The word for this is an Asynchronous function/method call. C and C++ don't have such a feature so you have to either call the function in a separate thread or use a system call that will run it in a separate process. Both of these methods tend to be platform specific, although there are cross platform threading libraries.
I know that in unix to do this in a separate process you would use fork(2) to create a new process and exec(3) to execute a new program in that process. I do not know what system calls would be required in Windows, but should be something similar.

Related

How to execute command from C program

What is the best way to execute command such as 'trap -p' etc directly from program written in ANSI C?
I tried:
system("bash");
system("trap -p");
But when I add system("bash") program dissappears. How to prevent it from dissapering or what is the better way to execute such commands?
EDIT:
Thank you all for helping me.
More details about what I intended to achieve:
I want to be able to:
-add new traps inside my program ( traps working only in my program )
-display currently set traps ( again, traps in my program )
Is that possible to achive in relatively easy way?
But when I add system("bash") program dissappears
Yes, bash is now running and your C program is waiting for it to terminate. It seems to have disappeared because you would be seeing a new shell running in your terminal. Try typing exit and your C program will continue. You can confirm this by adding a print statement after system("bash");.
You can get trap -p to produce output by specifying the -i option to bash, which makes it an interactive shell:
system("bash -i -c 'trap -p'");
From this it would seem that trap requires a tty, which non-interactive bash doesn't have.
Or you could put the trap command in a script and run it like this:
system("bash script.sh");
The contents of script.sh:
echo Before setting trap...
trap -p
trap somecmd SIGINT
echo After setting a trap...
trap -p
In the output you should see that initially there were no traps set (assuming that none were inherited from the shell that ran your C program), and then trap should show the newly created trap.
I am guessing you are on Linux or some other POSIX system
You should get a better picture of Linux programming by reading Advanced Linux Programming. It looks like you are misunderstanding processes and signals.
You cannot catch a signal inside the process running your C program from some shell (either your parent shell, or any child shell started with system(3). So the output of trap -p from any shell is not relevant to your program (but to the shell running it). Hence even using popen(3) like  FILE*fp = popen("trap -p", "r"); (or popen("bash -i -c 'trap -p'", "r")....) then reading from fp (and at last pclose-ing it) is useless.
If you want to handle signals inside your C program, read first carefully signal(7); then read POSIX signal.h documentation (notice sig_atomic_t); read also sigaction(2), fork(2), execve(2)
I want to be able to: add new traps inside my program
This has no meaning for C programs running on Linux or POSIX. A C program can handle (with great care and caution!) some signals, which are not traps.
[I want to:] display currently set traps
Again, "trap" has no sense inside a C or C++ program, but signals do. You don't really need to display the currently set signal handlers, because you have set them before. And sigaction(2) accepts a third oldact pointer to hold the previous signal action.
Processor traps (which are only handled by kernel code, not by application code) are remotely and indirectly related to signals. For example, a page fault (for implementation of virtual memory) is often handled by the kernel to fill the page cache with a page from disk (file or swap zone) but may translate to a SIGSEGV signal (for segmentation fault) sent to the process, which often terminates with a core dump.
If you install some signal handler in your C program, be sure to understand what are async-signal-safe functions (the only ones you are allowed to call from a signal handler; in particular calling fprintf or malloc -even indirectly- is forbidden, so is undefined behavior). A useful way of handling a signal is to declare some volatile sig_atomic_t variables and set them inside signal handlers (and test and reset them outside, e.g. in your event loop).
The shell trap builtin is used to manage some signals (and also exit and error conditions). To manage signals in C, use sigaction(2). To run something at exit(3) time, use atexit(3). To handle error conditions, be sure to test every individual syscalls(2) and most library functions (like scanf(3) or malloc(3) etc etc ..., see intro(3)), using errno(3)
Instead of running an interactive bash, it seems that you are looking for a way to run trap -p in a noninteractive Bash shell. Here's how you do that.
system("bash -c 'trap -p'");
However, your C-level signal handlers will not be visible in the trap -p output. Bash can only know about trap handlers which were defined in Bash; and the shell you are starting will not have any (unless they are inherited from the shell you used to start your C program).

change terminal directory using c language

i am trying to change the directory of my linux terminal using c language. the thing is i am using threads. i have tried to use chdir() but its not working, n yes chdir() is also a process function.
Actually the thing i am trying to implement is, i am trying to make a multi threaded program which compiles Linux kernel, and that is not possible without specifying directories( i have tried to do it without specifying directories but failed :) )
can anybody help me out with this issue?
Thanks in advance :)
You can't! No process can change the working directory of another. A process can only change its own WD. When you launch an external command such like your C program, then a new process is launched.
The cd command of your shell is an internal one.
It isn't very clear what you are trying to achieve. It appears that somehow you wish to emulate the behaviour of a script (or the make tool) using a C program, that is to say having the C program you wrote launch new processes (using system or perhaps a combination of fork and exec*). If that is the case, then what you actually want is to modify the environment variables of these processes for them to find the files they need. A forked process will inherit the environment of its parent, so all you need is to use getenv, putenv, setenv and unsetenv to retrieve and set the environment variables you want to add, update or remove; or you may use the specific execve, execvpe which let you specify exactly what environment should be available to the new program.
references:
fork system call
exec family of system calls
unix environment

is there another way than system() to execute a binary

I develop a C code on Linux and I would like to execute a binary say /usr/sbin/binary_program -p xxx, Is there another way than system() call to execute a binary?
Yes, and in general, system should never be used, for at least these reasons:
It suffers from all the dangers of shell quoting issues, so anything but a hard-coded command line is potentially dangerous.
It is not thread-safe.
It interferes with signal handling in the calling program.
It provides no way to get output from the executed program except for the exit status, unless the command explicitly saves output to a file.
For executing external programs, you should use posix_spawn, or fork followed by one of the exec-family functions. However, if possible you should avoid dependency on external programs/commands, especially when it would be easier and less error-prone to do the work directly in your program. For example I've seen ridiculous usages like system("sleep 1"); instead of sleep(1);.
Yes, you can use the exec* family of functions.
http://pubs.opengroup.org/onlinepubs/9699919799/functions/execv.html
If needed to simulate the behavior of system you can fork and then call an exec function.
The POSIX page of system says:
The system() function shall behave as if a child process were created using fork(), and the child process invoked the sh utility using execl() as follows:
execl(< shell path>, "sh", "-c", command, (char *)0);
It is important to realize that you can have several programs running simultaneously, and communicating thru pipes (or others Inter Process Communication). This is mostly possible thru a mixture of syscalls.
I strongly suggest reading Advanced Linux Programming, or some other good books explaining a lot more (than we can do in a few minutes) about various syscalls(2) involved, notably fork(2), pipe(2), dup2(2), execve(2), waitpid(2) and several others (perhaps poll(2) for multiplexing, e.g. to avoid deadlocks in circular pipes). The system(3) function is built above these syscalls (and /bin/sh)
That Advanced Linux Programming book has an entire chapter devoted to processes.
I also suggest to understand how a Unix command shell works. Either by studying the source code of some simple free shell (like sash) or at least by strace-ing it.
Practically speaking, popen(3) is more useful then system(3). You can get the output of the companion command.
Some libraries (Poco, Qt, Glib/GTK) also have powerful process management functions.
A new process is created with fork which is tricky to understand. A new program is started in the same process with execve.
All processes are created by fork (or perhaps vfork) except some few started magically by the kernel (/sbin/init, /sbin/modprobe, ...)

fork+exec pattern could be substituted by system(run-command-in-background)?

If the fork and exec patter is used just to run a program without freeze the current program, what's the advantage, for example, over using this single line:
system("program &"); // run in background, don't freeze
The system function creates a new shell instance for running the program, which is why you can run it in the background. The main difference from fork/exec is that using system like this actually creates two processes, the shell and the program, and that you can't communicate directly with the new program via anonymous pipes.
fork+exec is much more lightweight than system(). The later will create a process for the shell, the shell will parse the command line given and invoke the required executables. This means more memory, more execution time, etc. Obviously, if the program will run in background, these extra resources will be consumed only temporarily, but depending on how frequently you use it, the difference will be quite noticeable.
The man page for system clearly says that system executes the command by "calling /bin/sh -c command", which means system creates at least two processes: /bin/sh and then the program (the shell startup files may spawn much more than one process)
This can cause a few problems:
portability (what if a system doesn't have access to /bin/sh, or does not use & to run a process in the background?)
error handling (you can't know if the process exited with an error)
talking with the process (you can't send anything to the process, or get anything out of it)
performance, etc
The proper way to do this is fork+exec, which creates exactly one process. It gives you better control over the performance and resource consumption, and it's much easier to modify to do simple, important things (like error handling).

Write a dispatch program in c to run other c programs in Linux

I would like to write a small program that will run other programs. I'm not just trying to get their output as stdio for the current process, but rather want to simply use the program to use as a dispatch program.
I don't want to compile them together, but rather keep all the different programs separate.
I'm assuming that using a shell script would be the normal way of doing this, but I specifically want to know how it would be done in C on Linux.
You could do something like fork and use execve.
I'm not entirely understanding the problem though. Do you need the dispatcher to be able to read the output of the dispatched program?
You can use the system() API to call these other programs. What system() does is actually forks a shell and runs the program in that shell.
You can specify arguments to these external programs and even check their return status.
"man system" is your friend

Resources