So, this seemed simple at first, but after crawling Google and here, the answer doesn't seem as simple as I first thought.
Basically, I'm editing a MINIX kernel as part of a practical for my Operating Systems course, and I have to add a little function that spits out the number of running processes when you hit a function key in the Information Server. I've figured out how to integrate the functionality so all the other stuff works, but for the life of me, I can not figure out how to get the current number of processes running in the system into my C code and into a variable to print out.
First I thought there'd be a nifty Syscall like SYS_NUMPROCS or something that'd return the value, but no luck.
Then, I tried piping output from a system("ps -ax | wc -l") to a file and the file wouldn't create. I tried using popen() and no luck there either - even with a simple "ls" read into a buffer, it just bombs the code and "hangs" the run of the code, so there's no output.
So now I'm truly stumped, and any help would be super awesome, because at this point I've exhausted all the obvious options.
The only two things I can think of now would be a loop counting all the processes, but first you have to get to the system's process list, and I've heard vague things said about /proc/ as a directory, but I haven't a clue how to access/run through that or how it'd link up to getting the number of processes in the first place.
Thanks a stack (lol pun), guys :)
Also, I haven't included code explicitly because nothing I've written aside from basic printf'ing for cosmetic output, because none of the things I've tried gave me any joy :/
Edit notes: Guys, this is a kernel edit - I'm writing the function to printf the information in a system C file, then recompiling the kernel and rebooting the system to test. It's a UNIX (MINIX) kernel, not a Linux kernel, and it's not a user mode program.
My code for popen(), as some of you requested, is as follows:
public void cos_dmp(){
char buffer[512];
FILE * f;
f = popen("ps -ax | wc -l","r");
fgets(buffer, sizeof(buffer),f);
//buffer should now contain result of popen()
printf(buffer);
}
That's a bit of a hacked together version from what I remember and keeping it ultra simple and showing you guys that's what I was trying to do. Again though, there must be a better way to do this aside from essentially calling the output of a system() call.
Edit again: the above code woks perfectly from a user program but won't work from the kernel function. Anybody have an idea why?:/
struct kinfo kinfo;
int nr_tasks, nr_procs;
getsysinfo(PM_PROC_NR, SI_KINFO, &kinfo);
nr_procs = kinfo.nr_pro;
This will get you the number of processes running
try looking to see what ps does. Look at its source code; it knows how many processes there are
Perhaps you could show us the code your wrote for capturing the result of system("ps -ax | wc -l"), or the code you wrote to use popen and we could help you diagnose the problem with it.
Regardless, the most efficient way I can think of to count the number of existing (not the same as running) processes on the system is to opendir("/proc") and count the number of entries that are strings of decimal digits. Each process in the system will be represented by a subdirectory of /proc, named after the decimal process id number of that process.
So, if you find "/proc/3432", for example, then you know that there exists a process with a pid of "3432". Simply count the number of subdirectories you find whose names are decimal numbers.
Assumptions:
You are asking about Linux, not MINIX.
You are writing a user-mode program, not modifiying the kernel.
So I have been having the same problem and found a solution. (MINIX 3.1) within the method to count the processes use this code:
(This is ANSI C)
It simply runs through the process table and counts the number of processes.
I know this is an old thread but it might help someone in the future.
#include "../pm/mproc.h"
/* inside function */
struct mproc *mp;
int i, n=0;
printf("Number of running processes:\n");
getsysinfo(PM_PROC_NR, SI_PROC_TAB, mproc);
for (i = 0; i<NR_PROCS; i++) {
mp = &mprocs[i];
if (mp->mp_pid == 0 && i != PM_PROCS_NR) continue;
n++;
}
printf("%d", n);
/* function end */
I had the same assignment at my university so i will post my solution if someone needs it in future. I am using Minix 3.3 and VMware player for virtual machines.
In pm server at location /usr/src/minix/servers/pm there is glo.h file which contains various global variables used by pm server. In that file, there is fortunately one variable called procs_in_use defined as EXTERN int procs_in_use;
So simple printf("%d\n",procs_in_use); from a system call will show the number of current processes running. You can test this by adding fork() function in your user space program in the middle of a loop.
One more mention : first answer that says
struct kinfo kinfo;
int nr_tasks, nr_procs;
getsysinfo(PM_PROC_NR, SI_KINFO, &kinfo);
nr_procs = kinfo.nr_procs;
didn't work out for me. SI_KINFO no more exists so you should use SI_PROC_TABLE. Also there can be problems with permissions, so you will not be able to call this function from your regular system call. There is alternative function sys_getkinfo(&kinfo) that can be called from your fresh system call and that will do the same as the above. The problem is kinfo.nr_procs will not return number of current processes but number of maximum user processes that can be in operative system which is 256 by default, and can be changed manually in file where NR_PROCS is defined. On the other hand kinfo.nr_taskswill return maximum number of kernel processes that can be held by operative system, which is 5 by default.
Check this out: http://procps.sourceforge.net/
It's got source to a number of small utilities that do these kinds of things. It'll be a good learning experience :) and I think PS is i n there as pm100 noted.
If you're editing the kernel, the most efficient way to solve this problem is to maintain a count every time a process (i.e., a task_struct entry) is created (and make sure you decrement the count every where a process terminates).
You could always loop through the list of processes in the kernel using the built-in macro (but its expensive, so you should try to avoid it):
struct task_struct *p;
unsigned int count = 0;
for_each_process(task) {
count++;
}
Check this out: http://sourceforge.net/p/readproc/code/ci/master/tree/
#include"read_proc.h"
int main(void)
{
struct Root * root=read_proc();
printf("%lu\n",root->len);
return 0;
}
Related
I have 2 basic questions since I'm new at C:
How to go about passing the return value of a C program to another program? prog1 will list out items (number of items can be varied each time of execution) and I'd like to store and pass ONLY the last item value to another prog2 for different purpose. Basically the output of prog1 is below and I'd like to extract the last item on the list which is /dev/hidraw2 for the prog2. Prog2 is currently using hardcoded value and I'd like to make it more dynamic.
prog1 output:
/dev/hidraw0
/dev/hidraw1
/dev/hidraw2
prog1 code can be found here:
https://pastebin.pl/view/379db296
prog2 code snippet is below:
/* C */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
const char *bus_str(int bus);
int main(int argc, char **argv)
{
int fd;
int i, res, desc_size = 0;
char buf[256];
struct hidraw_report_descriptor rpt_desc;
struct hidraw_devinfo info;
char *device = "/dev/hidraw2"; /*** replace hardcoded value here dynamically ***/
if (argc > 1)
device = argv[1];
/* Open the Device with non-blocking reads. In real life,
don't use a hard coded path; use libudev instead. */
fd = open(device, O_RDWR);
If question 1 above is resolved, can I incorporate prog1 into prog2 directly even though they have different compilation parameters? Do you forsee any issue there?
prog1 compile command:
gcc -Wall -g -o prog1 prog1.c -ludev
prog2 compile command:
gcc prog2 prog2.c
One way, and there are many, is to use fork. fork() is a little unlike other C function calls. When you call it, you get an extra copy of the running process. You can then compare the return value to determine which process is the parent and which process is the child.
The overall logic would then look a little like:
while (looping) {
char device[] = (set to the desired value);
int childPID = fork();
if (childPID == 0) {
/* this is the child */
doWhatever(device);
exit(0);
} else {
/* this is the parent */
/* let's wait on the child to complete */
wait();
}
Now this example is very simple. There are many other considerations; but this approach avoids other more complex ways to pass information between processes. Basically the child is created as a copy of the program at the moment in time that fork() is called, so the contents of device will be shared between the two processes.
Some of the problems to watch out for is that children need to report their exit codes to their parent processes. So if you don't want to have one process running at a time, you'll need a more complex way to wait() on the children.
If you kill the parent process in this example, the children will also be killed. That may or may not be what you desire.
Other approaches (some much better than others):
Using IPC to create a producer / consumer pattern based on shared memory and semaphores (to control who's writing to the shared memory, so reading processes don't read partially written entries or remove items partially creating problems with writers.
Using the above approach (fork) but creating an unnamed pipe in the patern that the child then reads from. This can permit the child to process more than one request.
Using a named pipe (a very special kind of file) that exists independently of the two programs. This allows independent launching of the child(ren).
Using a regular file, written by the producer and read by the consumer(s). This will require some sort of signalling for when the file is safe to write to (so consumers don't get bad reads) and when the file is safe to read / shorten (so the writers don't corrupt the file).
I'm sure there are many other approaches; but, when you have two programs cooperating to solve a problem, you start to encounter a lot of issues that you don't normally have when only considering one program solving the problem.
Some of the things to consider:
The communication is reliable - files, sockets, networks, etc. all sometimes fail. You need to verify your sends were sent and provide some means for knowing your data is not corrupt due to the transport.
The act of communicating requires time - you will need to handle delays in both the packaging, insertion, retrieval, and unpackaging of the transmission; and, often those delays can change dramatically for each message.
The number of messages that can be handled is finite - transmission requires time, and time implies a rate of transmission. Since there is a rate involved, you cannot design a working program that ignores the limits of the communication path.
The message can be corrupted or eavesdropped - While we like to think that computers never make errors, when communicating errors in the data occur more frquently. These can be due to lots of reasons (people testing sockets with telnet, electrical interference with networks, pipe files being removed, etc.) In addition, the data itself is more easily read by others, which is a problem for some programs.
The way the transmission occurs changes - Even if you are using files instead of networks to transmit information, administrators can move files and insert symlinks. Networks may send every bit of information through a different path. Don't assume a static path.
You can't provide instructions to avoid critical issues - No computer has only one administrator, even if it is your own personal computer. Automated systems and subroutines, as well as other people, ensure that you'll never be able to provide instructions on how to work around issues to all the right people. Write your solutions avoiding a need for workarounds that are implemented by people following a custom "required" procedure.
Moving data is not free - it costs time, electricity, RAM, CPU, and possibly disk or network. These costs can grow (if not managed) to prevent your program from functioning, even if all other parts of the solution are correct.
Transportation of data is often not homogenous - Once you commit to a way of communicating information, odds are that it will not be easy to replace it with another way easily. Many of the solutions provide additional features that aren't present in other approaches, and even if you decide on "network only" transport, the difference between networks may make your solution less generic that you might think.
Armed with these realizations, it will be much easier for you to create a solution that works, and doesn't fall apart when some tiny detail changes.
I was trying to create a child process using fork but it is repeatedly returning -1, I tried to found the causes and I came to this:
Fork() will fail and no child process will be created if:
[EAGAIN] The system-imposed limit on the total number of pro-
cesses under execution would be exceeded. This limit
is configuration-dependent.
[EAGAIN] The system-imposed limit MAXUPRC (<sys/param.h>) on the
total number of processes under execution by a single
user would be exceeded.
[ENOMEM] There is insufficient swap space for the new process.
Now I don't know how to check the first and third point but on looking at point MAXUPRC - I looked into sys/param.h:
//<sys/param.h>
#define MAXUPRC CHILD_MAX /* max simultaneous processes */
CHILD_MAX has been mentioned here (unistd.h):
//<unistd.h> - DEFINED IN MY SYSTEM
#define _SC_CHILD_MAX 2
CHILD_MAX - _SC_CHILD_MAX
The maximum number of simultaneous processes per user ID.
Must not be less than _POSIX_CHILD_MAX (25).
Now I can't establish if keeping _SC_CHILD_MAX less than 25 is the reason or do I have to look into 1st and 3rd causes (they are hard to check as the system is Z/OS with limited access and I don't have much idea about it).
perror(""); isn't printing anything and errno is printing 655360.
#include<stdio.h>
#include<errno.h>
#include<unistd.h>
#include<stdlib.h>
int main()
{
long int prc_id;
prc_id=fork();
if(prc_id ==0)
calling_child();
else if(prc_id <0)
{
printf("errno - %d\n",errno);
printf("failed %d\n",prc_id);
exit(0);
}
return 0;
}
This above code runs fine and creates a child process on my own laptop (centos) but in dev environment I guess there are some restrictions.
calling_child is never called as the prc_id returned is -1 (not even first print statement is printed on entering the function).
I copied your sample program to my z/OS system running z/OS Version 2.3, with a minor enhancement since you left out the calling_child function (UPDATED to add the sysconf() value for SC_MAX_CHILD):
#include<stdio.h>
#include<errno.h>
#include<unistd.h>
#include<stdlib.h>
int main()
{
long int prc_id;
printf("SC_CHILD_MAX = %d\n", sysconf(_SC_CHILD_MAX));
prc_id=fork();
if(prc_id ==0)
calling_child();
else if(prc_id <0)
{
printf("errno - %d\n",errno);
printf("failed %d\n",prc_id);
exit(0);
}
return 0;
}
static void calling_child(void)
{
printf("Hello from PID %x\n", getpid());
return;
}
I put the code in a file called test2.c and built it with this shell command: c99 -o test2 -g test2.c
It compiles cleanly and I was able to run it with no problems. It produces this output:
SC_CHILD_MAX = 32767
Hello from PID 40100b2
Most likely your build or execution environment isn't configured properly. It absolutely works fine on my pretty basic system, and I didn't have to do anything unusual at all to get it running.
A few small hints...
How are you getting into the z/OS UNIX shell? If you're logging onto TSO then running the ISPF shell or the OMVS command, you might prefer simply SSH'ing into your z/OS system. I usually find this is the cleanest batch environment.
Second thing is that you probably want to double-check your C/C++ environment. There are some good debugging features built into the IBM XLC compiler - try man C99 (or whatever dialect you use) and have a read.
Third thing is that IBM includes the dbx debugger in z/OS, so if you really get stuck, just try running your executable under dbx and you can step through your program line at a time.
As for those ERRNOs and so on, don't forget to also look at the __errno2() values - they usually have a very specific reason code that goes along with the more generic errors. For example, your z/OS security administrator can certainly do things to limit your use of z/OS UNIX functions - that would be revealed in the __errno2() values pretty clearly.
Stick with it though - if you know UNIX or Linux, all the skills you have from using the shell to coding pretty much transfer 100% to z/OS if you put in a little time to learning the basics.
If you've been playing with fork(2) you may well have used up your limit of processes available to your process, see ulimit for your shell:
$ help ulimit | grep process
Ulimit provides control over the resources available to processes
-d the maximum size of a process's data segment
-l the maximum size a process may lock into memory
-u the maximum number of user processes
If so, logging out and logging back in again will solve the problem.
i want to implement a counter in Linux which keep a track of how many times
main() is called by any process.
when i start this counter thing as a process, from that time it will tell me how many times main() was called not by my program but in the entire OS system
example:
i start this as a daemon and then i create a simple code
#include <stdio.h>
int main(){
//some code
return 0;
}
Now here main is called so the counter will increment by one.
Can anyone explain me how can this be done.?
thanks
You might want to take a look at: Proc connector and socket filters
The Proc Connector and Socket Filters Posted on February 9, 2011 by scott
The proc connector is one of those interesting kernel features that most people rarely come across, and even more rarely find documentation on. Likewise the socket filter. This is a shame, because they’re both really quite useful interfaces that might serve a variety of purposes if they were better documented.
The proc connector allows you to receive notification of process events such fork and exec calls, as well as changes to a process’s uid, gid or sid (session id). These are provided through a socket-based interface by reading instances of struct proc_event defined in the kernel header....
main() is just a abstract code; assembler uses functions' name as a hint, and converts them into numbers. So you can't implement such counter.
main() is usually called once, what you mean may be a program which counts how many programs are executed.
There is popen in Linux which performs the given command, and yields the result as FILE *, so you can execute the ps command and parse it to get the list of the processes. You can continuously invoke popen and count the number of programs.
char Buffer[1024];
sprintf(Buffer,"ps ");
FILE *ptr = popen(Buffer, "r");
if(NULL != ptr)
{
while(fgets(Buffer, sizeof(Buffer),ptr));
pclose(ptr);
}
// Now the list of processes are in Buffer
I am currently trying to check wether the copy of a file from a directory to another is done.
I would like to know if the target file is still being copied.
So I would like to get the number of file descriptors openned on this file.
I use C langage and don't really find a way to resolve that problem.
If you have control of it, I would recommend using the copy-move idiom on the program doing the copying:
cp file1 otherdir/.file1.tmp
mv otherdir/.file1.tmp otherdir/file1
The mv just changes some filesystem entries and is atomic and very fast compared to the copy.
If you're able to open the file for writing, there's a good chance that the OS has finished the copy and has released its lock on it. Different operating systems may behave differently for this, however.
Another approach is to open both the source and destination files for reading and compare their sizes. If they're of identical size, the copy has very likely finished. You can use fseek() and ftell() to determine the size of a file in C:
fseek(fp, 0L, SEEK_END);
sz = ftell(fp);
In linux, try the lsof command, which lists all of the open files on your system.
edit 1: The only C language feature that comes to mind is the fstat function. You might be able to use that with the struct's st_mtime (last modification time) field - once that value stops changing (for, say, a period of 10 seconds), then you could assume that file copy operation has stopped.
edit 2: also, on linux, you could traverse /proc/[pid]/fd to see which files are open. The files in there are symlinks, but C's readlink() function could tell you its path, so you could see whether it is still open. Using getpid(), you would know the process ID of your program (if you are doing a file copy from within your program) to know where to look in /proc.
I think your basic mistake is trying to synchronize a C program with a shell tool/external program that's not intended for synchronization. If you have some degree of control over the program/script doing the copying, you should modify it to perform advisory locking of some sort (preferably fcntl-based) on the target file. Then your other program can simply block on acquiring the lock.
If you don't have any control over the program performing the copy, the only solutions depend on non-portable hacks like lsof or Linux inotify API.
(This answer makes the big, big assumption that this will be running on Linux.)
The C source code of lsof, a tool that tells which programs currently have an open file descriptor to a specific file, is freely available. However, just to warn you, I couldn't make any sense out of it. There are references to reading kernel memory, so to me it's either voodoo or black magic.
That said, nothing prevents you from running lsof through your own program. Running third-party programs from your own program is normally something you try to avoid for several reasons, like security (if a rogue user changes lsof for a malicious program, it will run with your program's privileges, with potentially catastrophic consequences) but inspecting the lsof source code, I came to the conclusion that there's no public API to determine which program has which file open. If you're not afraid of people changing programs in /usr/sbin, you might consider this.
int isOpen(const char* file)
{
char* command;
// BE AWARE THAT THIS WILL NOT WORK IF THE FILE NAME CONTAINS A DOUBLE QUOTE
// OR IF IT CAN SOMEHOW BE ALTERED THROUGH SHELL EXPANSION
// you should either try to fix it yourself, or use a function of the `exec`
// family that won't trigger shell expansion.
// It would be an EXTREMELY BAD idea to call `lsof` without an absolute path
// since it could result in another program being run. If this is not where
// `lsof` resides on your system, change it to the appropriate absolute path.
asprintf(&command, "/usr/sbin/lsof \"%s\"", file);
int result = system(command);
free(command);
return result;
}
If you also need to know which program has your file open (presumably cp?), you can use popen to read the output of lsof in a similar fashion. popen descriptors behave like fopen descriptors, so all you need to do is fread them and see if you can find your program's name. On my machine, lsof output looks like this:
$ lsof document.pdf
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
SomeApp 873 felix txt REG 14,3 303260 5165763 document.pdf
As poundifdef mentioned, the fstat() function can give you the current modification time. But fstat also gives you the size of the file.
Back in the dim dark ages of C when I was monitoring files being copied by various programs I had no control over I always:
Waited until the target file size was >= the source size, and
Waited until the target modification time was at least N seconds older than the current time. N being a number such a 5, and set larger if experience showed that was necessary. Yes 5 seconds seems extreme, but it is safe.
If you don't know what the target file is then the only real choice you have is #2, but user a larger N to allow for the worse case network and local CPU delays, with a healthy safety factor.
using boost libs will solve the issue
boost::filesystem::fstream fileStream(filePath, std::ios_base::in | std::ios_base::binary);
if(fileStream.is_open())
//not getting copied
else
//Wait, the file is getting copied
Hi
I'm trying to make a security feature for my C Project, so that if someone steals it, it becomes useless.
It works as following:
The main function only runs if the comparison of my macbook's Serial to an encrypted one is 1.
The Problem is that I cannot get the system info in the program.
When I do:
int main ()
{ i=0;
if (strcmp(system("system_profiler SPHardwareDataType | grep \"Serial Number\""),
"Serial Number (system): W80314GJATP"));
{
bla
bla
bla
}
else {for(i=0;i<100;i++)
{printf("Unauthorized Computer");
}
return 1;
}
It only prints info to stdout.
Is there a way to do that comparison?
Best Regards
Not an answer to your question, but keep in mind that these tricks are never really secure.
See for example this post at lifehacker (this is about OS X, but it doesn't really matter).
system() does not return a char pointer, it returns the exit code (an int) from command that was run. You could use popen() to run a command. popen() will return a FILE* that you can read from (it is from the program's stdout). You can then read and parse the program output accordingly.
system returns an int not a const char * of what would show up on the command interrupter. If you want the output of the program you will need to get that programs stdout.
Take a look at this question on how to get the output from a pipe.
If you honestly want to make it secure, use (for example) a BIOS serial number (or hard disk serial number) as a key to encrypt the executable. Write a small wrapper that reads the same data, uses it to decrypt the executable, and then runs the result. At least without access to the original hardware, this can be fairly difficult to work around (unlike the comparison you're doing). OTOH, with access to the original hardware, this is pretty easy to break as well.