Reputation:
I have the code below:
#include <stdio.h>
#include <unistd.h>
int main () {
int fd = open("filename.dat", O_CREAT|O_WRONLY|O_TRUNC, 0600);
int result = write(fd, "abcdefghijklmnopqrstuvxz", 100);
printf("\n\nfd = %d, result = %d, errno = %d", fd, result, errno);
close(fd);
return 0;
}
I am trying to understand what happens when I try to write more bytes to a file than I have available. So I am calling write
and asking the program to write 100 bytes while I have much less than that. The result: a bunch of stuff from stdout
ends up on filename.dat
. If instead of 100
I use strlen("abcdefghijklmnopqrstuvxz")
, I get the desired result. My question then is: why is the program trying to write beyond the '\0'
character on my string? Is there some undefined behavior going on here?
Upvotes: 1
Views: 1630
Reputation: 5325
I think that the basic issue here is that you're thinking of C strings as values, you think you're passing this value to the write function, and the write function is writing out your value plus extra junk.
C is lower level than that. In C, we don't really pass strings around, instead we pass pointers to strings, which are 'char *' values but with the added promise that they point to a valid block of memory that should be treated as a null-terminated string.
The write() function doesn't care about the null-terminated string convention. The parameters in the write call provide a file descriptor, a char *, and a buffer length.
Also, the compiler converts string constants into const char arrays. The equivalent of this happens at the top level:
const char *stringconst00001[27] = { 'a', 'b', 'c', ... 'y', 'z', '\0' }
And it does this in main():
int result = write(fd, stringconst00001, 100);
Upvotes: 0
Reputation: 1031
Because there are two techniques to represent a string. There is the null-terminated version, and there is another when you define its size and the pointer to the first byte. Write uses the second one. It needs a pointer where your data begins and a length to know how much data should copy to the file, but it doesn't see the null values. Sometimes these methods wraps a simple memcpy.
So when you defined the 100 length, in the memory after your abcdefghijklmnopqrstuvxz
the program stored your "bunch of stdout stuff". That's why you see garbage. You were lucky because you can get SEGFAULT easily in these cases!
Upvotes: 0
Reputation: 6555
The write()
function you are using does not care about the content. It just writes the no. of bytes you tell it to write in the file.
So when you say it to write 100 bytes and provide less than 100 bytes. The remaining bytes are taken as garbage value.
But when you are using strlen("abcdefghijklmnopqrstuvxz")
, you are asking the write()
to write bytes equal to the length of the string. So it works fine there
Upvotes: 0
Reputation: 11926
My question then is: why is the program trying to write beyond a \0
Because you want it to write 100 chars.
Is there some undefined behavior going on here?
If you increase that 100 to a large number and if that area is on a non-privilage area, it is undefined behaviour.
Upvotes: 0
Reputation: 182744
My question then is: why is the program trying to write beyond the '\0' character on my string?
The function write(2)
doesn't care about 0-terminators. It actually doesn't care about buffer contents at all: it will try to write as many bytes as you tell it.
Is there some undefined behavior going on here
Of course, trying to write more than you have might incur the wrath of the OS who could decide to terminate your process if it touches inaccessible memory.
Upvotes: 3