Sorry if the title doesn't make any sense, it's all I could think to call it.
I'm learning about how processes work in *nix systems (Linux in my case) and I know a little bit but I want to figure out how to do this, if possible, and I can't find anything about probably since I don't know what to call it.
The best way for me to explain this would be to give an example:
Say I have a music player which operates in the terminal, lets call it "musicplayer".
I want to play a sound file, so I would execute this command:
musicplayer play "/path/to/music.mp3"
Then this runs in the background and I'm back at my prompt in the terminal, I can just completely exit from the terminal and hear the music in the background etc...
Say halfway through the song I want to pause it:
musicplayer pause
Some how the music is paused.
How would this work? (I mean in terms of the process, the music is only an example, the question is not about music).
In my mind this is what's happening: [fork and play music] -> [tell the fork to pause].
I'm not very knowledgeable on the subject of processes yet so any help/explanation of this is highly appreciated.
I don't need code examples necessarily, just logically how this would work but if you wish to give examples you could give them in C.
Thanks in advance for any explanation.
You need to understand that forked processes do not share (implicitly) any data; conceptually parent and child processes have each their own address space and have their own copy of the data (using lazy copy on write techniques). See fork(2)
Hence, you need to make them explicitly communicate and synchronize with pipe(7)-s, fifo(7)-s, socket(7)-s, shared memory shm_overview(7) with semaphores sem_overview(7), eventfd(2) or whatever other means Linux provides you.
So read Advanced Linux Programming and learn about the syscalls(2) available on Linux to do Inter Process Communication. Don't forget to handle syscall failure.
For your music play command you would set up IPC and fork (see also daemon(3) to fork a daemon in the background).
For your music pause you would communicate with the other process. (you might perhaps consider stopping the process with the SIGSTOP signal(7) using kill(2)...)
You need to build in your head an image of all the IPC facilities available to chose the ones relevant for your situation
BTW, several command-line music players exist on Linux as free software. You could study their source code and/or strace(1) their execution.
I'd like to add one thing to Basiles answer: this is a very common problem so almost certainly you don't have to handle the details (that can be very complex) yourself. Good application frameworks will provide a solution for you so you can concentrate on making the application great.
As an example, take a look at GLibs GApplication: It handles application uniqueness so the first instance will keep running and any subsequent app invocations will just send a D-Bus message to the original instance and exit. The GApplication object in the original instance will emit a signal that tells your app e.g.that a musicplayer instance was started on command line and and the argument was "pause".
Related
I'm creating some pipes and handing it over to fork()/exec()'d child process as stdout and stderr FDs. But the child program doesn't output ANSI colours.
For e.g., the gcc command can output diagnostics with colours. But when I create it as a child of my program and hand over the piped FDs it doesn't send generate colours.
With a bit of snooping around, I found it tests isatty(STDERR_FILENO) and doesn't send ANSI colour codes when it returns false. Is there a way I can make my pipes be treated as TTYs in child process?
P.S. Also, please not I'm aware of unbuffer shell command which was recommended for similar question. I am looking for C/POSIX API solution that's portable across unices. Not just Linux.
There are two answers to your question, the direct answer and the answer to your XY problem. First, the latter. Generally, programs that can output color/formatting suitable for a terminal, or plain text, choose their default based on isatty, but let you pass an explicit option to enable or disable it. For GCC, this is -fdiagnostics-color=always. This is almost surely what you should be using.
But to answer your original question, the way to do this is not to use a pipe but instead a pseudo-tty (pty). The POSIX interfaces to do this are posix_openpt, grantpt, unlockpt, and ptsname (to get the name of the device to open). But there's a much nicer non-standardized interface, openpty, that does it all for you in one call, and an accompanying forkpty that automatically forks and connects the child's stdin/out/err up to it. I would use one of these if available (they're available on glibc and musl on Linux systems, and on most/all BSD systems).
Short answer is no. Longer answer is that rather than a pipe, you could setup a pseudo-tty, and run a command in it which captures the compilers output. That is a lot of work. Man 7 pty for a detailed description.
You could take a different approach, and define your own mapping of diagnostics to colours for various commands. Please do the non-bling-addicted world a favour and provide an option to not adorn the text....
I've been asked to create a dbus interface to a program that uses SocketCAN to communicate to a set of control units on a car (that's just background info and not relevant to the question). The original concept was to use a listener interface that spawned a new "node" for each control unit being interrogated in the car. This would lead to something like the following objects on the com.acme.myservice bus:
/com/acme/listener
/com/acme/node1
/com/acme/node2
...
/com/acme/nodeN
The idea is to take over the code from a C program that already communicates from the command line with a single ECU. That code depends on fork()ing in order to run parts of the communication cyclically and other parts in parallel for timing reasons.
I had planned on using the GDBusObjectManager model using new code for the listener and reusing the fork()ing code for each node instance. Unfortunately I ran into trouble because I still need to process DBus messages and relay the information to the (now forked) children and that's not supported:
On UNIX, the GLib mainloop is incompatible with fork(). Any program using the mainloop must either exec() or exit() from the child without returning to the mainloop.
I could restructure the forking code so that it executes in a single process in between iterations of the main loop instead of using g_main_loop_run but this will probably cause too much latency if there's a significant amount of data and multiple nodes running.
What's the best way around this? Is it possible to somehow handle these parallel items with a built-in glib mechanism or is there a way around the mainloop/forking issue? Is the only solution to use a different IPC mechanism between a single process using DBus and forked children doing the actual work? (This would probably be as much code as needed for the gdbus interface so it makes it sort of redundant)
My process launches a process - let it be a shell in this example, but it's applicable to any process really. I need to get notified when the shell creates new processes and to obtain their PIDs.
I can take a snapshot of the whole process tree at any given time (well, pstree can), but how do I monitor creation of new processes by a process with a given PID?
So far I've found several ways to do so at How to monitor an external process for events by its PID in C? none of which really solve my problem:
Monitoring NetLink proc interfaces. Problem: requires root permissions which I do not have.
Custom library overriding the syscalls loaded into the shell process by LD_PRELOAD. Problem: it will be inherited by the children of the shell as well, and I do not want that - I only want to monitor the shell.
ptrace()ing the shell. Problem: flags that notify the parent (i.e. my process) about creating new processes, i.e. PTRACE_O_TRACEFORK, PTRACE_O_TRACEVFORK and PTRACE_O_TRACECLONE propagate ptrace()ing to child processes, and I only want to monitor the shell.
Making the shell cooperate. Problem: In BASH command callbacks (as used in undistract-me) are very hacky. I'd also prefer to avoid shell-specific code.
I feel like I'm missing something simple here. I feel like I could make one of the above solutions work with more hacks, but... surely I don't have to resort to the big guns like LD_PRELOAD and ptrace() for such a simple task, do I?
JFYI I'm coding this in Vala, but C snippets are welcome too.
No generic solution has been found so far so I had to resort to making the shell cooperate:
ZSH has pre-exec hook documented in
http://zsh.sourceforge.net/Doc/Release/Functions.html
KSH has a
debug hook documented in http://www.manpagez.com/man/1/ksh/
a hack that adds pre-exec to BASH can be found in
https://github.com/jml/undistract-me
I simply write callback commands into the relevant environment variables depending on the shell.
I'm writing a program that spawns child processes. For security reasons, I want to limit what these processes can do. I know of security measures from outside the program such as chroot or ulimit, but I want to do something more than that. I want to limit the system calls done by the child process (for example preventing calls to open(), fork() and such things). Is there any way to do that? Optimally, the blocked system calls should return with an error but if that's not possible, then killing the process is also good.
I guess it can be done wuth ptrace() but from the man page I don't really understand how to use it for this purpose.
It sounds like SECCOMP_FILTER, added in kernel version 3.5, is what you're after. The libseccomp library provides an easy-to-use API for this functionality.
By the way, chroot() and setrlimit() are both system calls that can be called within your program - you'd probably want to use one or both of these in addition to seccomp filtering.
If you want to do it the ptrace way, you have some options (and some are really simple). First of all, I recommend you to follow the tutorial explained here. With it you can learn how to know what system calls are being called, and also the basic ptrace knowledge (don't worry, it's a very short tutorial). The options (that I know) you have are the following:
The easiest one would be to kill the child, that is this exact code here.
Secondly you could make the child fail, just by changing the registers with PTRACE_SETREGS, putting wrong values in them, and you can also change the return value of the system call if you want (again, with PTRACE_SETREGS).
Finally you could skip the system call. But for that you should know the address after the system call call, make the intruction register point there and set it (again, with PTRACE_SETREGS).
This question already has answers here:
Closed 13 years ago.
Possible Duplicate:
Linux API to list running processes?
How can I detect hung processes in Linux using C?
Under linux the way to do this is by examining the contents of /proc/[PID]/* a good one-stop location would be /proc/*/status. Its first two lines are:
Name: [program name]
State: R (running)
Of course, detecting hung processes is an entirely separate issue.
/proc//stat is a more machine-readable format of the same info as /proc//status, and is, in fact, what the ps(1) command reads to produce its output.
Monitoring and/or killing a process is just a matter of system calls. I'd think the toughest part of your question would really be reliably determining that a process is "hung", rather than meerly very busy (or waiting for a temporary condition).
In the general case, I'd think this would be rather difficult. Even Windows asks for a decision from the user when it thinks a program might be "hung" (on my system it is often wrong about that, too).
However, if you have a specific program that likes to hang in a specific way, I'd think you ought to be able to reliably detect that.
Seeing as the question has changed:
http://procps.sourceforge.net/
Is the source of ps and other process tools. They do indeed use proc (indicating it is probably the conventional and best way to read process information). Their source is quite readable. The file
/procps-3.2.8/proc/readproc.c
You can also link your program to libproc, which sould be available in your repo (or already installed I would say) but you will need the "-dev" variation for the headers and what-not. Using this API you can read process information and status.
You can use the psState() function through libproc to check for things like
#define PS_RUN 1 /* process is running */
#define PS_STOP 2 /* process is stopped */
#define PS_LOST 3 /* process is lost to control (EAGAIN) */
#define PS_UNDEAD 4 /* process is terminated (zombie) */
#define PS_DEAD 5 /* process is terminated (core file) */
#define PS_IDLE 6 /* process has not been run */
In response to comment
IIRC, unless your program is on the CPU and you can prod it from within the kernel with signals ... you can't really tell how responsive it is. Even then, after the trap a signal handler is called which may run fine in the state.
Best bet is to schedule another process on another core that can poke the process in some way while it is running (or in a loop, or non-responsive). But I could be wrong here, and it would be tricky.
Good Luck
You may be able to use whatever mechanism strace() uses to determine what system calls the process is making. Then, you could determine what system calls you end up in for things like pthread_mutex deadlocks, or whatever... You could then use a heuristic approach and just decide that if a process is hung on a lock system call for more than 30 seconds, it's deadlocked.
You can run 'strace -p ' on a process pid to determine what (if any) system calls it is making. If a process is not making any system calls but is using CPU time then it is either hung, or is running in a tight calculation loop inside userspace. You'd really need to know the expected behaviour of the individual program to know for sure. If it is not making system calls but is not using CPU, it could also just be idle or deadlocked.
The only bulletproof way to do this, is to modify the program being monitored to either send a 'ping' every so often to a 'watchdog' process, or to respond to a ping request when requested, eg, a socket connection where you can ask it "Are you Alive?" and get back "Yes". The program can be coded in such a way that it is unlikely to do the ping if it has gone off into the weeds somewhere and is not executing properly. I'm pretty sure this is how Windows knows a process is hung, because every Windows program has some sort of event queue where it processes a known set of APIs from the operating system.
Not necessarily a programmatic way, but one way to tell if a program is 'hung' is to break into it with gdb and pull a backtrace and see if it is stuck somewhere.