[5/5] msvcirt: Implement filebuf::open/close
Piotr Caban
piotr.caban at gmail.com
Tue Aug 4 10:21:56 CDT 2015
On 08/03/15 16:49, Iván Matellanes wrote:
> @@ -884,8 +893,16 @@ filebuf* __thiscall filebuf_attach(filebuf *this, filedesc fd)
> DEFINE_THISCALL_WRAPPER(filebuf_close, 4)
> filebuf* __thiscall filebuf_close(filebuf *this)
> {
> - FIXME("(%p) stub\n", this);
> - return NULL;
> + TRACE("(%p)\n", this);
> + if (this->fd == -1)
> + return NULL;
> +
> + streambuf_lock(&this->base);
> + call_streambuf_sync(&this->base);
Please handle call_streambuf_sync failure here.
> /* ?fd at filebuf@@QBEHXZ */
> @@ -911,8 +928,46 @@ int __thiscall filebuf_is_open(const filebuf *this)
> DEFINE_THISCALL_WRAPPER(filebuf_open, 16)
> filebuf* __thiscall filebuf_open(filebuf *this, const char *name, ios_open_mode mode, int protection)
> {
> - FIXME("(%p %s %d %d) stub\n", this, name, mode, protection);
> - return NULL;
> + const int inout_mode[4] = {-1, _O_RDONLY, _O_WRONLY, _O_RDWR};
> + const int share_mode[4] = {_SH_DENYRW, _SH_DENYWR, _SH_DENYRD, _SH_DENYNO};
> + int op_flags, sh_flags, fd;
> +
> + TRACE("(%p %s %d %d)\n", this, name, mode, protection);
It will be easier to read the logs if mode and protection is printed as
hexadecimal value. The same way op_flags and sh_flags should be printed.
> + if (this->fd != -1)
> + return NULL;
> +
> + /* mode */
> + if (mode & (OPENMODE_app|OPENMODE_trunc))
> + mode |= OPENMODE_out;
> + op_flags = inout_mode[mode & (OPENMODE_in|OPENMODE_out)];
> + if (op_flags < 0)
> + return NULL;
> + if (mode & OPENMODE_app)
> + op_flags |= _O_APPEND;
> + if ((mode & OPENMODE_trunc) ||
> + ((mode & OPENMODE_out) && !(mode & (OPENMODE_in|OPENMODE_app|OPENMODE_ate))))
> + op_flags |= _O_TRUNC;
> + if (!(mode & OPENMODE_nocreate))
> + op_flags |= _O_CREAT;
> + if (mode & OPENMODE_noreplace)
> + op_flags |= _O_EXCL;
> + op_flags |= (mode & OPENMODE_binary) ? _O_BINARY : _O_TEXT;
> +
> + /* share protection */
> + sh_flags = (protection & filebuf_sh_none) ? share_mode[(protection >> 9) & 3] : _SH_DENYNO;
> +
> + TRACE("op_flags %d, sh_flags %d\n", op_flags, sh_flags);
> + fd = _sopen(name, op_flags, sh_flags, _S_IREAD|_S_IWRITE);
> + if (fd < 0)
> + return NULL;
> +
> + streambuf_lock(&this->base);
> + this->fd = fd;
> + this->close = 1;
> + if (mode & OPENMODE_ate)
> + call_streambuf_seekoff(&this->base, 0, SEEKDIR_end, OPENMODE_in|OPENMODE_out);
Please handle seek failure here.
Thanks,
Piotr
More information about the wine-devel
mailing list