I have a c++ code where, I'm redirecting the stdout to a string. The code should be platform independent. In windows works fine, but under linux it doesn't builds.
Here is my code:
#include <fcntl.h>
int outBuffer[2];
int orgStdOutBuffer;
std::string stringBuff;
enum PIPES {READ, WRITE};
orgStdOutBuffer = dup(fileno(stdout));
outBuffer[READ] = 0;
outBuffer[WRITE] = 0;
if (_pipe(mStdOutBuffer, 65535, O_BINARY) == -1) {
return false;
}
fflush(stdout);
dup2(outBuffer[WRITE], fileno(stdout));
The problem is where I'm checking the end of the pipe:
if (!eof(outBuffer[READ])) {
stdOutBufferSize = read(outBuffer[READ], &(*stringBuff.begin()), buffSize);
}
Under linux gives the following error:
'eof' was not declared in this scope
'O_BINARY' was not declared in this scope
Can anybody help how can I make this code run under linux?
Related
I am trying to print the path of the current directory using
this
execl ("/bin/pwd", "pwd", NULL);
output: /home/user/Ubuntu
and want to print a desired text before the current path.
for example:
my name /home/user/ubntu
how this will be done?
#include <stdio.h>
#include <iostream>
#include <string.h>
#include <unistd.h>
#include <dirent.h>
using namespace std;
int main(){
string command;
while(command != "exit"){
cout<< "B-17235"<<return execl ("/bin/pwd", "pwd", NULL);
cin>> command;
}
return 0;
}
Think that the majority of Unix-Linux-Gnu commands are written in C or C++. Generally there are direct API calls either system calls (man 2) or standard C library (man 3) to get the information or do the job.
To get working directory, just use getcwd() as suggested by alk.
char buffer[256];
if (NULL == getcwd(buffer, sizeof(buffer))) {
perror("can't get current dir");
return 1;
}
If you wanted to get the output of a more complex command, the most direct way would be to use popen that encloses the fork, exec, and pipe management for you :
FILE *fd = popen("/bin/pwd", "r");
char buffer[256];
if (fgets(buffer, sizeof(buffer), fd) == NULL) {
perror("can't read command");
return 1;
}
if (buffer[strlen(buffer) - 1] != '\n') {
fprintf(stderr, "path too long";
return 1;
}
pclose(fd);
// ok the working directory is is buffer
You should not use that for a command as simple as pwd.
And don't forget : man is your friend ! man getcwd and man popen will give you plenty of information ...
I am trying to print the path of the current directory
Use the library function getcwd().
To have the function available it might be necessary to #define _XOPEN_SOURCE 500 or similar (please see the man-page linked above for details on this).
I want to get driver version of nVidia video card.
So I used WMI and get data from "DriverVersion" obejct of "Win32_VideoController" class.
But it was like "9.18.13.1106"(file version) and what I wanted is something like "311.06"(treiber version).
Where can I get that information?
If it is impossible on WMI, I want to know other way to get that.
Thanks.
You can do this using NVML from nVidia's Tesla Deployment Kit. You can retrieve the internal driver version (the one you're accustomed to seeing for an nVidia driver) with code like this:
#include <iostream>
#include <string>
#include <stdlib.h>
#include <nvml.h>
#include <windows.h>
namespace {
typedef nvmlReturn_t (*init)();
typedef nvmlReturn_t (*shutdown)();
typedef nvmlReturn_t (*get_version)(char *, unsigned);
class NVML {
init nvmlInit;
shutdown nvmlShutdown;
get_version nvmlGetDriverVersion;
std::string find_dll() {
std::string loc(getenv("ProgramW6432"));
loc += "\\Nvidia Corporation\\nvsmi\\nvml.dll";
return loc;
}
public:
NVML() {
HMODULE lib = LoadLibrary(find_dll().c_str());
nvmlInit = (init)GetProcAddress(lib, "nvmlInit");
nvmlShutdown = (shutdown)GetProcAddress(lib, "nvmlShutdown");
nvmlGetDriverVersion = (get_version)GetProcAddress(lib, "nvmlSystemGetDriverVersion");
if (NVML_SUCCESS != nvmlInit())
throw(std::runtime_error("Unable to initialize NVML"));
}
std::string get_ver() {
char buffer[81];
nvmlGetDriverVersion(buffer, sizeof(buffer));
return std::string(buffer);
}
~NVML() {
if (NVML_SUCCESS != nvmlShutdown())
throw(std::runtime_error("Unable to shut down NVML"));
}
};
}
int main() {
std::cout << "nVidia Driver version: " << NVML().get_ver();
}
Note that if you're writing this purely for your own use on a machine where you're free to edit the PATH, you can simplify this quite a bit. Most of the code deals with the fact that this uses NVML.DLL, which is in a directory that's not normally on the path, so the code loads that dynamically, and uses GetProcAddress to find the functions in it that we need to use. In this case, we're only using three functions, so it's not all that difficult to deal with, but it still at drastically increases the length of the code.
If we could ignore all that nonsense, the real code would just come out to something on this general order:
nvmlInit();
nvmlSystemGetDriverVersion(result, sizeof(result));
std::cout << result;
nvmlShutdown();
Anyway, to build it, you'll need a command line something like:
cl -Ic:\tdk\nvml\include nv_driver_version.cpp
...assuming you've installed the Tesla Deployment Kit at c:\tdk.
In any case, yes, I've tested this to at least some degree. On my desktop it prints out:
nVidia Driver version: 314.22
...which matches what I have installed.
To get the Nvidia driver version through C++ on Win64:
Download NVAPI https://developer.nvidia.com/rtx/path-tracing/nvapi/get-started, a few MB
The main folder of the downloaded archive contains several header files, one of which is nvapi.h. Those headers are needed for compilation. The subfolder amd64 contains nvapi64.lib, which is needed for linking. The following code will now show the driver version:
#include <iostream>
extern "C" {
#include "nvapi.h"
}
int main() {
NvAPI_Status status = NVAPI_OK;
NvAPI_ShortString str;
status = NvAPI_Initialize();
if (status == NVAPI_LIBRARY_NOT_FOUND) {
//in this case NvAPI_GetErrorMessage() will only return an empty string
std::printf("error no nvidia driver found\n");
} else if (status != NVAPI_OK) {
NvAPI_GetErrorMessage(status, str);
std::printf("error initializing nvapi: %s\n", str);
}
NvU32 version = 0;
NvAPI_ShortString branch;
status = NvAPI_SYS_GetDriverAndBranchVersion(&version, branch);
if (status != NVAPI_OK) {
NvAPI_GetErrorMessage(status, str);
std::printf("error getting driver version: %s\n", str);
} else {
std::printf("driver version %d.%d", version / 100, version % 100);
}
}
I have a problem with a program that I'm writing. It is a command line parser that parses bencode (used in torrent files). The program accepts a filename as it's command line. When I build and run the program in Microsoft Visual Studio 10.0 using the debugging Commmand Line arguments setting to input a command line the program tells me that it failed parsing.
If I open a command prompt and run the program from the command prompt with the same command line, the program works perfectly! What's going on? Is this a common problem with Visual Studio?
I used the debugger in Visual Studio to trace where the program fails and it appears that a call to the stat function ( http://msdn.microsoft.com/en-us/library/14h5k7ff.aspx ) used to get the length of the file returns an error in Visual Studio but works fine when run outside of Visual Studio.
The Code uses a Bencode parser which can be found here: http://funzix.git.sourceforge.net/git/gitweb.cgi?p=funzix/funzix;a=blob;f=bencode/bencode.c
And here is the code for the program:
#include <stdio.h>
#include "../Parse/bencode.h"
int main(int argc, char *argv[]){
if(argc != 2){
printf("Usage: whirlwind filename\n");
return 1;
}
char *buf;
long long len;
be_node *n;
//read the torrent file into a buffer and store at &buf
buf = read_file(argv[1], &len);
if(!buf){
buf = argv[1];
len = strlen(argv[1]);
}
printf("Decoding: %s\n", argv[1]);
n = be_decoden(buf, len);
if(!n){
printf("Parsing failed!\n");
return 1;
}
if(n->type != BE_DICT){
printf("This file is not a valid Bencoded Dictionary.\n");
return 1;
}
int i;
char* keyName;
for(i = 0; i < 10; i++){
keyName = n->val.d[i].key;
if(keyName == "announce"){
printf("\n\n");
}
printf("%s\n", keyName);
if(keyName == "announce"){
printf("\n\n");
}
}
return 0;
}
If you pass a relative path from Visual Studio you should be sure that it resolves correctly when your app runs inside the IDE. This problem arises because, when debugging, the current directory is usually \bin\debug.
To be on the safe side put a full pathname or read the location of your file from a configuration file.
I'm trying to Use Octave with Visual C++.
I have downloaded octave-3.6.1-vs2010-setup-1.exe. Created a new project, added octave include folder to include path, octinterp.lib and octave.lib to lib path, and I added Octave bin folder as running directory.
The program compiles and runs fine except feval function that causes the exception:
Microsoft C++ exception: octave_execution_exception at memory location 0x0012faef
and on Octave side:
Invalid resizing operation or ambiguous assignment to an out-of-bounds array element.
What am I doing wrong?
Code for a standalone program:
#include <octave/octave.h>
#include <octave/oct.h>
#include <octave/parse.h>
int main(int argc, char **argv)
{
if (octave_main (argc, argv, true))
{
ColumnVector NumRands(2);
NumRands(0) = 10;
NumRands(1) = 1;
octave_value_list f_arg, f_ret;
f_arg(0) = octave_value(NumRands);
f_ret = feval("rand",f_arg,1);
Matrix unis(f_ret(0).matrix_value());
}
else
{
error ("Octave interpreter initialization failed");
}
return 0;
}
Thanks in advance.
I tried it myself, and the problem seems to originate from the feval line.
Now I don't have an explanation as to why, but the problem was solved by simply switching to the "Release" configuration instead of the "Debug" configuration.
I am using the Octave3.6.1_vs2010 build, with VS2010 on WinXP.
Here is the code I tested:
#include <iostream>
#include <octave/oct.h>
#include <octave/octave.h>
#include <octave/parse.h>
int main(int argc, char **argv)
{
// Init Octave interpreter
if (!octave_main(argc, argv, true)) {
error("Octave interpreter initialization failed");
}
// x = rand(10,1)
ColumnVector sz(2);
sz(0) = 10; sz(1) = 1;
octave_value_list in = octave_value(sz);
octave_value_list out = feval("rand", in, 1);
// print random numbers
if (!error_state && out.length () > 0) {
Matrix x( out(0).matrix_value() );
std::cout << "x = \n" << x << std::endl;
}
return 0;
}
with an output:
x =
0.165897
0.0239711
0.957456
0.830028
0.859441
0.513797
0.870601
0.0643697
0.0605021
0.153486
I'd guess that its actually stopped pointing at the next line and the error actually lies at this line:
f_arg(0) = octave_value(NumRands);
You seem to be attempting to get a value (which value?) from a vector and then assigning it to element 0 of a vector that has not been defined as a vector.
I don't really know though ... I've never tried writing octave code like that. I'm just trying to work it out by translating the code to standard matlab/octave code and that line seems really odd to me ...
I have an application where I need to write a new getpid function to replace the original one of the OS. The implementation would be similar to:
pid_t getpid(void)
{
if (gi_PID != -1)
{
return gi_PID;
}
else
{
// OS level getpid() function
}
}
How can I call the original getpid() implementation of the OS through this function?
EDIT: I tried:
pid_t getpid(void)
{
if (gi_PID != -1)
{
return gi_PID;
}
else
{
return _getpid();
}
}
as Jonathan has suggested. This gave me the following errors when compiling with g++:
In function pid_t getpid()':
SerendibPlugin.cpp:882: error:
_getpid' undeclared (first use this
function) SerendibPlugin.cpp:882:
error: (Each undeclared identifier is
reported only once for each function
it appears in.)
EDIT 2: I've managed to get this to work by using a function pointer and setting it to the next second symbol with the id "getpid", using dlsym(RTLD_NEXT, "getpid").
Here's my sample code:
vi xx.c
"xx.c" 23 lines, 425 characters
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <iostream>
#include <dlfcn.h>
using namespace std;
pid_t(*___getpid)();
pid_t getpid(void)
{
cout << "My getpid" << endl;
cout << "PID :" << (*___getpid)() << endl;
return (*___getpid)();
}
int main(void)
{
___getpid = (pid_t(*)())dlsym(RTLD_NEXT, "getpid");
pid_t p1 = getpid();
printf("%d \n", (int)p1);
return(0);
}
g++ xx.c -o xout
My getpid
PID :7802
7802
On many systems, you will find that getpid() is a 'weak symbol' for _getpid(), which can be called in lieu of getpid().
The first version of the answer mentioned __getpid(); the mention was removed swiftly since it was erroneous.
This code works for me on Solaris 10 (SPARC) - with a C++ compiler:
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
extern "C" pid_t _getpid();
pid_t getpid(void)
{
return(-1);
}
int main(void)
{
pid_t p1 = getpid();
pid_t p2 = _getpid();
printf("%d vs %d\n", (int)p1, (int)p2);
return(0);
}
This code works for me on Solaris 10 (SPARC) - with a C compiler:
Black JL: cat xx.c
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
pid_t getpid(void)
{
return(-1);
}
int main(void)
{
pid_t p1 = getpid();
pid_t p2 = _getpid();
printf("%d vs %d\n", (int)p1, (int)p2);
return(0);
}
Black JL: make xx && ./xx
cc xx.c -o xx
"xx.c", line 13: warning: implicit function declaration: _getpid
-1 vs 29808
Black JL:
You can use a macro:
in a .h, included in every file where you want to replace the getpid function
#define getpid() mygetpid()
Then, put your own implementation in a .cpp
pid_t mygetpid() {
// do what you want
return (getpid)();
}
You're using the terminology a bit incorrectly. It's not possible to override getpid() because it's not a virtual function. All you can do is attempt to replace getpid with a different function by various evil means.
But I must ask, why are you doing this? Replacing getpid means that any component which was depending on the return of getpid will now be receiving you're presumably modified result. This change has a very high risk of changing some other component.
What you're offering is a new functionality and hence should be a different function.
That being said if you truly want to take this approach the best way is to dynamic loading of the function. The original DLL will still contain the getpid function and you can access that via a combination of LoadLibrary/GetProcAddress on Windows or dlopen/dlsym on Linux. If you're using a different OS please specify.
EDIT Responding to comments that getpid needs to be testable
If testing is the concern then why not instead have a custom getpid method for you're application. For example, applicationGetPid(). For normal execution this could be forwarded off to the system getpid function. But during Unit Testing it could be used to produce more predictable values.
pid_t applicationGetPid() {
#if UNIT_TEST
return SomeCodeForUnitTests;
#else
return getpid();
#endif
}