MCPcopy Create free account
hub / github.com/coreutils/coreutils / splice_write

Function splice_write

src/yes.c:101–187  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

99 report any error). Return FALSE if splice could not be used. */
100
101static bool
102splice_write (MAYBE_UNUSED char const *buf, MAYBE_UNUSED idx_t copysize)
103{
104 bool output_started = false;
105#if HAVE_SPLICE
106 idx_t page_size = getpagesize ();
107
108 bool stdout_is_pipe = isapipe (STDOUT_FILENO) > 0;
109
110 /* Determine buffer size: enlarge the target pipe,
111 then use 1/4 of actual capacity as the transfer size. */
112 int pipefd[2] = { -1, -1 };
113 idx_t splice_bufsize;
114 char *splice_buf = NULL;
115
116 if (stdout_is_pipe)
117 splice_bufsize = pipe_splice_size (STDOUT_FILENO, copysize);
118 else
119 {
120 if (pipe2 (pipefd, 0) < 0)
121 return false;
122 splice_bufsize = pipe_splice_size (pipefd[0], copysize);
123 }
124
125 if (splice_bufsize == 0)
126 goto done;
127
128 /* Allocate page-aligned buffer for vmsplice.
129 Needed with SPLICE_F_GIFT, but generally good for performance. */
130 if (! (splice_buf = alignalloc (page_size, splice_bufsize)))
131 goto done;
132
133 repeat_pattern (splice_buf, buf, copysize, splice_bufsize);
134
135 /* For the pipe case, vmsplice directly to stdout.
136 For the non-pipe case, vmsplice into the intermediate pipe
137 and then splice from it to stdout. */
138 int vmsplice_fd = stdout_is_pipe ? STDOUT_FILENO : pipefd[1];
139
140 for (;;)
141 {
142 struct iovec iov = { .iov_base = splice_buf,
143 .iov_len = splice_bufsize };
144
145 while (iov.iov_len > 0)
146 {
147 /* Use SPLICE_F_{GIFT,MOVE} to allow the kernel to take references
148 to the pages. I.e., we're indicating we won't make changes.
149 SPLICE_F_GIFT is only appropriate for full pages. */
150 unsigned int flags = iov.iov_len % page_size ? 0 : SPLICE_F_GIFT;
151 ssize_t n = vmsplice (vmsplice_fd, &iov, 1, flags);
152 if (n <= 0)
153 goto done;
154
155 if (stdout_is_pipe)
156 output_started = true;
157 else
158 {

Callers 1

mainFunction · 0.85

Calls 2

pipe_splice_sizeFunction · 0.85
repeat_patternFunction · 0.85

Tested by

no test coverage detected