[4/5] msvcirt: Implement filebuf::attach

Iván Matellanes matellanesivan at gmail.com
Mon Aug 3 09:49:01 CDT 2015


---
 dlls/msvcirt/msvcirt.c       | 11 ++++++--
 dlls/msvcirt/tests/msvcirt.c | 65 +++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 73 insertions(+), 3 deletions(-)

diff --git a/dlls/msvcirt/msvcirt.c b/dlls/msvcirt/msvcirt.c
index 8e9f93a..0fd9123 100644
--- a/dlls/msvcirt/msvcirt.c
+++ b/dlls/msvcirt/msvcirt.c
@@ -868,8 +868,15 @@ filebuf* __thiscall filebuf_scalar_dtor(filebuf *this, unsigned int flags)
 DEFINE_THISCALL_WRAPPER(filebuf_attach, 8)
 filebuf* __thiscall filebuf_attach(filebuf *this, filedesc fd)
 {
-    FIXME("(%p %d) stub\n", this, fd);
-    return NULL;
+    TRACE("(%p %d)\n", this, fd);
+    if (this->fd != -1)
+        return NULL;
+
+    streambuf_lock(&this->base);
+    this->fd = fd;
+    streambuf_allocate(&this->base);
+    streambuf_unlock(&this->base);
+    return this;
 }
 
 /* ?close at filebuf@@QAEPAV1 at XZ */
diff --git a/dlls/msvcirt/tests/msvcirt.c b/dlls/msvcirt/tests/msvcirt.c
index 8437e9c..b1d49a6 100644
--- a/dlls/msvcirt/tests/msvcirt.c
+++ b/dlls/msvcirt/tests/msvcirt.c
@@ -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_ctor)(filebuf*);
 static void (*__thiscall p_filebuf_dtor)(filebuf*);
+static filebuf* (*__thiscall p_filebuf_attach)(filebuf*, filedesc);
 
 /* 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 at HPEADH@Z");
         SET(p_filebuf_ctor, "??0filebuf@@QEAA at XZ");
         SET(p_filebuf_dtor, "??1filebuf@@UEAA at XZ");
+        SET(p_filebuf_attach, "?attach at filebuf@@QEAAPEAV1 at H@Z");
 
         SET(p_ios_copy_ctor, "??0ios@@IEAA at AEBV0@@Z");
         SET(p_ios_ctor, "??0ios@@IEAA at XZ");
@@ -324,6 +326,7 @@ static BOOL init(void)
         SET(p_filebuf_fd_reserve_ctor, "??0filebuf@@QAE at HPADH@Z");
         SET(p_filebuf_ctor, "??0filebuf@@QAE at XZ");
         SET(p_filebuf_dtor, "??1filebuf@@UAE at XZ");
+        SET(p_filebuf_attach, "?attach at filebuf@@QAEPAV1 at H@Z");
 
         SET(p_ios_copy_ctor, "??0ios@@IAE at ABV0@@Z");
         SET(p_ios_ctor, "??0ios@@IAE at XZ");
@@ -901,9 +904,32 @@ static void test_streambuf(void)
     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)
 {
-    filebuf fb1, fb2, fb3;
+    filebuf fb1, fb2, fb3, *pret;
+    struct filebuf_lock_arg lock_arg;
+    HANDLE thread;
 
     memset(&fb1, 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.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 */
     call_func1(p_filebuf_dtor, &fb1);
     call_func1(p_filebuf_dtor, &fb2);
     call_func1(p_filebuf_dtor, &fb3);
+
+    CloseHandle(lock_arg.lock);
+    CloseHandle(lock_arg.test);
+    CloseHandle(thread);
 }
 
 struct ios_lock_arg
-- 
2.1.4




More information about the wine-patches mailing list