ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
I'm sure this is a stupid question with a simple answer, but I'd like to get someone else's thoughts on it.
I've just started playing with the unistd.h and dirent.h headers, and was writing a little test program that used a few of what I thought would be the most common functions. Everything was working fine, but now I'm getting a weird segmentation fault after "Test point 4" is output to the screen. Am I right in thinking that's the EXIT function, of all things?
Another question (unrelated to current problem): Why do I get an error about "Switch argument not an integer" when using a switch/case? I thought it would function with any type of data as an argument. Am I completely dumb?
A little background on the setup:
Suse 9.0 non-graphical install, with g++ version 3.3.1
The code I'm running (compiled with g++ -ansi -pedantic -Wall):
int main(int argc, char * argv[])
{
//test out the unistd.h header file
//setup a test directory to work with
char * wd=argv[1];
//output the current directory
char * pwd; //setup a variable to use for getcwd
char * errval; //testable return value for error status
errval=getcwd(pwd, 256); //getcwd from dirent.h returns the full PWD
cout<<"Test point 1\n";
errtest(errval);
cout<<"Your current working directory is: "<<pwd<<endl;
//check the output of getcwd
//output list of files in current directory (ls)
DIR * tdir; //create a temp DIR pointer
struct dirent* tent; //and a struct dirent pointer
tdir=opendir(wd); //open a handle to the directory from argv[1]
cout<<"Test point 2\n";
while(tent=(readdir(tdir))) //read through the entire listing of files
cout<<tent->d_name<<endl; //and output it on stdout
cout<<"Test point 3\n";
closedir(tdir); //finally, close your open handle
cout<<"Test point 4\n";
exit(0);
}
:~> ./a.out /
Test point 1
Your current working directory is: /home/myrrdyn
Test point 2
.
..
bin
dev
etc
lib
mnt
opt
srv
tmp
var
usr
boot
home
proc
sbin
root
media
Test point 3
Test point 4
Segmentation fault
:~>
You're using getcwd() incorrectly. When you call it, pwd isn't initialized so it's a pointer to some random memory address. getcwd() attempts to store the address at that memory address. You can see how that would be bad. Try declaring pwd as something more like char pwd[256];
I didn't look through the rest of the program, but that pwd is definitely not right.
Thanks for your help. Yet I'm a touch confused. getcwd() does not want anything from pwd but it's address, and at some point during the call will assign a value to that location in memory. That's how you get the output from the function. So yes, you're right, it's just some random memory address, but it's not something I can't get back, and as far as the man page is concerned, it doesn't care what the data contained at that address happens to be.
Broken down, the steps would be:
getcwd() called
address of pwd passed
int value (256) passed
getcwd() finds the system's cwd and assigns the full path to a char starting at the address of pwd
getcwd() returns the path (success) or error value to errval
getcwd() exits
Ok, wait a sec. I think I see what I'm doing wrong, and why your array should work better than my pointer. All I'm getting is the first character in the path. Gods I've not played with this in far too long.
It's true that getcwd() only cares about the address of the buffer in which it will store the path, but you have to make sure that getcwd() stores it in memory that your program owns. You're responsible for allocating that memory. So you could either do the array thing, or you can malloc() the memory. getcwd() will always (as long as there isn't an error) return the exact same address that you pass to it (e.g. given that there aren't any errors, addr == getcwd(addr, size) will always be true)
Looking closer at the program, your errtest() function isn't correct. getcwd() doesn't return the error as a string. You can eliminate the whole errtest() function by rewriting you getcwd() call as something like:
getcwd() returns NULL on error, in which event the if() statement will be true, so it will print "getcwd(): Access denied" or whatever the error happens to be. Don't forget to #include <errno>
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.