Source code

Revision control

Other Tools

1
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2
*
3
* This Source Code Form is subject to the terms of the Mozilla Public
4
* License, v. 2.0. If a copy of the MPL was not distributed with this
5
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7
#include "mozilla/Assertions.h"
8
#include "ShutdownLayer.h"
9
#include "prerror.h"
10
#include "private/pprio.h"
11
#include "prmem.h"
12
#include <winsock2.h>
13
14
static PRDescIdentity sWinSockShutdownLayerIdentity;
15
static PRIOMethods sWinSockShutdownLayerMethods;
16
static PRIOMethods* sWinSockShutdownLayerMethodsPtr = nullptr;
17
18
namespace mozilla {
19
namespace net {
20
21
extern PRDescIdentity nsNamedPipeLayerIdentity;
22
23
} // namespace net
24
} // namespace mozilla
25
26
PRStatus WinSockClose(PRFileDesc* aFd) {
27
MOZ_RELEASE_ASSERT(aFd->identity == sWinSockShutdownLayerIdentity,
28
"Windows shutdown layer not on the top of the stack");
29
30
PROsfd osfd = PR_FileDesc2NativeHandle(aFd);
31
if (osfd != -1) {
32
shutdown(osfd, SD_BOTH);
33
}
34
35
aFd->identity = PR_INVALID_IO_LAYER;
36
37
if (aFd->lower) {
38
return aFd->lower->methods->close(aFd->lower);
39
} else {
40
return PR_SUCCESS;
41
}
42
}
43
44
nsresult mozilla::net::AttachShutdownLayer(PRFileDesc* aFd) {
45
if (!sWinSockShutdownLayerMethodsPtr) {
46
sWinSockShutdownLayerIdentity =
47
PR_GetUniqueIdentity("windows shutdown call layer");
48
sWinSockShutdownLayerMethods = *PR_GetDefaultIOMethods();
49
sWinSockShutdownLayerMethods.close = WinSockClose;
50
sWinSockShutdownLayerMethodsPtr = &sWinSockShutdownLayerMethods;
51
}
52
53
if (mozilla::net::nsNamedPipeLayerIdentity &&
54
PR_GetIdentitiesLayer(aFd, mozilla::net::nsNamedPipeLayerIdentity)) {
55
// Do not attach shutdown layer on named pipe layer,
56
// it is for PR_NSPR_IO_LAYER only.
57
return NS_OK;
58
}
59
60
PRFileDesc* layer;
61
PRStatus status;
62
63
layer = PR_CreateIOLayerStub(sWinSockShutdownLayerIdentity,
64
sWinSockShutdownLayerMethodsPtr);
65
if (!layer) {
66
return NS_OK;
67
}
68
69
status = PR_PushIOLayer(aFd, PR_NSPR_IO_LAYER, layer);
70
71
if (status == PR_FAILURE) {
72
PR_Free(layer); // PR_CreateIOLayerStub() uses PR_Malloc().
73
return NS_ERROR_FAILURE;
74
}
75
return NS_OK;
76
}