]> git.ipfire.org Git - thirdparty/openssl.git/blob - crypto/sleep.c
Raise an error on syscall failure in tls_retry_write_records
[thirdparty/openssl.git] / crypto / sleep.c
1 /*
2 * Copyright 2022-2024 The OpenSSL Project Authors. All Rights Reserved.
3 *
4 * Licensed under the Apache License 2.0 (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
8 */
9
10 #include <openssl/crypto.h>
11 #include "internal/e_os.h"
12
13 /* system-specific variants defining OSSL_sleep() */
14 #if defined(OPENSSL_SYS_UNIX) || defined(__DJGPP__)
15 #include <unistd.h>
16
17 void OSSL_sleep(uint64_t millis)
18 {
19 # ifdef OPENSSL_SYS_VXWORKS
20 struct timespec ts;
21
22 ts.tv_sec = (long int) (millis / 1000);
23 ts.tv_nsec = (long int) (millis % 1000) * 1000000ul;
24 nanosleep(&ts, NULL);
25 # elif defined(__TANDEM) && !defined(_REENTRANT)
26 # include <cextdecs.h(PROCESS_DELAY_)>
27
28 /* HPNS does not support usleep for non threaded apps */
29 PROCESS_DELAY_(millis * 1000);
30 # else
31 unsigned int s = (unsigned int)(millis / 1000);
32 unsigned int us = (unsigned int)((millis % 1000) * 1000);
33
34 if (s > 0)
35 sleep(s);
36 usleep(us);
37 # endif
38 }
39 #elif defined(_WIN32) && !defined(OPENSSL_SYS_UEFI)
40 # include <windows.h>
41
42 void OSSL_sleep(uint64_t millis)
43 {
44 /*
45 * Windows' Sleep() takes a DWORD argument, which is smaller than
46 * a uint64_t, so we need to limit it to 49 days, which should be enough.
47 */
48 DWORD limited_millis = (DWORD)-1;
49
50 if (millis < limited_millis)
51 limited_millis = (DWORD)millis;
52 Sleep(limited_millis);
53 }
54
55 #else
56 /* Fallback to a busy wait */
57 # include "internal/time.h"
58
59 static void ossl_sleep_secs(uint64_t secs)
60 {
61 /*
62 * sleep() takes an unsigned int argument, which is smaller than
63 * a uint64_t, so it needs to be limited to 136 years which
64 * should be enough even for Sleeping Beauty.
65 */
66 unsigned int limited_secs = UINT_MAX;
67
68 if (secs < limited_secs)
69 limited_secs = (unsigned int)secs;
70 sleep(limited_secs);
71 }
72
73 static void ossl_sleep_millis(uint64_t millis)
74 {
75 const OSSL_TIME finish
76 = ossl_time_add(ossl_time_now(), ossl_ms2time(millis));
77
78 while (ossl_time_compare(ossl_time_now(), finish) < 0)
79 /* busy wait */ ;
80 }
81
82 void OSSL_sleep(uint64_t millis)
83 {
84 ossl_sleep_secs(millis / 1000);
85 ossl_sleep_millis(millis % 1000);
86 }
87 #endif /* defined(OPENSSL_SYS_UNIX) || defined(__DJGPP__) */