Branch data Line data Source code
1 : : /*
2 : : * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 : : *
4 : : * Licensed under the Apache License, Version 2.0 (the "License").
5 : : * You may not use this file except in compliance with the License.
6 : : * A copy of the License is located at
7 : : *
8 : : * http://aws.amazon.com/apache2.0
9 : : *
10 : : * or in the "license" file accompanying this file. This file is distributed
11 : : * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 : : * express or implied. See the License for the specific language governing
13 : : * permissions and limitations under the License.
14 : : */
15 : :
16 : : #include <errno.h>
17 : : #include <fcntl.h>
18 : : #include <sys/mman.h>
19 : : #include <sys/stat.h>
20 : : #include <sys/types.h>
21 : : #include <unistd.h>
22 : :
23 : : #include "error/s2n_errno.h"
24 : : #include "stuffer/s2n_stuffer.h"
25 : : #include "utils/s2n_io.h"
26 : : #include "utils/s2n_safety.h"
27 : :
28 : : int s2n_stuffer_recv_from_fd(struct s2n_stuffer *stuffer, const int rfd, const uint32_t len, uint32_t *bytes_written)
29 : 2273 : {
30 [ - + ][ + - ]: 2273 : POSIX_PRECONDITION(s2n_stuffer_validate(stuffer));
31 : :
32 : : /* Make sure we have enough space to write */
33 [ - + ]: 2273 : POSIX_GUARD(s2n_stuffer_skip_write(stuffer, len));
34 : :
35 : : /* "undo" the skip write */
36 : 2273 : stuffer->write_cursor -= len;
37 : :
38 : 2273 : ssize_t r = 0;
39 [ - + ][ # # ]: 2273 : POSIX_ENSURE(stuffer->blob.data, S2N_ERR_READ);
40 [ + + ][ - + ]: 2273 : S2N_IO_RETRY_EINTR(r, read(rfd, stuffer->blob.data + stuffer->write_cursor, len));
41 [ + - ][ + + ]: 2273 : POSIX_ENSURE(r >= 0, S2N_ERR_READ);
42 : :
43 : : /* Record just how many bytes we have written */
44 [ # # ][ - + ]: 8 : POSIX_ENSURE((size_t) r <= UINT32_MAX, S2N_ERR_INTEGER_OVERFLOW);
45 [ - + ]: 8 : POSIX_GUARD(s2n_stuffer_skip_write(stuffer, (uint32_t) r));
46 [ + + ]: 8 : if (bytes_written != NULL) {
47 : 1 : *bytes_written = r;
48 : 1 : }
49 : 8 : return S2N_SUCCESS;
50 : 8 : }
51 : :
52 : : int s2n_stuffer_send_to_fd(struct s2n_stuffer *stuffer, const int wfd, const uint32_t len, uint32_t *bytes_sent)
53 : 2271 : {
54 [ - + ][ + - ]: 2271 : POSIX_PRECONDITION(s2n_stuffer_validate(stuffer));
55 : :
56 : : /* Make sure we even have the data */
57 [ - + ]: 2271 : POSIX_GUARD(s2n_stuffer_skip_read(stuffer, len));
58 : :
59 : : /* "undo" the skip read */
60 : 2271 : stuffer->read_cursor -= len;
61 : :
62 : 2271 : ssize_t w = 0;
63 [ + + ][ + - ]: 2271 : POSIX_ENSURE(stuffer->blob.data, S2N_ERR_WRITE);
64 [ - + ][ # # ]: 993 : S2N_IO_RETRY_EINTR(w, write(wfd, stuffer->blob.data + stuffer->read_cursor, len));
65 [ - + ][ # # ]: 993 : POSIX_ENSURE(w >= 0, S2N_ERR_WRITE);
66 : :
67 [ - + ][ # # ]: 993 : POSIX_ENSURE((size_t) w <= UINT32_MAX - stuffer->read_cursor, S2N_ERR_INTEGER_OVERFLOW);
68 : 993 : stuffer->read_cursor += w;
69 [ - + ]: 993 : if (bytes_sent != NULL) {
70 : 0 : *bytes_sent = w;
71 : 0 : }
72 : 993 : return S2N_SUCCESS;
73 : 993 : }
74 : :
75 : : int s2n_stuffer_alloc_ro_from_fd(struct s2n_stuffer *stuffer, int rfd)
76 : 0 : {
77 [ # # ][ # # ]: 0 : POSIX_ENSURE_MUT(stuffer);
78 : 0 : struct stat st = { 0 };
79 : :
80 [ # # ][ # # ]: 0 : POSIX_ENSURE(fstat(rfd, &st) >= 0, S2N_ERR_FSTAT);
81 : :
82 [ # # ][ # # ]: 0 : POSIX_ENSURE_GT(st.st_size, 0);
83 [ # # ][ # # ]: 0 : POSIX_ENSURE_LTE((uint64_t) st.st_size, UINT32_MAX);
84 : :
85 : 0 : uint8_t *map = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, rfd, 0);
86 [ # # ][ # # ]: 0 : POSIX_ENSURE(map != MAP_FAILED, S2N_ERR_MMAP);
87 : :
88 : 0 : struct s2n_blob b = { 0 };
89 [ # # ]: 0 : POSIX_GUARD(s2n_blob_init(&b, map, (uint32_t) st.st_size));
90 : 0 : return s2n_stuffer_init(stuffer, &b);
91 : 0 : }
92 : :
93 : : int s2n_stuffer_alloc_ro_from_file(struct s2n_stuffer *stuffer, const char *file)
94 : 0 : {
95 [ # # ][ # # ]: 0 : POSIX_ENSURE_MUT(stuffer);
96 [ # # ][ # # ]: 0 : POSIX_ENSURE_REF(file);
97 : :
98 : 0 : int fd = 0;
99 [ # # ][ # # ]: 0 : S2N_IO_RETRY_EINTR(fd, open(file, O_RDONLY));
100 [ # # ][ # # ]: 0 : POSIX_ENSURE(fd >= 0, S2N_ERR_OPEN);
101 : :
102 : 0 : int r = s2n_stuffer_alloc_ro_from_fd(stuffer, fd);
103 : :
104 [ # # ]: 0 : POSIX_GUARD(close(fd));
105 : :
106 : 0 : return r;
107 : 0 : }
|