joyent/libuv — pull request #714 by bsnote (2013-02-20 12:31:15+00:00)
Title: Safe allocation of memory for uv_fs_t

Recently I faced a problem of using functions which have `uv_fs_t` parameter. For example:

```c++
uv_fs_t* req = (uv_fs_t*)malloc(sizeof(uv_fs_t));
uv_fs_stat(uv_default_loop(), req, filename, stat_cb);
```

I checked this code using valgrind. It gives errors like

```
==28480== Invalid write of size 4
==28480== at 0x805AA3A: uv_fs_req_init (fs.c:78)
==28480== by 0x805B738: uv_fs_stat (fs.c:373)
...
==28480== Address 0x402aab4 is 4 bytes after a block of size 136 alloc'd
```

It turned out that the size of `uv_fs_t` in my code (136) is different from the size of `uv_fs_t` in libuv (144). Particularly the size of `statbuf` member differs, which is of type `struct stat`: 88 in my code vs 96 in libuv. I found `struct stat` definition in ``:

```c++
struct stat
{
...
#if defined __x86_64__ || !defined __USE_FILE_OFFSET64
__off_t st_size; /* Size of file, in bytes. */
#else
__off64_t st_size; /* Size of file, in bytes. */
#endif
...
#if defined __x86_64__ || !defined __USE_FILE_OFFSET64
__blkcnt_t st_blocks; /* Number 512-byte blocks allocated. */
#else
__blkcnt64_t st_blocks; /* Number 512-byte blocks allocated. */
#endif
...
};
```

As can be seen, the size of `struct stat` differs because of __USE_FILE_OFFSET64 definition. It is enabled in libuv by including `-D_FILE_OFFSET_BITS=64` compiler option but it is not enabled in my code. I can solve my problem by including `-D_FILE_OFFSET_BITS=64` too but I think it's tricky. It looks like a common problem and the solution is far from being obvious.

I am proposing two new public functions:
- uv_fs_t* uv_fs_alloc()
- void uv_fs_free(uv_fs_t*)

As far as I understand `uv_buf_init()` solves a similar problem though it doesn't allocate memory and returns struct by value.

What do you think?