Fstream fails to open even though the filename is correct

This is a small sample of code that I've been having trouble with. For some reason, even though config_filename stores (and outputs) the correct file location, it still displays the error. It compiles fine, but I get the message "The settings file is missing, please create the config.orc file" when I run it, along with the path of a file that I KNOW is there.
Is there anything obviously wrong with this code?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include <iostream>
#include <fstream>
#include <cstring>
#include <sstream>
#include <unistd.h>
using namespace std;
#define PATHSEPARATOR "/"

int main(int argc, char** argv)
{
	(void)argv,(void)argc;
	string config_filename = "";
	{
		stringstream pid_getter;
		pid_getter << "/proc/" << getpid() << "/exe";
		char buf[256];
		int len = readlink(pid_getter.str().c_str(), buf, sizeof(buf));
		if(len < 0) {
			// It has an error for some reason, and can't read the link
			cout << "Error: your system does not support /proc/<pid>/exe";
			cin.sync();
			cin.ignore();
			return 1;
		}
		buf[len] = '\0';
		config_filename = buf;
		config_filename += PATHSEPARATOR;
		config_filename += "config.orc";
		cout << "`" << config_filename << "`\n";
	}
	//Open config.orc file
	fstream config;
	config.open(config_filename.c_str());
	if(!config.is_open()) {
		cout << "The settings file is missing, please create the config.orc file" << endl;
		cin.ignore();
		return 1;
	}
	return 0;
}
Last edited on
Be sure that the working directory of your program is correct
Are you sure you have permission to read the file?

You could use stat() to check. Or you could look at errno.
What would cause a working directory to be incorrect?
The reason why this is troublesome is that eventually the goal is to be able to run the program from anywhere thanks to PATH. Therefore, the working directory might be anywhere.
Errno is 0 after the call (I output it after the cout << config_filename;)
and I even tried chmod 7777 config.orc, and sudo su.
The program still can't read the file.
What's this for:
(void)argv,(void)argc;
To avoid gcc complaining about you not using them?

I usually just do this:
1
2
argc = argc;
argv = argv;

Compiler probably gets rid of it but it avoids the error checking until I actually want to use them.
Last edited on
Are you trying to open an fstream in the virtual filesystem /proc? I've never tried that...
No, I use /proc with the pid to get the location of the executable. It outputs that correctly, though.
Yeah, I'm more used to casting them as (void) instead of doing that, chrisname. Reason being I can simple #define UNUSED (void) and the UNUSED argc;
It should work: http://i32.tinypic.com/1qphly.jpg

Edit:
@demosthenes2k8
Good idea.
No, I use /proc with the pid to get the location of the executable

Can't you just get that from argv[0] and getcwd()?
Last edited on
Nope. The reason being the above: if the path to the executable's stored in PATH, then argv[0] will just be "Oratr", not the actual path. And for the same reason, getcwd will return a bad value, because it's not being called from the directory that it's located in.

The fact that it's an absolute path wouldn't have anything to do with it, right?
What's wrong with a relative path?! This whole thing seems silly to me.
This works:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

int main(int argc, char** argv)
{
	char* cwd = calloc(FILENAME_MAX, 1),
	    * loc = calloc(FILENAME_MAX, 1);
	
	getcwd(cwd, FILENAME_MAX);
	
	printf("Current working directory: %s\n", cwd);

	if (argv[0][0] == '/') {
		strncpy(loc, argv[0], FILENAME_MAX);
	} else {
		size_t i = strlen(argv[0]);
		while (--i) {
			if (argv[0][i] == '/')
				break;
		}

		strncpy(loc, &(argv[0][i]), FILENAME_MAX);
		strncat(cwd, loc, FILENAME_MAX);
		loc = cwd;
	}

	printf("Executable file location: %s\n", loc);
	
	return 0;
}
$ ./tmp
Current working directory: /home/chris
Executable file location: /home/chris/tmp
[Fri Jul  9 22:05:01 BST 2010]-[~]
[chris@chris-al] $ /home/chris/tmp
Current working directory: /home/chris
Executable file location: /home/chris/tmp
Yeah, that should work, but that's not the problem. The problem is that the fstream doesn't open the file that is at that location.
Yes, but it fixes the issue of having to go through /proc just to find your executable file.
That code still fails when the program's folder is in the PATH, though.
http://dl.dropbox.com/u/285110/PATH.png
Does stat() tell you the file exists?

Also, nice bash prompt. What character is joining the brackets on the far left? And how do you get the time to update between prompts?
Yeah, that helped me fix it.
Apparently it was appending the name of the file onto the string, which caused it to error.

Thanks, I honestly just hacked it together from two other prompts that I liked. I don't know how to make a prompt, but I can definitely edit one!
PS1="\[\033[0;36m\]\033(0l\033(B\[\033[0m\][\[\033[1;31m\]\u\[\033[0m\]]\[\033[0;36m\]\033(0q\033(B\[\033[0m\][\[\033[1;33m\]@\h\[\033[0m\]]\[\033[0;36m\]\033(0q\033(B\[\033[0m\][\[\033[0;37m\]\T\[\033[0m\]]\[\033[0;36m\]\033(0q\033(B\033(0q\033(B\033(0q\033(B\033(0q\033(B\033(0q\033(B\033(0q\033(B\033(0q\033(B\033(0q\033(B\[\033[0m\][\[\033[1;33m\]\`if [ \$? = 0 ]; then echo \[\e[33m\]^_^\[\e[0m\]; else echo \[\e[31m\]O_O\[\e[0m\]; fi\`\[\033[0m\]]\n\[\033[0;36m\]├\[\033[0m\][\[\033[1;33m\]\w\[\033[0m\]]\n\[\033[0;36m\]\033(0m\033(B\[\033[0m\]>"
Both of the two that I used to make this were at http://maketecheasier.com/8-useful-and-interesting-bash-prompts/2009/09/04
Topic archived. No new replies allowed.