Reputation: 3
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
int main() {
char wd[10];
if(getcwd(wd,BUFSIZ) == NULL){ //BUFSIZ = 8192
perror("getcwd");
exit(1);
}
printf("wd = %s\n",wd);
}
This C code works well in Ubuntu Linux 20. The size of buffer wd is 10 but if I print the wd, it can output a string that is over size 10.
I think that the function uses the pointer of wd regardless of size, so it can work well but it can also print dummy string. Is it right?
//Edit :
printf("wd2 = %s\n",wd2); -> printf("wd = %s\n",wd);
Upvotes: 0
Views: 238
Reputation: 84607
Alright, let's get you straightened out:
wd
as char[10]
and then try and read 8192
bytes into it -- won't work,wd
and then try and output wd2
-- won't work, and your compiler should be screaming errors at you,\\n
is a literal "\n"
(two \\
are a literal '\'
) not a newline '\n'
#include <limits.h>
and #define _GNU_SOURCE
to make PATH_MAX
available -- which is the maximum length a pathname can be on your system (if any) -- then read that many bytes with getcwd()
.Putting it altogether, you can do:
#define _GNU_SOURCE /* needed for PATH_MAX */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <limits.h> /* needed for PATH_MAX */
int main (void) {
char wd[PATH_MAX]; /* define your buffer with size PATH_MAX */
if (getcwd (wd, PATH_MAX) == NULL) { /* get the same number of bytes */
perror("getcwd");
exit(1);
}
printf ("wd = %s\n", wd); /* output the results using same variable */
}
Compile
With the source in getcwd.c
and ALWAYS compiling with FULL WARNINGS ENABLED, you can do:
$ gcc -Wall -Wextra -pedantic -Wshadow -std=c11 -Ofast -o bin/getcwd getcwd.c
(note: I have a bin
directory in my current directory that I put executables in to keep from cluttering my source directory)
Don't accept code until it compiles without warning. Add -Werror
to treat warnings as errors so you can't cheat.
Example Use/Output
Running the program yields:
$ ./bin/getcwd
wd = /home/david/dev/src-c/tmp/debug
Let me know if you have further questions.
Upvotes: 0
Reputation: 62898
You lie to getcwd
about buffer size.
getcwd
does not magically know the buffer size. Buffers which know their own size is not a C language feature. That's why getcwd
needs the size parameter!
So, getcwd
happily writes beyond end of array.
In C, this is Undefined Behavior. Anything can happen, and "anything" includes what you observe here.
Upvotes: 1