(Ubuntu) C Computing CPU usage using /proc/stat - c

I'm trying to write a program in C that will read from /proc/stat, wait a second, then read from /proc/stat again a second later, then do some math to find the "current" CPU usage, as well as the usage for each core. I think that the easiest way to do this is to save the results of /proc/stat to a file, as well as a second file for the second "state" of /proc/stat. I would then read from it and calculate from there. For some reason, though, I have no clue why neither of my files are being created.
int main() {
FILE *state0;
FILE *state1;
state0 = fopen("/proc/stat", "w+");
delay();
state1 = fopen("/proc/stat", "w+");
char *con0 = malloc(500);
fprintf(state0, con0);
fclose(state0);
fclose(state1);
return 0;
}
And help is greatly appreciated

The issue is, when you try to save a file by calling:
fprintf(state0, con0);
You're trying to write the memory allocated at con0 to state0, which is a pointer to /proc/stat.
This of course fails because you don't have permissions to write to /proc/stat, which you shouldn't.
To open these files for reading, as tadman mentioned, you want to open the files in "r" mode:
FILE *state0;
FILE *state1;
state0 = fopen("/proc/stat", "r");
delay();
state1 = fopen("/proc/stat", "r");
What you'd want to do is create a separate file, for example:
FILE *newfile;
newfile = fopen("/tmp/procstattemp", "w");
and write to this file using:
fprintf(newfile, con0);
Also, you're allocating memory for con0, but you haven't written anything to this buffer.
If you want to save /proc/stat to a file, you'll need to read the file and copy it into con0 before writing your temporary file.
See also:
http://www.cplusplus.com/reference/cstdio/fprintf/
http://www.cplusplus.com/reference/cstdio/fopen/

Related

Why do I have NUL line in my written file using fopen fclose c++ linux?

I have some C code running on a linux OS into a portable device. I'm using a VRmagic system, similar to BeagleBone etc...).
In this code, I'm using the following function to write results inside a txt file.
//globale definition
FILE *logfile;
const char *logpath = "/MY_DEVICE/log.txt";
const char *main_folder_result_path = "/MEASUREMENT_RESULTS/";
const char *all_measurement_results_file_name = "all_computation_data.txt";
void save_to_log_file(const char *logpath,const char *message){
#ifdef savealllog
logfile = fopen(logpath,"a"); //logpath = "/MY_DEVICE/log.txt";
fprintf(logfile,"%s",message);
fclose(logfile);
#endif
#ifdef printalloutput
printf("%s",message);
#endif
}
void append_all_measurement_file(){
char buff[255];
char filename[255];
save_to_log_file(logpath," Appending all measurement file...");
sprintf(filename,"%s%s",main_folder_result_path,all_measurement_results_file_name);
//here after we create the header if the file does not exist already
FILE *pFile_all_measurement_results = fopen(filename, "r"); //lets try to read the file
if (pFile_all_measurement_results == NULL){ // if file does not exist
pFile_all_measurement_results = fopen(filename, "w");
fprintf(pFile_all_measurement_results,"date-time S_type Part_name batch count abs value_1 value_2 value_3 value_4\n");
fclose(pFile_all_measurement_results);
}
else{
fclose(pFile_all_measurement_results); //if file does exist then we have to close it here
}
//here after we are going to write results
pFile_all_measurement_results = fopen(filename, "a"); //lets open the file in append mode
fprintf(pFile_all_measurement_results,"%s %s %s %d %d %d ",dateandtimetps.dt,measurement_type_str,Name_Str, batch_number,count_number,absolute_measurement_number);
fprintf(pFile_all_measurement_results,"%.03f ", value_1);
fprintf(pFile_all_measurement_results,"%.03f ", value_2);
fprintf(pFile_all_measurement_results,"%.03f ", value_3);
fprintf(pFile_all_measurement_results,"%.03f\n", value_4); //(there are a bit more in reality.....)
fclose(pFile_all_measurement_results); //we can now close the file
save_to_log_file(logpath,"done.\n");
}
99.9% of the time all is OK.
But, randomly, I do have some NUL character in my file, and this happen when I turn OFF my system.
Looks like the file has not been closed properly or something like that for some reason.....
When I get my txt file, and open it with notepad++ on my computer, it does look like the following:
I can confirm that the device has been turned OFF between line 172 and line 174.
Many thanks for help
Just closing a file on Unix systems does not implicate the contents are instantly written to disk; usually buffering/caching is enabled.
To make sure the contents are written you can use sync() immediately after a write and/or close operation, which will minimize the risk of lost updates.
Additionally I recommend to use a journaling filesystem like ext4 (which may not be an option on external drives like USB pens, but is strongly recommend for all system and data partitions). This will not save you from data loss in case of a power failure or crash, but will avoid inconsistencies/partial writes like you are experiencing.

Reading a File in C: different behavior for "r" and "a+" flags

I want to open a file, read its contents, and then append a line to the file. I thought I should use the "a+" flag for the task.
I have a function which opens a file and returns a pointer to this file.
FILE* open_weekly_disk_file(char* filename){
FILE* weekly_log;
weekly_log = fopen(filename, "a+");
//weekly_log = fopen(filename, "r");
if(! weekly_log){
printf("The attempt to open the weekly log failed!\n");
return NULL;
} else{
return weekly_log;
}
}
Then I have a function which calls the function above and uses scanf to read contents from the file:
void sample_function(char* filename){
FILE* log;
char token[100], current_read[100];
int limit;
log = opened_weekly_disk_file(filename);
// The problem happens here
for(limit=0; limit < TOKEN_NUMBER; limit++){
if(fscanf(log, "%s%s", &token, &current_read) == 2){
printf("%s %s\n", token, current_read);
}
}
...
}
This code works when I use:
weekly_log = fopen(filename, "r");
But does not work when I change the "r" flag to "a+". I get a Segmentation fault right before the for loop.
That is because the mode spec "a" opens a file for appending, with the file pointer at the end. If you try to read from here, there is no data since the file pointer is at EOF. You should open with "r+" for reading and writing. If you read the whole file before writing, then the file pointer will be correctly positioned to append when you write more data.
If this is not enough, please explore ftell() and fseek() functions.
from this SO QA
from the man page:
a+
Open for reading and appending (writing at end of file). The file is
created if it does not exist. The initial file position for reading is
at the beginning of the file, but output is always appended to the end
of the file.
Answer:
There is just one pointer which initially is at the start of the file
but when a write operation is attempted it is moved to the end of the
file. You can reposition it using fseek or rewind anywhere in the file
for reading, but writing operations will move it back to the end of
file.
So, the problem is not the fact that the file is opened in append mode, because it is not, as far as reading from it is concerned.
The problem lies in what your code does in those three dots
log = opened_weekly_disk_file(filename);
...
The code quite probably writes to the file, making the file cursor move to the end of it before the reading occurs.

Does fprintf() always write over what's already in a file?

Say I have the following:
FILE *fp1 = fopen("file.txt", "w");
fprintf(fp1,"%i\n",counter);
When I run my program, it writes the counter to the file. But when I run the program again and end up with a different counter, instead of writing that counter below the first one, it just replaces the first one. Is there a way to make it not just replace whats already in the file each time I run the program?
Set the file access mode to "a" (append) as shown below:
FILE *fp1 = fopen("file.txt", "a");

File processing in c?

I have been given a raw file that holds several jpg images. I have to go through the file, find each jpg image, and put those images each in a separate file. So far I have code that can find each where each image begins and ends. I also have written code that names several file names I can use to put the pictures in. It is an array: char filename[] , that holds the names: image00.jpg - image29.jpg .
What I cannot figure out is how to open a file every time I find an image, an then close that file and open a new one for the next image. Do I need to use fwrite()? Also, each image is in blocks of 512 bytes, so I only have to check for a new image every 512 bytes once I find the first one. Do I need to add that into fwrite?
So, to summarize my questions, I don't understand how to use fwrite(), if that is what I should be using to write to these files.
Also, I do not know how to open the files using the names I have already created.
Thanks in advance for the help. Let me know if I need to post any other code.
Use fopen(rawfilename, "rb"); to open the raw file for reading. and fread to read from it.
Use fopen(outfilename, "wb"); to open output file for writing and fwrite to write to it.
As mentioned in my comment, you are assigning char *[] to char*, use char filename[] = "image00.jpg"; instead.
Don't forget to close each file after you finish its processing (r/w) (look at fclose() at the same site of other links)
Decide how much bytes to read each time by parsing the jpeg header. Use malloc to allocate the amount of bytes needed to be read, and remember, for each allocation of buffer you need to free the allocated buffer later.
Pretty much any book on C programming should cover the functions you need. As MByD pointed out, you'll want to use the functions fopen(), fwrite(), and fclose().
I imagine your code may include fragments that look something like
/* Warning: untested and probably out-of-order code */
...
char **filename = {
"image00.jpg", "image01.jpg", "image02.jpg",
...
"image29.jpg" };
...
int index = 0;
const int blocksize = 512; /* bytes */
...
index++;
...
FILE * output_file = fopen( filename[index], "wb");
fwrite( output_data, 1, blocksize, output_file );
fclose(output_file);
...

C - fwrite() not outputting to file

Never used fwrite(), so I'm not sure exactly what I'm doing wrong. I'm just testing it now and all I want to do is try to write a single char out to a file until it reaches the end. The file I'm writing to is one I downloaded from my teacher's website. When I check the properties of it, the type is only listed as "file". It's supposed to just be an empty 2MB file for us to write our code to (file system lab if anyone's wondering). Here's my code:
#include <stdio.h>
#include <string.h>
int main()
{
char c;
FILE *fp;
char testing[2] = {'c'};
fp = fopen("Drive2MB", "rw");
fseek(fp, 0, SEEK_SET); //make sure pointers at beginning of file
while((c=fgetc(fp))!=EOF)
{
fwrite(testing, 1, sizeof(testing), fp);
fseek(fp, 1, SEEK_CUR); //increment pointer 1 byte
}
fclose(fp);
}
When I run this, an error message pops up saying "Debug Assertion Failed!...Expression:("Invalid file open mode",0) and prints "The program '[3896] filesystem.exe: Native' has exited with code 3 (0x3)."
You have opened the file for reading (that's what the r stands for in fopen("Drive2MB", "r");). You may not write to a file opened for reading.
You're opening it in read only mode
Use r+ for the fopen
fp = fopen("Drive2MB", "r")
your openning your file in read only
try
fp = fopen("Drive2MB", "r+");
You've opened the file for reading with the "r" part of fopen. To write to the file, you can open it in read/write mode or write mode.
// Read/write mode
fp = fopen("Drive2MB", "r+");
// Write only mode
fp = fopen("Drive2MB", "w");
I never like to use "rw" personally. When you open a file, it really should have one reason to be opened. You also do not need to call fseek to move to the start of the file and you do not need to use fseek to advance the file pointer. fopen will automatically open it to the start of the file and fwrite will automatically advance the pointer. fseek should only be used if you are "seek"ing inside of the file to get to a specific point.
In the case you've given, you would only need write ("w") mode since you are not ever reading from the file.
Use fopen r+ or w+ to open the file.
Use fflush to flush data to disk after fwrite is complete.
Use ferror to check if there is any problem with the file stream after fwrite is complete.
Check whether the disk has enough free space.
I solved the problem with 3, 4.

Resources