msvcirt: Implement filebuf::open/close.
This commit is contained in:
parent
bb060fe62f
commit
95fd3af190
|
@ -19,8 +19,12 @@
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <io.h>
|
||||||
|
#include <share.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
#include "msvcirt.h"
|
#include "msvcirt.h"
|
||||||
#include "windef.h"
|
#include "windef.h"
|
||||||
|
@ -100,6 +104,8 @@ typedef struct {
|
||||||
int close;
|
int close;
|
||||||
} filebuf;
|
} filebuf;
|
||||||
|
|
||||||
|
filebuf* __thiscall filebuf_close(filebuf*);
|
||||||
|
|
||||||
/* class ios */
|
/* class ios */
|
||||||
struct _ostream;
|
struct _ostream;
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -549,6 +555,7 @@ void __thiscall streambuf_setp(streambuf *this, char *pb, char *ep)
|
||||||
/* ?sync@streambuf@@UAEHXZ */
|
/* ?sync@streambuf@@UAEHXZ */
|
||||||
/* ?sync@streambuf@@UEAAHXZ */
|
/* ?sync@streambuf@@UEAAHXZ */
|
||||||
DEFINE_THISCALL_WRAPPER(streambuf_sync, 4)
|
DEFINE_THISCALL_WRAPPER(streambuf_sync, 4)
|
||||||
|
#define call_streambuf_sync(this) CALL_VTBL_FUNC(this, 4, int, (streambuf*), (this))
|
||||||
int __thiscall streambuf_sync(streambuf *this)
|
int __thiscall streambuf_sync(streambuf *this)
|
||||||
{
|
{
|
||||||
TRACE("(%p)\n", this);
|
TRACE("(%p)\n", this);
|
||||||
|
@ -821,6 +828,8 @@ DEFINE_THISCALL_WRAPPER(filebuf_dtor, 4)
|
||||||
void __thiscall filebuf_dtor(filebuf* this)
|
void __thiscall filebuf_dtor(filebuf* this)
|
||||||
{
|
{
|
||||||
TRACE("(%p)\n", this);
|
TRACE("(%p)\n", this);
|
||||||
|
if (this->close)
|
||||||
|
filebuf_close(this);
|
||||||
streambuf_dtor(&this->base);
|
streambuf_dtor(&this->base);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -884,8 +893,21 @@ filebuf* __thiscall filebuf_attach(filebuf *this, filedesc fd)
|
||||||
DEFINE_THISCALL_WRAPPER(filebuf_close, 4)
|
DEFINE_THISCALL_WRAPPER(filebuf_close, 4)
|
||||||
filebuf* __thiscall filebuf_close(filebuf *this)
|
filebuf* __thiscall filebuf_close(filebuf *this)
|
||||||
{
|
{
|
||||||
FIXME("(%p) stub\n", this);
|
filebuf *ret;
|
||||||
return NULL;
|
|
||||||
|
TRACE("(%p)\n", this);
|
||||||
|
if (this->fd == -1)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
streambuf_lock(&this->base);
|
||||||
|
if (call_streambuf_sync(&this->base) == EOF || _close(this->fd) < 0) {
|
||||||
|
ret = NULL;
|
||||||
|
} else {
|
||||||
|
this->fd = -1;
|
||||||
|
ret = this;
|
||||||
|
}
|
||||||
|
streambuf_unlock(&this->base);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ?fd@filebuf@@QBEHXZ */
|
/* ?fd@filebuf@@QBEHXZ */
|
||||||
|
@ -911,8 +933,48 @@ int __thiscall filebuf_is_open(const filebuf *this)
|
||||||
DEFINE_THISCALL_WRAPPER(filebuf_open, 16)
|
DEFINE_THISCALL_WRAPPER(filebuf_open, 16)
|
||||||
filebuf* __thiscall filebuf_open(filebuf *this, const char *name, ios_open_mode mode, int protection)
|
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);
|
const int inout_mode[4] = {-1, _O_RDONLY, _O_WRONLY, _O_RDWR};
|
||||||
return NULL;
|
const int share_mode[4] = {_SH_DENYRW, _SH_DENYWR, _SH_DENYRD, _SH_DENYNO};
|
||||||
|
int op_flags, sh_flags, fd;
|
||||||
|
|
||||||
|
TRACE("(%p %s %x %x)\n", this, name, mode, protection);
|
||||||
|
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 %x, sh_flags %x\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->close = 1;
|
||||||
|
if ((mode & OPENMODE_ate) &&
|
||||||
|
call_streambuf_seekoff(&this->base, 0, SEEKDIR_end, mode & (OPENMODE_in|OPENMODE_out)) == EOF) {
|
||||||
|
_close(fd);
|
||||||
|
} else
|
||||||
|
this->fd = fd;
|
||||||
|
streambuf_unlock(&this->base);
|
||||||
|
return (this->fd == -1) ? NULL : this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ?overflow@filebuf@@UAEHH@Z */
|
/* ?overflow@filebuf@@UAEHH@Z */
|
||||||
|
@ -930,7 +992,7 @@ DEFINE_THISCALL_WRAPPER(filebuf_seekoff, 16)
|
||||||
streampos __thiscall filebuf_seekoff(filebuf *this, streamoff offset, ios_seek_dir dir, int mode)
|
streampos __thiscall filebuf_seekoff(filebuf *this, streamoff offset, ios_seek_dir dir, int mode)
|
||||||
{
|
{
|
||||||
FIXME("(%p %d %d %d) stub\n", this, offset, dir, mode);
|
FIXME("(%p %d %d %d) stub\n", this, offset, dir, mode);
|
||||||
return EOF;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ?setbuf@filebuf@@UAEPAVstreambuf@@PADH@Z */
|
/* ?setbuf@filebuf@@UAEPAVstreambuf@@PADH@Z */
|
||||||
|
@ -957,7 +1019,7 @@ DEFINE_THISCALL_WRAPPER(filebuf_sync, 4)
|
||||||
int __thiscall filebuf_sync(filebuf *this)
|
int __thiscall filebuf_sync(filebuf *this)
|
||||||
{
|
{
|
||||||
FIXME("(%p) stub\n", this);
|
FIXME("(%p) stub\n", this);
|
||||||
return EOF;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ?underflow@filebuf@@UAEHXZ */
|
/* ?underflow@filebuf@@UAEHXZ */
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <io.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <windef.h>
|
#include <windef.h>
|
||||||
#include <winbase.h>
|
#include <winbase.h>
|
||||||
|
@ -31,6 +32,17 @@ typedef enum {
|
||||||
IOSTATE_badbit = 0x4
|
IOSTATE_badbit = 0x4
|
||||||
} ios_io_state;
|
} ios_io_state;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
OPENMODE_in = 0x1,
|
||||||
|
OPENMODE_out = 0x2,
|
||||||
|
OPENMODE_ate = 0x4,
|
||||||
|
OPENMODE_app = 0x8,
|
||||||
|
OPENMODE_trunc = 0x10,
|
||||||
|
OPENMODE_nocreate = 0x20,
|
||||||
|
OPENMODE_noreplace = 0x40,
|
||||||
|
OPENMODE_binary = 0x80
|
||||||
|
} ios_open_mode;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
FLAGS_skipws = 0x1,
|
FLAGS_skipws = 0x1,
|
||||||
FLAGS_left = 0x2,
|
FLAGS_left = 0x2,
|
||||||
|
@ -49,6 +61,11 @@ typedef enum {
|
||||||
FLAGS_stdio = 0x4000
|
FLAGS_stdio = 0x4000
|
||||||
} ios_flags;
|
} ios_flags;
|
||||||
|
|
||||||
|
const int filebuf_sh_none = 0x800;
|
||||||
|
const int filebuf_sh_read = 0xa00;
|
||||||
|
const int filebuf_sh_write = 0xc00;
|
||||||
|
const int filebuf_openprot = 420;
|
||||||
|
|
||||||
/* class streambuf */
|
/* class streambuf */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
const vtable_ptr *vtable;
|
const vtable_ptr *vtable;
|
||||||
|
@ -135,6 +152,8 @@ static filebuf* (*__thiscall p_filebuf_fd_reserve_ctor)(filebuf*, int, char*, in
|
||||||
static filebuf* (*__thiscall p_filebuf_ctor)(filebuf*);
|
static filebuf* (*__thiscall p_filebuf_ctor)(filebuf*);
|
||||||
static void (*__thiscall p_filebuf_dtor)(filebuf*);
|
static void (*__thiscall p_filebuf_dtor)(filebuf*);
|
||||||
static filebuf* (*__thiscall p_filebuf_attach)(filebuf*, filedesc);
|
static filebuf* (*__thiscall p_filebuf_attach)(filebuf*, filedesc);
|
||||||
|
static filebuf* (*__thiscall p_filebuf_open)(filebuf*, const char*, ios_open_mode, int);
|
||||||
|
static filebuf* (*__thiscall p_filebuf_close)(filebuf*);
|
||||||
|
|
||||||
/* ios */
|
/* ios */
|
||||||
static ios* (*__thiscall p_ios_copy_ctor)(ios*, const ios*);
|
static ios* (*__thiscall p_ios_copy_ctor)(ios*, const ios*);
|
||||||
|
@ -271,6 +290,8 @@ static BOOL init(void)
|
||||||
SET(p_filebuf_ctor, "??0filebuf@@QEAA@XZ");
|
SET(p_filebuf_ctor, "??0filebuf@@QEAA@XZ");
|
||||||
SET(p_filebuf_dtor, "??1filebuf@@UEAA@XZ");
|
SET(p_filebuf_dtor, "??1filebuf@@UEAA@XZ");
|
||||||
SET(p_filebuf_attach, "?attach@filebuf@@QEAAPEAV1@H@Z");
|
SET(p_filebuf_attach, "?attach@filebuf@@QEAAPEAV1@H@Z");
|
||||||
|
SET(p_filebuf_open, "?open@filebuf@@QEAAPEAV1@PEBDHH@Z");
|
||||||
|
SET(p_filebuf_close, "?close@filebuf@@QEAAPEAV1@XZ");
|
||||||
|
|
||||||
SET(p_ios_copy_ctor, "??0ios@@IEAA@AEBV0@@Z");
|
SET(p_ios_copy_ctor, "??0ios@@IEAA@AEBV0@@Z");
|
||||||
SET(p_ios_ctor, "??0ios@@IEAA@XZ");
|
SET(p_ios_ctor, "??0ios@@IEAA@XZ");
|
||||||
|
@ -327,6 +348,8 @@ static BOOL init(void)
|
||||||
SET(p_filebuf_ctor, "??0filebuf@@QAE@XZ");
|
SET(p_filebuf_ctor, "??0filebuf@@QAE@XZ");
|
||||||
SET(p_filebuf_dtor, "??1filebuf@@UAE@XZ");
|
SET(p_filebuf_dtor, "??1filebuf@@UAE@XZ");
|
||||||
SET(p_filebuf_attach, "?attach@filebuf@@QAEPAV1@H@Z");
|
SET(p_filebuf_attach, "?attach@filebuf@@QAEPAV1@H@Z");
|
||||||
|
SET(p_filebuf_open, "?open@filebuf@@QAEPAV1@PBDHH@Z");
|
||||||
|
SET(p_filebuf_close, "?close@filebuf@@QAEPAV1@XZ");
|
||||||
|
|
||||||
SET(p_ios_copy_ctor, "??0ios@@IAE@ABV0@@Z");
|
SET(p_ios_copy_ctor, "??0ios@@IAE@ABV0@@Z");
|
||||||
SET(p_ios_ctor, "??0ios@@IAE@XZ");
|
SET(p_ios_ctor, "??0ios@@IAE@XZ");
|
||||||
|
@ -930,6 +953,10 @@ static void test_filebuf(void)
|
||||||
filebuf fb1, fb2, fb3, *pret;
|
filebuf fb1, fb2, fb3, *pret;
|
||||||
struct filebuf_lock_arg lock_arg;
|
struct filebuf_lock_arg lock_arg;
|
||||||
HANDLE thread;
|
HANDLE thread;
|
||||||
|
const char filename1[] = "test1";
|
||||||
|
const char filename2[] = "test2";
|
||||||
|
const char filename3[] = "test3";
|
||||||
|
char read_buffer[16];
|
||||||
|
|
||||||
memset(&fb1, 0xab, sizeof(filebuf));
|
memset(&fb1, 0xab, sizeof(filebuf));
|
||||||
memset(&fb2, 0xab, sizeof(filebuf));
|
memset(&fb2, 0xab, sizeof(filebuf));
|
||||||
|
@ -982,14 +1009,126 @@ static void test_filebuf(void)
|
||||||
ok(fb3.fd == 2, "wrong fd, expected 2 got %d\n", fb3.fd);
|
ok(fb3.fd == 2, "wrong fd, expected 2 got %d\n", fb3.fd);
|
||||||
fb3.base.do_lock = -1;
|
fb3.base.do_lock = -1;
|
||||||
|
|
||||||
|
/* open modes */
|
||||||
|
pret = (filebuf*) call_func4(p_filebuf_open, &fb1, filename1, OPENMODE_out, filebuf_openprot);
|
||||||
|
ok(pret == NULL, "wrong return, expected %p got %p\n", NULL, pret);
|
||||||
|
fb1.fd = -1;
|
||||||
|
pret = (filebuf*) call_func4(p_filebuf_open, &fb1, filename1,
|
||||||
|
OPENMODE_ate|OPENMODE_nocreate|OPENMODE_noreplace|OPENMODE_binary, filebuf_openprot);
|
||||||
|
ok(pret == NULL, "wrong return, expected %p got %p\n", NULL, pret);
|
||||||
|
fb1.base.do_lock = 0;
|
||||||
|
pret = (filebuf*) call_func4(p_filebuf_open, &fb1, filename1, OPENMODE_out, filebuf_openprot);
|
||||||
|
ok(pret == &fb1, "wrong return, expected %p got %p\n", &fb1, pret);
|
||||||
|
ok(_write(fb1.fd, "testing", 7) == 7, "_write failed\n");
|
||||||
|
pret = (filebuf*) call_func1(p_filebuf_close, &fb1);
|
||||||
|
ok(pret == &fb1, "wrong return, expected %p got %p\n", &fb1, pret);
|
||||||
|
ok(fb1.fd == -1, "wrong fd, expected -1 got %d\n", fb1.fd);
|
||||||
|
pret = (filebuf*) call_func4(p_filebuf_open, &fb1, filename1, OPENMODE_out, filebuf_openprot);
|
||||||
|
ok(pret == &fb1, "wrong return, expected %p got %p\n", &fb1, pret);
|
||||||
|
ok(_read(fb1.fd, read_buffer, 1) == -1, "file should not be open for reading\n");
|
||||||
|
pret = (filebuf*) call_func1(p_filebuf_close, &fb1);
|
||||||
|
ok(pret == &fb1, "wrong return, expected %p got %p\n", &fb1, pret);
|
||||||
|
pret = (filebuf*) call_func4(p_filebuf_open, &fb1, filename1, OPENMODE_app, filebuf_openprot);
|
||||||
|
ok(pret == &fb1, "wrong return, expected %p got %p\n", &fb1, pret);
|
||||||
|
ok(_read(fb1.fd, read_buffer, 1) == -1, "file should not be open for reading\n");
|
||||||
|
ok(_write(fb1.fd, "testing", 7) == 7, "_write failed\n");
|
||||||
|
ok(_lseek(fb1.fd, 0, SEEK_SET) == 0, "_lseek failed\n");
|
||||||
|
ok(_write(fb1.fd, "append", 6) == 6, "_write failed\n");
|
||||||
|
pret = (filebuf*) call_func1(p_filebuf_close, &fb1);
|
||||||
|
ok(pret == &fb1, "wrong return, expected %p got %p\n", &fb1, pret);
|
||||||
|
pret = (filebuf*) call_func4(p_filebuf_open, &fb1, filename1, OPENMODE_out|OPENMODE_ate, filebuf_openprot);
|
||||||
|
ok(pret == &fb1, "wrong return, expected %p got %p\n", &fb1, pret);
|
||||||
|
ok(_read(fb1.fd, read_buffer, 1) == -1, "file should not be open for reading\n");
|
||||||
|
ok(_lseek(fb1.fd, 0, SEEK_SET) == 0, "_lseek failed\n");
|
||||||
|
ok(_write(fb1.fd, "ate", 3) == 3, "_write failed\n");
|
||||||
|
pret = (filebuf*) call_func1(p_filebuf_close, &fb1);
|
||||||
|
ok(pret == &fb1, "wrong return, expected %p got %p\n", &fb1, pret);
|
||||||
|
pret = (filebuf*) call_func4(p_filebuf_open, &fb1, filename1, OPENMODE_in, filebuf_openprot);
|
||||||
|
ok(pret == &fb1, "wrong return, expected %p got %p\n", &fb1, pret);
|
||||||
|
ok(_read(fb1.fd, read_buffer, 13) == 13, "read failed\n");
|
||||||
|
read_buffer[13] = 0;
|
||||||
|
ok(!strncmp(read_buffer, "atetingappend", 13), "wrong contents, expected 'atetingappend' got '%s'\n", read_buffer);
|
||||||
|
pret = (filebuf*) call_func1(p_filebuf_close, &fb1);
|
||||||
|
ok(pret == &fb1, "wrong return, expected %p got %p\n", &fb1, pret);
|
||||||
|
pret = (filebuf*) call_func4(p_filebuf_open, &fb1, filename1, OPENMODE_in|OPENMODE_trunc, filebuf_openprot);
|
||||||
|
ok(pret == &fb1, "wrong return, expected %p got %p\n", &fb1, pret);
|
||||||
|
ok(_read(fb1.fd, read_buffer, 1) == 0, "read failed\n");
|
||||||
|
ok(_write(fb1.fd, "file1", 5) == 5, "_write failed\n");
|
||||||
|
pret = (filebuf*) call_func1(p_filebuf_close, &fb1);
|
||||||
|
ok(pret == &fb1, "wrong return, expected %p got %p\n", &fb1, pret);
|
||||||
|
pret = (filebuf*) call_func4(p_filebuf_open, &fb1, filename1, OPENMODE_in|OPENMODE_app, filebuf_openprot);
|
||||||
|
ok(pret == &fb1, "wrong return, expected %p got %p\n", &fb1, pret);
|
||||||
|
ok(_write(fb1.fd, "app", 3) == 3, "_write failed\n");
|
||||||
|
ok(_read(fb1.fd, read_buffer, 1) == 0, "read failed\n");
|
||||||
|
ok(_lseek(fb1.fd, 0, SEEK_SET) == 0, "_lseek failed\n");
|
||||||
|
ok(_read(fb1.fd, read_buffer, 8) == 8, "read failed\n");
|
||||||
|
read_buffer[8] = 0;
|
||||||
|
ok(!strncmp(read_buffer, "file1app", 8), "wrong contents, expected 'file1app' got '%s'\n", read_buffer);
|
||||||
|
fb1.base.do_lock = -1;
|
||||||
|
|
||||||
|
fb2.fd = -1;
|
||||||
|
pret = (filebuf*) call_func4(p_filebuf_open, &fb2, filename2, OPENMODE_out|OPENMODE_nocreate, filebuf_openprot);
|
||||||
|
ok(pret == NULL, "wrong return, expected %p got %p\n", NULL, pret);
|
||||||
|
pret = (filebuf*) call_func4(p_filebuf_open, &fb2, filename2, OPENMODE_in|OPENMODE_nocreate, filebuf_openprot);
|
||||||
|
ok(pret == NULL, "wrong return, expected %p got %p\n", NULL, pret);
|
||||||
|
fb2.base.do_lock = 0;
|
||||||
|
pret = (filebuf*) call_func4(p_filebuf_open, &fb2, filename2, OPENMODE_in, filebuf_openprot);
|
||||||
|
ok(pret == &fb2, "wrong return, expected %p got %p\n", &fb2, pret);
|
||||||
|
ok(_read(fb1.fd, read_buffer, 1) == 0, "read failed\n");
|
||||||
|
pret = (filebuf*) call_func1(p_filebuf_close, &fb2);
|
||||||
|
ok(pret == &fb2, "wrong return, expected %p got %p\n", &fb2, pret);
|
||||||
|
fb2.base.do_lock = -1;
|
||||||
|
pret = (filebuf*) call_func4(p_filebuf_open, &fb2, filename2, OPENMODE_in|OPENMODE_noreplace, filebuf_openprot);
|
||||||
|
ok(pret == NULL, "wrong return, expected %p got %p\n", NULL, pret);
|
||||||
|
pret = (filebuf*) call_func4(p_filebuf_open, &fb2, filename2, OPENMODE_trunc|OPENMODE_noreplace, filebuf_openprot);
|
||||||
|
ok(pret == NULL, "wrong return, expected %p got %p\n", NULL, pret);
|
||||||
|
pret = (filebuf*) call_func4(p_filebuf_open, &fb2, filename3, OPENMODE_out|OPENMODE_nocreate|OPENMODE_noreplace, filebuf_openprot);
|
||||||
|
ok(pret == NULL, "wrong return, expected %p got %p\n", NULL, pret);
|
||||||
|
|
||||||
|
/* open protection*/
|
||||||
|
fb3.fd = -1;
|
||||||
|
fb3.base.do_lock = 0;
|
||||||
|
pret = (filebuf*) call_func4(p_filebuf_open, &fb3, filename3, OPENMODE_in, filebuf_openprot);
|
||||||
|
ok(pret == &fb3, "wrong return, expected %p got %p\n", &fb3, pret);
|
||||||
|
fb2.base.do_lock = 0;
|
||||||
|
pret = (filebuf*) call_func4(p_filebuf_open, &fb2, filename3, OPENMODE_in|OPENMODE_out, filebuf_openprot);
|
||||||
|
ok(pret == &fb2, "wrong return, expected %p got %p\n", &fb2, pret);
|
||||||
|
pret = (filebuf*) call_func1(p_filebuf_close, &fb2);
|
||||||
|
ok(pret == &fb2, "wrong return, expected %p got %p\n", &fb2, pret);
|
||||||
|
fb2.base.do_lock = -1;
|
||||||
|
pret = (filebuf*) call_func1(p_filebuf_close, &fb3);
|
||||||
|
ok(pret == &fb3, "wrong return, expected %p got %p\n", &fb3, pret);
|
||||||
|
pret = (filebuf*) call_func4(p_filebuf_open, &fb3, filename3, OPENMODE_in, filebuf_sh_none);
|
||||||
|
ok(pret == &fb3, "wrong return, expected %p got %p\n", &fb3, pret);
|
||||||
|
pret = (filebuf*) call_func4(p_filebuf_open, &fb2, filename3, OPENMODE_in, filebuf_openprot);
|
||||||
|
ok(pret == NULL, "wrong return, expected %p got %p\n", NULL, pret);
|
||||||
|
fb3.base.do_lock = -1;
|
||||||
|
|
||||||
|
/* close */
|
||||||
|
pret = (filebuf*) call_func1(p_filebuf_close, &fb2);
|
||||||
|
ok(pret == NULL, "wrong return, expected %p got %p\n", NULL, pret);
|
||||||
|
fb3.base.do_lock = 0;
|
||||||
|
pret = (filebuf*) call_func1(p_filebuf_close, &fb3);
|
||||||
|
ok(pret == &fb3, "wrong return, expected %p got %p\n", &fb3, pret);
|
||||||
|
ok(fb3.fd == -1, "wrong fd, expected -1 got %d\n", fb3.fd);
|
||||||
|
fb3.fd = 5;
|
||||||
|
pret = (filebuf*) call_func1(p_filebuf_close, &fb3);
|
||||||
|
ok(pret == NULL, "wrong return, expected %p got %p\n", NULL, pret);
|
||||||
|
ok(fb3.fd == 5, "wrong fd, expected 5 got %d\n", fb3.fd);
|
||||||
|
fb3.base.do_lock = -1;
|
||||||
|
|
||||||
SetEvent(lock_arg.test);
|
SetEvent(lock_arg.test);
|
||||||
WaitForSingleObject(thread, INFINITE);
|
WaitForSingleObject(thread, INFINITE);
|
||||||
|
|
||||||
/* destructor */
|
/* destructor */
|
||||||
call_func1(p_filebuf_dtor, &fb1);
|
call_func1(p_filebuf_dtor, &fb1);
|
||||||
|
ok(fb1.fd == -1, "wrong fd, expected -1 got %d\n", fb1.fd);
|
||||||
call_func1(p_filebuf_dtor, &fb2);
|
call_func1(p_filebuf_dtor, &fb2);
|
||||||
call_func1(p_filebuf_dtor, &fb3);
|
call_func1(p_filebuf_dtor, &fb3);
|
||||||
|
|
||||||
|
ok(_unlink(filename1) == 0, "Couldn't unlink file named '%s'\n", filename1);
|
||||||
|
ok(_unlink(filename2) == 0, "Couldn't unlink file named '%s'\n", filename2);
|
||||||
|
ok(_unlink(filename3) == 0, "Couldn't unlink file named '%s'\n", filename3);
|
||||||
CloseHandle(lock_arg.lock);
|
CloseHandle(lock_arg.lock);
|
||||||
CloseHandle(lock_arg.test);
|
CloseHandle(lock_arg.test);
|
||||||
CloseHandle(thread);
|
CloseHandle(thread);
|
||||||
|
|
Loading…
Reference in New Issue