Background
I'm running linux... and I'm trying to write a basic little c++ program that connects to a postgresql database.
I'm trying to follow this article
http://www.tutorialspoint.com/postgresql/postgresql_c_cpp.htm
Problem
I've been able to compile the library... and I can see now that I have the following folder on my computer
/usr/local/include/pqxx
But when i try to write some basic code and compile it, I get the following error:
devbox2:/var/abus# g++ testdb.cpp -lpqxx -lpq
testdb.cpp:2:22: fatal error: pqxx/pqxx: No such file or directory
#include <pqxx/pqxx>
^
compilation terminated.
Source Code
Here's what the code looks like:
1 #include <iostream>
2 #include <pqxx/pqxx>
3
4 using namespace std;
5 using namespace pqxx;
6
7 int main(int argc, char* argv[])
8 {
9 try{
10 connection C("dbname=testdestination user=testuser password=testpassword \
11 hostaddr=127.0.0.1 port=5432");
12 if (C.is_open()) {
13 cout << "Opened database successfully: " << C.dbname() << endl;
14 } else {
15 cout << "Can't open database" << endl;
16 return 1;
17 }
18 C.disconnect ();
19 }catch (const std::exception &e){
20 cerr << e.what() << std::endl;
21 return 1;
22 }
23 }
What I've tried so far:
I've been poking around the /usr/local/include/pqxx folder and I can see that there is a file called pqxx... but it doesn't have any extension on it.
Here's a snippet from the ls -lah command for that folder:
-rw-r--r-- 1 root root 637 Dec 8 21:42 pipeline
-rw-r--r-- 1 root root 7.5K Dec 8 21:42 pipeline.hxx
-rw-r--r-- 1 root root 1.1K Dec 8 21:42 pqxx
-rw-r--r-- 1 root root 728 Dec 8 21:42 prepared_statement
-rw-r--r-- 1 root root 8.2K Dec 8 21:42 prepared_statement.hxx
I've also made sure that my PATH includes the /usr/local/include/pqxx folder. This is what my PATH looks like:
PATH='/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/lib/gcc:/usr/local/include/pqxx:/usr/local/include'
I'm not sure what else I should check. Any suggestions would be appreciated.
Thanks.
To find the include files, you must add an -I option, e.g.
g++ -I/usr/local/include testdb.cpp -lpqxx -lpq
Adding directories to PATH doesn't help here, PATH is for locating executables from the shell.
Related
I'm trying to read the png image with Gdk::Pixbuf::create_from_resource:
#include <iostream>
#include <gtkmm.h>
int main(int argc, char *argv[])
{
auto app = Gtk::Application::create(argc, argv, "org.gtkmm.examples.base");
Gtk::Window window;
window.set_default_size(100, 100);
try {
Glib::RefPtr<Gdk::Pixbuf> image
= Gdk::Pixbuf::create_from_resource("image.png");
} catch (const Glib::Error &error) {
std::cerr << "Failed to load an image: " << error.what() << std::endl;
}
return app->run(window);
}
But an error occurs:
$ ./a.out
Failed to load an image: The resource at “image.png” does not exist
$ ls -l
total 128
-rwxrwxr-x. 1 user user 36528 Jul 18 15:01 a.out
-rw-r--r--. 1 user user 88792 Jul 18 15:00 image.png
-rw-r--r--. 1 user user 449 Jul 18 15:00 main.cpp
gtkmm version 3.24.6
If you want to load an image file directly into your program, instead of:
Glib::RefPtr<Gdk::Pixbuf> image
= Gdk::Pixbuf::create_from_resource("image.png");
you would use the following statement:
Glib::RefPtr<Gdk::Pixbuf> image
= Gdk::Pixbuf::create_from_file("image.png");
If you do want to use the image file as a resource, you would need to first generate a resource file with the "glib-compile-resources" function using a resource definition XML file. For example.
glib-compile-resources --target=image.c --generate-source resource.xml
In your XML file, you probably would have some type of definition such as the following.
<gresources>
<gresource prefix="Image">
<file preprocess="xml-stripblanks">image.png</file>
</gresource>
</gresources>
Then in your program, your creation statement would be similar to the following.
Glib::RefPtr<Gdk::Pixbuf> image = Gdk::Pixbuf::create_from_resource("Image/image.png");
Finally, you would revise your compile command to include the generated resource file with your "main.cpp" file to create your program.
g++ -Wno-format -o a.out main.cpp image.c `pkg-config --cflags --libs gtkmm-3.0` `pkg-config --cflags --libs gdkmm-3.0`
Hope that clarifies things.
Regards.
I'm trying to loop so that my program can get the weight of all files in a folder, and if the weight of any of these is equal to X, it will do an action, I need to know how I can loop like this, and i have a func to know whats the file size
std::ifstream::pos_type filesize(const char* filename)
{
std::ifstream in(filename, std::ifstream::ate | std::ifstream::binary);
return in.tellg();
}
Here's a short example program that demonstrates how to use C++17's <filesystem> library to iterate over a directory. If your compiler is fairly up-to-date, it should support C++17 without issue.
#include <filesystem>
#include <iostream>
int main() {
namespace fs = std::filesystem;
fs::path pwd(""); // Current directory program was executed from
pwd = fs::absolute(pwd);
for (auto& i : fs::directory_iterator(pwd)) {
try {
if (fs::file_size(i.path()) / 1024 > 2048) {
std::cout << i.path() << " is larger than 2MB\n";
}
} catch (fs::filesystem_error& e) {
std::cerr << e.what() << '\n';
}
}
}
This was the contents of the directory:
.
├── a.out
├── fiveKB
├── fourMB
├── main.cpp
└── oneMB
0 directories, 5 files
And information about the files:
drwxr-xr-x 7 user staff 224B Jul 29 22:11 ./
drwxr-xr-x 13 user staff 416B Jul 29 21:59 ../
-rwxr-xr-x 1 user staff 47K Jul 29 22:10 a.out*
-rw-r--r-- 1 user staff 5.0K Jul 29 21:58 fiveKB
-rw-r--r-- 1 user staff 4.0M Jul 29 21:59 fourMB
-rw-r--r-- 1 user staff 450B Jul 29 22:11 main.cpp
-rw-r--r-- 1 user staff 1.0M Jul 29 21:59 oneMB
And finally, the output:
"/Users/user/Documents/tmp/test/fourMB" is larger than 2MB
I write some code as below with c++17 msvc:
#include <filesystem>
#include <iostream>
int main()
{
using namespace std::filesystem;
std::wstring s = L"c:\\windows\\system32\\applicationframehost.exe";
path p(s);
std::cout << absolute(p) << std::endl;
std::cout << exists(p) << std::endl;
std::cin.get();
return 0;
}
and run it on windows 10.
the application prints 0 -> means that file does not exist.
But it really exists and when I try with Cygwin ls -l command, it shows a good result:
#myuser> ls -l c:\windows\system32\applicationframehost.exe
-rwxr-xr-x 2 cody.nguyen 1049089 69800 Apr 12 2018 'c:\windows\system32\applicationframehost.exe'
Could you please explain me why and how to solve this issue from code?
thanks,
P/S: the function exists(p) works perfectly with almost other files except some in C:\Windows\System32\. I just tried to run my application with admin/system/user rights but got same results.
With ls -l command I just run it with user privilege only.
Learning about the /proc/ directory today, in particular I'm interested in the security implications of having all the information about a process semi-publicly available, so I wrote a simple program that does some simple whatnot that allows me to explore some properties of the /proc/ directory:
#include <iostream>
#include <unistd.h>
#include <fcntl.h>
using namespace std;
extern char** environ;
void is_linux() {
#ifdef __linux
cout << "this is running on linux" << endl;
#endif
}
int main(int argc, char* argv[]) {
is_linux();
cout << "hello world" << endl;
int fd = open("afile.txt", O_RDONLY | O_CREAT, 0600);
cout << "afile.txt open on: " << fd << endl;
cout << "current pid: " << getpid() << endl;;
cout << "launch arguments: " << endl;
for (int index = 0; index != argc; ++index) {
cout << argv[index] << endl;
}
cout << "program environment: " << endl;
for (char** entry = environ; *entry; ++entry) {
cout << *entry << endl;
}
pause();
}
Interestingly though (to me anyway), when I check the file-descriptors folder (/pid/<PID#>/fd), I see this:
root#excalibur-VirtualBox:/proc/1546/fd# ls -l
total 0
lrwx------ 1 root root 64 Nov 7 09:12 0 -> /dev/null
lrwx------ 1 root root 64 Nov 7 09:12 1 -> /dev/null
lrwx------ 1 root root 64 Nov 7 09:12 2 -> /dev/null
lrwx------ 1 root root 64 Nov 7 09:12 3 -> socket:[11050]
why do the file descriptors point to /dev/null? Is that to prevent user's from being able to inject content into a file without actually being the process itself, or am I off base on that? And even more curious, why does the file descriptor to an open file point to a socket? That seems really odd. If anyone can shed some light on this for me, I would really appreciate it. Thanks!
You are definitely looking at the wrong /proc directory (for other PID or on another computer). The contents of /proc/<pid>/fd for your program should look like here:
lrwx------ 1 user group 64 Nov 7 22:15 0 -> /dev/pts/4
lrwx------ 1 user group 64 Nov 7 22:15 1 -> /dev/pts/4
lrwx------ 1 user group 64 Nov 7 22:15 2 -> /dev/pts/4
lr-x------ 1 user group 64 Nov 7 22:15 3 -> /tmp/afile.txt
Here we can see that file descriptors 0, 1, and 2 are shown as symbolic links to the pseudo terminal in which the program is running. It could be /dev/null if you started your program with input, output, and error redirection. The file descriptor #3 points to the file afile.txt which is currently opened.
I have an Isilon NAS in 10.20.30.11 for example, and I mounted it like following:
mount 10.20.30.11:/folder /content
I could use ls command to find the file in folder or /content. Its mod is 777.
bash-3.00# ls -l /content/a/b/1.txt
total 344131
rwxrwxrwx 1 1005 65533 140750 Feb 28 00:58 1.txt
But I cannot access it by access() function.
#include <iostream>
#include <string>
#include <unistd.h>
#include <cerrno>
using namespace std;
#include <stdio.h>
int main( int argc, const char* argv[] )
{
int returnVal = 0;
returnVal = access(argv[1], R_OK);
cout << returnVal << endl;
cout << errno << endl;
return 0;
}
It will return -1 and 2 as a result, which means 'No such file or directory'.
./a.out /content/a/b/1.txt
-1
2
#define ENOENT 2 /* No such file or directory */
It is not a permission problem I think, because the mod is 777, and the result is 'No such file or directory'.
From the Linux man pages.
access() may not work correctly on NFS
file systems with UID mapping enabled,
because UID mapping is done on the
server and hidden from the client,
which checks permissions.
Finally, it is found that it need to use following command to mount the Isilon storage.
mount -o vers=2,proto=tcp
1.2.3.4:/remote /mnt
The version and protocol need specified.
Thanks!