Linux programme - different results each run

U

ulyses

Hi i have got quite strange problem. I wrote programme which shows all
runnign processes. This info is get from /proc dir. When a dir that is
process dir is found stat file is read and pid, name and state are get
from it. The thing is that on my machine every time I run it, it gives
different results. Sometimes it shows nothing - most of the times.
Sometimes it shows info about 4 processes. Sometimes it works
correctly. I don't now whats wrong, I 've tried to find the mistake,
but I could'n. I begginer programmer and I don't know how to cope with
this problem. Please help me!

Here is the code:

Code:
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <dirent.h>
#include <stdlib.h>

int isNum(char );
int isProcDir(char * );
int showRunningProcesses();

int main()
{

	showRunningProcesses();

	return 0;

}

/*

Function indicates if char given in data variable is number.
If it is it returns 0. If it is not a number it returns 1.

*/
int isNum(char data)
{

	switch(data)
	{
		case '0': return 0;
		case '1': return 0;
		case '2': return 0;
		case '3': return 0;
		case '4': return 0;
		case '5': return 0;
		case '6': return 0;
		case '7': return 0;
		case '8': return 0;
		case '9': return 0;
		default : return 1;
	}

}

/*

Function indicates if char given by *path pointer
is process dir (in /proc file system). If it is it
returns 0. If it is not it returns 1.

*/

int isProcDir(char *path)
{
	struct stat st;
	int i;
	int path_length;

	lstat(path, &st);
	path_length = strlen(path);

	//printf("running.. %s\n", path);
	//printf("%o", st.st_mode);
	if (S_ISDIR(st.st_mode))
		return 1;
	else if(S_ISLNK(st.st_mode))
		return 1;
	else if(S_ISCHR(st.st_mode))
		return 1;
	else if(S_ISBLK(st.st_mode))
		return 1;
	else if(S_ISFIFO(st.st_mode))
		return 1;
	else if(S_ISSOCK(st.st_mode))
		return 1;
	else if(S_ISREG(st.st_mode))
		return 1;
	else
	{
		//printf("path: %s \n", path);
		//fprintf(stderr, "found");


		for(i=0; i<path_length; i++)
		{
			if (isNum(path[i]))
			{
				return 1;
			}
		}

		return 0;
	}

}

int showRunningProcesses()
{

	int i;
	DIR *directory, *process_directory;
	FILE *fp;
	struct dirent *dir_entry;
	char *path = (char *)malloc(50);
	char *name;
	char pid[10], procName[15], state[5];

	strcat(path,"/proc/");

	if( ( directory=opendir(path) ) == NULL )
	{
		fprintf(stderr,	"Couldn't open /proc dir.");
		return 1;

	}

	while(dir_entry=readdir(directory))
	{

		/*
		Check if read directory is process
		directory.
		*/

		if( !( isProcDir(dir_entry->d_name) ) )
		{

		//printf("running..");

		/*
		A process directory was found.
		*/

		/*
		Add to path variable name of the
		process directory and then add "/"
		to make path correct.
		*/
		strcat(path, dir_entry->d_name);
		strcat(path,"/");

		//printf("%s\n", path);

		if ( (process_directory=opendir(path) ) == NULL)
		{
			printf("Couldn't open process directory.");
			return 1;
		}
		else
		{
			strcat(path,"stat");

			if ( ( fp=fopen(path,"r") ) == NULL)
			{
				printf("Couldn't open process stat file.");
				return 1;
			}
			else
			{
				fscanf(fp,"%s", &pid);
				printf("PID: %s",pid);
				fscanf(fp,"%s", &procName);
				printf("\t\tName: %s", procName);
				fscanf(fp,"%s", &state);
				printf("\t\tState: %s\n", state);

				fclose(fp);
			}

		}

		closedir(process_directory);

		strcpy(path,"");
		strcat(path,"/proc/");
		
		}
		
	}
	
	closedir(directory);

}

Thank you,
John
 
K

Keith Thompson

Hi i have got quite strange problem. I wrote programme which shows all
runnign processes. This info is get from /proc dir. When a dir that is
process dir is found stat file is read and pid, name and state are get
from it. The thing is that on my machine every time I run it, it gives
different results. Sometimes it shows nothing - most of the times.
Sometimes it shows info about 4 processes. Sometimes it works
correctly. I don't now whats wrong, I 've tried to find the mistake,
but I could'n. I begginer programmer and I don't know how to cope with
this problem. Please help me!

This is Linux-specific and off-topic in comp.nlag.c. Try
comp.os.linux.programmer.

A few things did jump out at me:
int main()
{

showRunningProcesses();

return 0;

}

showRunningProcesses() returns an int; you ignore the result.
/*

Function indicates if char given in data variable is number.
If it is it returns 0. If it is not a number it returns 1.

*/
int isNum(char data)
{

switch(data)
{
case '0': return 0;
case '1': return 0;
case '2': return 0;
case '3': return 0;
case '4': return 0;
case '5': return 0;
case '6': return 0;
case '7': return 0;
case '8': return 0;
case '9': return 0;
default : return 1;
}

}

This is backwards; logically, it should return 0 for false, 1 for
true. Names starting with "is" and a lowercase letter are reserved;
"is_Num" or "is_num" would be ok. And there's already a function that
does exactly what you want: isdigit() said:
/*

Function indicates if char given by *path pointer
is process dir (in /proc file system). If it is it
returns 0. If it is not it returns 1.

*/
int isProcDir(char *path)

Some of the same comments as above apply here.
{
struct stat st;
int i;
int path_length;

lstat(path, &st);
path_length = strlen(path);

//printf("running.. %s\n", path);
//printf("%o", st.st_mode);
if (S_ISDIR(st.st_mode))
return 1;
else if(S_ISLNK(st.st_mode))
return 1;
else if(S_ISCHR(st.st_mode))
return 1;
else if(S_ISBLK(st.st_mode))
return 1;
else if(S_ISFIFO(st.st_mode))
return 1;
else if(S_ISSOCK(st.st_mode))
return 1;
else if(S_ISREG(st.st_mode))
return 1;
else
{
//printf("path: %s \n", path);
//fprintf(stderr, "found");


for(i=0; i<path_length; i++)
{
if (isNum(path))
{
return 1;
}
}

return 0;
}

}

int showRunningProcesses()
{

int i;
DIR *directory, *process_directory;
FILE *fp;
struct dirent *dir_entry;
char *path = (char *)malloc(50);
char *name;
char pid[10], procName[15], state[5];

strcat(path,"/proc/");

if( ( directory=opendir(path) ) == NULL )
{
fprintf(stderr, "Couldn't open /proc dir.");
return 1;

}

while(dir_entry=readdir(directory))
{

/*
Check if read directory is process
directory.
*/

if( !( isProcDir(dir_entry->d_name) ) )
{

//printf("running..");

/*
A process directory was found.
*/

/*
Add to path variable name of the
process directory and then add "/"
to make path correct.
*/
strcat(path, dir_entry->d_name);
strcat(path,"/");

//printf("%s\n", path);

if ( (process_directory=opendir(path) ) == NULL)
{
printf("Couldn't open process directory.");
return 1;
}
else
{
strcat(path,"stat");

if ( ( fp=fopen(path,"r") ) == NULL)
{
printf("Couldn't open process stat file.");
return 1;
}
else
{
fscanf(fp,"%s", &pid);
printf("PID: %s",pid);
fscanf(fp,"%s", &procName);
printf("\t\tName: %s", procName);
fscanf(fp,"%s", &state);
printf("\t\tState: %s\n", state);

fclose(fp);
}

}

closedir(process_directory);

strcpy(path,"");
strcat(path,"/proc/");

}

}

closedir(directory);

}

[/code]

Thank you,
John
 
T

Tydr Schnubbis

I'm not a linux programmer, but I found one thing that can make things
not work.

Hi i have got quite strange problem. I wrote programme which shows all
runnign processes. This info is get from /proc dir. When a dir that is
process dir is found stat file is read and pid, name and state are get
from it. The thing is that on my machine every time I run it, it gives
different results. Sometimes it shows nothing - most of the times.
Sometimes it shows info about 4 processes. Sometimes it works
correctly. I don't now whats wrong, I 've tried to find the mistake,
but I could'n. I begginer programmer and I don't know how to cope with
this problem. Please help me!

Here is the code:

Code:
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <dirent.h>
#include <stdlib.h>

int isNum(char );
int isProcDir(char * );
int showRunningProcesses();

int main()
{

	showRunningProcesses();

	return 0;

}

/*

Function indicates if char given in data variable is number.
If it is it returns 0. If it is not a number it returns 1.

*/
int isNum(char data)
{

	switch(data)
	{
		case '0': return 0;
		case '1': return 0;
		case '2': return 0;
		case '3': return 0;
		case '4': return 0;
		case '5': return 0;
		case '6': return 0;
		case '7': return 0;
		case '8': return 0;
		case '9': return 0;
		default : return 1;
	}

}

/*

Function indicates if char given by *path pointer
is process dir (in /proc file system). If it is it
returns 0. If it is not it returns 1.

*/

int isProcDir(char *path)
{
	struct stat st;
	int i;
	int path_length;

	lstat(path, &st);
	path_length = strlen(path);

	//printf("running.. %s\n", path);
	//printf("%o", st.st_mode);
	if (S_ISDIR(st.st_mode))
		return 1;
	else if(S_ISLNK(st.st_mode))
		return 1;
	else if(S_ISCHR(st.st_mode))
		return 1;
	else if(S_ISBLK(st.st_mode))
		return 1;
	else if(S_ISFIFO(st.st_mode))
		return 1;
	else if(S_ISSOCK(st.st_mode))
		return 1;
	else if(S_ISREG(st.st_mode))
		return 1;
	else
	{
		//printf("path: %s \n", path);
		//fprintf(stderr, "found");


		for(i=0; i<path_length; i++)
		{
			if (isNum(path[i]))
			{
				return 1;
			}
		}

		return 0;
	}

}

int showRunningProcesses()
{

	int i;
	DIR *directory, *process_directory;
	FILE *fp;
	struct dirent *dir_entry;
	char *path = (char *)malloc(50);[/QUOTE]

If this is C code, you don't need to cast the return value of malloc. 
And since you never change the size of the buffer, you can just do this 
instead, and then you can remove the first strcat or strcpy too:

char path[50] = "/proc/";[QUOTE]
char *name;
	char pid[10], procName[15], state[5];

	strcat(path,"/proc/");[/QUOTE]

strcat won't work on uninitialized strings, use strcpy instead.[QUOTE]
if( ( directory=opendir(path) ) == NULL )
	{
		fprintf(stderr,	"Couldn't open /proc dir.");
		return 1;

	}

	while(dir_entry=readdir(directory))
	{

		/*
		Check if read directory is process
		directory.
		*/

		if( !( isProcDir(dir_entry->d_name) ) )
		{

		//printf("running..");

		/*
		A process directory was found.
		*/

		/*
		Add to path variable name of the
		process directory and then add "/"
		to make path correct.
		*/
		strcat(path, dir_entry->d_name);
		strcat(path,"/");

		//printf("%s\n", path);

		if ( (process_directory=opendir(path) ) == NULL)
		{
			printf("Couldn't open process directory.");
			return 1;
		}
		else
		{
			strcat(path,"stat");

			if ( ( fp=fopen(path,"r") ) == NULL)
			{
				printf("Couldn't open process stat file.");
				return 1;
			}
			else
			{
				fscanf(fp,"%s", &pid);
				printf("PID: %s",pid);
				fscanf(fp,"%s", &procName);
				printf("\t\tName: %s", procName);
				fscanf(fp,"%s", &state);
				printf("\t\tState: %s\n", state);

				fclose(fp);
			}

		}

		closedir(process_directory);

		strcpy(path,"");
		strcat(path,"/proc/");[/QUOTE]

strcpy(path,"") is the same as doing path = '\0'.  Even better, just 
delete that line, and just do strcpy(path,"/proc/"). You could also do 
path[6] = '\0' instead.[QUOTE]
}
		
	}
	
	closedir(directory);

}

Thank you,
John
 
M

msigwald

There is nothing wrong with ignoring the result of a function. That has
no effect whatsoever in the resulting behavior of a program, provided
it was intentionally desgined to do so.
 
K

Keith Thompson

There is nothing wrong with ignoring the result of a function. That has
no effect whatsoever in the resulting behavior of a program, provided
it was intentionally desgined to do so.

Please read <http://cfaj.freeshell.org/google/> and follow its advice.

Whether ignoring the result of a function is an error depends on the
circumstances. In the posted program, the function
showRunningProcesses() is declared to return an int, and in fact it
returns a value of 1 to indicate an error. It doesn't make sense to
do that and then ignore the result in the only place it's called.

Something else I just noticed is that, though it returns 1 to indicate
an error, it just falls off the end if there's no error. If it
succeeds, an attempt to use the returned value will invoke undefined
behavior. The solution is to explicitly "return 0;" on success.

The main program should probably do an "exit(EXIT_SUCCESS);" if the
function succeeds, and an "exit(EXIT_FAILURE);" if it fails.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,581
Members
45,056
Latest member
GlycogenSupporthealth

Latest Threads

Top