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(a)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