I would like to get the process memory on qnx. On a shell,I can get the result using the command showmem -P pid. In c I open a pipe for the command but then I would like to parse the output of the command but I don't know how is it done.
int main()
{
pid_t self;
FILE *fp;
char *command;
self=getpid();
sprintf(command,"showmem -P %d",self);
fp = popen(command,"r");
// Then I want to read the elements that results from this command line
}
Your idea with the popen and showmem is feasible. You just have to parse the result from the popen() in order to extract the memory information.
Here is an example, assuming you don't have shared objects:
int main(int argc, char *argv[]) {
pid_t self;
FILE *fp;
char command[30];
const int MAX_BUFFER = 2048;
char buffer[MAX_BUFFER];
char* p;
char* delims = { " ," };
int memory[] = {-1, -1, -1, -1, -1 };
int valueindex = -1;
int parserindex = 0;
self = getpid();
sprintf(command, "showmem -P %d", self);
fp = popen(command, "r");
if (fp) {
while (!feof(fp)) {
if (fgets(buffer, MAX_BUFFER, fp) != NULL) {
p = strtok( buffer, delims );
while (p != NULL) {
if (parserindex >=8 && parserindex <= 13) {
memory[++valueindex] = atoi(p);
}
p = strtok(NULL, delims);
parserindex +=1;
}
}
}
pclose(fp);
}
printf("Memory Information:\n");
printf("Total: %i\n", memory[0]);
printf("Code: %i\n", memory[1]);
printf("Data: %i\n", memory[2]);
printf("Heap: %i\n", memory[3]);
printf("Stack: %i\n", memory[4]);
printf("Other: %i\n", memory[5]);
return EXIT_SUCCESS;
}
This program generates the following output:
Memory Information:
Total: 851968
Code: 741376
Data: 24576
Heap: 73728
Stack: 12288
Other: 0
Related
I'm trying to read a file and store its content in a variable, here's my code:
#define _BSD_SOURCE
#include <stdio.h>
#include <sys/stat.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
// CEK ROUTER MODEL
char* router_model;
char* model() {
char filename[] = "/tmp/cpuinfo";
char* key = "system type";
char* value;
FILE *file = fopen(filename, "r");
if (file != NULL) {
char line[1000];
while (fgets(line, sizeof line, file) != NULL) /* read a line from a file */ {
//fprintf(stdout, "%s", line); //print the file contents on stdout.
if (strncmp(line, key, strlen(key)) == 0) {
char* value = strchr(line, ':');
value += 2;
router_model = strdup(value);
break; // once the key has been found we can stop reading
}
}
fclose(file);
}
else {
perror(filename); //print the error message on stderr.
}
return router_model;
}
// TULIS SERIAL NUMBER KE FILE
char tulis(char p[100]) {
// Write a serial number to a file
char sn[30];
char encrypt_sn[300];
printf("Serial Number:\n");
scanf("%s", sn);
FILE *f = fopen("/tmp/halo/fsn-55cfc8770b69cc07268fae7f25ee444c", "w");
if (f == NULL) {
printf("Error opening file!\n");
exit(1);
}
fprintf(f,"Serial Number: %s", sn);
fclose(f);
sprintf(encrypt_sn, "ccrypt -e /tmp/halo/fsn-55cfc8770b69cc07268fae7f25ee444c -K %s", p);
system(encrypt_sn);
system("mv /tmp/halo/fsn-55cfc8770b69cc07268fae7f25ee444c.cpt /tmp/halo/fsn-55cfc8770b69cc07268fae7f25ee444c");
printf("Serial number is saved in /tmp/halo/fsn-55cfc8770b69cc07268fae7f25ee444c\n");
return 0;
}
// BACA SERIAL NUMBER & SIMPAN DALAM SEBUAH VARIABLE
char baca(char p[100]) {
// Store the serial number from a file in a variable
char line[50];
char decrypt_sn[300];
char key[30] = "Serial Number";
char *serial_number;
if( access( "/tmp/halo/fsn-55cfc8770b69cc07268fae7f25ee444c", F_OK ) != -1 ) {
system("cp /tmp/halo/fsn-55cfc8770b69cc07268fae7f25ee444c /tmp/");
system("mv /tmp/fsn-55cfc8770b69cc07268fae7f25ee444c /tmp/fsn-55cfc8770b69cc07268fae7f25ee444c.cpt");
sprintf(decrypt_sn, "ccrypt -d /tmp/fsn-55cfc8770b69cc07268fae7f25ee444c.cpt -K %s", p);
system(decrypt_sn);
FILE *file = fopen("/tmp/fsn-55cfc8770b69cc07268fae7f25ee444c", "r");
if (file == NULL) {
printf("Error opening file!\n");
exit(1);
}
while (fgets(line, sizeof line, file) != NULL) /* read a line from a file */ {
//fprintf(stdout, "%s", line); //print the file contents on stdout.
if (strncmp(line, key, strlen(key)) == 0) {
char* value = strchr(line, ':');
value += 2;
serial_number = strdup(value);
break; // once the key has been found we can stop reading
}
}
fclose(file);
//printf("Your hardware serial number is: (%s)\n", serial_number);
remove("/tmp/fsn-55cfc8770b69cc07268fae7f25ee444c");
}
else {
printf("fsn not found\n");
return -1;
}
return 0;
}
int main(int argc, char* argv[]) {
char *r;
char *del;
char *decrypt;
int ret;
char input[30];
char *p;
char *original_sn;
p = "MmI4MTUxM2FjMjRlMDkzYmRkZGQyMjcwMjQ4OWY3MDAwNGZiYTM0MWNkZGIxNTdlYzAxN2";
//tulis(p);
original_sn = baca(p);
printf("SN: %s\n", original_sn);
return 0;
}
The file is /tmp/halo/fsn-55cfc8770b69cc07268fae7f25ee444c and the content of that file is Serial Number: 1866203214226041 and original_sn should output 1866203214226041. However when I run that code I get:
test.c: In function ‘main’:
test.c:105:14: warning: assignment makes pointer from integer without a cast [-Wint-conversion]
original_sn = baca(p);
^
SN: (null)
How do I fix it ?
This happens because your baca function returns a char, whereas you are assigning its return value to a char *. Maybe you wanted to use a char variable.
If function baca can change the contents of the memory block pointed by the input argument:
Change this:
char* p = "MmI4MTUxM2FjMjRlMDkzYmRkZGQyMjcwMjQ4OWY3MDAwNGZiYTM0MWNkZGIxNTdlYzAxN2";
To this:
char p[] = "MmI4MTUxM2FjMjRlMDkzYmRkZGQyMjcwMjQ4OWY3MDAwNGZiYTM0MWNkZGIxNTdlYzAxN2";
If function baca cannot change the contents of the memory block pointed by the input argument:
Change this:
char baca(char p[])
To this:
char baca(const char* p)
In baca you are allocating initialised memory using strdup:
serial_number = strdup(value);
, then you do nothing with that.
It is clear that you think that the function returns a pointer to that memory so you can print it's content. However, it is not what you are doing. Because all your baca function is doing is returning a value indecating if it sucseede (0) or not (-1). And you are jut ignoring that pointer and leaving some wasted unused memory allocated by your prog.
Their are 2 methodes to fix your code:
Method1 : returning the serial_number
char* baca(const char* p) {
// Store the serial number from a file in a variable
char line[50];
char decrypt_sn[300];
char key[30] = "Serial Number";
char *serial_number=NULL;
if( access( "/tmp/halo/fsn-55cfc8770b69cc07268fae7f25ee444c", F_OK ) != -1 ) {
system("cp /tmp/halo/fsn-55cfc8770b69cc07268fae7f25ee444c /tmp/");
system("mv /tmp/fsn-55cfc8770b69cc07268fae7f25ee444c /tmp/fsn-55cfc8770b69cc07268fae7f25ee444c.cpt");
sprintf(decrypt_sn, "ccrypt -d /tmp/fsn-55cfc8770b69cc07268fae7f25ee444c.cpt -K %s", p);
system(decrypt_sn);
FILE *file = fopen("/tmp/fsn-55cfc8770b69cc07268fae7f25ee444c", "r");
if (file == NULL) {
printf("Error opening file!\n");
exit(1);
}
while (fgets(line, sizeof line, file) != NULL) /* read a line from a file */ {
//fprintf(stdout, "%s", line); //print the file contents on stdout.
if (strncmp(line, key, strlen(key)) == 0) {
char* value = strchr(line, ':');
if(value!=NULL){/*testing the return value for erros so you prog doesn't cruch*/
value += 2;
serial_number = strdup(value);
}
/*in case off erreor you can choose one of two options:*/
/*optinon1: print an error mesage then kill your prog*/
else{
printf("Error: corrupted file!\n");
exit(1);
}
/*option 2: removing the else part your baca then will return NULL and the calling code should understand that an error has occured*/
break;
}
}
fclose(file);
remove("/tmp/fsn-55cfc8770b69cc07268fae7f25ee444c");
}
else {
printf("fsn not found\n");
}
return serial_number;
}
int main(int argc, char* argv[]) {
char *r;
char *del;
char *decrypt;
int ret;
char input[30];
char *p;
char *original_sn;
p = "MmI4MTUxM2FjMjRlMDkzYmRkZGQyMjcwMjQ4OWY3MDAwNGZiYTM0MWNkZGIxNTdlYzAxN2";
//tulis(p);
original_sn = baca(p);
if(original_sn!=NULL){
printf("SN: %s\n", original_sn);
free(original_sn);/*you should free the memory allocated by strdup once you are done using it.*/
}
else{
printf("An error has occured\n");
}
return 0;
}
Method2 : pass by reference
char baca(const char* p, char **serial_number) {
// Store the serial number from a file in a variable
char line[50];
char decrypt_sn[300];
char key[30] = "Serial Number";
char ret = 0;/*the return value 0 means no error.*/
if( access( "/tmp/halo/fsn-55cfc8770b69cc07268fae7f25ee444c", F_OK ) != -1 ) {
system("cp /tmp/halo/fsn-55cfc8770b69cc07268fae7f25ee444c /tmp/");
system("mv /tmp/fsn-55cfc8770b69cc07268fae7f25ee444c /tmp/fsn-55cfc8770b69cc07268fae7f25ee444c.cpt");
sprintf(decrypt_sn, "ccrypt -d /tmp/fsn-55cfc8770b69cc07268fae7f25ee444c.cpt -K %s", p);
system(decrypt_sn);
FILE *file = fopen("/tmp/fsn-55cfc8770b69cc07268fae7f25ee444c", "r");
if (file == NULL) {
printf("Error opening file!\n");
exit(1);
}
while (fgets(line, sizeof line, file) != NULL) /* read a line from a file */ {
//fprintf(stdout, "%s", line); //print the file contents on stdout.
if (strncmp(line, key, strlen(key)) == 0) {
char* value = strchr(line, ':');
if(value!=NULL){/*testing the return value for erros so you prog doesn't cruch*/
value += 2;
*serial_number = strdup(value);
}
/*in case off erreor you can choose one of two options:*/
else{
/*optinon1: print an error mesage then kill your prog*/
/*option 2: making the return value non 0 and the calling code should understand that an error has occured*/
#define OPTION1
#ifdef OPTION1
printf("Error: corrupted file!\n");
exit(1);
#else
ret=-2; //to used this option comment out #define OPTION1
#endif
}
break;
}
}
fclose(file);
remove("/tmp/fsn-55cfc8770b69cc07268fae7f25ee444c");
}
else {
printf("fsn not found\n");
ret=-1;
}
return ret;
}
int main(int argc, char* argv[]) {
char *r;
char *del;
char *decrypt;
int ret;
char input[30];
char *p;
char *original_sn=NULL;
p = "MmI4MTUxM2FjMjRlMDkzYmRkZGQyMjcwMjQ4OWY3MDAwNGZiYTM0MWNkZGIxNTdlYzAxN2";
//tulis(p);
switch(baca(p,&original_sn))
{
case 0: //evrything is fine
printf("SN: %s\n", original_sn);
free(original_sn);
break;
case -1:/* handle each error as you should*/
case -2:
default:
printf("An error has occured\n");
}
return 0;
}
Hope this helps. :).
I have looked for an answer to my question for almost two days and tried every solution suggested to no avail.
I am trying to access a file through a linux terminal using my C Program.
I want to run popen() to do this.
The command I want to run in popen() is : grep -o %s /usr/share/dict/words
Where %s is a variable word that changes each iteration. I have tried using pointers, arrays, and alternative functions such as asprintf() / snprintf()
Here is the code I have right now:
char *message = (char *)malloc(500);
strcpy(message, "grep -n");
printf("%s", message);
strcat(message, "hello");
printf("%s", message);
strcat(message, " /usr/share/dict/words"); // SEG FAULT OCCURS HERE
printf("%s", message);
I would then pass this to popen.
I have also tried initializing as: char message[500] and this returns the same error in the same spot.
Here is my full code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "caeserheader.h"
int main( int argc, char *argv[]){
char *inputfile;
int n = 0;
int shiftamount = 0;
//Determine amount of arguments
if(argc == 2){
inputfile = argv[1];
}
else if(argc == 3){
inputfile = argv[1];
n = atoi(argv[2]);
shiftamount = n * (-1) ;
}
else{
printf("Please enter a proper number of arguments.");
return -1;
}
//OPENS INPUT FILE
FILE *input = fopen(inputfile, "r");
if(input == NULL){
printf("\n FILE NOT FOUND.");
perror("fopen");
return -1;
}
//RESERVES MEMORY AND GRABS STRING
fseek(input, 0L, SEEK_END);
long Tsize = ftell(input);
rewind(input);
char *inputtext;
inputtext = calloc( 1, Tsize+1);
//ERROR CHECKING
if(!inputtext){
fclose(input), printf("MEMORY FAILED.");
}
if(1!=fread( inputtext, Tsize, 1, input)){
fclose(input), free(inputtext), printf("READ FAIL.");
}
//CREATES DECRYPTED STRING
char newletter;
char *newstring;
int i;
//WITH GIVEN NUMBER OF SHIFTS
if(argc == 3){
newstring = malloc(Tsize + 1);
for(i=0; i<Tsize; i++){
newletter = shift(inputtext[i], shiftamount);
newstring[i] = newletter;
}
}
//WITHOUT GIVEN NUMBER OF SHIFTS
if(argc == 2){
char *message = (char *)malloc(500); //SEG FAULT SOMEWHERE HERE?
// strcpy(message, "grep -n");
// printf("%s", message);
//strcat(message, "hello");
// printf("%s", message);
// strcat(message, "/usr/share/dict/words");
//printf("%s", message);
// word = strtok(inputtext," ,.-!?\n");
// int i;
//for(i=0; i<10; i++){
//word = strtok(NULL," ,.-!?\n");
//printf("\n%s", word);
//}
// if(( fp = popen(message, "r")) == NULL){
//perror("No file stream found.");
//return -1;
// }
// else {
// pclose(fp);
// printf("FOUND.");
// }
}
// PUTS DECRYPTED STRING IN NEW FILE
char copiedname[100];
strcpy(copiedname, inputfile);
strcat(copiedname, ".dec");
FILE *newfile = fopen(copiedname, "w");
fputs(newstring, newfile);
// free(newstring);
fclose(input);
fclose(newfile);
return 0;
}
You have set inputfile to argv[1] and later you have used strcat to append to it. Don't do this. You don't own argv.
The strcat function appends a copy of the source string to the destination string, and then returns a pointer to the destination string. It does not "add two strings and return the result" which is how you seem to be using it.
so I have a method that moves a string from a file to a char array in c, but when I try to print it out I am getting a weird output in the terminal that looks like a bunch of for each char spot and each box has 4 0's and 1's.
Here's the my code:
int main(int argc, char** argv){
if(argc != 3){
printf("not valid # of arguments");
return 1;
}
struct stat info;
int status;
status = stat(argv[2], &info);
if(status != 0){
printf("Error, errno = %d\n", errno);
return 1;
}
//command line argument is file
if(S_ISREG (info.st_mode)){
printf("%s is a file \n", argv[2]);
char *string1;
string1 = getFileString(argv[2]);
printf("string in file is %s \n", string1);
free(string1);
return 0;
}
if(S_ISDIR(info.st_mode)){
printf("%s is a directory \n", argv[2]);
openDirRec(argv[2]);
//what to do if command line argument is directory
}
return 0;
}
char* getFileString(char *fileName){
FILE* qp;
qp = fopen(fileName, "r");
char ch;
struct stat st;
if(stat(fileName, &st) != 0) {
return NULL;
}
/*int sizeCheck = 0;
while((ch=fgetc(qp))!=EOF){
sizeCheck++;
}
*/
int sizeCheck = st.st_size;
if(sizeCheck == 0){
return NULL;
}
else{
//fseek(qp, SEEK_SET, 0);
char *fileString;
fileString = (char*)malloc(sizeof(char) * sizeCheck + 1);
memset(fileString, 0, sizeCheck + 1);
//rewind(qp);
int count = 0;
while((ch=fgetc(qp)!=EOF)){
fileString[count] = ch;
count++;
}
printf("%s\n", fileString);
fileString[sizeCheck] = '\0';
fclose(qp);
return fileString;
}
}
This line is the culprit.
while((ch=fgetc(qp)!=EOF))
Due to operator precedence, that is equivalent to:
while(ch = (fgetc(qp)!=EOF) )
what you need is a little rearrangement of the parantheses.
while((ch=fgetc(qp)) != EOF)
in my program, I provide a directory which contains text files. Each of the text files contain a few hundred lines in the following format
Username,Password,BloodType,Domain,Number
I then create a thread for each file in the directory which will merge-sort(by number) these lines into the array char* text_lines[6000];
I can't figure out why I'm getting a segmentation fault because I'm getting different output on every run.
Heres my code:
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <sys/types.h>
#include <dirent.h>
#include <string.h>
void store_line(char* line);
void* my_merge_sort(void* file);
char** text_lines;
int main(int argc, char* argv[])
{
if(argc != 2)
{
fprintf(stderr, "usage: ./coolsort <directory>\n");
}
else
{
text_lines = malloc(6000 * sizeof(char*));
DIR* the_directory;
int filecount = 0;
struct dirent* directory_files[50];
if((the_directory = opendir(argv[1])) != NULL)
{
//make a list of the files in the directory
while((directory_files[filecount++] = readdir(the_directory))) ;
filecount--;
//<<<DEBUGGING INFO>
int i;
fprintf(stderr,"there are %i files in %s:\n", filecount, argv[1]);
for(i = 0; i < filecount; i++)
{
fprintf(stderr, "%s\n",directory_files[i]->d_name);
}
char cwd[512];
chdir(argv[1]);
getcwd(cwd, sizeof(cwd));
fprintf(stderr, "the CWD is: %s\n", cwd);
//<DEBUGGING INFO>>>
//lets start some threads
pthread_t threads[filecount-2];
int x = 0;
for(i = 0; i < (filecount); i++ )
{
if (!strcmp (directory_files[i]->d_name, "."))
continue;
if (!strcmp (directory_files[i]->d_name, ".."))
continue;
pthread_create(&threads[x++], NULL, my_merge_sort, (void*)directory_files[i]->d_name);
}
//do stuff here
//
}
else
{
fprintf(stderr, "Failed to open directory: %s\n", argv[1]);
}
}
}
void* my_merge_sort(void* file)
{
fprintf(stderr, "We got into the function!\n");
FILE* fp = fopen(file, "r");
char* buffer;
char* line;
char delim[2] = "\n";
int numbytes;
//minimize I/O's by reading the entire file into memory;
fseek(fp, 0L, SEEK_END);
numbytes = ftell(fp);
fseek(fp, 0L, SEEK_SET);
buffer = (char*)calloc(numbytes, sizeof(char));
fread(buffer, sizeof(char), numbytes, fp);
fclose(fp);
//now read the buffer by '\n' delimiters
line = strtok(buffer, delim);
fprintf(stderr, "Heres the while loop\n");
while(line != NULL)
{
store_line(line);
line = strtok(buffer, NULL);
}
free(buffer);
}
void store_line(char* line)
{
//extract the ID.no, which is the fifth comma-seperated-token.
char delim[] = ",";
char* buff;
int id;
int i;
strtok(line, delim);
for(i = 0; i < 3; i++)
{
strtok(line, NULL);
}
buff = strtok(line, NULL);
id = atoi(buff);
//copy the line to text_lines[id]
memcpy(text_lines[id], line, strlen(line));
}
edit: I checked to make sure that it would fit into the initial array, and found that the highest ID is only 3000;
You use of strtok() is wrong:
line = strtok(buffer, NULL);
should be
line = strtok(NULL, delim);
Another mistakes should be fixed similarly.
The elements of text_lines are uninitialized:
text_lines = malloc(6000 * sizeof(char*));
this allocated 6000 pointers to char, but none of these pointers are initialized.
I'm having issues with fprintf in my RPC program. It opens a file but won't read the content into a file. It will print the content using printf but fprint leaves the file blank. How do I fix this issue? Thank you
#include <rpc/rpc.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include"lab5.h"
char * filename(char *str)
{
file = str;
printf("filename = %s\n",file);
return file;
}
int writefile(char *content)
{
FILE *fp1;
fp1 = fopen("recfile.txt", "w");
if(fp1 == NULL)
{
printf("File can't be created\n");
return 0;
}
printf("%s\n",content);
int i = fprintf(fp1, "%s", content);
printf("i = %d\n",i);
close(fp1);
return 1;
}
int findwordcount(char* searchword)
{
char *grep;
int count;
int status;
FILE *fp;
grep = (char*)calloc(150, sizeof(char));
strcpy(grep, "grep -c \"");
strcat(grep, searchword);
strcat(grep, "\" ");
strcat(grep, "recfile.txt");
strcat(grep, " > wordcount.txt");
status = system(grep);
printf("status = %d\n", status);
if(status != 0)
{
count = 0;
}
else
{
fp = fopen("wordcount.txt", "r");
fscanf(fp, "%d", &count);
printf("count = %d\n", count);
}
return count;
}
In your function int writefile (char *content); you are currently using close(fp1);. Instead to close the file, you should fclose(fp1) instead.