C code equivalent
What is the C function for the bash command
du -ks /home
besides using system("du -ks /home") is there a C function that will do the same ?
Why not use the system call
Using system() is usually considered bad programming practice and should be avoided if at all possible. It has some security risks and other issues.
I'm not aware of a specific function that will do all of this recursively for you like "du" can, but using the dirent.h functions (start with "man 3 opendir" and go from there) to grab files/directories and the stat.h functions ("man 2 stat" and its associated functions) you could write up something yourself that could emulate the basics of the "du" command fairly easily.
Hope this helps.
Last edited by /home/skillet; July 7th, 2003 at 04:43 PM.
a better alternative ?
You said "using system() is usually considered bad programming practice and should be avoided if at all possible. It has some security risks and other issues."
If this is the case, then how would you run a bash command within a C program? The problem of trying to write a C program to do what Bash does is that it makes programming very long and complicated. For example
f = popen("ifconfig", "r");
1) The example above run a Bash command within C. Trying to write a C code to access the ifconfig would be very long and time consuming. In fact the ifconfig command was written in C. Why reinvent the wheel by writing your own code ?
2) would the above code be more secure than the code
Last edited by linh; July 8th, 2003 at 09:39 AM.
I'm not saying you -have- to reinvent the wheel each time, just that system() is not generally a good function to use in these cases. The biggest worry would be the security risk due to if it is run from a program with sgid or suid priveleges, someone could gain priveleges they shouldn't have by exploiting this using environment variables among other things. That's the biggest worry I remember (while learning to program, people with a lot more active brain cells than I used to yell at anyone who even thought of using system()). I did a "man 3 system" on a Linux box just now and their man page even warns about this. Also, something I'd forgotten, system() ignores SIGINT and SIGQUIT signals unless you have a specific signal handler defined for those. Meaning, if your program hangs during the system() call at any point, you can't Control-C to exit, you'd have to get out the axe and do a "kill -9" (which is bad form as it doesn't close file handlers, etc -- it just starts pimp slapping, heh).
But if you wanted to emulate "du", then those functions I mentioned earlier would be useful. Why do that? Well, maybe you want to avoid the overhead of spawning another process and streamline the code by simply doing what you want it to do while ignoring all of "du"s other features, etc etc. There are a number of reasons, but as you said, there's no need to reinvent the wheel if you don't have to. But I'd rather write 10 lines of integrated code than write 5 lines of code which will spawn another process to do the same thing while possibly introducing security risks, zombie processes or the use of more resources. And for the sake of portability, not all shell commands have the same arguments across various systems, and in cases where they do, some don't do the same things (for instance, I wrote my own "wc" command awhile back as I was working on Tru64 Unix and it had some features I liked but lacked some of those I was used to in GNU's "wc", so I made my own and had the best of both worlds); also, some shell commands might change with an upgrade to the system, maybe they don't function the same anymore; all these require you to go make changes to your application later. But if it is integrated and simply does what you want it to do and cuts out all the rest while following good programming standards, then you don't have to touch it again after it is working. (Maybe this is just some small app for yourself you're tinking with and these things don't matter, that is certainly understandable, but I thought I'd throw it out there anyway to explain why sometimes it is better to integrate.)
I think your popen() solution would be okay and allows you to manipulate the data via the FILE handler, which is good and gives you more control. This seems like a good use of popen() if you're needing to parse the data returned for some reason. As far as security goes with popen(), I'm not really sure. I think it is certainly a much better solution than system() or using exec() calls (some of the exec() functions have their own security risks similar to system(), although they're more useful and I'd recommend those over system()).
du -ks /home
Hello /home/skillet. Thank you for the extra information on the weakness of system() function.
I did a du -ks command and got the number as shown below
root:~# du -ks /home
I searched for this file number (6517759 ) in /proc/ but I could not find it.
The program below will do as you have suggested, but the number 6517759 is not shown. Please help me correct the code
so that 6517759 will showed up.
/* #include <signal.h> */
/* #include <sys/stat.h> */
DIR *d = opendir("/proc");
struct dirent *de;
while ((de = readdir(d)) != NULL)
/* for this directory, check the name, we want only numeric */
/* filenames (pid). */
pid = strtoul(de -> d_name, & end, 10);
if (*end != '\0')
continue; // skip this dir.
sprintf( buf, "/proc/%d/cmdline", pid);
fp = fopen(buf, "rt");
if (fp == NULL)
fgets(buf, sizeof(buf), fp);
/* compare command line to see if it is the program you want. */
/* Perhaps drop the first argument */
/* and just compare the first token and see if the name matches. */
printf ("buf = %s pid = %d\n", buf, pid);
/* if (match(buf,what_we_are_looking_for))
the pid in question is in pid!
buf = init  pid = 1
buf = /proc/2/cmdline pid = 2
buf = /proc/3/cmdline pid = 3
buf = /proc/4/cmdline pid = 4
buf = /proc/5/cmdline pid = 5
Last edited by linh; July 8th, 2003 at 01:51 PM.