Linux programme - different results each run

Discussion in 'C Programming' started by ulyses@autograf.pl, Dec 11, 2005.

  1. Guest

    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
     
    , Dec 11, 2005
    #1
    1. Advertising

  2. writes:
    > 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(), declared in <ctype.h>.

    > /*
    >
    > 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
    >


    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
     
    Keith Thompson, Dec 11, 2005
    #2
    1. Advertising

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

    wrote:
    > 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);[/color]
    
    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/";[color=blue]
    > 	char *name;
    > 	char pid[10], procName[15], state[5];
    > 
    > 	strcat(path,"/proc/");[/color]
    
    strcat won't work on uninitialized strings, use strcpy instead.[color=blue]
    > 
    > 	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/");[/color]
    
    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.[color=blue]
    > 		
    > 		}
    > 		
    > 	}
    > 	
    > 	closedir(directory);
    > 
    > }
    > 
    > 
    >
    > Thank you,
    > John
    >
     
    Tydr Schnubbis, Dec 11, 2005
    #3
  4. Guest

    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.
     
    , Dec 11, 2005
    #4
  5. "" <> writes:
    > 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.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
     
    Keith Thompson, Dec 11, 2005
    #5
  6. fangshi Guest

    Delete S_ISDIR(st.st_mode)) .
     
    fangshi, Dec 12, 2005
    #6
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Qiangning Hong
    Replies:
    12
    Views:
    715
    Grant Edwards
    Jul 12, 2006
  2. Kerry, Richard
    Replies:
    2
    Views:
    414
    Piet van Oostrum
    Jul 13, 2006
  3. =?Utf-8?B?Ymlj?=
    Replies:
    1
    Views:
    367
    Alexey Smirnov
    May 5, 2007
  4. Igor Nn
    Replies:
    7
    Views:
    445
    Johnny Morrice
    May 28, 2011
  5. fmbright
    Replies:
    8
    Views:
    218
Loading...

Share This Page