msvcirt: Implement filebuf::attach.
This commit is contained in:
parent
2f702e3dd6
commit
e2659db454
|
@ -868,8 +868,15 @@ filebuf* __thiscall filebuf_scalar_dtor(filebuf *this, unsigned int flags)
|
||||||
DEFINE_THISCALL_WRAPPER(filebuf_attach, 8)
|
DEFINE_THISCALL_WRAPPER(filebuf_attach, 8)
|
||||||
filebuf* __thiscall filebuf_attach(filebuf *this, filedesc fd)
|
filebuf* __thiscall filebuf_attach(filebuf *this, filedesc fd)
|
||||||
{
|
{
|
||||||
FIXME("(%p %d) stub\n", this, fd);
|
TRACE("(%p %d)\n", this, fd);
|
||||||
|
if (this->fd != -1)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
streambuf_lock(&this->base);
|
||||||
|
this->fd = fd;
|
||||||
|
streambuf_allocate(&this->base);
|
||||||
|
streambuf_unlock(&this->base);
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ?close@filebuf@@QAEPAV1@XZ */
|
/* ?close@filebuf@@QAEPAV1@XZ */
|
||||||
|
|
|
@ -134,6 +134,7 @@ static filebuf* (*__thiscall p_filebuf_fd_ctor)(filebuf*, int);
|
||||||
static filebuf* (*__thiscall p_filebuf_fd_reserve_ctor)(filebuf*, int, char*, int);
|
static filebuf* (*__thiscall p_filebuf_fd_reserve_ctor)(filebuf*, int, char*, int);
|
||||||
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);
|
||||||
|
|
||||||
/* ios */
|
/* ios */
|
||||||
static ios* (*__thiscall p_ios_copy_ctor)(ios*, const ios*);
|
static ios* (*__thiscall p_ios_copy_ctor)(ios*, const ios*);
|
||||||
|
@ -269,6 +270,7 @@ static BOOL init(void)
|
||||||
SET(p_filebuf_fd_reserve_ctor, "??0filebuf@@QEAA@HPEADH@Z");
|
SET(p_filebuf_fd_reserve_ctor, "??0filebuf@@QEAA@HPEADH@Z");
|
||||||
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_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");
|
||||||
|
@ -324,6 +326,7 @@ static BOOL init(void)
|
||||||
SET(p_filebuf_fd_reserve_ctor, "??0filebuf@@QAE@HPADH@Z");
|
SET(p_filebuf_fd_reserve_ctor, "??0filebuf@@QAE@HPADH@Z");
|
||||||
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_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");
|
||||||
|
@ -901,9 +904,32 @@ static void test_streambuf(void)
|
||||||
CloseHandle(thread);
|
CloseHandle(thread);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct filebuf_lock_arg
|
||||||
|
{
|
||||||
|
filebuf *fb1, *fb2, *fb3;
|
||||||
|
HANDLE lock;
|
||||||
|
HANDLE test;
|
||||||
|
};
|
||||||
|
|
||||||
|
static DWORD WINAPI lock_filebuf(void *arg)
|
||||||
|
{
|
||||||
|
struct filebuf_lock_arg *lock_arg = arg;
|
||||||
|
call_func1(p_streambuf_lock, &lock_arg->fb1->base);
|
||||||
|
call_func1(p_streambuf_lock, &lock_arg->fb2->base);
|
||||||
|
call_func1(p_streambuf_lock, &lock_arg->fb3->base);
|
||||||
|
SetEvent(lock_arg->lock);
|
||||||
|
WaitForSingleObject(lock_arg->test, INFINITE);
|
||||||
|
call_func1(p_streambuf_unlock, &lock_arg->fb1->base);
|
||||||
|
call_func1(p_streambuf_unlock, &lock_arg->fb2->base);
|
||||||
|
call_func1(p_streambuf_unlock, &lock_arg->fb3->base);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void test_filebuf(void)
|
static void test_filebuf(void)
|
||||||
{
|
{
|
||||||
filebuf fb1, fb2, fb3;
|
filebuf fb1, fb2, fb3, *pret;
|
||||||
|
struct filebuf_lock_arg lock_arg;
|
||||||
|
HANDLE thread;
|
||||||
|
|
||||||
memset(&fb1, 0xab, sizeof(filebuf));
|
memset(&fb1, 0xab, sizeof(filebuf));
|
||||||
memset(&fb2, 0xab, sizeof(filebuf));
|
memset(&fb2, 0xab, sizeof(filebuf));
|
||||||
|
@ -926,10 +952,47 @@ static void test_filebuf(void)
|
||||||
ok(fb3.fd == -1, "wrong fd, expected -1 got %d\n", fb3.fd);
|
ok(fb3.fd == -1, "wrong fd, expected -1 got %d\n", fb3.fd);
|
||||||
ok(fb3.close == 0, "wrong value, expected 0 got %d\n", fb3.close);
|
ok(fb3.close == 0, "wrong value, expected 0 got %d\n", fb3.close);
|
||||||
|
|
||||||
|
lock_arg.fb1 = &fb1;
|
||||||
|
lock_arg.fb2 = &fb2;
|
||||||
|
lock_arg.fb3 = &fb3;
|
||||||
|
lock_arg.lock = CreateEventW(NULL, FALSE, FALSE, NULL);
|
||||||
|
ok(lock_arg.lock != NULL, "CreateEventW failed\n");
|
||||||
|
lock_arg.test = CreateEventW(NULL, FALSE, FALSE, NULL);
|
||||||
|
ok(lock_arg.test != NULL, "CreateEventW failed\n");
|
||||||
|
thread = CreateThread(NULL, 0, lock_filebuf, (void*)&lock_arg, 0, NULL);
|
||||||
|
ok(thread != NULL, "CreateThread failed\n");
|
||||||
|
WaitForSingleObject(lock_arg.lock, INFINITE);
|
||||||
|
|
||||||
|
/* attach */
|
||||||
|
pret = (filebuf*) call_func2(p_filebuf_attach, &fb1, 2);
|
||||||
|
ok(pret == NULL, "wrong return, expected %p got %p\n", NULL, pret);
|
||||||
|
ok(fb1.base.allocated == 0, "wrong allocate value, expected 0 got %d\n", fb1.base.allocated);
|
||||||
|
ok(fb1.fd == 1, "wrong fd, expected 1 got %d\n", fb1.fd);
|
||||||
|
fb2.fd = -1;
|
||||||
|
fb2.base.do_lock = 0;
|
||||||
|
pret = (filebuf*) call_func2(p_filebuf_attach, &fb2, 3);
|
||||||
|
ok(pret == &fb2, "wrong return, expected %p got %p\n", &fb2, pret);
|
||||||
|
ok(fb2.base.allocated == 0, "wrong allocate value, expected 0 got %d\n", fb2.base.allocated);
|
||||||
|
ok(fb2.fd == 3, "wrong fd, expected 3 got %d\n", fb2.fd);
|
||||||
|
fb2.base.do_lock = -1;
|
||||||
|
fb3.base.do_lock = 0;
|
||||||
|
pret = (filebuf*) call_func2(p_filebuf_attach, &fb3, 2);
|
||||||
|
ok(pret == &fb3, "wrong return, expected %p got %p\n", &fb3, pret);
|
||||||
|
ok(fb3.base.allocated == 1, "wrong allocate value, expected 1 got %d\n", fb3.base.allocated);
|
||||||
|
ok(fb3.fd == 2, "wrong fd, expected 2 got %d\n", fb3.fd);
|
||||||
|
fb3.base.do_lock = -1;
|
||||||
|
|
||||||
|
SetEvent(lock_arg.test);
|
||||||
|
WaitForSingleObject(thread, INFINITE);
|
||||||
|
|
||||||
/* destructor */
|
/* destructor */
|
||||||
call_func1(p_filebuf_dtor, &fb1);
|
call_func1(p_filebuf_dtor, &fb1);
|
||||||
call_func1(p_filebuf_dtor, &fb2);
|
call_func1(p_filebuf_dtor, &fb2);
|
||||||
call_func1(p_filebuf_dtor, &fb3);
|
call_func1(p_filebuf_dtor, &fb3);
|
||||||
|
|
||||||
|
CloseHandle(lock_arg.lock);
|
||||||
|
CloseHandle(lock_arg.test);
|
||||||
|
CloseHandle(thread);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ios_lock_arg
|
struct ios_lock_arg
|
||||||
|
|
Loading…
Reference in New Issue