How to Start Process on Linux Os in C, C++

Linux equivalent of Process.Start()

The way to start a new process on Linux is by using fork and exec. This you can wrap in your own System class that holds the PID and provides methods to kill the process etc. An example of such a class is QProcess from the Qt library.

What are the ways to create a new process in C?

As far as I'm aware only fork, vfork and clone are used to create new processes in linux. (posix_spawn is not a syscall, but rather a library function which uses one of the syscalls above to create the process).

exec (and its sibling functions) is used to "mutate" a process, changing its memory layout according to the given ELF file.

(the example below is a very simplified version of the process, that leaves a lot of things out)

For example, when you run a command from your bash terminal, it uses fork (or clone). After the fork syscall, a new process is created and its memory layout is exactly the same as your bash terminal (To understand it better, read about Virtualization & COW, Copy-On-Write). Afterwards, the new process calls execv (or a similar function) to execute the ELF given to it by the command.

Start a process in the background in Linux with C

The 'logcat' command seems to be for Android development - that might explain the odd location of the command.

The key operation that you must fix is to ensure that you close your current standard input (the terminal) and open /dev/null/ for the input device:

close(0);
if ((fd = open("/dev/null", O_RDONLY)) != 0)
...error - failed to open /dev/null!

This means that your daemonized child process will not read anything from the terminal.


What I think you want to do is:

  1. Run your launcher program from a command line, which will have standard input, standard output and standard error connected to 'the terminal'.
  2. Inside your program, you want to replace the standard input so it comes from /dev/null.
  3. You want to leave standard output alone - you want logcat to write to the current standard output.
  4. You probably want to leave standard error alone too.

At some point in the proceedings, you do your daemonization properly (borrowing the link from @bstpierre's answer), making sure that the terminal you are connected to is not your controlling terminal, so that interrupts and hangups sent to the terminal don't affect your daemon. The plumbing is simpler than what you have set up - you should deal with standard input and leave standard output and standard error unchanged (instead of changing the outputs and leaving the input unchanged).

Now, you might want the output to go to /dev/console; if so, then it is reasonable to revise the code to open /dev/console. However, it is not reasonable to fall back on /dev/null if you can't open /dev/console; your program should report an error and fail (because there is no point in having logcat writing to /dev/null!). Make sure you open the console with the O_NOCTTY flag so it does not become the controlling terminal for the daemon.

The final comment I'd make is:

  • Are you sure you want random text appearing over your terminal or console when it is in use for other things?

I don't much like it when that happens.


See also: SO 958249

How to launch a process inside a minimal linux kernel environment?

You can basically run a process instead of init, if that is what you intend to do. To run a process instead of the systems init application, you can either replace the original init or pass init=/path/to/you/application as a kernel parameter to your VM.

But there are several things you should keep in mind:

All libraries need to be present in your VM at the same locations as on the system you have build the application on. This includes also the basic c-library it has been built against. You can get a list of all those libraries using

ldd hello_world

As an example, if you compile the following program

#include <stdio.h>

int main(int argc, char** argv) {
printf("hello world!\n");
return 0;
}

you might get something like this as a result for ldd

$ ldd test
linux-vdso.so.1 => (0x00007ffdba6ba000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f8559f50000)
/lib64/ld-linux-x86-64.so.2 (0x000055fc58ece000)

If you replace the init process, you need to take care of console interrupts and handle them properly. If you don't you risk really bad system crashes. As a result, it is a good idea to keep an init process and let that process start your application, if you do not really know what you are up to.

I have seen the output of your command in the past. Are you using a shell-script to start your application? If so, it might indicate that you are currently missing some libraries in your virtual environment.

Edit:

Maybe you could instead create a statically linked application which means to compile all libraries into the same file. On gcc you could use that -static switch for that. See the difference:

$ gcc -o test test.c
$ ldd test
linux-vdso.so.1 => (0x00007ffcd1f22000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f088d43a000)
/lib64/ld-linux-x86-64.so.2 (0x00005580f8a2b000)
$ gcc -static -o test test.c
$ ldd test
not a dynamic executable

As already mentioned you can use ldd to find the required libraries. Another option I would normally use is objdump, as the output is more detailed.

So for my application that would mean something like this (I have shortened the output to the relevant section):

$ objdump -p test

test: file format elf64-x86-64

[...]

Dynamic Section:
NEEDED libc.so.6
INIT 0x00000000004003c8
FINI 0x00000000004005c4
INIT_ARRAY 0x0000000000600e10
INIT_ARRAYSZ 0x0000000000000008
FINI_ARRAY 0x0000000000600e18
FINI_ARRAYSZ 0x0000000000000008
[...]

So in my case, that is libc.so.6 I would need to copy from /lib/x86_64-linux-gnu/libc.so.6 on my host to /lib/x86_64-linux-gnu/libc.so.6 within the virtual machine.

Hope that helps.

New Process Creation in Operating System (Unix)

Typically, the parent process issues the fork() system call, creating a duplicate process having (mostly) the same properties as the original process (different process ID, for example). From there, the child process issues one of the exec family system calls to replace its own process image with a new one. This is explained quite well on the Unix SE.

Sample Image

In your case, the shell is the parent process, and the "new program" you are running is the child process which eventually calls exec.



Related Topics



Leave a reply



Submit