Results 1 to 6 of 6
Hi,
I am working on a c++ program that needs to use system calls like pidof, pgrep, and top.
I know that the system() command uses a string but I ...
- 07-16-2008 #1Just Joined!
- Join Date
- Jul 2008
- Posts
- 3
Using Linux System Calls in c++
Hi,
I am working on a c++ program that needs to use system calls like pidof, pgrep, and top.
I know that the system() command uses a string but I am having trouble getting it to accept the output of another command as a variable in that string.
I am using pgrep progName to save the program's pid. I was able to save it to file which I then had to read from but it seems like you should be able to pipe the standard output to a variable?
In any case I saved the pid to a variable but now am having trouble getting it to read that variable in the next system call which uses top -p pid. I need to pull the information about a specific process' cpu and memory usage so I can add monitoring to a server program.
If there are better ways to do it...... I am open to suggestions.
Thanks
- 07-17-2008 #2
There is indeed an easier way to do this.
The popen() function opens a pipe to a command. This will execute the command and allow you to either write to it (appearing as the command's stdin) or read from it (you read its stdout). Some documentation:
Pipe to a Subprocess - The GNU C Library
Once you've done this, you can read the output via fgets(). And finally, you can add it into your new command with sprintf().
As for the system() function, first off, this is not a "system call". A system call is a function that hooks directly into the kernel. You can use the syscall() function to do so directly, or you can use a glibc wrapper (for instance, the chmod() function).
In any event, system() is used when you want to run a command for its side effect, not for its input or output. system() opens up a new instance of the shell and runs the program. When you want I/O from the new process, popen() is your friend; when you want deep control over the new process, the fork()/exec combo is your friend.
I hope that helps!
EDIT:
It just dawned on me that you're using C++. You can definitely use all of the above (they are Linux C, and you can use C from C++), but if you're looking for a pure C++ solution, you might try Googling for a C++ wrapper around popen(). You can also use popen() and such, and then when you get the PID as a char*, convert it to an std::string.
Alternatively, we can continue with your approach above. You have the PID in a variable, you now need to make a string. You can use string streams to construct a string with the PID in it, and then use that string in your system() function:
C++ String StreamsDISTRO=Arch
Registered Linux User #388732
- 07-17-2008 #3Just Joined!
- Join Date
- Jul 2008
- Posts
- 3
Thanks - You have given me a lot of help!
Thanks, I appreciate all of your suggestions and will start looking at the functions you mentioned. Linux is so rich it's hard to know where to start. Are there any books you would recommend I invest in to speed up my learning curve?
- 07-18-2008 #4
Most of what I know about Linux I learned by doing. It's just that I've been doing it for a few years now
.
As far as programming goes, we have the Standard C Library, and then the GNU C Library (glibc). glibc implements the standard library as well as all of the functions required by the POSIX standard (a standard that all Unixes adhere to), as well as some GNU-specific extensions. You can find a good guide to using all of these at:
The GNU C Library
If you want to learn C (which is the most popular Linux language these days), I suggest the book "The C Programming Language" by Kernighan & Ritchie. Ritchie is the creator of the C language, and this is an excellent book.
As far as C++, I don't do much C++. I don't believe that there is any Linux-specific C++ in any event. I used the book "C++: How to Program" by Deitel & Deitel to learn it, but I don't know of any particularly great book for C++.
Basically, to get used to Linux, just try things out. Most likely, anything you want to learn someone else wanted to learn also, so there are tons of guides and tutorials out there. And this forum is a particularly great resource if you need help or pointers with anything.DISTRO=Arch
Registered Linux User #388732
- 07-18-2008 #5Just Joined!
- Join Date
- Jul 2008
- Posts
- 3
Great Ideas
This is what I've been working on.... don't mind if it is clumsy. I had been using system(" ") in c++ but it will only take commands so I couldn't set variables. I took a shot with the set command which I saw somewhere to make a variable but it wasn't working either. I was able to combine my variable with string components to make a command for system() but found out it wanted a const char* instead.
I am thinking of writing a Linux script that I can call from c++ and hopefully export the variables to it (not sure yet). I will try popen(), fgets() and sprintf() which you recommended.
Following along the lines I had started in trying to make system() calls I have this which works in a linux script.
var1=$(top -n 1 -p $(/sbin/pidof prog) | grep prog| awk '{print $1}');
var2=$(top -n 1 -p $(/sbin/pidof prog | grep prog | awk '{print $5}');
var3=$(top -n 1 -p $(/sbin/pidof prog) | grep prog | awk '{print $7}');
var4=$(top -n 1 -p $(/sbin/pidof prog) | grep prog | awk '{print $8}');
var5=$(top -n 1 -p $(/sbin/pidof prog) | grep prog | awk '{print $9}');
var6=$(top -n 1 -p $(/sbin/pidof prog) | grep prog | awk '{print $10}');
echo $var1 $var2 $var3 $var4 $var5 $var6;
I would like to make 1 top call and then pull all the variables I want from it but haven't run across how to do that if it is possible. Any suggestions? I will try to do the same thing in c++ with popen, fgets and sprintf this weekend.
Thanks again for your help.
- 07-20-2008 #6
Yes indeed. You can do this with only a single top call. We will do this by saving the output of top, and then taking what we want:
We only have to invoke top once, and then we just awk that same line over and over to get the desired information.Code:prog_pid=$(/sbin/pidof prog) top_output=$(top -p "$prod_pid" | grep prog) var1 = echo "$top_output" | awk '{print $1}' var2 = echo "$top_output" | awk '{print $5}' # and so on
A similar approach would work within C++. You use popen() to read that single line from top, and then do your processing.
As far as setting variables in a child program, you can do so by using the environment:
Environment Variables - The GNU C Library
Or, you could pass values as commandline arguments to be read by the child. Be aware that a child cannot change anything about its parents (except by its exit code or captured output).DISTRO=Arch
Registered Linux User #388732


Reply With Quote