/* Functional tests for Socket public functions */ static void do_other_work(void) { /* while waiting for nonblocking I/O to complete */ (void) PR_Sleep(2*60); }
// Test a message send???? nsresult nsEudoraCompose::SendTheMessage(nsIFile *pMailImportLocation, nsIFile **pMsg) { nsresult rv = CreateComponents(); if (NS_SUCCEEDED( rv)) rv = CreateIdentity(); if (NS_FAILED( rv)) return( rv); // IMPORT_LOG0( "Outlook Compose created necessary components\n"); nsString bodyType; nsString charSet; nsString headerVal; GetHeaderValue( m_pHeaders, m_headerLen, "From:", headerVal); if (!headerVal.IsEmpty()) m_pMsgFields->SetFrom( headerVal); GetHeaderValue( m_pHeaders, m_headerLen, "To:", headerVal); if (!headerVal.IsEmpty()) m_pMsgFields->SetTo( headerVal); GetHeaderValue( m_pHeaders, m_headerLen, "Subject:", headerVal); if (!headerVal.IsEmpty()) m_pMsgFields->SetSubject( headerVal); GetHeaderValue( m_pHeaders, m_headerLen, "Content-type:", headerVal); bodyType = headerVal; ExtractType( bodyType); ExtractCharset( headerVal); // Use platform charset as default if the msg doesn't specify one // (ie, no 'charset' param in the Content-Type: header). As the last // resort we'll use the mail default charset. // (ie, no 'charset' param in the Content-Type: header) or if the // charset parameter fails a length sanity check. // As the last resort we'll use the mail default charset. if ( headerVal.IsEmpty() || (headerVal.Length() > kContentTypeLengthSanityCheck) ) { CopyASCIItoUTF16(nsMsgI18NFileSystemCharset(), headerVal); if (headerVal.IsEmpty()) { // last resort if (m_defCharset.IsEmpty()) { nsString defaultCharset; NS_GetLocalizedUnicharPreferenceWithDefault(nsnull, "mailnews.view_default_charset", NS_LITERAL_STRING("ISO-8859-1"), defaultCharset); m_defCharset = defaultCharset; } headerVal = m_defCharset; } } m_pMsgFields->SetCharacterSet( NS_LossyConvertUTF16toASCII(headerVal).get() ); charSet = headerVal; GetHeaderValue( m_pHeaders, m_headerLen, "CC:", headerVal); if (!headerVal.IsEmpty()) m_pMsgFields->SetCc( headerVal); GetHeaderValue( m_pHeaders, m_headerLen, "Message-ID:", headerVal); if (!headerVal.IsEmpty()) m_pMsgFields->SetMessageId( NS_LossyConvertUTF16toASCII(headerVal).get() ); GetHeaderValue( m_pHeaders, m_headerLen, "Reply-To:", headerVal); if (!headerVal.IsEmpty()) m_pMsgFields->SetReplyTo( headerVal); // what about all of the other headers?!?!?!?!?!?! char *pMimeType; if (!bodyType.IsEmpty()) pMimeType = ToNewCString(bodyType); else pMimeType = ToNewCString(m_bodyType); // IMPORT_LOG0( "Outlook compose calling CreateAndSendMessage\n"); nsMsgAttachedFile *pAttach = GetLocalAttachments(); /* l10n - I have the body of the message in the system charset, I need to "encode" it to be the charset for the message *UNLESS* of course, I don't know what the charset of the message should be? How do I determine what the charset should be if it doesn't exist? */ nsString uniBody; NS_CopyNativeToUnicode( nsDependentCString(m_pBody), uniBody); nsCString body; rv = nsMsgI18NConvertFromUnicode( NS_LossyConvertUTF16toASCII(charSet).get(), uniBody, body); if (NS_FAILED( rv)) { // in this case, if we did not use the default compose // charset, then try that. if (!charSet.Equals( m_defCharset)) { body.Truncate(); rv = nsMsgI18NConvertFromUnicode( NS_LossyConvertUTF16toASCII(charSet).get(), uniBody, body); } } uniBody.Truncate(); // See if it's a draft msg (ie, no From: or no To: AND no Cc: AND no Bcc:). // Eudora saves sent and draft msgs in Out folder (ie, mixed) and it does // store Bcc: header in the msg itself. nsMsgDeliverMode mode = nsIMsgSend::nsMsgDeliverNow; nsAutoString from, to, cc, bcc; rv = m_pMsgFields->GetFrom(from); rv = m_pMsgFields->GetTo(to); rv = m_pMsgFields->GetCc(cc); rv = m_pMsgFields->GetBcc(bcc); if ( from.IsEmpty() || to.IsEmpty() && cc.IsEmpty() && bcc.IsEmpty() ) mode = nsIMsgSend::nsMsgSaveAsDraft; // We only get the editor interface when there's embedded content. // Otherwise pEditor remains NULL. That way we only import with the pseudo // editor when it helps. nsRefPtr<nsEudoraEditor> pEudoraEditor = new nsEudoraEditor(m_pBody, pMailImportLocation); nsCOMPtr<nsIEditor> pEditor; if (pEudoraEditor->HasEmbeddedContent()) // There's embedded content that we need to import, so query for the editor interface pEudoraEditor->QueryInterface( NS_GET_IID(nsIEditor), getter_AddRefs(pEditor) ); if (NS_FAILED( rv)) { rv = m_pSendProxy->CreateAndSendMessage( pEditor.get(), // pseudo editor shell when there's embedded content s_pIdentity, // dummy identity nsnull, // account key m_pMsgFields, // message fields PR_FALSE, // digest = NO PR_TRUE, // dont_deliver = YES, make a file mode, // mode nsnull, // no message to replace pMimeType, // body type m_pBody, // body pointer m_bodyLen, // body length nsnull, // remote attachment data pAttach, // local attachments nsnull, // related part nsnull, // parent window nsnull, // progress listener m_pListener, // listener nsnull, // password EmptyCString(), // originalMsgURI nsnull); // message compose type } else { rv = m_pSendProxy->CreateAndSendMessage( pEditor.get(), // pseudo editor shell when there's embedded content s_pIdentity, // dummy identity nsnull, // account key m_pMsgFields, // message fields PR_FALSE, // digest = NO PR_TRUE, // dont_deliver = YES, make a file mode, // mode nsnull, // no message to replace pMimeType, // body type body.get(), // body pointer body.Length(), // body length nsnull, // remote attachment data pAttach, // local attachments nsnull, // related part nsnull, // parent window nsnull, // progress listener m_pListener, // listener nsnull, // password EmptyCString(), // originalMsgURI nsnull); // message compose type } // IMPORT_LOG0( "Returned from CreateAndSendMessage\n"); if (pAttach) delete [] pAttach; EudoraSendListener *pListen = (EudoraSendListener *)m_pListener; if (NS_FAILED( rv)) { IMPORT_LOG1( "*** Error, CreateAndSendMessage FAILED: 0x%lx\n", rv); // IMPORT_LOG1( "Headers: %80s\n", m_pHeaders); } else { // wait for the listener to get done! PRInt32 abortCnt = 0; PRInt32 cnt = 0; PRInt32 sleepCnt = 1; while (!pListen->m_done && (abortCnt < kHungAbortCount)) { PR_Sleep( sleepCnt); cnt++; if (cnt > kHungCount) { abortCnt++; sleepCnt *= 2; cnt = 0; } } if (abortCnt >= kHungAbortCount) { IMPORT_LOG0( "**** Create and send message hung\n"); IMPORT_LOG1( "Headers: %s\n", m_pHeaders); IMPORT_LOG1( "Body: %s\n", m_pBody); rv = NS_ERROR_FAILURE; } } if (pMimeType) NS_Free( pMimeType); if (pListen->m_location) { pListen->m_location->Clone(pMsg); rv = NS_OK; } else { rv = NS_ERROR_FAILURE; IMPORT_LOG0( "*** Error, Outlook compose unsuccessful\n"); } pListen->Reset(); return( rv); }
int main(int argc, char* argv[]) { if (test_common_init(&argc, &argv) != 0) return -1; nsresult rv; if (argc < 4) { printf("usage: TestSocketTransport <host> <port> <path>\n"); return -1; } { nsCOMPtr<nsIServiceManager> servMan; NS_InitXPCOM2(getter_AddRefs(servMan), nullptr, nullptr); nsCOMPtr<nsIComponentRegistrar> registrar = do_QueryInterface(servMan); NS_ASSERTION(registrar, "Null nsIComponentRegistrar"); if (registrar) registrar->AutoRegister(nullptr); #if defined(PR_LOGGING) gTestLog = PR_NewLogModule("Test"); #endif // Make sure the DNS service is initialized on the main thread nsCOMPtr<nsIDNSService> dns = do_GetService(NS_DNSSERVICE_CONTRACTID, &rv); if (NS_FAILED(rv)) return rv; nsCOMPtr<nsPISocketTransportService> sts = do_GetService(kSocketTransportServiceCID, &rv); if (NS_FAILED(rv)) return rv; LOG(("phase 1 tests...\n")); LOG(("flags = { OPEN_UNBUFFERED, OPEN_UNBUFFERED }\n")); rv = RunCloseTest(sts, argv[1], atoi(argv[2]), nsITransport::OPEN_UNBUFFERED, nsITransport::OPEN_UNBUFFERED); NS_ASSERTION(NS_SUCCEEDED(rv), "RunCloseTest failed"); LOG(("flags = { OPEN_BUFFERED, OPEN_UNBUFFERED }\n")); rv = RunCloseTest(sts, argv[1], atoi(argv[2]), 0 /* nsITransport::OPEN_BUFFERED */, nsITransport::OPEN_UNBUFFERED); NS_ASSERTION(NS_SUCCEEDED(rv), "RunCloseTest failed"); LOG(("flags = { OPEN_UNBUFFERED, OPEN_BUFFERED }\n")); rv = RunCloseTest(sts, argv[1], atoi(argv[2]), nsITransport::OPEN_UNBUFFERED, 0 /*nsITransport::OPEN_BUFFERED */); NS_ASSERTION(NS_SUCCEEDED(rv), "RunCloseTest failed"); LOG(("flags = { OPEN_BUFFERED, OPEN_BUFFERED }\n")); rv = RunCloseTest(sts, argv[1], atoi(argv[2]), 0 /*nsITransport::OPEN_BUFFERED */, 0 /*nsITransport::OPEN_BUFFERED */); NS_ASSERTION(NS_SUCCEEDED(rv), "RunCloseTest failed"); LOG(("calling Shutdown on socket transport service:\n")); sts->Shutdown(); LOG(("calling Init on socket transport service:\n")); sts->Init(); LOG(("phase 2 tests...\n")); LOG(("flags = { OPEN_UNBUFFERED, OPEN_UNBUFFERED }\n")); rv = RunTest(sts, argv[1], atoi(argv[2]), argv[3], nsITransport::OPEN_UNBUFFERED, nsITransport::OPEN_UNBUFFERED); NS_ASSERTION(NS_SUCCEEDED(rv), "RunTest failed"); LOG(("flags = { OPEN_BUFFERED, OPEN_UNBUFFERED }\n")); rv = RunTest(sts, argv[1], atoi(argv[2]), argv[3], 0 /* nsITransport::OPEN_BUFFERED */, nsITransport::OPEN_UNBUFFERED); NS_ASSERTION(NS_SUCCEEDED(rv), "RunTest failed"); LOG(("flags = { OPEN_UNBUFFERED, OPEN_BUFFERED }\n")); rv = RunTest(sts, argv[1], atoi(argv[2]), argv[3], nsITransport::OPEN_UNBUFFERED, 0 /*nsITransport::OPEN_BUFFERED */); NS_ASSERTION(NS_SUCCEEDED(rv), "RunTest failed"); LOG(("flags = { OPEN_BUFFERED, OPEN_BUFFERED }\n")); rv = RunTest(sts, argv[1], atoi(argv[2]), argv[3], 0 /*nsITransport::OPEN_BUFFERED */, 0 /*nsITransport::OPEN_BUFFERED */); NS_ASSERTION(NS_SUCCEEDED(rv), "RunTest failed"); LOG(("waiting 1 second before calling Shutdown...\n")); PR_Sleep(PR_SecondsToInterval(1)); LOG(("calling Shutdown on socket transport service:\n")); sts->Shutdown(); // give background threads a chance to finish whatever work they may // be doing. LOG(("waiting 1 second before exiting...\n")); PR_Sleep(PR_SecondsToInterval(1)); } // this scopes the nsCOMPtrs // no nsCOMPtrs are allowed to be alive when you call NS_ShutdownXPCOM rv = NS_ShutdownXPCOM(nullptr); NS_ASSERTION(NS_SUCCEEDED(rv), "NS_ShutdownXPCOM failed"); return 0; }
static void PR_CALLBACK Thread(void *sleep) { PR_Sleep(PR_SecondsToInterval((PRUint32)sleep)); printf("Thread exiting\n"); }
/* Non-blocking I/O */ static void ClientNB(void *arg) { PRFileDesc *sock; PRSocketOptionData opt; PRUint16 port = (PRUint16) arg; PRNetAddr addr; char buf[BUFFER_SIZE]; PRPollDesc pd; PRInt32 npds; PRInt32 nbytes; int i; int j; sock = PR_OpenTCPSocket(PR_AF_INET6); if (NULL == sock) { fprintf(stderr, "PR_OpenTCPSocket failed\n"); exit(1); } opt.option = PR_SockOpt_Nonblocking; opt.value.non_blocking = PR_TRUE; if (PR_SetSocketOption(sock, &opt) == PR_FAILURE) { fprintf(stderr, "PR_SetSocketOption failed\n"); exit(1); } memset(&addr, 0, sizeof(addr)); if (PR_SetNetAddr(PR_IpAddrLoopback, PR_AF_INET6, port, &addr) == PR_FAILURE) { fprintf(stderr, "PR_SetNetAddr failed\n"); exit(1); } if (PR_Connect(sock, &addr, PR_INTERVAL_NO_TIMEOUT) == PR_FAILURE) { if (PR_GetError() != PR_IN_PROGRESS_ERROR) { fprintf(stderr, "PR_Connect failed\n"); exit(1); } pd.fd = sock; pd.in_flags = PR_POLL_WRITE | PR_POLL_EXCEPT; npds = PR_Poll(&pd, 1, PR_INTERVAL_NO_TIMEOUT); if (-1 == npds) { fprintf(stderr, "PR_Poll failed\n"); exit(1); } if (1 != npds) { fprintf(stderr, "PR_Poll returned %d, absurd!\n", npds); exit(1); } if (PR_GetConnectStatus(&pd) == PR_FAILURE) { fprintf(stderr, "PR_GetConnectStatus failed\n"); exit(1); } } for (i = 0; i < iterations; i++) { PR_Sleep(PR_SecondsToInterval(1)); memset(buf, 2*i, send_amount[i]); while ((nbytes = PR_Send(sock, buf, send_amount[i], 0, PR_INTERVAL_NO_TIMEOUT)) == -1) { if (PR_GetError() != PR_WOULD_BLOCK_ERROR) { fprintf(stderr, "PR_Send failed\n"); exit(1); } pd.fd = sock; pd.in_flags = PR_POLL_WRITE; npds = PR_Poll(&pd, 1, PR_INTERVAL_NO_TIMEOUT); if (-1 == npds) { fprintf(stderr, "PR_Poll failed\n"); exit(1); } if (1 != npds) { fprintf(stderr, "PR_Poll returned %d, absurd!\n", npds); exit(1); } } if (send_amount[i] != nbytes) { fprintf(stderr, "PR_Send returned %d, absurd!\n", nbytes); exit(1); } memset(buf, 0, sizeof(buf)); while ((nbytes = PR_Recv(sock, buf, recv_amount[i], PR_MSG_PEEK, PR_INTERVAL_NO_TIMEOUT)) == -1) { if (PR_GetError() != PR_WOULD_BLOCK_ERROR) { fprintf(stderr, "PR_Recv failed\n"); exit(1); } pd.fd = sock; pd.in_flags = PR_POLL_READ; npds = PR_Poll(&pd, 1, PR_INTERVAL_NO_TIMEOUT); if (-1 == npds) { fprintf(stderr, "PR_Poll failed\n"); exit(1); } if (1 != npds) { fprintf(stderr, "PR_Poll returned %d, absurd!\n", npds); exit(1); } } if (send_amount[i] != nbytes) { fprintf(stderr, "PR_Recv returned %d, absurd!\n", nbytes); exit(1); } for (j = 0; j < nbytes; j++) { if (buf[j] != 2*i+1) { fprintf(stderr, "byte %d should be %d but is %d\n", j, 2*i+1, buf[j]); exit(1); } } fprintf(stderr, "client: peeked expected data\n"); memset(buf, 0, sizeof(buf)); nbytes = PR_Recv(sock, buf, recv_amount[i], PR_MSG_PEEK, PR_INTERVAL_NO_TIMEOUT); if (-1 == nbytes) { fprintf(stderr, "PR_Recv failed\n"); exit(1); } if (send_amount[i] != nbytes) { fprintf(stderr, "PR_Recv returned %d, absurd!\n", nbytes); exit(1); } for (j = 0; j < nbytes; j++) { if (buf[j] != 2*i+1) { fprintf(stderr, "byte %d should be %d but is %d\n", j, 2*i+1, buf[j]); exit(1); } } fprintf(stderr, "client: peeked expected data\n"); memset(buf, 0, sizeof(buf)); nbytes = PR_Recv(sock, buf, recv_amount[i], 0, PR_INTERVAL_NO_TIMEOUT); if (-1 == nbytes) { fprintf(stderr, "PR_Recv failed\n"); exit(1); } if (send_amount[i] != nbytes) { fprintf(stderr, "PR_Recv returned %d, absurd!\n", nbytes); exit(1); } for (j = 0; j < nbytes; j++) { if (buf[j] != 2*i+1) { fprintf(stderr, "byte %d should be %d but is %d\n", j, 2*i+1, buf[j]); exit(1); } } fprintf(stderr, "client: received expected data\n"); } if (PR_Close(sock) == PR_FAILURE) { fprintf(stderr, "PR_Close failed\n"); exit(1); } }
static void PR_CALLBACK ClientThread(void *_action) { PRInt32 action = * (PRInt32 *) _action; PRInt32 iterations = count; PRFileDesc *sock = NULL; serverAddr.inet.family = AF_INET; serverAddr.inet.port = PR_htons(BASE_PORT); serverAddr.inet.ip = PR_htonl(INADDR_LOOPBACK); for (; iterations--;) { PRInt32 rv; char buf[CLIENT_DATA]; sock = PR_NewTCPSocket(); if (!sock) { if (!debug_mode) failed_already=1; else printf("client: unable to create socket\n"); return; } if (action != CLIENT_TIMEOUT_ACCEPT) { if ((rv = PR_Connect(sock, &serverAddr, timeoutTime)) < 0) { if (!debug_mode) failed_already=1; else printf( "client: unable to connect to server (%ld, %ld, %ld, %ld)\n", iterations, rv, PR_GetError(), PR_GetOSError()); goto ErrorExit; } if (action != CLIENT_TIMEOUT_SEND) { if ((rv = PR_Send(sock, buf, CLIENT_DATA, 0, timeoutTime))< 0) { if (!debug_mode) failed_already=1; else printf("client: unable to send to server (%d, %ld, %ld)\n", CLIENT_DATA, rv, PR_GetError()); goto ErrorExit; } } else { PR_Sleep(PR_SecondsToInterval(TIMEOUTSECS+ 1)); } } else { PR_Sleep(PR_SecondsToInterval(TIMEOUTSECS+ 1)); } if (debug_mode) printf("."); PR_Close(sock); } if (debug_mode) printf("\n"); ErrorExit: if (sock != NULL) PR_Close(sock); }
static void PR_CALLBACK unjoinable(void *arg) { PR_Sleep(PR_INTERVAL_NO_TIMEOUT); }
int main(int argc, char **argv) { int numberOfThreads = 1; if (argc > 1) numberOfThreads = atoi(argv[1]); NS_InitXPCOM2(nsnull, nsnull, nsnull); // Scope code so everything is destroyed before we run call NS_ShutdownXPCOM { nsCOMPtr<nsIComponentRegistrar> registrar; NS_GetComponentRegistrar(getter_AddRefs(registrar)); registrar->AutoRegister(nsnull); RunApartmentTest(); nsCOMPtr<nsIThread> eventLoopThread; NS_NewThread(getter_AddRefs(eventLoopThread)); nsCOMPtr<nsIRunnable> test = new TestSyncProxyToSelf(); eventLoopThread->Dispatch(test, NS_DISPATCH_NORMAL); PRThread *eventLoopPRThread; eventLoopThread->GetPRThread(&eventLoopPRThread); PR_ASSERT(eventLoopPRThread); LOG(("TEST: Spawn Threads:\n")); nsCOMArray<nsIThread> threads; for (PRInt32 spawn = 0; spawn < numberOfThreads; spawn++) { test = new ProxyTest(eventLoopPRThread, spawn); nsCOMPtr<nsIThread> thread; NS_NewThread(getter_AddRefs(thread), test); threads.AppendObject(thread); LOG(("TEST: \tThread (%d) spawned\n", spawn)); PR_Sleep( PR_MillisecondsToInterval(250) ); } LOG(("TEST: All Threads Spawned.\n")); LOG(("TEST: Wait for threads.\n")); for (PRInt32 i = 0; i < numberOfThreads; i++) { LOG(("TEST: Thread (%d) Join...\n", i)); nsresult rv = threads[i]->Shutdown(); LOG(("TEST: Thread (%d) Joined. (error: %x).\n", i, rv)); } LOG(("TEST: Shutting down event loop thread\n")); eventLoopThread->Shutdown(); } LOG(("TEST: Calling Cleanup.\n")); NS_ShutdownXPCOM(nsnull); LOG(("TEST: Return zero.\n")); return 0; }
// This will create two objects both descendants of a single IID. void TestCase_TwoClassesOneInterface(void *arg) { ArgsStruct *argsStruct = (ArgsStruct*) arg; nsCOMPtr<nsIProxyObjectManager> manager = do_GetService(NS_XPCOMPROXY_CONTRACTID); printf("ProxyObjectManager: %p \n", (void *) manager.get()); PR_ASSERT(manager); nsITestProxy *proxyObject; nsITestProxy *proxyObject2; nsTestXPCFoo* foo = new nsTestXPCFoo(); nsTestXPCFoo2* foo2 = new nsTestXPCFoo2(); PR_ASSERT(foo); PR_ASSERT(foo2); manager->GetProxyForObject(argsStruct->thread, NS_GET_IID(nsITestProxy), foo, NS_PROXY_SYNC, (void**)&proxyObject); manager->GetProxyForObject(argsStruct->thread, NS_GET_IID(nsITestProxy), foo2, NS_PROXY_SYNC, (void**)&proxyObject2); if (proxyObject && proxyObject2) { // release ownership of the real object. PRInt32 a; nsresult rv; PRInt32 threadNumber = argsStruct->threadNumber; printf("Deleting real Object (%d)\n", threadNumber); NS_RELEASE(foo); printf("Deleting real Object 2 (%d)\n", threadNumber); NS_RELEASE(foo2); printf("Thread (%d) Prior to calling proxyObject->Test.\n", threadNumber); rv = proxyObject->Test(threadNumber, 0, &a); printf("Thread (%d) error: %d.\n", threadNumber, rv); printf("Thread (%d) Prior to calling proxyObject->Test2.\n", threadNumber); rv = proxyObject->Test2(); printf("Thread (%d) error: %d.\n", threadNumber, rv); printf("Thread (%d) Prior to calling proxyObject2->Test2.\n", threadNumber); rv = proxyObject2->Test2(); printf("Thread (%d) proxyObject2 error: %d.\n", threadNumber, rv); printf("Deleting Proxy Object (%d)\n", threadNumber ); NS_RELEASE(proxyObject); printf("Deleting Proxy Object 2 (%d)\n", threadNumber ); NS_RELEASE(proxyObject2); } PR_Sleep( PR_MillisecondsToInterval(1000) ); // If your thread goes away, your stack goes away. Only use ASYNC on calls that do not have out parameters }
static PRIntn PR_CALLBACK RealMain( PRIntn argc, char **argv ) { PRFileDesc *listenSock, *sock; PRUint16 listenPort; PRNetAddr addr; char buf[CHUNK_SIZE]; PRThread *clientThread; PRInt32 retVal; PRSocketOptionData optval; PRIntn i; PRIntervalTime unitTime = PR_MillisecondsToInterval(UNIT_TIME); /* Create a listening socket */ if ((listenSock = PR_NewTCPSocket()) == NULL) { fprintf(stderr, "Can't create a new TCP socket\n"); exit(1); } addr.inet.family = PR_AF_INET; addr.inet.ip = PR_htonl(PR_INADDR_ANY); addr.inet.port = PR_htons(0); if (PR_Bind(listenSock, &addr) == PR_FAILURE) { fprintf(stderr, "Can't bind socket\n"); exit(1); } if (PR_GetSockName(listenSock, &addr) == PR_FAILURE) { fprintf(stderr, "PR_GetSockName failed\n"); exit(1); } listenPort = PR_ntohs(addr.inet.port); if (PR_Listen(listenSock, 5) == PR_FAILURE) { fprintf(stderr, "Can't listen on a socket\n"); exit(1); } PR_snprintf(buf, sizeof(buf), "The server thread is listening on port %hu\n\n", listenPort); printf("%s", buf); clientThread = PR_CreateThread(PR_USER_THREAD, clientThreadFunc, (void *) listenPort, PR_PRIORITY_NORMAL, PR_LOCAL_THREAD, PR_UNJOINABLE_THREAD, 0); if (clientThread == NULL) { fprintf(stderr, "can't create thread\n"); exit(1); } printf("client thread created.\n"); optval.option = PR_SockOpt_Nonblocking; optval.value.non_blocking = PR_TRUE; PR_SetSocketOption(listenSock, &optval); /* time 0 */ sock = PR_Accept(listenSock, NULL, PR_INTERVAL_NO_TIMEOUT); if (sock != NULL || PR_GetError() != PR_WOULD_BLOCK_ERROR) { PL_PrintError("First Accept\n"); fprintf(stderr, "First PR_Accept() xxx\n" ); exit(1); } printf("accept: EWOULDBLOCK, good\n"); fflush(stdout); /* time 2 */ PR_Sleep(2 * unitTime); sock = PR_Accept(listenSock, NULL, PR_INTERVAL_NO_TIMEOUT); if (sock == NULL) { PL_PrintError("Second Accept\n"); fprintf(stderr, "Second PR_Accept() failed: (%d, %d)\n", PR_GetError(), PR_GetOSError()); exit(1); } printf("accept: succeeded, good\n"); fflush(stdout); PR_Close(listenSock); PR_SetSocketOption(sock, &optval); /* time 3, 5, 6, 8, etc. */ for (i = 0; i < NUMBER_ROUNDS; i++) { PR_Sleep(unitTime); retVal = PR_Recv(sock, buf, sizeof(buf), 0, PR_INTERVAL_NO_TIMEOUT); if (retVal != -1 || PR_GetError() != PR_WOULD_BLOCK_ERROR) { PL_PrintError("First Receive:\n"); fprintf(stderr, "First PR_Recv: retVal: %ld, Error: %ld\n", retVal, PR_GetError()); exit(1); } printf("read: EWOULDBLOCK, good\n"); fflush(stdout); PR_Sleep(2 * unitTime); retVal = PR_Recv(sock, buf, sizeof(buf), 0, PR_INTERVAL_NO_TIMEOUT); if (retVal != CHUNK_SIZE) { PL_PrintError("Second Receive:\n"); fprintf(stderr, "Second PR_Recv: retVal: %ld, Error: %ld\n", retVal, PR_GetError()); exit(1); } printf("read: %d bytes, good\n", retVal); fflush(stdout); } PR_Close(sock); printf("All tests finished\n"); printf("PASS\n"); return 0; }
static void PR_CALLBACK clientThreadFunc(void *arg) { PRUintn port = (PRUintn)arg; PRFileDesc *sock; PRNetAddr addr; char buf[CHUNK_SIZE]; int i; PRIntervalTime unitTime = PR_MillisecondsToInterval(UNIT_TIME); PRSocketOptionData optval; PRStatus retVal; PRInt32 nBytes; /* Initialize the buffer so that Purify won't complain */ memset(buf, 0, sizeof(buf)); addr.inet.family = PR_AF_INET; addr.inet.port = PR_htons((PRUint16)port); addr.inet.ip = PR_htonl(PR_INADDR_LOOPBACK); PR_snprintf(buf, sizeof(buf), "%hu", addr.inet.ip); /* time 1 */ PR_Sleep(unitTime); sock = PR_NewTCPSocket(); optval.option = PR_SockOpt_Nonblocking; optval.value.non_blocking = PR_TRUE; PR_SetSocketOption(sock, &optval); retVal = PR_Connect(sock, &addr, PR_INTERVAL_NO_TIMEOUT); if (retVal == PR_FAILURE && PR_GetError() == PR_IN_PROGRESS_ERROR) { #if !defined(USE_PR_SELECT) PRPollDesc pd; PRInt32 n; fprintf(stderr, "connect: EWOULDBLOCK, good\n"); pd.fd = sock; pd.in_flags = PR_POLL_WRITE; n = PR_Poll(&pd, 1, PR_INTERVAL_NO_TIMEOUT); PR_ASSERT(n == 1); PR_ASSERT(pd.out_flags == PR_POLL_WRITE); #else PR_fd_set writeSet; PRInt32 n; fprintf(stderr, "connect: EWOULDBLOCK, good\n"); PR_FD_ZERO(&writeSet); PR_FD_SET(sock, &writeSet); n = PR_Select(0, NULL, &writeSet, NULL, PR_INTERVAL_NO_TIMEOUT); PR_ASSERT(n == 1); PR_ASSERT(PR_FD_ISSET(sock, &writeSet)); #endif } printf("client connected\n"); fflush(stdout); /* time 4, 7, 11, etc. */ for (i = 0; i < NUMBER_ROUNDS; i++) { PR_Sleep(3 * unitTime); nBytes = PR_Write(sock, buf, sizeof(buf)); if (nBytes == -1) { if (PR_GetError() == PR_WOULD_BLOCK_ERROR) { fprintf(stderr, "write: EWOULDBLOCK\n"); exit(1); } else { fprintf(stderr, "write: failed\n"); } } printf("client sent %d bytes\n", nBytes); fflush(stdout); } PR_Close(sock); }
int main(int argc, char **argv) { PRHostEnt he; PRStatus status; PRIntn next_index; PRUint16 port_number; char netdb_buf[PR_NETDB_BUF_SIZE]; PRNetAddr client_addr, server_addr; PRThread *client_thread, *server_thread; PRIntervalTime delta = PR_MillisecondsToInterval(500); err_out = PR_STDERR; std_out = PR_STDOUT; accept_timeout = PR_SecondsToInterval(2); emu_layer_ident = PR_GetUniqueIdentity("Emulated AcceptRead"); emu_layer_methods = *PR_GetDefaultIOMethods(); emu_layer_methods.acceptread = emu_AcceptRead; if (argc != 2 && argc != 3) port_number = DEFAULT_PORT; else port_number = (PRUint16)atoi(argv[(argc == 2) ? 1 : 2]); status = PR_InitializeNetAddr(PR_IpAddrAny, port_number, &server_addr); if (PR_SUCCESS != status) { PL_FPrintError(err_out, "PR_InitializeNetAddr failed"); PR_ProcessExit(1); } if (argc < 3) { status = PR_InitializeNetAddr( PR_IpAddrLoopback, port_number, &client_addr); if (PR_SUCCESS != status) { PL_FPrintError(err_out, "PR_InitializeNetAddr failed"); PR_ProcessExit(1); } } else { status = PR_GetHostByName( argv[1], netdb_buf, sizeof(netdb_buf), &he); if (status == PR_FAILURE) { PL_FPrintError(err_out, "PR_GetHostByName failed"); PR_ProcessExit(1); } next_index = PR_EnumerateHostEnt(0, &he, port_number, &client_addr); if (next_index == -1) { PL_FPrintError(err_out, "PR_EnumerateHostEnt failed"); PR_ProcessExit(1); } } for ( write_dally = 0; write_dally < accept_timeout + (2 * delta); write_dally += delta) { PR_fprintf( std_out, "Testing w/ write_dally = %d msec\n", PR_IntervalToMilliseconds(write_dally)); server_thread = PR_CreateThread( PR_USER_THREAD, AcceptingThread, &server_addr, PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0); if (server_thread == NULL) { PL_FPrintError(err_out, "PR_CreateThread (server) failed"); PR_ProcessExit(1); } PR_Sleep(delta); /* let the server pot thicken */ client_thread = PR_CreateThread( PR_USER_THREAD, ConnectingThread, &client_addr, PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0); if (client_thread == NULL) { PL_FPrintError(err_out, "PR_CreateThread (client) failed"); PR_ProcessExit(1); } if (PR_JoinThread(client_thread) == PR_FAILURE) PL_FPrintError(err_out, "PR_JoinThread (client) failed"); if (PR_JoinThread(server_thread) == PR_FAILURE) PL_FPrintError(err_out, "PR_JoinThread (server) failed"); } return 0; }
NS_IMETHODIMP nsSafeFileOutputStream::Finish() { nsresult rv = Flush(); if (NS_SUCCEEDED(rv)) rv = nsFileOutputStream::Close(); // if there is no temp file, don't try to move it over the original target. // It would destroy the targetfile if close() is called twice. if (!mTempFile) return rv; // Only overwrite if everything was ok, and the temp file could be closed. if (NS_SUCCEEDED(mWriteResult) && NS_SUCCEEDED(rv)) { NS_ENSURE_STATE(mTargetFile); if (!mTargetFileExists) { // If the target file did not exist when we were initialized, then the // temp file we gave out was actually a reference to the target file. // since we succeeded in writing to the temp file (and hence succeeded // in writing to the target file), there is nothing more to do. #ifdef DEBUG PRBool equal; if (NS_FAILED(mTargetFile->Equals(mTempFile, &equal)) || !equal) NS_ERROR("mTempFile not equal to mTargetFile"); #endif } else { nsCAutoString targetFilename; rv = mTargetFile->GetNativeLeafName(targetFilename); if (NS_SUCCEEDED(rv)) { // This will replace target. // Celtx change: Antivirus software, or anything else that // monitors the filesystem for changes, can interfere with // frequent saves to the same file, manifesting itself in // a NS_ERROR_FILE_ACCESS_DENIED result. // The current delay setting PRIntervalTime delay = PR_MillisecondsToInterval(50); // Give up when we exceed this PRIntervalTime timeout = PR_SecondsToInterval(2) + PR_IntervalNow(); #ifdef XP_MACOSX PRBool extensionHidden = PR_FALSE; nsCOMPtr<nsILocalFileMac> macFile = do_QueryInterface(mTargetFile); nsCOMPtr<nsILocalFileMac> macTempFile = do_QueryInterface(mTempFile); if (macFile && macTempFile) { macFile->GetExtensionHidden(&extensionHidden); macTempFile->SetExtensionHidden(extensionHidden); } #endif do { rv = mTempFile->MoveToNative(nsnull, targetFilename); if (NS_SUCCEEDED(rv)) break; NS_ERROR("MoveToNative failed, backing off and retrying"); PR_Sleep(delay); delay *= 2; } while (PR_IntervalNow() < timeout); if (NS_FAILED(rv)) mTempFile->Remove(PR_FALSE); } } } else { mTempFile->Remove(PR_FALSE); // if writing failed, propagate the failure code to the caller. if (NS_FAILED(mWriteResult)) rv = mWriteResult; } mTempFile = nsnull; return rv; }
static PRStatus ProcessRequest(PRFileDesc *fd, CSServer_t *server) { PRStatus drv, rv; char buffer[1024]; PRFileDesc *file = NULL; PRThread * me = PR_GetCurrentThread(); PRInt32 bytes, descbytes, netbytes, filebytes = 0; CSDescriptor_t *descriptor = PR_NEW(CSDescriptor_t); PRIntervalTime timeout = PR_MillisecondsToInterval(DEFAULT_SERVER_TIMEOUT); TEST_LOG( cltsrv_log_file, TEST_LOG_VERBOSE, ("\tProcessRequest(0x%p): receiving desciptor\n", me)); bytes = PR_Recv( fd, descriptor, sizeof(*descriptor), RECV_FLAGS, timeout); if (-1 == bytes) { rv = PR_FAILURE; if (Aborted(rv)) goto exit; if (PR_IO_TIMEOUT_ERROR == PR_GetError()) { TEST_LOG( cltsrv_log_file, TEST_LOG_ERROR, ("\tProcessRequest(0x%p): receive timeout\n", me)); } goto exit; } if (0 == bytes) { rv = PR_FAILURE; TEST_LOG( cltsrv_log_file, TEST_LOG_ERROR, ("\tProcessRequest(0x%p): unexpected end of file\n", me)); goto exit; } descbytes = PR_ntohl(descriptor->size); TEST_ASSERT(sizeof(*descriptor) == bytes); TEST_LOG( cltsrv_log_file, TEST_LOG_VERBOSE, ("\t\tProcessRequest(0x%p): read descriptor {%d, %s}\n", me, descbytes, descriptor->filename)); file = PR_Open( descriptor->filename, (PR_CREATE_FILE | PR_WRONLY), 0666); if (NULL == file) { rv = PR_FAILURE; if (Aborted(rv)) goto aborted; if (PR_IO_TIMEOUT_ERROR == PR_GetError()) { TEST_LOG( cltsrv_log_file, TEST_LOG_ERROR, ("\tProcessRequest(0x%p): open file timeout\n", me)); goto aborted; } } TEST_ASSERT(NULL != file); filebytes = 0; while (filebytes < descbytes) { netbytes = sizeof(buffer); if ((descbytes - filebytes) < netbytes) netbytes = descbytes - filebytes; TEST_LOG( cltsrv_log_file, TEST_LOG_VERBOSE, ("\tProcessRequest(0x%p): receive %d bytes\n", me, netbytes)); bytes = PR_Recv(fd, buffer, netbytes, RECV_FLAGS, timeout); if (-1 == bytes) { rv = PR_FAILURE; if (Aborted(rv)) goto aborted; if (PR_IO_TIMEOUT_ERROR == PR_GetError()) { TEST_LOG( cltsrv_log_file, TEST_LOG_ERROR, ("\t\tProcessRequest(0x%p): receive data timeout\n", me)); goto aborted; } /* * XXX: I got (PR_CONNECT_RESET_ERROR, ERROR_NETNAME_DELETED) * on NT here. This is equivalent to ECONNRESET on Unix. * -wtc */ TEST_LOG( cltsrv_log_file, TEST_LOG_WARNING, ("\t\tProcessRequest(0x%p): unexpected error (%d, %d)\n", me, PR_GetError(), PR_GetOSError())); goto aborted; } if(0 == bytes) { TEST_LOG( cltsrv_log_file, TEST_LOG_WARNING, ("\t\tProcessRequest(0x%p): unexpected end of stream\n", me)); rv = PR_FAILURE; goto aborted; } filebytes += bytes; netbytes = bytes; /* The byte count for PR_Write should be positive */ MY_ASSERT(netbytes > 0); TEST_LOG( cltsrv_log_file, TEST_LOG_VERBOSE, ("\tProcessRequest(0x%p): write %d bytes to file\n", me, netbytes)); bytes = PR_Write(file, buffer, netbytes); if (netbytes != bytes) { rv = PR_FAILURE; if (Aborted(rv)) goto aborted; if (PR_IO_TIMEOUT_ERROR == PR_GetError()) { TEST_LOG( cltsrv_log_file, TEST_LOG_ERROR, ("\t\tProcessRequest(0x%p): write file timeout\n", me)); goto aborted; } } TEST_ASSERT(bytes > 0); } PR_Lock(server->ml); server->operations += 1; server->bytesTransferred += filebytes; PR_Unlock(server->ml); rv = PR_Close(file); if (Aborted(rv)) goto aborted; TEST_ASSERT(PR_SUCCESS == rv); file = NULL; TEST_LOG( cltsrv_log_file, TEST_LOG_VERBOSE, ("\t\tProcessRequest(0x%p): opening %s\n", me, descriptor->filename)); file = PR_Open(descriptor->filename, PR_RDONLY, 0); if (NULL == file) { rv = PR_FAILURE; if (Aborted(rv)) goto aborted; if (PR_IO_TIMEOUT_ERROR == PR_GetError()) { TEST_LOG( cltsrv_log_file, TEST_LOG_ERROR, ("\t\tProcessRequest(0x%p): open file timeout\n", PR_GetCurrentThread())); goto aborted; } TEST_LOG( cltsrv_log_file, TEST_LOG_ERROR, ("\t\tProcessRequest(0x%p): other file open error (%u, %u)\n", me, PR_GetError(), PR_GetOSError())); goto aborted; } TEST_ASSERT(NULL != file); netbytes = 0; while (netbytes < descbytes) { filebytes = sizeof(buffer); if ((descbytes - netbytes) < filebytes) filebytes = descbytes - netbytes; TEST_LOG( cltsrv_log_file, TEST_LOG_VERBOSE, ("\tProcessRequest(0x%p): read %d bytes from file\n", me, filebytes)); bytes = PR_Read(file, buffer, filebytes); if (filebytes != bytes) { rv = PR_FAILURE; if (Aborted(rv)) goto aborted; if (PR_IO_TIMEOUT_ERROR == PR_GetError()) TEST_LOG( cltsrv_log_file, TEST_LOG_ERROR, ("\t\tProcessRequest(0x%p): read file timeout\n", me)); else TEST_LOG( cltsrv_log_file, TEST_LOG_ERROR, ("\t\tProcessRequest(0x%p): other file error (%d, %d)\n", me, PR_GetError(), PR_GetOSError())); goto aborted; } TEST_ASSERT(bytes > 0); netbytes += bytes; filebytes = bytes; TEST_LOG( cltsrv_log_file, TEST_LOG_VERBOSE, ("\t\tProcessRequest(0x%p): sending %d bytes\n", me, filebytes)); bytes = PR_Send(fd, buffer, filebytes, SEND_FLAGS, timeout); if (filebytes != bytes) { rv = PR_FAILURE; if (Aborted(rv)) goto aborted; if (PR_IO_TIMEOUT_ERROR == PR_GetError()) { TEST_LOG( cltsrv_log_file, TEST_LOG_ERROR, ("\t\tProcessRequest(0x%p): send data timeout\n", me)); goto aborted; } break; } TEST_ASSERT(bytes > 0); } PR_Lock(server->ml); server->bytesTransferred += filebytes; PR_Unlock(server->ml); rv = PR_Shutdown(fd, PR_SHUTDOWN_BOTH); if (Aborted(rv)) goto aborted; rv = PR_Close(file); if (Aborted(rv)) goto aborted; TEST_ASSERT(PR_SUCCESS == rv); file = NULL; aborted: PR_ClearInterrupt(); if (NULL != file) PR_Close(file); drv = PR_Delete(descriptor->filename); TEST_ASSERT(PR_SUCCESS == drv); exit: TEST_LOG( cltsrv_log_file, TEST_LOG_VERBOSE, ("\t\tProcessRequest(0x%p): Finished\n", me)); PR_DELETE(descriptor); #if defined(WIN95) PR_Sleep(PR_MillisecondsToInterval(200)); /* lth. see note [1] */ #endif return rv; } /* ProcessRequest */
// for nsIRunnable. this thread spins in ldap_result() awaiting the next // message. once one arrives, it dispatches it to the nsILDAPMessageListener // on the main thread. // // XXX do all returns from this function need to do thread cleanup? // NS_IMETHODIMP nsLDAPConnectionLoop::Run(void) { PR_LOG(gLDAPLogModule, PR_LOG_DEBUG, ("nsLDAPConnection::Run() entered\n")); // wait for results // while(1) { // Exit this thread if we no longer have an nsLDAPConnection // associated with it. We also aquire a lock here, to make sure // to avoid a possible race condition when the nsLDAPConnection // is destructed during the call to do_QueryReferent() (since that // function isn't MT safe). // nsresult rv; PR_Lock(mLock); nsCOMPtr<nsILDAPConnection> strongConn = do_QueryReferent(mWeakConn, &rv); PR_Unlock(mLock); if (NS_FAILED(rv)) { mWeakConn = 0; return NS_OK; } // we use a raw connection because we need to call non-interface // methods mRawConn = static_cast<nsLDAPConnection *>(static_cast<nsILDAPConnection *>(strongConn.get())); // XXX deal with timeouts better // NS_ASSERTION(mRawConn->mConnectionHandle, "nsLDAPConnection::Run(): " "no connection created.\n"); // We can't enumerate over mPendingOperations itself, because the // callback needs to modify mPendingOperations. So we clone it first, // and enumerate over the clone. It kinda sucks that we need to do // this everytime we poll, but the hashtable will pretty much always // be small. // // only clone if the number of pending operations is non-zero // otherwise, put the LDAP connection thread to sleep (briefly) // until there is pending operations.. if (mRawConn->mPendingOperations->Count()) { nsHashtable *hashtableCopy = mRawConn->mPendingOperations->Clone(); if (hashtableCopy) { hashtableCopy->Enumerate(CheckLDAPOperationResult, this); delete hashtableCopy; } else { // punt and hope it works next time around NS_ERROR("nsLDAPConnectionLoop::Run() error cloning hashtable"); } } else { PR_Sleep(PR_MillisecondsToInterval(40)); } } // This will never happen, but here just in case. // return NS_OK; }
/* * this handles modules that do not support C_WaitForSlotEvent(). * The internal flags are stored. Note that C_WaitForSlotEvent() does not * have a timeout, so we don't have one for handleWaitForSlotEvent() either. */ PK11SlotInfo * secmod_HandleWaitForSlotEvent(SECMODModule *mod, unsigned long flags, PRIntervalTime latency) { PRBool removableSlotsFound = PR_FALSE; int i; int error = SEC_ERROR_NO_EVENT; if (!moduleLock) { PORT_SetError(SEC_ERROR_NOT_INITIALIZED); return NULL; } PZ_Lock(mod->refLock); if (mod->evControlMask & SECMOD_END_WAIT) { mod->evControlMask &= ~SECMOD_END_WAIT; PZ_Unlock(mod->refLock); PORT_SetError(SEC_ERROR_NO_EVENT); return NULL; } mod->evControlMask |= SECMOD_WAIT_SIMULATED_EVENT; while (mod->evControlMask & SECMOD_WAIT_SIMULATED_EVENT) { PZ_Unlock(mod->refLock); /* now is a good time to see if new slots have been added */ SECMOD_UpdateSlotList(mod); /* loop through all the slots on a module */ SECMOD_GetReadLock(moduleLock); for (i=0; i < mod->slotCount; i++) { PK11SlotInfo *slot = mod->slots[i]; PRUint16 series; PRBool present; /* perm modules do not change */ if (slot->isPerm) { continue; } removableSlotsFound = PR_TRUE; /* simulate the PKCS #11 module flags. are the flags different * from the last time we called? */ series = slot->series; present = PK11_IsPresent(slot); if ((slot->flagSeries != series) || (slot->flagState != present)) { slot->flagState = present; slot->flagSeries = series; SECMOD_ReleaseReadLock(moduleLock); PZ_Lock(mod->refLock); mod->evControlMask &= ~SECMOD_END_WAIT; PZ_Unlock(mod->refLock); return PK11_ReferenceSlot(slot); } } SECMOD_ReleaseReadLock(moduleLock); /* if everything was perm modules, don't lock up forever */ if ((mod->slotCount !=0) && !removableSlotsFound) { error =SEC_ERROR_NO_SLOT_SELECTED; PZ_Lock(mod->refLock); break; } if (flags & CKF_DONT_BLOCK) { PZ_Lock(mod->refLock); break; } PR_Sleep(latency); PZ_Lock(mod->refLock); } mod->evControlMask &= ~SECMOD_END_WAIT; PZ_Unlock(mod->refLock); PORT_SetError(error); return NULL; }
// Test a message send???? nsresult nsEudoraCompose::SendTheMessage(nsIFile *pMailImportLocation, nsIFile **pMsg) { nsresult rv = CreateComponents(); if (NS_FAILED(rv)) return rv; // IMPORT_LOG0("Outlook Compose created necessary components\n"); nsString bodyType; nsString charSet; nsString headerVal; GetHeaderValue(m_pHeaders, m_headerLen, "From:", headerVal); if (!headerVal.IsEmpty()) m_pMsgFields->SetFrom(headerVal); GetHeaderValue(m_pHeaders, m_headerLen, "To:", headerVal); if (!headerVal.IsEmpty()) m_pMsgFields->SetTo(headerVal); GetHeaderValue(m_pHeaders, m_headerLen, "Subject:", headerVal); if (!headerVal.IsEmpty()) m_pMsgFields->SetSubject(headerVal); GetHeaderValue(m_pHeaders, m_headerLen, "Content-type:", headerVal); bodyType = headerVal; ExtractType(bodyType); ExtractCharset(headerVal); // Use platform charset as default if the msg doesn't specify one // (ie, no 'charset' param in the Content-Type: header). As the last // resort we'll use the mail default charset. // (ie, no 'charset' param in the Content-Type: header) or if the // charset parameter fails a length sanity check. // As the last resort we'll use the mail default charset. if (headerVal.IsEmpty() || (headerVal.Length() > kContentTypeLengthSanityCheck)) { headerVal.AssignASCII(nsMsgI18NFileSystemCharset()); if (headerVal.IsEmpty()) { // last resort if (m_defCharset.IsEmpty()) { nsString defaultCharset; NS_GetLocalizedUnicharPreferenceWithDefault(nullptr, "mailnews.view_default_charset", NS_LITERAL_STRING("ISO-8859-1"), defaultCharset); m_defCharset = defaultCharset; } headerVal = m_defCharset; } } m_pMsgFields->SetCharacterSet(NS_LossyConvertUTF16toASCII(headerVal).get()); charSet = headerVal; GetHeaderValue(m_pHeaders, m_headerLen, "CC:", headerVal); if (!headerVal.IsEmpty()) m_pMsgFields->SetCc(headerVal); GetHeaderValue(m_pHeaders, m_headerLen, "Message-ID:", headerVal); if (!headerVal.IsEmpty()) m_pMsgFields->SetMessageId(NS_LossyConvertUTF16toASCII(headerVal).get()); GetHeaderValue(m_pHeaders, m_headerLen, "Reply-To:", headerVal); if (!headerVal.IsEmpty()) m_pMsgFields->SetReplyTo(headerVal); // what about all of the other headers?!?!?!?!?!?! char *pMimeType; if (!bodyType.IsEmpty()) pMimeType = ToNewCString(NS_LossyConvertUTF16toASCII(bodyType)); else pMimeType = ToNewCString(m_bodyType); nsCOMPtr<nsIArray> pAttach; GetLocalAttachments(getter_AddRefs(pAttach)); nsEudoraEditor eudoraEditor(m_pBody, pMailImportLocation); nsCOMPtr<nsIArray> embeddedObjects; if (eudoraEditor.HasEmbeddedContent()) eudoraEditor.GetEmbeddedObjects(getter_AddRefs(embeddedObjects)); nsString uniBody; NS_CopyNativeToUnicode(nsDependentCString(m_pBody), uniBody); /* l10n - I have the body of the message in the system charset, I need to "encode" it to be the charset for the message *UNLESS* of course, I don't know what the charset of the message should be? How do I determine what the charset should be if it doesn't exist? */ nsCString body; rv = nsMsgI18NConvertFromUnicode(NS_LossyConvertUTF16toASCII(charSet).get(), uniBody, body); if (NS_FAILED(rv) && !charSet.Equals(m_defCharset)) { // in this case, if we did not use the default compose // charset, then try that. body.Truncate(); rv = nsMsgI18NConvertFromUnicode(NS_LossyConvertUTF16toASCII(charSet).get(), uniBody, body); } uniBody.Truncate(); // See if it's a draft msg (ie, no From: or no To: AND no Cc: AND no Bcc:). // Eudora saves sent and draft msgs in Out folder (ie, mixed) and it does // store Bcc: header in the msg itself. nsAutoString from, to, cc, bcc; rv = m_pMsgFields->GetFrom(from); rv = m_pMsgFields->GetTo(to); rv = m_pMsgFields->GetCc(cc); rv = m_pMsgFields->GetBcc(bcc); bool createAsDraft = from.IsEmpty() || (to.IsEmpty() && cc.IsEmpty() && bcc.IsEmpty()); nsCOMPtr<nsIImportService> impService(do_GetService(NS_IMPORTSERVICE_CONTRACTID, &rv)); NS_ENSURE_SUCCESS(rv, rv); rv = impService->CreateRFC822Message( s_pIdentity, // dummy identity m_pMsgFields, // message fields pMimeType, // body type body, // body pointer createAsDraft, pAttach, // local attachments embeddedObjects, m_pListener); // listener EudoraSendListener *pListen = (EudoraSendListener *)m_pListener; if (NS_FAILED(rv)) { IMPORT_LOG1("*** Error, CreateAndSendMessage FAILED: 0x%lx\n", rv); // IMPORT_LOG1("Headers: %80s\n", m_pHeaders); } else { // wait for the listener to get done! int32_t abortCnt = 0; int32_t cnt = 0; int32_t sleepCnt = 1; while (!pListen->m_done && (abortCnt < kHungAbortCount)) { PR_Sleep(sleepCnt); cnt++; if (cnt > kHungCount) { abortCnt++; sleepCnt *= 2; cnt = 0; } } if (abortCnt >= kHungAbortCount) { IMPORT_LOG0("**** Create and send message hung\n"); IMPORT_LOG1("Headers: %s\n", m_pHeaders); IMPORT_LOG1("Body: %s\n", m_pBody); rv = NS_ERROR_FAILURE; } } if (pMimeType) NS_Free(pMimeType); if (pListen->m_location) { pListen->m_location->Clone(pMsg); rv = NS_OK; } else { rv = NS_ERROR_FAILURE; IMPORT_LOG0("*** Error, Outlook compose unsuccessful\n"); } pListen->Reset(); return rv; }
int poll(struct pollfd *filedes, unsigned long nfds, int timeout) #endif { #ifdef AIX struct pollfd *filedes = (struct pollfd *) listptr; #endif struct pollfd *pfd, *epfd; _PRUnixPollDesc *unixpds, *unixpd, *eunixpd; PRIntervalTime ticks; PRInt32 pdcnt; int ready; /* * Easy special case: zero timeout. Simply call the native * poll() with no fear of blocking. */ if (timeout == 0) { #if defined(AIX) return _MD_POLL(listptr, nfds, timeout); #else return _MD_POLL(filedes, nfds, timeout); #endif } if (!_pr_initialized) { _PR_ImplicitInitialization(); } #ifndef _PR_LOCAL_THREADS_ONLY if (_PR_IS_NATIVE_THREAD(_PR_MD_CURRENT_THREAD())) { return _MD_POLL(filedes, nfds, timeout); } #endif /* We do not support the pollmsg structures on AIX */ #ifdef AIX PR_ASSERT((nfds & 0xff00) == 0); #endif if (timeout < 0 && timeout != -1) { errno = EINVAL; return -1; } /* Convert timeout from miliseconds to ticks */ if (timeout == -1) { ticks = PR_INTERVAL_NO_TIMEOUT; } else { ticks = PR_MillisecondsToInterval(timeout); } /* Check for no descriptor case (just do a timeout) */ if (nfds == 0) { PR_Sleep(ticks); return 0; } unixpds = (_PRUnixPollDesc *) PR_MALLOC(nfds * sizeof(_PRUnixPollDesc)); if (NULL == unixpds) { errno = EAGAIN; return -1; } pdcnt = 0; epfd = filedes + nfds; unixpd = unixpds; for (pfd = filedes; pfd < epfd; pfd++) { /* * poll() ignores negative fd's. */ if (pfd->fd >= 0) { unixpd->osfd = pfd->fd; #ifdef _PR_USE_POLL unixpd->in_flags = pfd->events; #else /* * Map the poll events to one of the three that can be * represented by the select fd_sets: * POLLIN, POLLRDNORM ===> readable * POLLOUT, POLLWRNORM ===> writable * POLLPRI, POLLRDBAND ===> exception * POLLNORM, POLLWRBAND (and POLLMSG on some platforms) * are ignored. * * The output events POLLERR and POLLHUP are never turned on. * POLLNVAL may be turned on. */ unixpd->in_flags = 0; if (pfd->events & (POLLIN #ifdef POLLRDNORM | POLLRDNORM #endif )) { unixpd->in_flags |= _PR_UNIX_POLL_READ; } if (pfd->events & (POLLOUT #ifdef POLLWRNORM | POLLWRNORM #endif )) { unixpd->in_flags |= _PR_UNIX_POLL_WRITE; } if (pfd->events & (POLLPRI #ifdef POLLRDBAND | POLLRDBAND #endif )) { unixpd->in_flags |= PR_POLL_EXCEPT; } #endif /* _PR_USE_POLL */ unixpd->out_flags = 0; unixpd++; pdcnt++; } } ready = _PR_WaitForMultipleFDs(unixpds, pdcnt, ticks); if (-1 == ready) { if (PR_GetError() == PR_PENDING_INTERRUPT_ERROR) { errno = EINTR; /* XXX we aren't interrupted by a signal, but... */ } else { errno = PR_GetOSError(); } } if (ready <= 0) { goto done; } /* * Copy the out_flags from the _PRUnixPollDesc structures to the * user's pollfd structures and free the allocated memory */ unixpd = unixpds; for (pfd = filedes; pfd < epfd; pfd++) { pfd->revents = 0; if (pfd->fd >= 0) { #ifdef _PR_USE_POLL pfd->revents = unixpd->out_flags; #else if (0 != unixpd->out_flags) { if (unixpd->out_flags & _PR_UNIX_POLL_READ) { if (pfd->events & POLLIN) { pfd->revents |= POLLIN; } #ifdef POLLRDNORM if (pfd->events & POLLRDNORM) { pfd->revents |= POLLRDNORM; } #endif } if (unixpd->out_flags & _PR_UNIX_POLL_WRITE) { if (pfd->events & POLLOUT) { pfd->revents |= POLLOUT; } #ifdef POLLWRNORM if (pfd->events & POLLWRNORM) { pfd->revents |= POLLWRNORM; } #endif } if (unixpd->out_flags & _PR_UNIX_POLL_EXCEPT) { if (pfd->events & POLLPRI) { pfd->revents |= POLLPRI; } #ifdef POLLRDBAND if (pfd->events & POLLRDBAND) { pfd->revents |= POLLRDBAND; } #endif } if (unixpd->out_flags & _PR_UNIX_POLL_ERR) { pfd->revents |= POLLERR; } if (unixpd->out_flags & _PR_UNIX_POLL_NVAL) { pfd->revents |= POLLNVAL; } if (unixpd->out_flags & _PR_UNIX_POLL_HUP) { pfd->revents |= POLLHUP; } } #endif /* _PR_USE_POLL */ unixpd++; } } done: PR_DELETE(unixpds); return ready; }
int main(int32_t argc, char *argv[]) { if (test_common_init(&argc, &argv) != 0) return -1; bool allTestsPassed = true; ScopedXPCOM xpcom("TestCookie"); { nsresult rv0; nsCOMPtr<nsICookieService> cookieService = do_GetService(kCookieServiceCID, &rv0); if (NS_FAILED(rv0)) return -1; nsCOMPtr<nsIPrefBranch> prefBranch = do_GetService(kPrefServiceCID, &rv0); if (NS_FAILED(rv0)) return -1; InitPrefs(prefBranch); bool rv[20]; nsCString cookie; /* The basic idea behind these tests is the following: * * we set() some cookie, then try to get() it in various ways. we have * several possible tests we perform on the cookie string returned from * get(): * * a) check whether the returned string is null (i.e. we got no cookies * back). this is used e.g. to ensure a given cookie was deleted * correctly, or to ensure a certain cookie wasn't returned to a given * host. * b) check whether the returned string exactly matches a given string. * this is used where we want to make sure our cookie service adheres to * some strict spec (e.g. ordering of multiple cookies), or where we * just know exactly what the returned string should be. * c) check whether the returned string contains/does not contain a given * string. this is used where we don't know/don't care about the * ordering of multiple cookies - we just want to make sure the cookie * string contains them all, in some order. * * the results of each individual testing operation from CheckResult() is * stored in an array of bools, which is then checked against the expected * outcomes (all successes), by PrintResult(). the overall result of all * tests to date is kept in |allTestsPassed|, for convenient display at the * end. * * Interpreting the output: * each setting/getting operation will print output saying exactly what * it's doing and the outcome, respectively. this information is only * useful for debugging purposes; the actual result of the tests is * printed at the end of each block of tests. this will either be "all * tests passed" or "tests X Y Z failed", where X, Y, Z are the indexes * of rv (i.e. zero-based). at the conclusion of all tests, the overall * passed/failed result is printed. * * NOTE: this testsuite is not yet comprehensive or complete, and is * somewhat contrived - still under development, and needs improving! */ // *** basic tests sBuffer = PR_sprintf_append(sBuffer, "*** Beginning basic tests...\n"); // test some basic variations of the domain & path SetACookie(cookieService, "http://www.basic.com", nullptr, "test=basic", nullptr); GetACookie(cookieService, "http://www.basic.com", nullptr, getter_Copies(cookie)); rv[0] = CheckResult(cookie.get(), MUST_EQUAL, "test=basic"); GetACookie(cookieService, "http://www.basic.com/testPath/testfile.txt", nullptr, getter_Copies(cookie)); rv[1] = CheckResult(cookie.get(), MUST_EQUAL, "test=basic"); GetACookie(cookieService, "http://www.basic.com./", nullptr, getter_Copies(cookie)); rv[2] = CheckResult(cookie.get(), MUST_BE_NULL); GetACookie(cookieService, "http://www.basic.com.", nullptr, getter_Copies(cookie)); rv[3] = CheckResult(cookie.get(), MUST_BE_NULL); GetACookie(cookieService, "http://www.basic.com./testPath/testfile.txt", nullptr, getter_Copies(cookie)); rv[4] = CheckResult(cookie.get(), MUST_BE_NULL); GetACookie(cookieService, "http://www.basic2.com/", nullptr, getter_Copies(cookie)); rv[5] = CheckResult(cookie.get(), MUST_BE_NULL); SetACookie(cookieService, "http://www.basic.com", nullptr, "test=basic; max-age=-1", nullptr); GetACookie(cookieService, "http://www.basic.com/", nullptr, getter_Copies(cookie)); rv[6] = CheckResult(cookie.get(), MUST_BE_NULL); allTestsPassed = PrintResult(rv, 7) && allTestsPassed; // *** domain tests sBuffer = PR_sprintf_append(sBuffer, "*** Beginning domain tests...\n"); // test some variations of the domain & path, for different domains of // a domain cookie SetACookie(cookieService, "http://www.domain.com", nullptr, "test=domain; domain=domain.com", nullptr); GetACookie(cookieService, "http://domain.com", nullptr, getter_Copies(cookie)); rv[0] = CheckResult(cookie.get(), MUST_EQUAL, "test=domain"); GetACookie(cookieService, "http://domain.com.", nullptr, getter_Copies(cookie)); rv[1] = CheckResult(cookie.get(), MUST_BE_NULL); GetACookie(cookieService, "http://www.domain.com", nullptr, getter_Copies(cookie)); rv[2] = CheckResult(cookie.get(), MUST_EQUAL, "test=domain"); GetACookie(cookieService, "http://foo.domain.com", nullptr, getter_Copies(cookie)); rv[3] = CheckResult(cookie.get(), MUST_EQUAL, "test=domain"); SetACookie(cookieService, "http://www.domain.com", nullptr, "test=domain; domain=domain.com; max-age=-1", nullptr); GetACookie(cookieService, "http://domain.com", nullptr, getter_Copies(cookie)); rv[4] = CheckResult(cookie.get(), MUST_BE_NULL); SetACookie(cookieService, "http://www.domain.com", nullptr, "test=domain; domain=.domain.com", nullptr); GetACookie(cookieService, "http://domain.com", nullptr, getter_Copies(cookie)); rv[5] = CheckResult(cookie.get(), MUST_EQUAL, "test=domain"); GetACookie(cookieService, "http://www.domain.com", nullptr, getter_Copies(cookie)); rv[6] = CheckResult(cookie.get(), MUST_EQUAL, "test=domain"); GetACookie(cookieService, "http://bah.domain.com", nullptr, getter_Copies(cookie)); rv[7] = CheckResult(cookie.get(), MUST_EQUAL, "test=domain"); SetACookie(cookieService, "http://www.domain.com", nullptr, "test=domain; domain=.domain.com; max-age=-1", nullptr); GetACookie(cookieService, "http://domain.com", nullptr, getter_Copies(cookie)); rv[8] = CheckResult(cookie.get(), MUST_BE_NULL); SetACookie(cookieService, "http://www.domain.com", nullptr, "test=domain; domain=.foo.domain.com", nullptr); GetACookie(cookieService, "http://foo.domain.com", nullptr, getter_Copies(cookie)); rv[9] = CheckResult(cookie.get(), MUST_BE_NULL); SetACookie(cookieService, "http://www.domain.com", nullptr, "test=domain; domain=moose.com", nullptr); GetACookie(cookieService, "http://foo.domain.com", nullptr, getter_Copies(cookie)); rv[10] = CheckResult(cookie.get(), MUST_BE_NULL); SetACookie(cookieService, "http://www.domain.com", nullptr, "test=domain; domain=domain.com.", nullptr); GetACookie(cookieService, "http://foo.domain.com", nullptr, getter_Copies(cookie)); rv[11] = CheckResult(cookie.get(), MUST_BE_NULL); SetACookie(cookieService, "http://www.domain.com", nullptr, "test=domain; domain=..domain.com", nullptr); GetACookie(cookieService, "http://foo.domain.com", nullptr, getter_Copies(cookie)); rv[12] = CheckResult(cookie.get(), MUST_BE_NULL); SetACookie(cookieService, "http://www.domain.com", nullptr, "test=domain; domain=..domain.com.", nullptr); GetACookie(cookieService, "http://foo.domain.com", nullptr, getter_Copies(cookie)); rv[13] = CheckResult(cookie.get(), MUST_BE_NULL); SetACookie(cookieService, "http://path.net/path/file", nullptr, "test=taco; path=\"/bogus\"", nullptr); GetACookie(cookieService, "http://path.net/path/file", nullptr, getter_Copies(cookie)); rv[14] = CheckResult(cookie.get(), MUST_EQUAL, "test=taco"); SetACookie(cookieService, "http://path.net/path/file", nullptr, "test=taco; max-age=-1", nullptr); GetACookie(cookieService, "http://path.net/path/file", nullptr, getter_Copies(cookie)); rv[15] = CheckResult(cookie.get(), MUST_BE_NULL); allTestsPassed = PrintResult(rv, 16) && allTestsPassed; // *** path tests sBuffer = PR_sprintf_append(sBuffer, "*** Beginning path tests...\n"); // test some variations of the domain & path, for different paths of // a path cookie SetACookie(cookieService, "http://path.net/path/file", nullptr, "test=path; path=/path", nullptr); GetACookie(cookieService, "http://path.net/path", nullptr, getter_Copies(cookie)); rv[0] = CheckResult(cookie.get(), MUST_EQUAL, "test=path"); GetACookie(cookieService, "http://path.net/path/", nullptr, getter_Copies(cookie)); rv[1] = CheckResult(cookie.get(), MUST_EQUAL, "test=path"); GetACookie(cookieService, "http://path.net/path/hithere.foo", nullptr, getter_Copies(cookie)); rv[2] = CheckResult(cookie.get(), MUST_EQUAL, "test=path"); GetACookie(cookieService, "http://path.net/path?hithere/foo", nullptr, getter_Copies(cookie)); rv[3] = CheckResult(cookie.get(), MUST_EQUAL, "test=path"); GetACookie(cookieService, "http://path.net/path2", nullptr, getter_Copies(cookie)); rv[4] = CheckResult(cookie.get(), MUST_BE_NULL); GetACookie(cookieService, "http://path.net/path2/", nullptr, getter_Copies(cookie)); rv[5] = CheckResult(cookie.get(), MUST_BE_NULL); SetACookie(cookieService, "http://path.net/path/file", nullptr, "test=path; path=/path; max-age=-1", nullptr); GetACookie(cookieService, "http://path.net/path/", nullptr, getter_Copies(cookie)); rv[6] = CheckResult(cookie.get(), MUST_BE_NULL); SetACookie(cookieService, "http://path.net/path/file", nullptr, "test=path; path=/path/", nullptr); GetACookie(cookieService, "http://path.net/path", nullptr, getter_Copies(cookie)); rv[7] = CheckResult(cookie.get(), MUST_EQUAL, "test=path"); GetACookie(cookieService, "http://path.net/path/", nullptr, getter_Copies(cookie)); rv[8] = CheckResult(cookie.get(), MUST_EQUAL, "test=path"); SetACookie(cookieService, "http://path.net/path/file", nullptr, "test=path; path=/path/; max-age=-1", nullptr); GetACookie(cookieService, "http://path.net/path/", nullptr, getter_Copies(cookie)); rv[9] = CheckResult(cookie.get(), MUST_BE_NULL); // note that a site can set a cookie for a path it's not on. // this is an intentional deviation from spec (see comments in // nsCookieService::CheckPath()), so we test this functionality too SetACookie(cookieService, "http://path.net/path/file", nullptr, "test=path; path=/foo/", nullptr); GetACookie(cookieService, "http://path.net/path", nullptr, getter_Copies(cookie)); rv[10] = CheckResult(cookie.get(), MUST_BE_NULL); GetACookie(cookieService, "http://path.net/foo", nullptr, getter_Copies(cookie)); rv[11] = CheckResult(cookie.get(), MUST_EQUAL, "test=path"); SetACookie(cookieService, "http://path.net/path/file", nullptr, "test=path; path=/foo/; max-age=-1", nullptr); GetACookie(cookieService, "http://path.net/foo/", nullptr, getter_Copies(cookie)); rv[12] = CheckResult(cookie.get(), MUST_BE_NULL); // bug 373228: make sure cookies with paths longer than 1024 bytes, // and cookies with paths or names containing tabs, are rejected. // the following cookie has a path > 1024 bytes explicitly specified in the cookie SetACookie(cookieService, "http://path.net/", nullptr, "test=path; path=/1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890/", nullptr); GetACookie(cookieService, "http://path.net/1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890", nullptr, getter_Copies(cookie)); rv[13] = CheckResult(cookie.get(), MUST_BE_NULL); // the following cookie has a path > 1024 bytes implicitly specified by the uri path SetACookie(cookieService, "http://path.net/1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890/", nullptr, "test=path", nullptr); GetACookie(cookieService, "http://path.net/1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890/", nullptr, getter_Copies(cookie)); rv[14] = CheckResult(cookie.get(), MUST_BE_NULL); // the following cookie includes a tab in the path SetACookie(cookieService, "http://path.net/", nullptr, "test=path; path=/foo\tbar/", nullptr); GetACookie(cookieService, "http://path.net/foo\tbar/", nullptr, getter_Copies(cookie)); rv[15] = CheckResult(cookie.get(), MUST_BE_NULL); // the following cookie includes a tab in the name SetACookie(cookieService, "http://path.net/", nullptr, "test\ttabs=tab", nullptr); GetACookie(cookieService, "http://path.net/", nullptr, getter_Copies(cookie)); rv[16] = CheckResult(cookie.get(), MUST_BE_NULL); // the following cookie includes a tab in the value - allowed SetACookie(cookieService, "http://path.net/", nullptr, "test=tab\ttest", nullptr); GetACookie(cookieService, "http://path.net/", nullptr, getter_Copies(cookie)); rv[17] = CheckResult(cookie.get(), MUST_EQUAL, "test=tab\ttest"); SetACookie(cookieService, "http://path.net/", nullptr, "test=tab\ttest; max-age=-1", nullptr); GetACookie(cookieService, "http://path.net/", nullptr, getter_Copies(cookie)); rv[18] = CheckResult(cookie.get(), MUST_BE_NULL); allTestsPassed = PrintResult(rv, 19) && allTestsPassed; // *** expiry & deletion tests // XXX add server time str parsing tests here sBuffer = PR_sprintf_append(sBuffer, "*** Beginning expiry & deletion tests...\n"); // test some variations of the expiry time, // and test deletion of previously set cookies SetACookie(cookieService, "http://expireme.org/", nullptr, "test=expiry; max-age=-1", nullptr); GetACookie(cookieService, "http://expireme.org/", nullptr, getter_Copies(cookie)); rv[0] = CheckResult(cookie.get(), MUST_BE_NULL); SetACookie(cookieService, "http://expireme.org/", nullptr, "test=expiry; max-age=0", nullptr); GetACookie(cookieService, "http://expireme.org/", nullptr, getter_Copies(cookie)); rv[1] = CheckResult(cookie.get(), MUST_BE_NULL); SetACookie(cookieService, "http://expireme.org/", nullptr, "test=expiry; expires=bad", nullptr); GetACookie(cookieService, "http://expireme.org/", nullptr, getter_Copies(cookie)); rv[2] = CheckResult(cookie.get(), MUST_EQUAL, "test=expiry"); SetACookie(cookieService, "http://expireme.org/", nullptr, "test=expiry; expires=Thu, 10 Apr 1980 16:33:12 GMT", nullptr); GetACookie(cookieService, "http://expireme.org/", nullptr, getter_Copies(cookie)); rv[3] = CheckResult(cookie.get(), MUST_BE_NULL); SetACookie(cookieService, "http://expireme.org/", nullptr, "test=expiry; expires=\"Thu, 10 Apr 1980 16:33:12 GMT", nullptr); GetACookie(cookieService, "http://expireme.org/", nullptr, getter_Copies(cookie)); rv[4] = CheckResult(cookie.get(), MUST_BE_NULL); SetACookie(cookieService, "http://expireme.org/", nullptr, "test=expiry; expires=\"Thu, 10 Apr 1980 16:33:12 GMT\"", nullptr); GetACookie(cookieService, "http://expireme.org/", nullptr, getter_Copies(cookie)); rv[5] = CheckResult(cookie.get(), MUST_BE_NULL); SetACookie(cookieService, "http://expireme.org/", nullptr, "test=expiry; max-age=60", nullptr); GetACookie(cookieService, "http://expireme.org/", nullptr, getter_Copies(cookie)); rv[6] = CheckResult(cookie.get(), MUST_EQUAL, "test=expiry"); SetACookie(cookieService, "http://expireme.org/", nullptr, "test=expiry; max-age=-20", nullptr); GetACookie(cookieService, "http://expireme.org/", nullptr, getter_Copies(cookie)); rv[7] = CheckResult(cookie.get(), MUST_BE_NULL); SetACookie(cookieService, "http://expireme.org/", nullptr, "test=expiry; max-age=60", nullptr); GetACookie(cookieService, "http://expireme.org/", nullptr, getter_Copies(cookie)); rv[8] = CheckResult(cookie.get(), MUST_EQUAL, "test=expiry"); SetACookie(cookieService, "http://expireme.org/", nullptr, "test=expiry; expires=Thu, 10 Apr 1980 16:33:12 GMT", nullptr); GetACookie(cookieService, "http://expireme.org/", nullptr, getter_Copies(cookie)); rv[9] = CheckResult(cookie.get(), MUST_BE_NULL); SetACookie(cookieService, "http://expireme.org/", nullptr, "test=expiry; max-age=60", nullptr); SetACookie(cookieService, "http://expireme.org/", nullptr, "newtest=expiry; max-age=60", nullptr); GetACookie(cookieService, "http://expireme.org/", nullptr, getter_Copies(cookie)); rv[10] = CheckResult(cookie.get(), MUST_CONTAIN, "test=expiry"); rv[11] = CheckResult(cookie.get(), MUST_CONTAIN, "newtest=expiry"); SetACookie(cookieService, "http://expireme.org/", nullptr, "test=differentvalue; max-age=0", nullptr); GetACookie(cookieService, "http://expireme.org/", nullptr, getter_Copies(cookie)); rv[12] = CheckResult(cookie.get(), MUST_EQUAL, "newtest=expiry"); SetACookie(cookieService, "http://expireme.org/", nullptr, "newtest=evendifferentvalue; max-age=0", nullptr); GetACookie(cookieService, "http://expireme.org/", nullptr, getter_Copies(cookie)); rv[13] = CheckResult(cookie.get(), MUST_BE_NULL); SetACookie(cookieService, "http://foo.expireme.org/", nullptr, "test=expiry; domain=.expireme.org; max-age=60", nullptr); GetACookie(cookieService, "http://expireme.org/", nullptr, getter_Copies(cookie)); rv[14] = CheckResult(cookie.get(), MUST_EQUAL, "test=expiry"); SetACookie(cookieService, "http://bar.expireme.org/", nullptr, "test=differentvalue; domain=.expireme.org; max-age=0", nullptr); GetACookie(cookieService, "http://expireme.org/", nullptr, getter_Copies(cookie)); rv[15] = CheckResult(cookie.get(), MUST_BE_NULL); allTestsPassed = PrintResult(rv, 16) && allTestsPassed; // *** multiple cookie tests sBuffer = PR_sprintf_append(sBuffer, "*** Beginning multiple cookie tests...\n"); // test the setting of multiple cookies, and test the order of precedence // (a later cookie overwriting an earlier one, in the same header string) SetACookie(cookieService, "http://multiple.cookies/", nullptr, "test=multiple; domain=.multiple.cookies \n test=different \n test=same; domain=.multiple.cookies \n newtest=ciao \n newtest=foo; max-age=-6 \n newtest=reincarnated", nullptr); GetACookie(cookieService, "http://multiple.cookies/", nullptr, getter_Copies(cookie)); rv[0] = CheckResult(cookie.get(), MUST_NOT_CONTAIN, "test=multiple"); rv[1] = CheckResult(cookie.get(), MUST_CONTAIN, "test=different"); rv[2] = CheckResult(cookie.get(), MUST_CONTAIN, "test=same"); rv[3] = CheckResult(cookie.get(), MUST_NOT_CONTAIN, "newtest=ciao"); rv[4] = CheckResult(cookie.get(), MUST_NOT_CONTAIN, "newtest=foo"); rv[5] = CheckResult(cookie.get(), MUST_CONTAIN, "newtest=reincarnated"); SetACookie(cookieService, "http://multiple.cookies/", nullptr, "test=expiry; domain=.multiple.cookies; max-age=0", nullptr); GetACookie(cookieService, "http://multiple.cookies/", nullptr, getter_Copies(cookie)); rv[6] = CheckResult(cookie.get(), MUST_NOT_CONTAIN, "test=same"); SetACookie(cookieService, "http://multiple.cookies/", nullptr, "\n test=different; max-age=0 \n", nullptr); GetACookie(cookieService, "http://multiple.cookies/", nullptr, getter_Copies(cookie)); rv[7] = CheckResult(cookie.get(), MUST_NOT_CONTAIN, "test=different"); SetACookie(cookieService, "http://multiple.cookies/", nullptr, "newtest=dead; max-age=0", nullptr); GetACookie(cookieService, "http://multiple.cookies/", nullptr, getter_Copies(cookie)); rv[8] = CheckResult(cookie.get(), MUST_BE_NULL); allTestsPassed = PrintResult(rv, 9) && allTestsPassed; // *** parser tests sBuffer = PR_sprintf_append(sBuffer, "*** Beginning parser tests...\n"); // test the cookie header parser, under various circumstances. SetACookie(cookieService, "http://parser.test/", nullptr, "test=parser; domain=.parser.test; ;; ;=; ,,, ===,abc,=; abracadabra! max-age=20;=;;", nullptr); GetACookie(cookieService, "http://parser.test/", nullptr, getter_Copies(cookie)); rv[0] = CheckResult(cookie.get(), MUST_EQUAL, "test=parser"); SetACookie(cookieService, "http://parser.test/", nullptr, "test=parser; domain=.parser.test; max-age=0", nullptr); GetACookie(cookieService, "http://parser.test/", nullptr, getter_Copies(cookie)); rv[1] = CheckResult(cookie.get(), MUST_BE_NULL); SetACookie(cookieService, "http://parser.test/", nullptr, "test=\"fubar! = foo;bar\\\";\" parser; domain=.parser.test; max-age=6\nfive; max-age=2.63,", nullptr); GetACookie(cookieService, "http://parser.test/", nullptr, getter_Copies(cookie)); rv[2] = CheckResult(cookie.get(), MUST_CONTAIN, "test=\"fubar! = foo"); rv[3] = CheckResult(cookie.get(), MUST_CONTAIN, "five"); SetACookie(cookieService, "http://parser.test/", nullptr, "test=kill; domain=.parser.test; max-age=0 \n five; max-age=0", nullptr); GetACookie(cookieService, "http://parser.test/", nullptr, getter_Copies(cookie)); rv[4] = CheckResult(cookie.get(), MUST_BE_NULL); // test the handling of VALUE-only cookies (see bug 169091), // i.e. "six" should assume an empty NAME, which allows other VALUE-only // cookies to overwrite it SetACookie(cookieService, "http://parser.test/", nullptr, "six", nullptr); GetACookie(cookieService, "http://parser.test/", nullptr, getter_Copies(cookie)); rv[5] = CheckResult(cookie.get(), MUST_EQUAL, "six"); SetACookie(cookieService, "http://parser.test/", nullptr, "seven", nullptr); GetACookie(cookieService, "http://parser.test/", nullptr, getter_Copies(cookie)); rv[6] = CheckResult(cookie.get(), MUST_EQUAL, "seven"); SetACookie(cookieService, "http://parser.test/", nullptr, " =eight", nullptr); GetACookie(cookieService, "http://parser.test/", nullptr, getter_Copies(cookie)); rv[7] = CheckResult(cookie.get(), MUST_EQUAL, "eight"); SetACookie(cookieService, "http://parser.test/", nullptr, "test=six", nullptr); GetACookie(cookieService, "http://parser.test/", nullptr, getter_Copies(cookie)); rv[9] = CheckResult(cookie.get(), MUST_CONTAIN, "test=six"); allTestsPassed = PrintResult(rv, 10) && allTestsPassed; // *** path ordering tests sBuffer = PR_sprintf_append(sBuffer, "*** Beginning path ordering tests...\n"); // test that cookies are returned in path order - longest to shortest. // if the header doesn't specify a path, it's taken from the host URI. SetACookie(cookieService, "http://multi.path.tests/", nullptr, "test1=path; path=/one/two/three", nullptr); SetACookie(cookieService, "http://multi.path.tests/", nullptr, "test2=path; path=/one \n test3=path; path=/one/two/three/four \n test4=path; path=/one/two \n test5=path; path=/one/two/", nullptr); SetACookie(cookieService, "http://multi.path.tests/one/two/three/four/five/", nullptr, "test6=path", nullptr); SetACookie(cookieService, "http://multi.path.tests/one/two/three/four/five/six/", nullptr, "test7=path; path=", nullptr); SetACookie(cookieService, "http://multi.path.tests/", nullptr, "test8=path; path=/", nullptr); GetACookie(cookieService, "http://multi.path.tests/one/two/three/four/five/six/", nullptr, getter_Copies(cookie)); rv[0] = CheckResult(cookie.get(), MUST_EQUAL, "test7=path; test6=path; test3=path; test1=path; test5=path; test4=path; test2=path; test8=path"); allTestsPassed = PrintResult(rv, 1) && allTestsPassed; // *** httponly tests sBuffer = PR_sprintf_append(sBuffer, "*** Beginning httponly tests...\n"); // Since this cookie is NOT set via http, setting it fails SetACookieNoHttp(cookieService, "http://httponly.test/", "test=httponly; httponly"); GetACookie(cookieService, "http://httponly.test/", nullptr, getter_Copies(cookie)); rv[0] = CheckResult(cookie.get(), MUST_BE_NULL); // Since this cookie is set via http, it can be retrieved SetACookie(cookieService, "http://httponly.test/", nullptr, "test=httponly; httponly", nullptr); GetACookie(cookieService, "http://httponly.test/", nullptr, getter_Copies(cookie)); rv[1] = CheckResult(cookie.get(), MUST_EQUAL, "test=httponly"); // ... but not by web content GetACookieNoHttp(cookieService, "http://httponly.test/", getter_Copies(cookie)); rv[2] = CheckResult(cookie.get(), MUST_BE_NULL); // Non-Http cookies should not replace HttpOnly cookies SetACookie(cookieService, "http://httponly.test/", nullptr, "test=httponly; httponly", nullptr); SetACookieNoHttp(cookieService, "http://httponly.test/", "test=not-httponly"); GetACookie(cookieService, "http://httponly.test/", nullptr, getter_Copies(cookie)); rv[3] = CheckResult(cookie.get(), MUST_EQUAL, "test=httponly"); // ... and, if an HttpOnly cookie already exists, should not be set at all GetACookieNoHttp(cookieService, "http://httponly.test/", getter_Copies(cookie)); rv[4] = CheckResult(cookie.get(), MUST_BE_NULL); // Non-Http cookies should not delete HttpOnly cookies SetACookie(cookieService, "http://httponly.test/", nullptr, "test=httponly; httponly", nullptr); SetACookieNoHttp(cookieService, "http://httponly.test/", "test=httponly; max-age=-1"); GetACookie(cookieService, "http://httponly.test/", nullptr, getter_Copies(cookie)); rv[5] = CheckResult(cookie.get(), MUST_EQUAL, "test=httponly"); // ... but HttpOnly cookies should SetACookie(cookieService, "http://httponly.test/", nullptr, "test=httponly; httponly; max-age=-1", nullptr); GetACookie(cookieService, "http://httponly.test/", nullptr, getter_Copies(cookie)); rv[6] = CheckResult(cookie.get(), MUST_BE_NULL); // Non-Httponly cookies can replace HttpOnly cookies when set over http SetACookie(cookieService, "http://httponly.test/", nullptr, "test=httponly; httponly", nullptr); SetACookie(cookieService, "http://httponly.test/", nullptr, "test=not-httponly", nullptr); GetACookieNoHttp(cookieService, "http://httponly.test/", getter_Copies(cookie)); rv[7] = CheckResult(cookie.get(), MUST_EQUAL, "test=not-httponly"); // scripts should not be able to set httponly cookies by replacing an existing non-httponly cookie SetACookie(cookieService, "http://httponly.test/", nullptr, "test=not-httponly", nullptr); SetACookieNoHttp(cookieService, "http://httponly.test/", "test=httponly; httponly"); GetACookieNoHttp(cookieService, "http://httponly.test/", getter_Copies(cookie)); rv[8] = CheckResult(cookie.get(), MUST_EQUAL, "test=not-httponly"); allTestsPassed = PrintResult(rv, 9) && allTestsPassed; // *** Cookie prefix tests sBuffer = PR_sprintf_append(sBuffer, "*** Beginning cookie prefix tests...\n"); // prefixed cookies can't be set from insecure HTTP SetACookie(cookieService, "http://prefixed.test/", nullptr, "__Secure-test1=test", nullptr); SetACookie(cookieService, "http://prefixed.test/", nullptr, "__Secure-test2=test; secure", nullptr); SetACookie(cookieService, "http://prefixed.test/", nullptr, "__Host-test1=test", nullptr); SetACookie(cookieService, "http://prefixed.test/", nullptr, "__Host-test2=test; secure", nullptr); GetACookie(cookieService, "http://prefixed.test/", nullptr, getter_Copies(cookie)); rv[0] = CheckResult(cookie.get(), MUST_BE_NULL); // prefixed cookies won't be set without the secure flag SetACookie(cookieService, "https://prefixed.test/", nullptr, "__Secure-test=test", nullptr); SetACookie(cookieService, "https://prefixed.test/", nullptr, "__Host-test=test", nullptr); GetACookie(cookieService, "https://prefixed.test/", nullptr, getter_Copies(cookie)); rv[1] = CheckResult(cookie.get(), MUST_BE_NULL); // prefixed cookies can be set when done correctly SetACookie(cookieService, "https://prefixed.test/", nullptr, "__Secure-test=test; secure", nullptr); SetACookie(cookieService, "https://prefixed.test/", nullptr, "__Host-test=test; secure", nullptr); GetACookie(cookieService, "https://prefixed.test/", nullptr, getter_Copies(cookie)); rv[2] = CheckResult(cookie.get(), MUST_CONTAIN, "__Secure-test=test"); rv[3] = CheckResult(cookie.get(), MUST_CONTAIN, "__Host-test=test"); // but when set must not be returned to the host insecurely GetACookie(cookieService, "http://prefixed.test/", nullptr, getter_Copies(cookie)); rv[4] = CheckResult(cookie.get(), MUST_BE_NULL); // Host-prefixed cookies cannot specify a domain SetACookie(cookieService, "https://host.prefixed.test/", nullptr, "__Host-a=test; secure; domain=prefixed.test", nullptr); SetACookie(cookieService, "https://host.prefixed.test/", nullptr, "__Host-b=test; secure; domain=.prefixed.test", nullptr); SetACookie(cookieService, "https://host.prefixed.test/", nullptr, "__Host-c=test; secure; domain=host.prefixed.test", nullptr); SetACookie(cookieService, "https://host.prefixed.test/", nullptr, "__Host-d=test; secure; domain=.host.prefixed.test", nullptr); GetACookie(cookieService, "https://host.prefixed.test/", nullptr, getter_Copies(cookie)); rv[5] = CheckResult(cookie.get(), MUST_BE_NULL); // Host-prefixed cookies can only have a path of "/" SetACookie(cookieService, "https://host.prefixed.test/some/path", nullptr, "__Host-e=test; secure", nullptr); SetACookie(cookieService, "https://host.prefixed.test/some/path", nullptr, "__Host-f=test; secure; path=/", nullptr); SetACookie(cookieService, "https://host.prefixed.test/some/path", nullptr, "__Host-g=test; secure; path=/some", nullptr); GetACookie(cookieService, "https://host.prefixed.test/", nullptr, getter_Copies(cookie)); rv[6] = CheckResult(cookie.get(), MUST_EQUAL, "__Host-f=test"); allTestsPassed = PrintResult(rv, 7) && allTestsPassed; // *** nsICookieManager{2} interface tests sBuffer = PR_sprintf_append(sBuffer, "*** Beginning nsICookieManager{2} interface tests...\n"); nsCOMPtr<nsICookieManager> cookieMgr = do_GetService(NS_COOKIEMANAGER_CONTRACTID, &rv0); if (NS_FAILED(rv0)) return -1; nsCOMPtr<nsICookieManager2> cookieMgr2 = do_QueryInterface(cookieMgr); if (!cookieMgr2) return -1; mozilla::NeckoOriginAttributes attrs; // first, ensure a clean slate rv[0] = NS_SUCCEEDED(cookieMgr->RemoveAll()); // add some cookies rv[1] = NS_SUCCEEDED(cookieMgr2->AddNative(NS_LITERAL_CSTRING("cookiemgr.test"), // domain NS_LITERAL_CSTRING("/foo"), // path NS_LITERAL_CSTRING("test1"), // name NS_LITERAL_CSTRING("yes"), // value false, // is secure false, // is httponly true, // is session INT64_MAX, // expiry time &attrs)); // originAttributes rv[2] = NS_SUCCEEDED(cookieMgr2->AddNative(NS_LITERAL_CSTRING("cookiemgr.test"), // domain NS_LITERAL_CSTRING("/foo"), // path NS_LITERAL_CSTRING("test2"), // name NS_LITERAL_CSTRING("yes"), // value false, // is secure true, // is httponly true, // is session PR_Now() / PR_USEC_PER_SEC + 2, // expiry time &attrs)); // originAttributes rv[3] = NS_SUCCEEDED(cookieMgr2->AddNative(NS_LITERAL_CSTRING("new.domain"), // domain NS_LITERAL_CSTRING("/rabbit"), // path NS_LITERAL_CSTRING("test3"), // name NS_LITERAL_CSTRING("yes"), // value false, // is secure false, // is httponly true, // is session INT64_MAX, // expiry time &attrs)); // originAttributes // confirm using enumerator nsCOMPtr<nsISimpleEnumerator> enumerator; rv[4] = NS_SUCCEEDED(cookieMgr->GetEnumerator(getter_AddRefs(enumerator))); int32_t i = 0; bool more; nsCOMPtr<nsICookie2> expiredCookie, newDomainCookie; while (NS_SUCCEEDED(enumerator->HasMoreElements(&more)) && more) { nsCOMPtr<nsISupports> cookie; if (NS_FAILED(enumerator->GetNext(getter_AddRefs(cookie)))) break; ++i; // keep tabs on the second and third cookies, so we can check them later nsCOMPtr<nsICookie2> cookie2(do_QueryInterface(cookie)); if (!cookie2) break; nsAutoCString name; cookie2->GetName(name); if (name.EqualsLiteral("test2")) expiredCookie = cookie2; else if (name.EqualsLiteral("test3")) newDomainCookie = cookie2; } rv[5] = i == 3; // check the httpOnly attribute of the second cookie is honored GetACookie(cookieService, "http://cookiemgr.test/foo/", nullptr, getter_Copies(cookie)); rv[6] = CheckResult(cookie.get(), MUST_CONTAIN, "test2=yes"); GetACookieNoHttp(cookieService, "http://cookiemgr.test/foo/", getter_Copies(cookie)); rv[7] = CheckResult(cookie.get(), MUST_NOT_CONTAIN, "test2=yes"); // check CountCookiesFromHost() uint32_t hostCookies = 0; rv[8] = NS_SUCCEEDED(cookieMgr2->CountCookiesFromHost(NS_LITERAL_CSTRING("cookiemgr.test"), &hostCookies)) && hostCookies == 2; // check CookieExists() using the third cookie bool found; rv[9] = NS_SUCCEEDED(cookieMgr2->CookieExists(newDomainCookie, &found)) && found; // remove the cookie, block it, and ensure it can't be added again rv[10] = NS_SUCCEEDED(cookieMgr->RemoveNative(NS_LITERAL_CSTRING("new.domain"), // domain NS_LITERAL_CSTRING("test3"), // name NS_LITERAL_CSTRING("/rabbit"), // path true, // is blocked &attrs)); // originAttributes rv[11] = NS_SUCCEEDED(cookieMgr2->CookieExists(newDomainCookie, &found)) && !found; rv[12] = NS_SUCCEEDED(cookieMgr2->AddNative(NS_LITERAL_CSTRING("new.domain"), // domain NS_LITERAL_CSTRING("/rabbit"), // path NS_LITERAL_CSTRING("test3"), // name NS_LITERAL_CSTRING("yes"), // value false, // is secure false, // is httponly true, // is session INT64_MIN, // expiry time &attrs)); // originAttributes rv[13] = NS_SUCCEEDED(cookieMgr2->CookieExists(newDomainCookie, &found)) && !found; // sleep four seconds, to make sure the second cookie has expired PR_Sleep(4 * PR_TicksPerSecond()); // check that both CountCookiesFromHost() and CookieExists() count the // expired cookie rv[14] = NS_SUCCEEDED(cookieMgr2->CountCookiesFromHost(NS_LITERAL_CSTRING("cookiemgr.test"), &hostCookies)) && hostCookies == 2; rv[15] = NS_SUCCEEDED(cookieMgr2->CookieExists(expiredCookie, &found)) && found; // double-check RemoveAll() using the enumerator rv[16] = NS_SUCCEEDED(cookieMgr->RemoveAll()); rv[17] = NS_SUCCEEDED(cookieMgr->GetEnumerator(getter_AddRefs(enumerator))) && NS_SUCCEEDED(enumerator->HasMoreElements(&more)) && !more; allTestsPassed = PrintResult(rv, 18) && allTestsPassed; // *** eviction and creation ordering tests sBuffer = PR_sprintf_append(sBuffer, "*** Beginning eviction and creation ordering tests...\n"); // test that cookies are // a) returned by order of creation time (oldest first, newest last) // b) evicted by order of lastAccessed time, if the limit on cookies per host (50) is reached nsAutoCString name; nsAutoCString expected; for (int32_t i = 0; i < 60; ++i) { name = NS_LITERAL_CSTRING("test"); name.AppendInt(i); name += NS_LITERAL_CSTRING("=creation"); SetACookie(cookieService, "http://creation.ordering.tests/", nullptr, name.get(), nullptr); if (i >= 10) { expected += name; if (i < 59) expected += NS_LITERAL_CSTRING("; "); } } GetACookie(cookieService, "http://creation.ordering.tests/", nullptr, getter_Copies(cookie)); rv[0] = CheckResult(cookie.get(), MUST_EQUAL, expected.get()); allTestsPassed = PrintResult(rv, 1) && allTestsPassed; // XXX the following are placeholders: add these tests please! // *** "noncompliant cookie" tests // *** IP address tests // *** speed tests sBuffer = PR_sprintf_append(sBuffer, "\n*** Result: %s!\n\n", allTestsPassed ? "all tests passed" : "TEST(S) FAILED"); } if (!allTestsPassed) { // print the entire log printf("%s", sBuffer); return 1; } PR_smprintf_free(sBuffer); sBuffer = nullptr; return 0; }
int select(int width, fd_set *rd, fd_set *wr, fd_set *ex, struct timeval *tv) #endif { int osfd; _PRUnixPollDesc *unixpds, *unixpd, *eunixpd; PRInt32 pdcnt; PRIntervalTime timeout; int retVal; #if defined(HPUX9) || defined(AIX_RENAME_SELECT) fd_set *rd = (fd_set*) rl; fd_set *wr = (fd_set*) wl; fd_set *ex = (fd_set*) el; #endif #if 0 /* * Easy special case: zero timeout. Simply call the native * select() with no fear of blocking. */ if (tv != NULL && tv->tv_sec == 0 && tv->tv_usec == 0) { #if defined(HPUX9) || defined(AIX_RENAME_SELECT) return _MD_SELECT(width, rl, wl, el, tv); #else return _MD_SELECT(width, rd, wr, ex, tv); #endif } #endif if (!_pr_initialized) { _PR_ImplicitInitialization(); } #ifndef _PR_LOCAL_THREADS_ONLY if (_PR_IS_NATIVE_THREAD(_PR_MD_CURRENT_THREAD())) { return _MD_SELECT(width, rd, wr, ex, tv); } #endif if (width < 0 || width > FD_SETSIZE) { errno = EINVAL; return -1; } /* Compute timeout */ if (tv) { /* * These acceptable ranges for t_sec and t_usec are taken * from the select() man pages. */ if (tv->tv_sec < 0 || tv->tv_sec > 100000000 || tv->tv_usec < 0 || tv->tv_usec >= 1000000) { errno = EINVAL; return -1; } /* Convert microseconds to ticks */ timeout = PR_MicrosecondsToInterval(1000000*tv->tv_sec + tv->tv_usec); } else { /* tv being a NULL pointer means blocking indefinitely */ timeout = PR_INTERVAL_NO_TIMEOUT; } /* Check for no descriptors case (just doing a timeout) */ if ((!rd && !wr && !ex) || !width) { PR_Sleep(timeout); return 0; } /* * Set up for PR_Poll(). The PRPollDesc array is allocated * dynamically. If this turns out to have high performance * penalty, one can change to use a large PRPollDesc array * on the stack, and allocate dynamically only when it turns * out to be not large enough. * * I allocate an array of size 'width', which is the maximum * number of fds we may need to poll. */ unixpds = (_PRUnixPollDesc *) PR_CALLOC(width * sizeof(_PRUnixPollDesc)); if (!unixpds) { errno = ENOMEM; return -1; } pdcnt = 0; unixpd = unixpds; for (osfd = 0; osfd < width; osfd++) { int in_flags = 0; if (rd && FD_ISSET(osfd, rd)) { in_flags |= _PR_UNIX_POLL_READ; } if (wr && FD_ISSET(osfd, wr)) { in_flags |= _PR_UNIX_POLL_WRITE; } if (ex && FD_ISSET(osfd, ex)) { in_flags |= _PR_UNIX_POLL_EXCEPT; } if (in_flags) { unixpd->osfd = osfd; unixpd->in_flags = in_flags; unixpd->out_flags = 0; unixpd++; pdcnt++; } } /* * see comments in mozilla/cmd/xfe/mozilla.c (look for * "PR_XGetXtHackFD") */ { int needToLockXAgain; needToLockXAgain = 0; if (rd && (_pr_xt_hack_fd != -1) && FD_ISSET(_pr_xt_hack_fd, rd) && PR_XIsLocked() && (!_pr_xt_hack_okayToReleaseXLock || _pr_xt_hack_okayToReleaseXLock())) { PR_XUnlock(); needToLockXAgain = 1; } /* This is the potentially blocking step */ retVal = _PR_WaitForMultipleFDs(unixpds, pdcnt, timeout); if (needToLockXAgain) { PR_XLock(); } } if (retVal > 0) { /* Compute select results */ if (rd) ZAP_SET(rd, width); if (wr) ZAP_SET(wr, width); if (ex) ZAP_SET(ex, width); /* * The return value can be either the number of ready file * descriptors or the number of set bits in the three fd_set's. */ retVal = 0; /* we're going to recompute */ eunixpd = unixpds + pdcnt; for (unixpd = unixpds; unixpd < eunixpd; unixpd++) { if (unixpd->out_flags) { int nbits = 0; /* The number of set bits on for this fd */ if (unixpd->out_flags & _PR_UNIX_POLL_NVAL) { errno = EBADF; PR_LOG(_pr_io_lm, PR_LOG_ERROR, ("select returns EBADF for %d", unixpd->osfd)); retVal = -1; break; } /* * If a socket has a pending error, it is considered * both readable and writable. (See W. Richard Stevens, * Unix Network Programming, Vol. 1, 2nd Ed., Section 6.3, * pp. 153-154.) We also consider a socket readable if * it has a hangup condition. */ if (rd && (unixpd->in_flags & _PR_UNIX_POLL_READ) && (unixpd->out_flags & (_PR_UNIX_POLL_READ | _PR_UNIX_POLL_ERR | _PR_UNIX_POLL_HUP))) { FD_SET(unixpd->osfd, rd); nbits++; } if (wr && (unixpd->in_flags & _PR_UNIX_POLL_WRITE) && (unixpd->out_flags & (_PR_UNIX_POLL_WRITE | _PR_UNIX_POLL_ERR))) { FD_SET(unixpd->osfd, wr); nbits++; } if (ex && (unixpd->in_flags & _PR_UNIX_POLL_WRITE) && (unixpd->out_flags & PR_POLL_EXCEPT)) { FD_SET(unixpd->osfd, ex); nbits++; } PR_ASSERT(nbits > 0); #if defined(HPUX) || defined(SOLARIS) || defined(SUNOS4) || defined(OSF1) || defined(AIX) retVal += nbits; #else /* IRIX */ retVal += 1; #endif } } } PR_ASSERT(tv || retVal != 0); PR_LOG(_pr_io_lm, PR_LOG_MIN, ("select returns %d", retVal)); PR_DELETE(unixpds); return retVal; }
void nsPluginInstance::threadMain(void) { DBG("nsPluginInstance::threadMain started\n"); DBG("URL: %s\n", _url.c_str()); PR_Lock(playerLock); // Initialize Gnash core library. DBG("Gnash core initialized.\n"); // Init logfile. gnash::RcInitFile& rcinit = gnash::RcInitFile::getDefaultInstance(); std::string logfilename = std::string("T:npgnash.log"); rcinit.setDebugLog(logfilename); gnash::LogFile& dbglogfile = gnash::LogFile::getDefaultInstance(); dbglogfile.setWriteDisk(true); dbglogfile.setVerbosity(GNASH_DEBUG_LEVEL); DBG("Gnash logging initialized: %s\n", logfilename.c_str()); // Init sound. //_sound_handler.reset(gnash::sound::create_sound_handler_sdl()); //gnash::set_sound_handler(_sound_handler.get()); DBG("Gnash sound initialized.\n"); // Init GUI. int old_mouse_x = 0, old_mouse_y = 0, old_mouse_buttons = 0; _render_handler = (gnash::render_handler *) gnash::create_render_handler_agg("BGR24"); // _memaddr = (unsigned char *) malloc(getMemSize()); static_cast<gnash::render_handler_agg_base *>(_render_handler)->init_buffer( getMemAddr(), getMemSize(), _width, _height, _rowstride); gnash::set_render_handler(_render_handler); DBG("Gnash GUI initialized: %ux%u\n", _width, _height); gnash::URL url(_url); VariableMap vars; gnash::URL::parse_querystring(url.querystring(), vars); for (VariableMap::iterator i = vars.begin(), ie = vars.end(); i != ie; i++) { _flashVars[i->first] = i->second; } gnash::set_base_url(url); gnash::movie_definition* md = NULL; try { md = gnash::createMovie(url, _url.c_str(), false); } catch (const gnash::GnashException& err) { md = NULL; } if (!md) { /* * N.B. Can't use the goto here, as C++ complains about "jump to * label 'done' from here crosses initialization of ..." a bunch * of things. Sigh. So, instead, I duplicate the cleanup code * here. TODO: Remove this duplication. */ // goto done; PR_Unlock(playerLock); DBG("Clean up Gnash.\n"); //gnash::clear(); DBG("nsPluginInstance::threadMain exiting\n"); return; } DBG("Movie created: %s\n", _url.c_str()); int movie_width = static_cast<int>(md->get_width_pixels()); int movie_height = static_cast<int>(md->get_height_pixels()); float movie_fps = md->get_frame_rate(); DBG("Movie dimensions: %ux%u (%.2f fps)\n", movie_width, movie_height, movie_fps); gnash::SystemClock clock; // use system clock here... gnash::movie_root& root = gnash::VM::init(*md, clock).getRoot(); DBG("Gnash VM initialized.\n"); // Register this plugin as listener for FsCommands from the core // (movie_root) #if 0 /* Commenting out for now as registerFSCommandCallback() has changed. */ root.registerFSCommandCallback(FSCommand_callback); #endif // Register a static function to handle ActionScript events such // as Mouse.hide, Stage.align etc. // root.registerEventCallback(&staticEventHandlingFunction); md->completeLoad(); DBG("Movie loaded.\n"); std::auto_ptr<gnash::Movie> mr(md->createMovie()); mr->setVariables(_flashVars); root.setRootMovie(mr.release()); //root.set_display_viewport(0, 0, _width, _height); root.set_background_alpha(1.0f); gnash::Movie* mi = root.getRootMovie(); DBG("Movie instance created.\n"); //ShowWindow(_window, SW_SHOW); IIntuition->ShowWindow(_window,NULL); for (;;) { // DBG("Inside main thread loop.\n"); if (_shutdown) { DBG("Main thread shutting down.\n"); break; } size_t cur_frame = mi->get_current_frame(); // DBG("Got current frame number: %d.\n", cur_frame); size_t tot_frames = mi->get_frame_count(); // DBG("Got total frame count: %d.\n", tot_frames); // DBG("Advancing one frame.\n"); root.advance(); // DBG("Going to next frame.\n"); root.goto_frame(cur_frame + 1); // DBG("Ensuring frame is loaded.\n"); //root.get_movie_definition()->ensure_frame_loaded(tot_frames); // DBG("Setting play state to PLAY.\n"); root.set_play_state(gnash::MovieClip::PLAYSTATE_PLAY); if (old_mouse_x != mouse_x || old_mouse_y != mouse_y) { old_mouse_x = mouse_x; old_mouse_y = mouse_y; //root.notify_mouse_moved(mouse_x, mouse_y); } if (old_mouse_buttons != mouse_buttons) { old_mouse_buttons = mouse_buttons; int mask = 1; //root.notify_mouse_clicked(mouse_buttons > 0, mask); } root.display(); #if 0 RECT rt; GetClientRect(_window, &rt); InvalidateRect(_window, &rt, FALSE); InvalidatedRanges ranges; ranges.setSnapFactor(1.3f); ranges.setSingleMode(false); root.add_invalidated_bounds(ranges, false); ranges.growBy(40.0f); ranges.combine_ranges(); if (!ranges.isNull()) { InvalidateRect(_window, &rt, FALSE); } root.display(); #endif // DBG("Unlocking playerLock mutex.\n"); PR_Unlock(playerLock); // DBG("Sleeping.\n"); PR_Sleep(PR_INTERVAL_MIN); // DBG("Acquiring playerLock mutex.\n"); PR_Lock(playerLock); } done: PR_Unlock(playerLock); DBG("Clean up Gnash.\n"); /* * N.B. As per server/impl.cpp:clear(), all of Gnash's threads aren't * guaranteed to be terminated by this, yet. Therefore, when Firefox * unloads npgnash.dll after calling NS_PluginShutdown(), and there are * still Gnash threads running, they will try and access memory that was * freed as part of the unloading of npgnash.dll, resulting in a process * abend. */ //gnash::clear(); DBG("nsPluginInstance::threadMain exiting\n"); }
bool ObtainSpoolLock(const char *aSpoolName, int aSeconds /* number of seconds to retry */, bool *aUsingLockFile) { NS_ENSURE_TRUE(aUsingLockFile, false); /* * Locking procedures: * If the directory is not writable, we want to use the appropriate system * utilites to lock the file. * If the directory is writable, we want to go through the create-and-link * locking procedures to make it atomic for certain networked file systems. * This involves creating a .mozlock file and attempting to hard-link it to * the customary .lock file. */ nsCOMPtr<nsILocalFile> spoolFile; nsresult rv = NS_NewNativeLocalFile(nsDependentCString(aSpoolName), true, getter_AddRefs(spoolFile)); NS_ENSURE_SUCCESS(rv, false); nsCOMPtr<nsIFile> directory; rv = spoolFile->GetParent(getter_AddRefs(directory)); NS_ENSURE_SUCCESS(rv, false); rv = directory->IsWritable(aUsingLockFile); NS_ENSURE_SUCCESS(rv, false); if (!*aUsingLockFile) { LOG(("Attempting to use kernel file lock")); PRFileDesc *fd; rv = spoolFile->OpenNSPRFileDesc(PR_RDWR, 0, &fd); NS_ENSURE_SUCCESS(rv, false); PRStatus lock_result; int retry_count = 0; do { lock_result = PR_TLockFile(fd); retry_count++; LOG(("Attempt %d of %d to lock file", retry_count, aSeconds)); if (aSeconds > 0 && lock_result == PR_FAILURE) { // pause 1sec, waiting for .lock to go away PRIntervalTime sleepTime = 1000; // 1 second PR_Sleep(sleepTime); } } while (lock_result == PR_FAILURE && retry_count < aSeconds); LOG(("Lock result: %d", lock_result)); PR_Close(fd); return lock_result == PR_SUCCESS; } // How to lock using files: // step 1: create SPOOLNAME.mozlock // 1a: can remove it if it already exists (probably crash-droppings) // step 2: hard-link SPOOLNAME.mozlock to SPOOLNAME.lock for NFS atomicity // 2a: if SPOOLNAME.lock is >60sec old then nuke it from orbit // 2b: repeat step 2 until retry-count expired or hard-link succeeds // step 3: remove SPOOLNAME.mozlock // step 4: If step 2 hard-link failed, fail hard; we do not hold the lock // DONE. // // (step 2a not yet implemented) nsCAutoString mozlockstr(aSpoolName); mozlockstr.Append(".mozlock"); nsCAutoString lockstr(aSpoolName); lockstr.Append(".lock"); // Create nsILocalFile for the spool.mozlock file nsCOMPtr<nsILocalFile> tmplocfile; rv = NS_NewNativeLocalFile(mozlockstr, true, getter_AddRefs(tmplocfile)); if (NS_FAILED(rv)) return false; // THOUGHT: hmm, perhaps use MakeUnique to generate us a unique mozlock? // ... perhaps not, MakeUnique implementation looks racey -- use mktemp()? // step 1: create SPOOLNAME.mozlock rv = tmplocfile->Create(nsIFile::NORMAL_FILE_TYPE, 0666); if (NS_FAILED(rv) && rv != NS_ERROR_FILE_ALREADY_EXISTS) { // can't create our .mozlock file... game over already LOG(("Failed to create file %s\n", mozlockstr.get())); return false; } // step 2: hard-link .mozlock file to .lock file (this wackiness // is necessary for non-racey locking on NFS-mounted spool dirs) // n.b. XPCOM utilities don't support hard-linking yet, so we // skip out to <unistd.h> and the POSIX interface for link() int link_result = 0; int retry_count = 0; do { link_result = link(mozlockstr.get(),lockstr.get()); retry_count++; LOG(("Attempt %d of %d to create lock file", retry_count, aSeconds)); if (aSeconds > 0 && link_result == -1) { // pause 1sec, waiting for .lock to go away PRIntervalTime sleepTime = 1000; // 1 second PR_Sleep(sleepTime); } } while (link_result == -1 && retry_count < aSeconds); LOG(("Link result: %d", link_result)); // step 3: remove .mozlock file, in any case rv = tmplocfile->Remove(false /* non-recursive */); if (NS_FAILED(rv)) { // Could not delete our .mozlock file... very unusual, but // not fatal. LOG(("Unable to delete %s", mozlockstr.get())); } // step 4: now we know whether we succeeded or failed return link_result == 0; }
int main(int argc, char **argv) { PLOptStatus os; PRBool cleanup = PR_FALSE; PRThreadScope type = PR_LOCAL_THREAD; PRFileDesc *err = PR_GetSpecialFD(PR_StandardError); PLOptState *opt = PL_CreateOptState(argc, argv, "Ghs:S:t:cC:"); PRIntn concurrency = 1, child_sleep = 10, main_sleep = 5, threads = 1; PR_STDIO_INIT(); while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) { if (PL_OPT_BAD == os) continue; switch (opt->option) { case 'c': /* call PR_Cleanup() before exiting */ cleanup = PR_TRUE; break; case 'G': /* local vs global threads */ type = PR_GLOBAL_THREAD; break; case 's': /* time to sleep */ child_sleep = atoi(opt->value); break; case 'S': /* time to sleep */ main_sleep = atoi(opt->value); break; case 'C': /* number of cpus to create */ concurrency = atoi(opt->value); break; case 't': /* number of threads to create */ threads = atoi(opt->value); break; case 'h': /* user wants some guidance */ Help(); /* so give him an earful */ return 2; /* but not a lot else */ break; default: break; } } PL_DestroyOptState(opt); PR_fprintf(err, "Cleanup settings\n"); PR_fprintf(err, "\tThread type: %s\n", (PR_LOCAL_THREAD == type) ? "LOCAL" : "GLOBAL"); PR_fprintf(err, "\tConcurrency: %d\n", concurrency); PR_fprintf(err, "\tNumber of threads: %d\n", threads); PR_fprintf(err, "\tThread sleep: %d\n", child_sleep); PR_fprintf(err, "\tMain sleep: %d\n", main_sleep); PR_fprintf(err, "\tCleanup will %sbe called\n\n", (cleanup) ? "" : "NOT "); PR_SetConcurrency(concurrency); while (threads-- > 0) (void)PR_CreateThread( PR_USER_THREAD, Thread, (void*)child_sleep, PR_PRIORITY_NORMAL, type, PR_UNJOINABLE_THREAD, 0); PR_Sleep(PR_SecondsToInterval(main_sleep)); if (cleanup) PR_Cleanup(); PR_fprintf(err, "main() exiting\n"); return 0; } /* main */
NSAPI_PUBLIC void systhread_yield(void) { PR_Sleep(PR_INTERVAL_NO_WAIT); }
/* Blocking I/O */ static void ServerB(void *arg) { PRFileDesc *listenSock = (PRFileDesc *) arg; PRFileDesc *sock; char buf[BUFFER_SIZE]; PRInt32 nbytes; int i; int j; sock = PR_Accept(listenSock, NULL, PR_INTERVAL_NO_TIMEOUT); if (NULL == sock) { fprintf(stderr, "PR_Accept failed\n"); exit(1); } for (i = 0; i < iterations; i++) { memset(buf, 0, sizeof(buf)); nbytes = PR_Recv(sock, buf, recv_amount[i], PR_MSG_PEEK, PR_INTERVAL_NO_TIMEOUT); if (-1 == nbytes) { fprintf(stderr, "PR_Recv failed\n"); exit(1); } if (send_amount[i] != nbytes) { fprintf(stderr, "PR_Recv returned %d, absurd!\n", nbytes); exit(1); } for (j = 0; j < nbytes; j++) { if (buf[j] != 2*i) { fprintf(stderr, "byte %d should be %d but is %d\n", j, 2*i, buf[j]); exit(1); } } fprintf(stderr, "server: peeked expected data\n"); memset(buf, 0, sizeof(buf)); nbytes = PR_Recv(sock, buf, recv_amount[i], PR_MSG_PEEK, PR_INTERVAL_NO_TIMEOUT); if (-1 == nbytes) { fprintf(stderr, "PR_Recv failed\n"); exit(1); } if (send_amount[i] != nbytes) { fprintf(stderr, "PR_Recv returned %d, absurd!\n", nbytes); exit(1); } for (j = 0; j < nbytes; j++) { if (buf[j] != 2*i) { fprintf(stderr, "byte %d should be %d but is %d\n", j, 2*i, buf[j]); exit(1); } } fprintf(stderr, "server: peeked expected data\n"); memset(buf, 0, sizeof(buf)); nbytes = PR_Recv(sock, buf, recv_amount[i], 0, PR_INTERVAL_NO_TIMEOUT); if (-1 == nbytes) { fprintf(stderr, "PR_Recv failed\n"); exit(1); } if (send_amount[i] != nbytes) { fprintf(stderr, "PR_Recv returned %d, absurd!\n", nbytes); exit(1); } for (j = 0; j < nbytes; j++) { if (buf[j] != 2*i) { fprintf(stderr, "byte %d should be %d but is %d\n", j, 2*i, buf[j]); exit(1); } } fprintf(stderr, "server: received expected data\n"); PR_Sleep(PR_SecondsToInterval(1)); memset(buf, 2*i+1, send_amount[i]); nbytes = PR_Send(sock, buf, send_amount[i], 0, PR_INTERVAL_NO_TIMEOUT); if (-1 == nbytes) { fprintf(stderr, "PR_Send failed\n"); exit(1); } if (send_amount[i] != nbytes) { fprintf(stderr, "PR_Send returned %d, absurd!\n", nbytes); exit(1); } } if (PR_Close(sock) == PR_FAILURE) { fprintf(stderr, "PR_Close failed\n"); exit(1); } }
PRStatus RCThread::Sleep(const RCInterval& ticks) { PRIntervalTime tmo = ticks; return PR_Sleep(tmo); }
static void PR_CALLBACK Clientel(void *arg) { PRStatus rv; PRFileDesc *xport; PRInt32 bytes, sampled; PRIntervalTime now, interval; PRBool do_display = PR_FALSE; Shared *shared = (Shared*)arg; char *buffer = (char*)PR_Malloc(buffer_size); PRNetAddr *server_address = &shared->server_address; PRIntervalTime connect_timeout = PR_SecondsToInterval(5); PRIntervalTime sampling_interval = PR_SecondsToInterval(SAMPLING_INTERVAL); PR_fprintf(err, "Client connecting to "); (void)PrintAddress(server_address); do { xport = PR_Socket(domain, PR_SOCK_STREAM, protocol); if (NULL == xport) { PL_FPrintError(err, "PR_Socket"); return; } if (xport_buffer != -1) { PRSocketOptionData data; data.option = PR_SockOpt_RecvBufferSize; data.value.recv_buffer_size = (PRSize)xport_buffer; rv = PR_SetSocketOption(xport, &data); if (PR_FAILURE == rv) PL_FPrintError(err, "PR_SetSocketOption - ignored"); data.option = PR_SockOpt_SendBufferSize; data.value.send_buffer_size = (PRSize)xport_buffer; rv = PR_SetSocketOption(xport, &data); if (PR_FAILURE == rv) PL_FPrintError(err, "PR_SetSocketOption - ignored"); } rv = PR_Connect(xport, server_address, connect_timeout); if (PR_FAILURE == rv) { PL_FPrintError(err, "PR_Connect"); if (PR_IO_TIMEOUT_ERROR != PR_GetError()) PR_Sleep(connect_timeout); PR_Close(xport); /* delete it and start over */ } } while (PR_FAILURE == rv); do { bytes = PR_Recv( xport, buffer, buffer_size, 0, PR_INTERVAL_NO_TIMEOUT); PR_Lock(shared->ml); now = PR_IntervalNow(); shared->sampled += bytes; interval = now - shared->timein; if (interval > sampling_interval) { sampled = shared->sampled; shared->timein = now; shared->sampled = 0; do_display = PR_TRUE; } PR_Unlock(shared->ml); if (do_display) { PRUint32 rate = sampled / PR_IntervalToMilliseconds(interval); PR_fprintf(err, "%u streams @ %u Kbytes/sec\n", shared->threads, rate); do_display = PR_FALSE; } } while (bytes > 0); } /* Clientel */
// typedef PRBool // (* nsHashtableEnumFunc) // (nsHashKey *aKey, void *aData, void* aClosure); PRBool CheckLDAPOperationResult(nsHashKey *aKey, void *aData, void* aClosure) { int lderrno; nsresult rv; PRInt32 returnCode; LDAPMessage *msgHandle; nsCOMPtr<nsILDAPMessage> msg; PRBool operationFinished = PR_TRUE; struct timeval timeout = { 0, 0 }; PRIntervalTime sleepTime = PR_MillisecondsToInterval(40); // we need to access some of the connection loop's objects // nsLDAPConnectionLoop *loop = static_cast<nsLDAPConnectionLoop *>(aClosure); // get the console service so we can log messages // nsCOMPtr<nsIConsoleService> consoleSvc = do_GetService(kConsoleServiceContractId, &rv); if (NS_FAILED(rv)) { NS_ERROR("CheckLDAPOperationResult() couldn't get console service"); return NS_ERROR_FAILURE; } returnCode = ldap_result(loop->mRawConn->mConnectionHandle, aKey->HashCode(), LDAP_MSG_ONE, &timeout, &msgHandle); // if we didn't error or timeout, create an nsILDAPMessage // switch (returnCode) { case 0: // timeout // the connection may not exist yet. sleep for a while // to avoid a problem where the LDAP connection/thread isn't // ready quite yet, and we want to avoid a very busy loop. // PR_Sleep(sleepTime); return PR_TRUE; case -1: // something went wrong lderrno = ldap_get_lderrno(loop->mRawConn->mConnectionHandle, 0, 0); // Sleep briefly, to avoid a very busy loop again. // PR_Sleep(sleepTime); switch (lderrno) { case LDAP_SERVER_DOWN: // We might want to shutdown the thread here, but it has // implications to the user of the nsLDAPConnection, so // for now we just ignore it. It's up to the owner of // the nsLDAPConnection to detect the error, and then // create a new connection. // PR_LOG(gLDAPLogModule, PR_LOG_DEBUG, ("CheckLDAPOperationResult(): ldap_result returned" " LDAP_SERVER_DOWN")); break; case LDAP_DECODING_ERROR: consoleSvc->LogStringMessage( NS_LITERAL_STRING("LDAP: WARNING: decoding error; possible corrupt data received").get()); NS_WARNING("CheckLDAPOperationResult(): ldaperrno = " "LDAP_DECODING_ERROR after ldap_result()"); break; case LDAP_NO_MEMORY: NS_ERROR("CheckLDAPOperationResult(): Couldn't allocate memory" " while getting async operation result"); // punt and hope things work out better next time around break; case LDAP_PARAM_ERROR: // I think it's possible to hit a race condition where we're // continuing to poll for a result after the C SDK connection // has removed the operation because the connection has gone // dead. In theory we should fix this. Practically, it's // unclear to me whether it matters. // NS_WARNING("CheckLDAPOperationResult(): ldap_result returned" " LDAP_PARAM_ERROR"); break; default: NS_ERROR("CheckLDAPOperationResult(): lderrno set to " "unexpected value after ldap_result() " "call in nsLDAPConnection::Run()"); PR_LOG(gLDAPLogModule, PR_LOG_ERROR, ("lderrno = 0x%x", lderrno)); break; } break; case LDAP_RES_SEARCH_ENTRY: case LDAP_RES_SEARCH_REFERENCE: // XXX what should we do with LDAP_RES_SEARCH_EXTENDED? // not done yet, so we shouldn't remove the op from the conn q operationFinished = PR_FALSE; // fall through to default case default: // initialize the message and call the callback // we want nsLDAPMessage specifically, not a compatible, since // we're sharing native objects used by the LDAP C SDK // nsLDAPMessage *rawMsg; NS_NEWXPCOM(rawMsg, nsLDAPMessage); if (!rawMsg) { NS_ERROR("CheckLDAPOperationResult(): couldn't allocate memory" " for new LDAP message; search entry dropped"); // punt and hope things work out better next time around break; } // initialize the message, using a protected method not available // through nsILDAPMessage (which is why we need the raw pointer) // rv = rawMsg->Init(loop->mRawConn, msgHandle); // now let the scoping mechanisms provided by nsCOMPtr manage // the reference for us. // msg = rawMsg; switch (rv) { case NS_OK: { PRInt32 errorCode; rawMsg->GetErrorCode(&errorCode); // maybe a version error, e.g., using v3 on a v2 server. // if we're using v3, try v2. // if (errorCode == LDAP_PROTOCOL_ERROR && loop->mRawConn->mVersion == nsILDAPConnection::VERSION3) { nsCAutoString password; loop->mRawConn->mVersion = nsILDAPConnection::VERSION2; ldap_set_option(loop->mRawConn->mConnectionHandle, LDAP_OPT_PROTOCOL_VERSION, &loop->mRawConn->mVersion); nsCOMPtr <nsILDAPOperation> operation = static_cast<nsILDAPOperation *>(static_cast<nsISupports *>(aData)); // we pass in an empty password to tell the operation that // it should use the cached password. // rv = operation->SimpleBind(password); if (NS_SUCCEEDED(rv)) { operationFinished = PR_FALSE; // we don't want to notify callers that we're done... return PR_TRUE; } } // If we're midway through a SASL Bind, we need to continue // without letting our caller know what we're up to! // if (errorCode == LDAP_SASL_BIND_IN_PROGRESS) { struct berval *creds; ldap_parse_sasl_bind_result( loop->mRawConn->mConnectionHandle, msgHandle, &creds, 0); nsCOMPtr <nsILDAPOperation> operation = static_cast<nsILDAPOperation *> (static_cast<nsISupports *>(aData)); rv = operation->SaslStep(creds->bv_val, creds->bv_len); if (NS_SUCCEEDED(rv)) { return PR_TRUE; } } } break; case NS_ERROR_LDAP_DECODING_ERROR: consoleSvc->LogStringMessage( NS_LITERAL_STRING("LDAP: WARNING: decoding error; possible corrupt data received").get()); NS_WARNING("CheckLDAPOperationResult(): ldaperrno = " "LDAP_DECODING_ERROR after ldap_result()"); return PR_TRUE; case NS_ERROR_OUT_OF_MEMORY: // punt and hope things work out better next time around return PR_TRUE; case NS_ERROR_ILLEGAL_VALUE: case NS_ERROR_UNEXPECTED: default: // shouldn't happen; internal error // NS_ERROR("CheckLDAPOperationResult(): nsLDAPMessage::Init() " "returned unexpected value."); // punt and hope things work out better next time around return PR_TRUE; } // invoke the callback on the nsILDAPOperation corresponding to // this message // rv = loop->mRawConn->InvokeMessageCallback(msgHandle, msg, operationFinished); if (NS_FAILED(rv)) { NS_ERROR("CheckLDAPOperationResult(): error invoking message" " callback"); // punt and hope things work out better next time around return PR_TRUE; } break; } return PR_TRUE; }
PR_IMPLEMENT(PRInt32) PR_Select( PRInt32 unused, PR_fd_set *pr_rd, PR_fd_set *pr_wr, PR_fd_set *pr_ex, PRIntervalTime timeout) { #if !defined(NEED_SELECT) PRInt32 npds = 0; /* ** Find out how many fds are represented in the three lists. ** Then allocate a polling descriptor for the logical union ** (there can't be any overlapping) and call PR_Poll(). */ PRPollDesc *copy, *poll; static PRBool warning = PR_TRUE; if (warning) warning = _PR_Obsolete( "PR_Select()", "PR_Poll()"); /* try to get an initial guesss at how much space we need */ npds = 0; if ((NULL != pr_rd) && ((pr_rd->hsize + pr_rd->nsize - npds) > 0)) npds = pr_rd->hsize + pr_rd->nsize; if ((NULL != pr_wr) && ((pr_wr->hsize + pr_wr->nsize - npds) > 0)) npds = pr_wr->hsize + pr_wr->nsize; if ((NULL != pr_ex) && ((pr_ex->hsize + pr_ex->nsize - npds) > 0)) npds = pr_ex->hsize + pr_ex->nsize; if (0 == npds) { PR_Sleep(timeout); return 0; } copy = poll = (PRPollDesc*)PR_Calloc(npds + PD_INCR, sizeof(PRPollDesc)); if (NULL == poll) goto out_of_memory; poll[npds + PD_INCR - 1].fd = (PRFileDesc*)-1; poll = _pr_setfd(pr_rd, PR_POLL_READ, poll); if (NULL == poll) goto out_of_memory; poll = _pr_setfd(pr_wr, PR_POLL_WRITE, poll); if (NULL == poll) goto out_of_memory; poll = _pr_setfd(pr_ex, PR_POLL_EXCEPT, poll); if (NULL == poll) goto out_of_memory; unused = 0; while (NULL != poll[unused].fd && (PRFileDesc*)-1 != poll[unused].fd) { ++unused; } PR_ASSERT(unused > 0); npds = PR_Poll(poll, unused, timeout); if (npds > 0) { /* Copy the results back into the fd sets */ if (NULL != pr_rd) pr_rd->nsize = pr_rd->hsize = 0; if (NULL != pr_wr) pr_wr->nsize = pr_wr->hsize = 0; if (NULL != pr_ex) pr_ex->nsize = pr_ex->hsize = 0; for (copy = &poll[unused - 1]; copy >= poll; --copy) { if (copy->out_flags & PR_POLL_NVAL) { PR_SetError(PR_BAD_DESCRIPTOR_ERROR, 0); npds = -1; break; } if (copy->out_flags & PR_POLL_READ) if (NULL != pr_rd) pr_rd->harray[pr_rd->hsize++] = copy->fd; if (copy->out_flags & PR_POLL_WRITE) if (NULL != pr_wr) pr_wr->harray[pr_wr->hsize++] = copy->fd; if (copy->out_flags & PR_POLL_EXCEPT) if (NULL != pr_ex) pr_ex->harray[pr_ex->hsize++] = copy->fd; } } PR_DELETE(poll); return npds; out_of_memory: PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); return -1; #endif /* !defined(NEED_SELECT) */ }
int main(int argc, char* argv[]) { if (test_common_init(&argc, &argv) != 0) return -1; nsresult rv; if (argc < 2) { printf("usage: %s <file-to-read>\n", argv[0]); return -1; } char* fileName = argv[1]; { nsCOMPtr<nsIServiceManager> servMan; NS_InitXPCOM2(getter_AddRefs(servMan), nullptr, nullptr); nsCOMPtr<nsIComponentRegistrar> registrar = do_QueryInterface(servMan); NS_ASSERTION(registrar, "Null nsIComponentRegistrar"); if (registrar) registrar->AutoRegister(nullptr); #if defined(PR_LOGGING) gTestLog = PR_NewLogModule("Test"); #endif nsCOMPtr<nsIFile> srcFile; rv = NS_NewNativeLocalFile(nsDependentCString(fileName), false, getter_AddRefs(srcFile)); if (NS_FAILED(rv)) return rv; nsCOMPtr<nsIFile> destFile; rv = srcFile->Clone(getter_AddRefs(destFile)); if (NS_FAILED(rv)) return rv; nsCAutoString leafName; rv = destFile->GetNativeLeafName(leafName); if (NS_FAILED(rv)) return rv; nsCAutoString newName(leafName); newName.Append(NS_LITERAL_CSTRING(".1")); rv = destFile->SetNativeLeafName(newName); if (NS_FAILED(rv)) return rv; rv = RunTest(srcFile, destFile); NS_ASSERTION(NS_SUCCEEDED(rv), "RunTest failed"); newName = leafName; newName.Append(NS_LITERAL_CSTRING(".2")); rv = destFile->SetNativeLeafName(newName); if (NS_FAILED(rv)) return rv; rv = RunBlockingTest(srcFile, destFile); NS_ASSERTION(NS_SUCCEEDED(rv), "RunBlockingTest failed"); // give background threads a chance to finish whatever work they may // be doing. PR_Sleep(PR_SecondsToInterval(1)); } // this scopes the nsCOMPtrs // no nsCOMPtrs are allowed to be alive when you call NS_ShutdownXPCOM rv = NS_ShutdownXPCOM(nullptr); NS_ASSERTION(NS_SUCCEEDED(rv), "NS_ShutdownXPCOM failed"); return NS_OK; }