tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

ShutdownLayer.cpp (2219B)


      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 }