Value of strings different, but printing them shows the same value - c++

I am running the following code to check if a file exists or not, but when passing the string to stat, it return fail.
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
int main ()
{
struct stat statbuf;
char tmp_buf1[100];
char result [100];
char result1[100]="/root/file.sh";
strcpy(tmp_buf1,"echo $HOME/file.sh");
FILE* fp;
fp = popen(tmp_buf1,"r");
printf("Name passed is:%s\n",tmp_buf1);
fread(result,1,sizeof(result),fp);
fclose (fp);
printf("The full path is %s\n",result);
int rc = 0;
// To find out difference b/w the the strings, I am doing a strcmp, it is returning 10.
int r = strcmp(result,result1);
printf (" Return is = %d\n",r);
rc = stat(result, &statbuf);
if ( rc == -1 ) {
printf("File is NOT HERE!\n");
printf("Return Code = %d",rc);
}
else
printf("Found it !");
}
Not sure how come these strings are not same.

strcpy(tmp_buf1,"echo $HOME/file.sh");
echo ends the string it shall echo with a newline '\n', ASCII code 10. That's the difference between the two strings. Try it with
strcpy(tmp_buf1,"echo -n $HOME/file.sh");
On another note, a FILE* opened with popen ought to be closed with pclose, not with fclose.

Related

segmentation fault while reading from a file

I have a problem with the following code:
#include <iostream>
#include <stdio.h>
#include "ISBNPrefix.h"
using namespace std;
int main() {
FILE* file = NULL;
int area = 0, i = 0;
long s;
file = open("swagger.txt");
fscanf(file, "%ld", &s);
cout << s << endl;
}
and here's ISBNPrefix.cpp:
#include <iostream>
#include <stdio.h>
#include "ISBNPrefix.h"
using namespace std;
FILE* open(const char filename[]) {
FILE* file = NULL;
file = fopen("filename", "r");
if (file != NULL)
return file;
else return NULL;
}
my ISBNPrefix.h
FILE* open (const char filename[]);
And the content of swagger.txt is: 123456789
When I try to run it to test if it copies the 123456789 into my variable i get a segmentation fault!
You have problem in your function for opening a file:
FILE* open(const char filename[]) {
FILE* file = NULL;
file = fopen("filename", "r"); <-- here
it should be file = fopen(filename, "r");
Also you designed open function to return NULL if there is no file, but then you don't check its return value once you call it:
file = open("swagger.txt");
if (file == NULL) ... <-- you should check the return value
fscanf(file, "%ld", &s);
Also note that fopen and fscanf are C-style functions. Since you are using C++, there are other more convenient means how to read data from a file. Have a look at std::ifstream. Also when you work with C headers in C++, you should include their C++ wrappers: cstdio, cstdlib, etc.
You need fopen for a start. Where does ISBNPrefix.cpp come into the picture?

Get process name on specified port [duplicate]

I need a C/C++ API that allows me to list the running processes on a Linux system, and list the files each process has open.
I do not want to end up reading the /proc/ file system directly.
Can anyone think of a way to do this?
http://procps.sourceforge.net/
http://procps.cvs.sourceforge.net/viewvc/procps/procps/proc/readproc.c?view=markup
Is the source of ps and other process tools. They do indeed use proc (indicating it is probably the conventional and best way). Their source is quite readable. The file
/procps-3.2.8/proc/readproc.c
May be useful. Also a useful suggestion as posted by ephemient is linking to the API provided by libproc, which should be available in your repo (or already installed I would say) but you will need the "-dev" variation for the headers and what-not.
Good Luck
If you do not want to read from '/proc. Then you can consider writing a Kernel module which will implement your own system call. And your system call should be written so that it can obtain the list of current processes, such as:
/* ProcessList.c
Robert Love Chapter 3
*/
#include < linux/kernel.h >
#include < linux/sched.h >
#include < linux/module.h >
int init_module(void) {
struct task_struct *task;
for_each_process(task) {
printk("%s [%d]\n",task->comm , task->pid);
}
return 0;
}
void cleanup_module(void) {
printk(KERN_INFO "Cleaning Up.\n");
}
The code above is taken from my article here at http://linuxgazette.net/133/saha.html.Once you have your own system call, you can call it from your user space program.
Here you go (C/C++):
You could have found it here:
http://ubuntuforums.org/showthread.php?t=657097
Essentially, what it does is loop through all numeric folders in /proc/<pid>, and then it does a readlink on /proc/<pid>/exe, or if you want the command-line-arguments cat /proc/<pid>/cmdline
The file-descriptors open by the process are in /proc/<pid>/fd/<descriptor>, and you get the file name by doing a readlink on each symlink, e.g. readlink /proc/<pid>/fd/<descriptor>. fd can be a device, such as /dev/null, a socket, or a file, and potentially more.
#include <unistd.h>
ssize_t readlink(const char *path, char *buf, size_t bufsiz);
On success, readlink() returns the number of bytes placed in buf.
On error, -1 is returned and errno is set to indicate the error.
This is, by the way, the same that readproc.c does (or at least did).
Of course, hopefully they did it without buffer overflow possiblity.
#ifndef __cplusplus
#define _GNU_SOURCE
#endif
#include <unistd.h>
#include <dirent.h>
#include <sys/types.h> // for opendir(), readdir(), closedir()
#include <sys/stat.h> // for stat()
#ifdef __cplusplus
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdarg>
#else
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#endif
#define PROC_DIRECTORY "/proc/"
#define CASE_SENSITIVE 1
#define CASE_INSENSITIVE 0
#define EXACT_MATCH 1
#define INEXACT_MATCH 0
int IsNumeric(const char* ccharptr_CharacterList)
{
for ( ; *ccharptr_CharacterList; ccharptr_CharacterList++)
if (*ccharptr_CharacterList < '0' || *ccharptr_CharacterList > '9')
return 0; // false
return 1; // true
}
int strcmp_Wrapper(const char *s1, const char *s2, int intCaseSensitive)
{
if (intCaseSensitive)
return !strcmp(s1, s2);
else
return !strcasecmp(s1, s2);
}
int strstr_Wrapper(const char* haystack, const char* needle, int intCaseSensitive)
{
if (intCaseSensitive)
return (int) strstr(haystack, needle);
else
return (int) strcasestr(haystack, needle);
}
#ifdef __cplusplus
pid_t GetPIDbyName(const char* cchrptr_ProcessName, int intCaseSensitiveness, int intExactMatch)
#else
pid_t GetPIDbyName_implements(const char* cchrptr_ProcessName, int intCaseSensitiveness, int intExactMatch)
#endif
{
char chrarry_CommandLinePath[100] ;
char chrarry_NameOfProcess[300] ;
char* chrptr_StringToCompare = NULL ;
pid_t pid_ProcessIdentifier = (pid_t) -1 ;
struct dirent* de_DirEntity = NULL ;
DIR* dir_proc = NULL ;
int (*CompareFunction) (const char*, const char*, int) ;
if (intExactMatch)
CompareFunction = &strcmp_Wrapper;
else
CompareFunction = &strstr_Wrapper;
dir_proc = opendir(PROC_DIRECTORY) ;
if (dir_proc == NULL)
{
perror("Couldn't open the " PROC_DIRECTORY " directory") ;
return (pid_t) -2 ;
}
// Loop while not NULL
while ( (de_DirEntity = readdir(dir_proc)) )
{
if (de_DirEntity->d_type == DT_DIR)
{
if (IsNumeric(de_DirEntity->d_name))
{
strcpy(chrarry_CommandLinePath, PROC_DIRECTORY) ;
strcat(chrarry_CommandLinePath, de_DirEntity->d_name) ;
strcat(chrarry_CommandLinePath, "/cmdline") ;
FILE* fd_CmdLineFile = fopen (chrarry_CommandLinePath, "rt") ; // open the file for reading text
if (fd_CmdLineFile)
{
fscanf(fd_CmdLineFile, "%s", chrarry_NameOfProcess) ; // read from /proc/<NR>/cmdline
fclose(fd_CmdLineFile); // close the file prior to exiting the routine
if (strrchr(chrarry_NameOfProcess, '/'))
chrptr_StringToCompare = strrchr(chrarry_NameOfProcess, '/') +1 ;
else
chrptr_StringToCompare = chrarry_NameOfProcess ;
//printf("Process name: %s\n", chrarry_NameOfProcess);
//printf("Pure Process name: %s\n", chrptr_StringToCompare );
if ( CompareFunction(chrptr_StringToCompare, cchrptr_ProcessName, intCaseSensitiveness) )
{
pid_ProcessIdentifier = (pid_t) atoi(de_DirEntity->d_name) ;
closedir(dir_proc) ;
return pid_ProcessIdentifier ;
}
}
}
}
}
closedir(dir_proc) ;
return pid_ProcessIdentifier ;
}
#ifdef __cplusplus
pid_t GetPIDbyName(const char* cchrptr_ProcessName)
{
return GetPIDbyName(cchrptr_ProcessName, CASE_INSENSITIVE, EXACT_MATCH) ;
}
#else
// C cannot overload functions - fixed
pid_t GetPIDbyName_Wrapper(const char* cchrptr_ProcessName, ... )
{
int intTempArgument ;
int intInputArguments[2] ;
// intInputArguments[0] = 0 ;
// intInputArguments[1] = 0 ;
memset(intInputArguments, 0, sizeof(intInputArguments) ) ;
int intInputIndex ;
va_list argptr;
va_start( argptr, cchrptr_ProcessName );
for (intInputIndex = 0; (intTempArgument = va_arg( argptr, int )) != 15; ++intInputIndex)
{
intInputArguments[intInputIndex] = intTempArgument ;
}
va_end( argptr );
return GetPIDbyName_implements(cchrptr_ProcessName, intInputArguments[0], intInputArguments[1]);
}
#define GetPIDbyName(ProcessName,...) GetPIDbyName_Wrapper(ProcessName, ##__VA_ARGS__, (int) 15)
#endif
int main()
{
pid_t pid = GetPIDbyName("bash") ; // If -1 = not found, if -2 = proc fs access error
printf("PID %d\n", pid);
return EXIT_SUCCESS ;
}
If you don't do it, then I guess whatever API you will use will end up reading the /proc filesystem. Here are some examples of program doing this:
qps
htop
procps
But unfortunately, that does not constitute an API.
PS and every other tool(EXCEPT for Kernel Modules) read from /proc. /proc is a special filesystem created on the fly by the kernel so that user mode processes can read data that will otherwise only be available for the kernel.
The recommended way is therefore, reading from /proc.
You can quickly intuitively look at the /proc filesystem to see how its structured.
For every process there is a /proc/pid where pid is the process id number. Inside this folder there are several files which include different data about the current process.
If you run
strace ps -aux
you will see how the program ps reads this data from /proc.
The only way to do this without reading /proc would be to call "ps aux", go through every line, read the second column (the PID) and call lsof -p [PID] with it.
...I'd suggest reading /proc ;)
There's a library libprocps from the procps-ng project. On Ubuntu 13.04, if you do strace ps, then you can see that ps uses libprocps.
Reading proc is not too bad. I can't show you in C++, but the following D code should point you in the right direction:
import std.stdio;
import std.string;
import std.file;
import std.regexp;
import std.c.linux.linux;
alias std.string.split explode;
string srex = "^/proc/[0-9]+$";
string trex = "State:[ \t][SR]";
RegExp rex;
RegExp rext;
string[] scanPidDirs(string target)
{
string[] result;
bool callback(DirEntry* de)
{
if (de.isdir)
{
if (rex.find(de.name) >= 0)
{
string[] a = explode(de.name, "/");
string pid = a[a.length-1];
string x = cast(string) std.file.read(de.name ~ "/status");
int n = rext.find(x);
if (n >= 0)
{
x = cast(string) std.file.read(de.name ~ "/cmdline");
// This is null terminated
if (x.length) x.length = x.length-1;
a = explode(x, "/");
if (a.length)
x = a[a.length-1];
else
x = "";
if (x == target)
{
result ~= pid ~ "/" ~x;
}
}
}
}
return true;
}
listdir("/proc", &callback);
return result.dup;
}
void main(string[] args)
{
rex= new RegExp(srex);
rext= new RegExp(trex);
string[] a = scanPidDirs(args[1]);
if (!a.length)
{
writefln("Not found");
return;
}
writefln("%d matching processes", a.length);
foreach (s; a)
{
string[] p = explode(s, "/");
int pid = atoi(p[0]);
writef("Stop %s (%d)? ", s, pid);
string r = readln();
if (r == "Y\n" || r == "y\n")
kill(pid, SIGUSR1);
}
}
Easy way to fin pid of any process by name
pid_t GetPIDbyName(char* ps_name)
{
FILE *fp;
char *cmd=(char*)calloc(1,200);
sprintf(cmd,"pidof %s",ps_name);
fp=popen(cmd,"r");
fread(cmd,1,200,fp);
fclose(fp);
return atoi(cmd);
}

Help Editing Code to Fix "Argument list too long" Error

I am currently doing some testing with a new addition to the ICU dictionary-based break iterator.
I have code that allows me to test the word-breaking on a text document but when the text document is too large it gives the error: bash: ./a.out: Argument list too long
I am not sure how to edit the code to break-up the argument list when it gets too long so that a file of any size can be run through the code. The original code author is quite busy, would someone be willing to help out?
I tried removing the printing of what is being examined to see if that would help, but I still get the error on large files (printing what is being examined isn't necessary - I just need the result).
If the code could be modified to read the source text file line by line and export the results line by line to another text file (ending up with all the lines when it is done), that would be perfect.
The code is as follows:
/*
Written by George Rhoten to test how word segmentation works.
Code inspired by the break ICU sample.
Here is an example to run this code under Cygwin.
PATH=$PATH:icu-test/source/lib ./a.exe "`cat input.txt`" > output.txt
Encode input.txt as UTF-8.
The output text is UTF-8.
*/
#include <stdio.h>
#include <unicode/brkiter.h>
#include <unicode/ucnv.h>
#define ZW_SPACE "\xE2\x80\x8B"
void printUnicodeString(const UnicodeString &s) {
int32_t len = s.length() * U8_MAX_LENGTH + 1;
char *charBuf = new char[len];
len = s.extract(0, s.length(), charBuf, len, NULL);
charBuf[len] = 0;
printf("%s", charBuf);
delete charBuf;
}
/* Creating and using text boundaries */
int main(int argc, char **argv)
{
ucnv_setDefaultName("UTF-8");
UnicodeString stringToExamine("Aaa bbb ccc. Ddd eee fff.");
printf("Examining: ");
if (argc > 1) {
// Override the default charset.
stringToExamine = UnicodeString(argv[1]);
if (stringToExamine.charAt(0) == 0xFEFF) {
// Remove the BOM
stringToExamine = UnicodeString(stringToExamine, 1);
}
}
printUnicodeString(stringToExamine);
puts("");
//print each sentence in forward and reverse order
UErrorCode status = U_ZERO_ERROR;
BreakIterator* boundary = BreakIterator::createWordInstance(NULL, status);
if (U_FAILURE(status)) {
printf("Failed to create sentence break iterator. status = %s",
u_errorName(status));
exit(1);
}
printf("Result: ");
//print each word in order
boundary->setText(stringToExamine);
int32_t start = boundary->first();
int32_t end = boundary->next();
while (end != BreakIterator::DONE) {
if (start != 0) {
printf(ZW_SPACE);
}
printUnicodeString(UnicodeString(stringToExamine, start, end-start));
start = end;
end = boundary->next();
}
delete boundary;
return 0;
}
Thanks so much!
-Nathan
The Argument list too long error message is coming from the bash shell and is happening before your code even gets started executing.
The only code you can fix to eliminate this problem is the bash source code (or maybe it is in the kernel) and then, you're always going to run into a limit. If you increase from 2048 files on command line to 10,000, then some day you'll need to process 10,001 files ;-)
There are numerous solutions to managing 'too big' argument lists.
The standardized solution is the xargs utility.
find / -print | xargs echo
is a un-helpful, but working example.
See How to use "xargs" properly when argument list is too long for more info.
Even xargs has problems, because file names can contain spaces, new-line chars, and other unfriendly stuff.
I hope this helps.
The code below reads the content of a file whos name is given as the first parameter on the command-line and places it in a str::buffer. Then, instead of calling the function UnicodeString with argv[1], use that buffer instead.
#include<iostream>
#include<fstream>
using namespace std;
int main(int argc, char **argv)
{
std::string buffer;
if(argc > 1) {
std::ifstream t;
t.open(argv[1]);
std::string line;
while(t){
std::getline(t, line);
buffer += line + '\n';
}
}
cout << buffer;
return 0;
}
Update:
Input to UnicodeString should be char*. The function GetFileIntoCharPointer does that.
Note that only the most rudimentary error checking is implemented below!
#include<iostream>
#include<fstream>
using namespace std;
char * GetFileIntoCharPointer(char *pFile, long &lRet)
{
FILE * fp = fopen(pFile,"rb");
if (fp == NULL) return 0;
fseek(fp, 0, SEEK_END);
long size = ftell(fp);
fseek(fp, 0, SEEK_SET);
char *pData = new char[size + 1];
lRet = fread(pData, sizeof(char), size, fp);
fclose(fp);
return pData;
}
int main(int argc, char **argv)
{
long Len;
char * Data = GetFileIntoCharPointer(argv[1], Len);
std::cout << Data << std::endl;
if (Data != NULL)
delete [] Data;
return 0;
}

How to store the system command output in a variable?

I am executing a system() function which returns me a file name. Now I dont want to display the output on the screen(ie the filename) or pipe to a newfile. I just want to store it in a variable. is that possible? if so, how?
thanks
A single filename? Yes. That is certainly possible, but not using system().
Use popen(). This is available in c and c++, you've tagged your question with both but are probably going to code in one or the other.
Here's an example in C:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
FILE *fpipe;
char *command = "ls";
char c = 0;
if (0 == (fpipe = (FILE*)popen(command, "r")))
{
perror("popen() failed.");
exit(EXIT_FAILURE);
}
while (fread(&c, sizeof c, 1, fpipe))
{
printf("%c", c);
}
pclose(fpipe);
return EXIT_SUCCESS;
}
Well,There is one more easy way by which you can store command output in a file which is called redirection method. I think redirection is quite easy and It will be useful in your case.
so For Example this is my code in c++
#include <iostream>
#include <cstdlib>
#include <string>
using namespace std;
int main(){
system("ls -l >> a.text");
return 0;
}
Here redirection sign easily redirect all output of that command into a.text file.
You can use popen(3) and read from that file.
FILE *popen(const char *command, const char *type);
So basically you run your command and then read from the FILE returned. popen(3) works just like system (invokes the shell) so you should be able to run anything with it.
Here is my C++ implementation, which redirects system() stdout to a logging system. It uses GNU libc's getline(). It will throw an exception if it can't run the command, but will not throw if the command runs with non-zero status.
void infoLogger(const std::string& line); // DIY logger.
int LoggedSystem(const string& prefix, const string& cmd)
{
infoLogger(cmd);
FILE* fpipe = popen(cmd.c_str(), "r");
if (fpipe == NULL)
throw std::runtime_error(string("Can't run ") + cmd);
char* lineptr;
size_t n;
ssize_t s;
do {
lineptr = NULL;
s = getline(&lineptr, &n, fpipe);
if (s > 0 && lineptr != NULL) {
if (lineptr[s - 1] == '\n')
lineptr[--s ] = 0;
if (lineptr[s - 1] == '\r')
lineptr[--s ] = 0;
infoLogger(prefix + lineptr);
}
if (lineptr != NULL)
free(lineptr);
} while (s > 0);
int status = pclose(fpipe);
infoLogger(String::Format("Status:%d", status));
return status;
}

How can I read keyboard input to character strings? (C++)

getc (stdin) reads keyboard input to integers, but what if I want to read keyboard input to character strings?
#include "stdafx.h"
#include "string.h"
#include "stdio.h"
void CharReadWrite(FILE *fin);
FILE *fptr2;
int _tmain(int argc, _TCHAR* argv[])
{
char alpha= getc(stdin);
char filename=alpha;
if (fopen_s( &fptr2, filename, "r" ) != 0 )
printf( "File stream %s was not opened\n", filename );
else
printf( "The file %s was opened\n", filename );
CharReadWrite(fptr2);
fclose(fptr2);
return 0;
}
void CharReadWrite(FILE *fin){
int c;
while ((c=fgetc(fin)) !=EOF) {
putchar(c);}
}
Continuing with the theme of getc you can use fgets to read a line of input into a character buffer.
E.g.
char buffer[1024];
char *line = fgets(buffer, sizeof(buffer), stdin);
if( !line ) {
if( feof(stdin) ) {
printf("end of file\n");
} else if( ferror(stdin) ) {
printf("An error occurerd\n");
exit(0);
}
} else {
printf("You entered: %s", line);
}
Note that ryansstack's answer is a much better, easier and safer solution given you are using C++.
http://www.cplusplus.com/reference/iostream/istream/getline/
Ta da!
A character (ASCII) is just an unsigned 8 bit integral value, ie. it can have a value between 0-255. If you have a look at an ASCII table you can see how the integer values map to characters. But in general you can just jump between the types, ie:
int chInt = getc(stdin);
char ch = chInt;
// more simple
char ch = getc(stdin);
// to be explicit
char ch = static_cast<char>(getc(stdin));
Edit: If you are set on using getc to read in the file name, you could do the following:
char buf[255];
int c;
int i=0;
while (1)
{
c = getc(stdin);
if ( c=='\n' || c==EOF )
break;
buf[i++] = c;
}
buf[i] = 0;
This is a pretty low level way of reading character inputs, the other responses give higher level/safer methods, but again if you're set on getc...
Since you already are mixing "C" code with "C++" by using printf, why not continue and use scanf scanf("%s", &mystring); in order to read and format it all nicely ?
Or of course what already was said.. getline