Skip to content

std: implement sendfile on linux - #4131

Closed
terinjokes wants to merge 1 commit into
ziglang:masterfrom
terinjokes:patches/sendfile
Closed

std: implement sendfile on linux#4131
terinjokes wants to merge 1 commit into
ziglang:masterfrom
terinjokes:patches/sendfile

Conversation

@terinjokes

Copy link
Copy Markdown
Contributor

This changset adds a sendfile(2) syscall bindings to the linux bits
component. Where available, the sendfile64(2) syscall will be
transparently called.

A wrapping function has also been added to the std.os to transform
errno returns to Zig errors.

@daurnimatordaurnimator left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should also add a prototype in std/c.zig so that libc's function is used when linking against libc.

Comment threadlib/std/os.zig Outdated
while (true) {
var rc: usize = undefined;
var err: usize = undefined;
if (builtin.os == .linux) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should just be an unconditional system.sendfile. If someone attempts to call this function on a system without it then they will get a compile error indicating as much.

@daurnimatordaurnimator added os-linux Linux standard library This issue involves writing Zig code for the standard library. labels Jan 10, 2020
@terinjokes

Copy link
Copy Markdown
ContributorAuthor

@daurnimator I had added it to c.zig locally, but building anything linking against C fails with an unrelated error, so I can't test if my changes are good.

@terinjokes

Copy link
Copy Markdown
ContributorAuthor
/usr/lib/zig/std/os.zig:3301:60: error: cast discards const qualifier
switch (errno(system.setsockopt(fd, level, optname, opt.ptr, @intCast(socklen_t, opt.len)))) {

@terinjokes

terinjokes commented Jan 10, 2020

Copy link
Copy Markdown
ContributorAuthor

Per discussion on IRC, this PR can likely be extended with macOS and FreeBSD support:

  • Extend the os.zig wrapper to accept hdr, sbytes, and flags parameters.
  • Handle writing headers and trailers on systems where this isn't the default. Document what systems they're written atomically.
  • The BSD and Linux handle updates to the offset pointer different, so I may need to also document the behavior and what would be portable.

Windows has TransmitFile as part of mswsock, which looks similar. Will have to investigate farther.

Comment threadlib/std/os.zig Outdated
Comment on lines +3118 to +3119
/// There was insufficient memory for reading from infd.
NoMem,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm surprised (and disappointed) this error is even possible; the kernel should be able to make this "just work" even if it is forced to use a small stack-based buffer due to heap memory pressure.

By convention, ENOMEM in zig turns into one of these two things:

  • error.OutOfMemory if it is userspace heap memory that is exhausted
  • error.SystemResources if it is kernel space memory or other resources that are unavailable.

In this case I believe it would be error.SystemResources.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reading through the kernel sources, this actually comes from files that have a mandatory lock, and the underlying splice() cannot return ENOMEM.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@shawnl Thanks, I can update the comment. I'll likely take @andrewrk's recommendation of using error.SystemResources in this case.

@terinjokes

Copy link
Copy Markdown
ContributorAuthor

I've pushed updates to the Linux support to accept the wider *BSD parameters, and to send the header and trailer iovecs. I doubt I have implemented the behavior to match correctly.

Next up to to add support sendfile(2) from FreeBSD libc. Then I'll be in a better place to verify the behavior is the same.

This changset adds a `sendfile(2)` syscall bindings to the linux bits
component. Where available, the `sendfile64(2)` syscall will be
transparently called.
A wrapping function has also been added to the std.os to transform
errno returns to Zig errors.
Change-Id: I86769fc4382c0771e3656e7b21137bafd99a4411
Comment threadlib/std/c/freebsd.zig
trailers: [*]iovec_const,
trl_cnt: c_int,
};
pub extern "c" fn sendfile(fd: c_int, s: c_int, offset: u64, nbytes: usize, sf_hdtr: ?*sf_hdtr, sbytes: ?*u64, flags: c_int) c_int;

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I need to double check that the offset parameters here should be u64 instead of off_t.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think zig should support 32-bit off_t, in which case they are the same, but yeah probably still use off_t even if it must be u64.

@andrewrk

Copy link
Copy Markdown
Member

Thanks! This is merged into #4611.

@andrewrkandrewrk closed this Mar 3, 2020
@terinjokes

Copy link
Copy Markdown
ContributorAuthor

Sorry for not getting this as polished as I liked. Thank you for taking the time to carry it through.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

os-linuxLinuxstandard libraryThis issue involves writing Zig code for the standard library.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@terinjokes@andrewrk@daurnimator@shawnl
, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
std: implement sendfile on linux by terinjokes · Pull Request #4131 · ziglang/zig · GitHub
Skip to content

std: implement sendfile on linux - #4131

Closed
terinjokes wants to merge 1 commit into
ziglang:masterfrom
terinjokes:patches/sendfile
Closed

std: implement sendfile on linux#4131
terinjokes wants to merge 1 commit into
ziglang:masterfrom
terinjokes:patches/sendfile

Conversation

@terinjokes

Copy link
Copy Markdown
Contributor

This changset adds a sendfile(2) syscall bindings to the linux bits
component. Where available, the sendfile64(2) syscall will be
transparently called.

A wrapping function has also been added to the std.os to transform
errno returns to Zig errors.

@daurnimatordaurnimator left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should also add a prototype in std/c.zig so that libc's function is used when linking against libc.

Comment threadlib/std/os.zig Outdated
while (true) {
var rc: usize = undefined;
var err: usize = undefined;
if (builtin.os == .linux) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should just be an unconditional system.sendfile. If someone attempts to call this function on a system without it then they will get a compile error indicating as much.

@daurnimatordaurnimator added os-linux Linux standard library This issue involves writing Zig code for the standard library. labels Jan 10, 2020
@terinjokes

Copy link
Copy Markdown
ContributorAuthor

@daurnimator I had added it to c.zig locally, but building anything linking against C fails with an unrelated error, so I can't test if my changes are good.

@terinjokes

Copy link
Copy Markdown
ContributorAuthor
/usr/lib/zig/std/os.zig:3301:60: error: cast discards const qualifier
switch (errno(system.setsockopt(fd, level, optname, opt.ptr, @intCast(socklen_t, opt.len)))) {

@terinjokes

terinjokes commented Jan 10, 2020

Copy link
Copy Markdown
ContributorAuthor

Per discussion on IRC, this PR can likely be extended with macOS and FreeBSD support:

  • Extend the os.zig wrapper to accept hdr, sbytes, and flags parameters.
  • Handle writing headers and trailers on systems where this isn't the default. Document what systems they're written atomically.
  • The BSD and Linux handle updates to the offset pointer different, so I may need to also document the behavior and what would be portable.

Windows has TransmitFile as part of mswsock, which looks similar. Will have to investigate farther.

Comment threadlib/std/os.zig Outdated
Comment on lines +3118 to +3119
/// There was insufficient memory for reading from infd.
NoMem,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm surprised (and disappointed) this error is even possible; the kernel should be able to make this "just work" even if it is forced to use a small stack-based buffer due to heap memory pressure.

By convention, ENOMEM in zig turns into one of these two things:

  • error.OutOfMemory if it is userspace heap memory that is exhausted
  • error.SystemResources if it is kernel space memory or other resources that are unavailable.

In this case I believe it would be error.SystemResources.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reading through the kernel sources, this actually comes from files that have a mandatory lock, and the underlying splice() cannot return ENOMEM.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@shawnl Thanks, I can update the comment. I'll likely take @andrewrk's recommendation of using error.SystemResources in this case.

@terinjokes

Copy link
Copy Markdown
ContributorAuthor

I've pushed updates to the Linux support to accept the wider *BSD parameters, and to send the header and trailer iovecs. I doubt I have implemented the behavior to match correctly.

Next up to to add support sendfile(2) from FreeBSD libc. Then I'll be in a better place to verify the behavior is the same.

This changset adds a `sendfile(2)` syscall bindings to the linux bits
component. Where available, the `sendfile64(2)` syscall will be
transparently called.
A wrapping function has also been added to the std.os to transform
errno returns to Zig errors.
Change-Id: I86769fc4382c0771e3656e7b21137bafd99a4411
Comment threadlib/std/c/freebsd.zig
trailers: [*]iovec_const,
trl_cnt: c_int,
};
pub extern "c" fn sendfile(fd: c_int, s: c_int, offset: u64, nbytes: usize, sf_hdtr: ?*sf_hdtr, sbytes: ?*u64, flags: c_int) c_int;

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I need to double check that the offset parameters here should be u64 instead of off_t.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think zig should support 32-bit off_t, in which case they are the same, but yeah probably still use off_t even if it must be u64.

@andrewrk

Copy link
Copy Markdown
Member

Thanks! This is merged into #4611.

@andrewrkandrewrk closed this Mar 3, 2020
@terinjokes

Copy link
Copy Markdown
ContributorAuthor

Sorry for not getting this as polished as I liked. Thank you for taking the time to carry it through.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

os-linuxLinuxstandard libraryThis issue involves writing Zig code for the standard library.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@terinjokes@andrewrk@daurnimator@shawnl
, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' std: implement sendfile on linux by terinjokes · Pull Request #4131 · ziglang/zig · GitHub
Skip to content

std: implement sendfile on linux - #4131

Closed
terinjokes wants to merge 1 commit into
ziglang:masterfrom
terinjokes:patches/sendfile
Closed

std: implement sendfile on linux#4131
terinjokes wants to merge 1 commit into
ziglang:masterfrom
terinjokes:patches/sendfile

Conversation

@terinjokes

Copy link
Copy Markdown
Contributor

This changset adds a sendfile(2) syscall bindings to the linux bits
component. Where available, the sendfile64(2) syscall will be
transparently called.

A wrapping function has also been added to the std.os to transform
errno returns to Zig errors.

@daurnimatordaurnimator left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should also add a prototype in std/c.zig so that libc's function is used when linking against libc.

Comment threadlib/std/os.zig Outdated
while (true) {
var rc: usize = undefined;
var err: usize = undefined;
if (builtin.os == .linux) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should just be an unconditional system.sendfile. If someone attempts to call this function on a system without it then they will get a compile error indicating as much.

@daurnimatordaurnimator added os-linux Linux standard library This issue involves writing Zig code for the standard library. labels Jan 10, 2020
@terinjokes

Copy link
Copy Markdown
ContributorAuthor

@daurnimator I had added it to c.zig locally, but building anything linking against C fails with an unrelated error, so I can't test if my changes are good.

@terinjokes

Copy link
Copy Markdown
ContributorAuthor
/usr/lib/zig/std/os.zig:3301:60: error: cast discards const qualifier
switch (errno(system.setsockopt(fd, level, optname, opt.ptr, @intCast(socklen_t, opt.len)))) {

@terinjokes

terinjokes commented Jan 10, 2020

Copy link
Copy Markdown
ContributorAuthor

Per discussion on IRC, this PR can likely be extended with macOS and FreeBSD support:

  • Extend the os.zig wrapper to accept hdr, sbytes, and flags parameters.
  • Handle writing headers and trailers on systems where this isn't the default. Document what systems they're written atomically.
  • The BSD and Linux handle updates to the offset pointer different, so I may need to also document the behavior and what would be portable.

Windows has TransmitFile as part of mswsock, which looks similar. Will have to investigate farther.

Comment threadlib/std/os.zig Outdated
Comment on lines +3118 to +3119
/// There was insufficient memory for reading from infd.
NoMem,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm surprised (and disappointed) this error is even possible; the kernel should be able to make this "just work" even if it is forced to use a small stack-based buffer due to heap memory pressure.

By convention, ENOMEM in zig turns into one of these two things:

  • error.OutOfMemory if it is userspace heap memory that is exhausted
  • error.SystemResources if it is kernel space memory or other resources that are unavailable.

In this case I believe it would be error.SystemResources.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reading through the kernel sources, this actually comes from files that have a mandatory lock, and the underlying splice() cannot return ENOMEM.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@shawnl Thanks, I can update the comment. I'll likely take @andrewrk's recommendation of using error.SystemResources in this case.

@terinjokes

Copy link
Copy Markdown
ContributorAuthor

I've pushed updates to the Linux support to accept the wider *BSD parameters, and to send the header and trailer iovecs. I doubt I have implemented the behavior to match correctly.

Next up to to add support sendfile(2) from FreeBSD libc. Then I'll be in a better place to verify the behavior is the same.

This changset adds a `sendfile(2)` syscall bindings to the linux bits
component. Where available, the `sendfile64(2)` syscall will be
transparently called.
A wrapping function has also been added to the std.os to transform
errno returns to Zig errors.
Change-Id: I86769fc4382c0771e3656e7b21137bafd99a4411
Comment threadlib/std/c/freebsd.zig
trailers: [*]iovec_const,
trl_cnt: c_int,
};
pub extern "c" fn sendfile(fd: c_int, s: c_int, offset: u64, nbytes: usize, sf_hdtr: ?*sf_hdtr, sbytes: ?*u64, flags: c_int) c_int;

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I need to double check that the offset parameters here should be u64 instead of off_t.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think zig should support 32-bit off_t, in which case they are the same, but yeah probably still use off_t even if it must be u64.

@andrewrk

Copy link
Copy Markdown
Member

Thanks! This is merged into #4611.

@andrewrkandrewrk closed this Mar 3, 2020
@terinjokes

Copy link
Copy Markdown
ContributorAuthor

Sorry for not getting this as polished as I liked. Thank you for taking the time to carry it through.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

os-linuxLinuxstandard libraryThis issue involves writing Zig code for the standard library.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@terinjokes@andrewrk@daurnimator@shawnl
, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' std: implement sendfile on linux by terinjokes · Pull Request #4131 · ziglang/zig · GitHub
Skip to content

std: implement sendfile on linux - #4131

Closed
terinjokes wants to merge 1 commit into
ziglang:masterfrom
terinjokes:patches/sendfile
Closed

std: implement sendfile on linux#4131
terinjokes wants to merge 1 commit into
ziglang:masterfrom
terinjokes:patches/sendfile

Conversation

@terinjokes

Copy link
Copy Markdown
Contributor

This changset adds a sendfile(2) syscall bindings to the linux bits
component. Where available, the sendfile64(2) syscall will be
transparently called.

A wrapping function has also been added to the std.os to transform
errno returns to Zig errors.

@daurnimatordaurnimator left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should also add a prototype in std/c.zig so that libc's function is used when linking against libc.

Comment threadlib/std/os.zig Outdated
while (true) {
var rc: usize = undefined;
var err: usize = undefined;
if (builtin.os == .linux) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should just be an unconditional system.sendfile. If someone attempts to call this function on a system without it then they will get a compile error indicating as much.

@daurnimatordaurnimator added os-linux Linux standard library This issue involves writing Zig code for the standard library. labels Jan 10, 2020
@terinjokes

Copy link
Copy Markdown
ContributorAuthor

@daurnimator I had added it to c.zig locally, but building anything linking against C fails with an unrelated error, so I can't test if my changes are good.

@terinjokes

Copy link
Copy Markdown
ContributorAuthor
/usr/lib/zig/std/os.zig:3301:60: error: cast discards const qualifier
switch (errno(system.setsockopt(fd, level, optname, opt.ptr, @intCast(socklen_t, opt.len)))) {

@terinjokes

terinjokes commented Jan 10, 2020

Copy link
Copy Markdown
ContributorAuthor

Per discussion on IRC, this PR can likely be extended with macOS and FreeBSD support:

  • Extend the os.zig wrapper to accept hdr, sbytes, and flags parameters.
  • Handle writing headers and trailers on systems where this isn't the default. Document what systems they're written atomically.
  • The BSD and Linux handle updates to the offset pointer different, so I may need to also document the behavior and what would be portable.

Windows has TransmitFile as part of mswsock, which looks similar. Will have to investigate farther.

Comment threadlib/std/os.zig Outdated
Comment on lines +3118 to +3119
/// There was insufficient memory for reading from infd.
NoMem,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm surprised (and disappointed) this error is even possible; the kernel should be able to make this "just work" even if it is forced to use a small stack-based buffer due to heap memory pressure.

By convention, ENOMEM in zig turns into one of these two things:

  • error.OutOfMemory if it is userspace heap memory that is exhausted
  • error.SystemResources if it is kernel space memory or other resources that are unavailable.

In this case I believe it would be error.SystemResources.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reading through the kernel sources, this actually comes from files that have a mandatory lock, and the underlying splice() cannot return ENOMEM.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@shawnl Thanks, I can update the comment. I'll likely take @andrewrk's recommendation of using error.SystemResources in this case.

@terinjokes

Copy link
Copy Markdown
ContributorAuthor

I've pushed updates to the Linux support to accept the wider *BSD parameters, and to send the header and trailer iovecs. I doubt I have implemented the behavior to match correctly.

Next up to to add support sendfile(2) from FreeBSD libc. Then I'll be in a better place to verify the behavior is the same.

This changset adds a `sendfile(2)` syscall bindings to the linux bits
component. Where available, the `sendfile64(2)` syscall will be
transparently called.
A wrapping function has also been added to the std.os to transform
errno returns to Zig errors.
Change-Id: I86769fc4382c0771e3656e7b21137bafd99a4411
Comment threadlib/std/c/freebsd.zig
trailers: [*]iovec_const,
trl_cnt: c_int,
};
pub extern "c" fn sendfile(fd: c_int, s: c_int, offset: u64, nbytes: usize, sf_hdtr: ?*sf_hdtr, sbytes: ?*u64, flags: c_int) c_int;

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I need to double check that the offset parameters here should be u64 instead of off_t.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think zig should support 32-bit off_t, in which case they are the same, but yeah probably still use off_t even if it must be u64.

@andrewrk

Copy link
Copy Markdown
Member

Thanks! This is merged into #4611.

@andrewrkandrewrk closed this Mar 3, 2020
@terinjokes

Copy link
Copy Markdown
ContributorAuthor

Sorry for not getting this as polished as I liked. Thank you for taking the time to carry it through.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

os-linuxLinuxstandard libraryThis issue involves writing Zig code for the standard library.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@terinjokes@andrewrk@daurnimator@shawnl
, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' std: implement sendfile on linux by terinjokes · Pull Request #4131 · ziglang/zig · GitHub
Skip to content

std: implement sendfile on linux - #4131

Closed
terinjokes wants to merge 1 commit into
ziglang:masterfrom
terinjokes:patches/sendfile
Closed

std: implement sendfile on linux#4131
terinjokes wants to merge 1 commit into
ziglang:masterfrom
terinjokes:patches/sendfile

Conversation

@terinjokes

Copy link
Copy Markdown
Contributor

This changset adds a sendfile(2) syscall bindings to the linux bits
component. Where available, the sendfile64(2) syscall will be
transparently called.

A wrapping function has also been added to the std.os to transform
errno returns to Zig errors.

@daurnimatordaurnimator left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should also add a prototype in std/c.zig so that libc's function is used when linking against libc.

Comment threadlib/std/os.zig Outdated
while (true) {
var rc: usize = undefined;
var err: usize = undefined;
if (builtin.os == .linux) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should just be an unconditional system.sendfile. If someone attempts to call this function on a system without it then they will get a compile error indicating as much.

@daurnimatordaurnimator added os-linux Linux standard library This issue involves writing Zig code for the standard library. labels Jan 10, 2020
@terinjokes

Copy link
Copy Markdown
ContributorAuthor

@daurnimator I had added it to c.zig locally, but building anything linking against C fails with an unrelated error, so I can't test if my changes are good.

@terinjokes

Copy link
Copy Markdown
ContributorAuthor
/usr/lib/zig/std/os.zig:3301:60: error: cast discards const qualifier
switch (errno(system.setsockopt(fd, level, optname, opt.ptr, @intCast(socklen_t, opt.len)))) {

@terinjokes

terinjokes commented Jan 10, 2020

Copy link
Copy Markdown
ContributorAuthor

Per discussion on IRC, this PR can likely be extended with macOS and FreeBSD support:

  • Extend the os.zig wrapper to accept hdr, sbytes, and flags parameters.
  • Handle writing headers and trailers on systems where this isn't the default. Document what systems they're written atomically.
  • The BSD and Linux handle updates to the offset pointer different, so I may need to also document the behavior and what would be portable.

Windows has TransmitFile as part of mswsock, which looks similar. Will have to investigate farther.

Comment threadlib/std/os.zig Outdated
Comment on lines +3118 to +3119
/// There was insufficient memory for reading from infd.
NoMem,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm surprised (and disappointed) this error is even possible; the kernel should be able to make this "just work" even if it is forced to use a small stack-based buffer due to heap memory pressure.

By convention, ENOMEM in zig turns into one of these two things:

  • error.OutOfMemory if it is userspace heap memory that is exhausted
  • error.SystemResources if it is kernel space memory or other resources that are unavailable.

In this case I believe it would be error.SystemResources.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reading through the kernel sources, this actually comes from files that have a mandatory lock, and the underlying splice() cannot return ENOMEM.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@shawnl Thanks, I can update the comment. I'll likely take @andrewrk's recommendation of using error.SystemResources in this case.

@terinjokes

Copy link
Copy Markdown
ContributorAuthor

I've pushed updates to the Linux support to accept the wider *BSD parameters, and to send the header and trailer iovecs. I doubt I have implemented the behavior to match correctly.

Next up to to add support sendfile(2) from FreeBSD libc. Then I'll be in a better place to verify the behavior is the same.

This changset adds a `sendfile(2)` syscall bindings to the linux bits
component. Where available, the `sendfile64(2)` syscall will be
transparently called.
A wrapping function has also been added to the std.os to transform
errno returns to Zig errors.
Change-Id: I86769fc4382c0771e3656e7b21137bafd99a4411
Comment threadlib/std/c/freebsd.zig
trailers: [*]iovec_const,
trl_cnt: c_int,
};
pub extern "c" fn sendfile(fd: c_int, s: c_int, offset: u64, nbytes: usize, sf_hdtr: ?*sf_hdtr, sbytes: ?*u64, flags: c_int) c_int;

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I need to double check that the offset parameters here should be u64 instead of off_t.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think zig should support 32-bit off_t, in which case they are the same, but yeah probably still use off_t even if it must be u64.

@andrewrk

Copy link
Copy Markdown
Member

Thanks! This is merged into #4611.

@andrewrkandrewrk closed this Mar 3, 2020
@terinjokes

Copy link
Copy Markdown
ContributorAuthor

Sorry for not getting this as polished as I liked. Thank you for taking the time to carry it through.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

os-linuxLinuxstandard libraryThis issue involves writing Zig code for the standard library.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@terinjokes@andrewrk@daurnimator@shawnl
, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' std: implement sendfile on linux by terinjokes · Pull Request #4131 · ziglang/zig · GitHub
Skip to content

std: implement sendfile on linux - #4131

Closed
terinjokes wants to merge 1 commit into
ziglang:masterfrom
terinjokes:patches/sendfile
Closed

std: implement sendfile on linux#4131
terinjokes wants to merge 1 commit into
ziglang:masterfrom
terinjokes:patches/sendfile

Conversation

@terinjokes

Copy link
Copy Markdown
Contributor

This changset adds a sendfile(2) syscall bindings to the linux bits
component. Where available, the sendfile64(2) syscall will be
transparently called.

A wrapping function has also been added to the std.os to transform
errno returns to Zig errors.

@daurnimatordaurnimator left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should also add a prototype in std/c.zig so that libc's function is used when linking against libc.

Comment threadlib/std/os.zig Outdated
while (true) {
var rc: usize = undefined;
var err: usize = undefined;
if (builtin.os == .linux) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should just be an unconditional system.sendfile. If someone attempts to call this function on a system without it then they will get a compile error indicating as much.

@daurnimatordaurnimator added os-linux Linux standard library This issue involves writing Zig code for the standard library. labels Jan 10, 2020
@terinjokes

Copy link
Copy Markdown
ContributorAuthor

@daurnimator I had added it to c.zig locally, but building anything linking against C fails with an unrelated error, so I can't test if my changes are good.

@terinjokes

Copy link
Copy Markdown
ContributorAuthor
/usr/lib/zig/std/os.zig:3301:60: error: cast discards const qualifier
switch (errno(system.setsockopt(fd, level, optname, opt.ptr, @intCast(socklen_t, opt.len)))) {

@terinjokes

terinjokes commented Jan 10, 2020

Copy link
Copy Markdown
ContributorAuthor

Per discussion on IRC, this PR can likely be extended with macOS and FreeBSD support:

  • Extend the os.zig wrapper to accept hdr, sbytes, and flags parameters.
  • Handle writing headers and trailers on systems where this isn't the default. Document what systems they're written atomically.
  • The BSD and Linux handle updates to the offset pointer different, so I may need to also document the behavior and what would be portable.

Windows has TransmitFile as part of mswsock, which looks similar. Will have to investigate farther.

Comment threadlib/std/os.zig Outdated
Comment on lines +3118 to +3119
/// There was insufficient memory for reading from infd.
NoMem,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm surprised (and disappointed) this error is even possible; the kernel should be able to make this "just work" even if it is forced to use a small stack-based buffer due to heap memory pressure.

By convention, ENOMEM in zig turns into one of these two things:

  • error.OutOfMemory if it is userspace heap memory that is exhausted
  • error.SystemResources if it is kernel space memory or other resources that are unavailable.

In this case I believe it would be error.SystemResources.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reading through the kernel sources, this actually comes from files that have a mandatory lock, and the underlying splice() cannot return ENOMEM.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@shawnl Thanks, I can update the comment. I'll likely take @andrewrk's recommendation of using error.SystemResources in this case.

@terinjokes

Copy link
Copy Markdown
ContributorAuthor

I've pushed updates to the Linux support to accept the wider *BSD parameters, and to send the header and trailer iovecs. I doubt I have implemented the behavior to match correctly.

Next up to to add support sendfile(2) from FreeBSD libc. Then I'll be in a better place to verify the behavior is the same.

This changset adds a `sendfile(2)` syscall bindings to the linux bits
component. Where available, the `sendfile64(2)` syscall will be
transparently called.
A wrapping function has also been added to the std.os to transform
errno returns to Zig errors.
Change-Id: I86769fc4382c0771e3656e7b21137bafd99a4411
Comment threadlib/std/c/freebsd.zig
trailers: [*]iovec_const,
trl_cnt: c_int,
};
pub extern "c" fn sendfile(fd: c_int, s: c_int, offset: u64, nbytes: usize, sf_hdtr: ?*sf_hdtr, sbytes: ?*u64, flags: c_int) c_int;

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I need to double check that the offset parameters here should be u64 instead of off_t.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think zig should support 32-bit off_t, in which case they are the same, but yeah probably still use off_t even if it must be u64.

@andrewrk

Copy link
Copy Markdown
Member

Thanks! This is merged into #4611.

@andrewrkandrewrk closed this Mar 3, 2020
@terinjokes

Copy link
Copy Markdown
ContributorAuthor

Sorry for not getting this as polished as I liked. Thank you for taking the time to carry it through.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

os-linuxLinuxstandard libraryThis issue involves writing Zig code for the standard library.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@terinjokes@andrewrk@daurnimator@shawnl
, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' std: implement sendfile on linux by terinjokes · Pull Request #4131 · ziglang/zig · GitHub
Skip to content

std: implement sendfile on linux - #4131

Closed
terinjokes wants to merge 1 commit into
ziglang:masterfrom
terinjokes:patches/sendfile
Closed

std: implement sendfile on linux#4131
terinjokes wants to merge 1 commit into
ziglang:masterfrom
terinjokes:patches/sendfile

Conversation

@terinjokes

Copy link
Copy Markdown
Contributor

This changset adds a sendfile(2) syscall bindings to the linux bits
component. Where available, the sendfile64(2) syscall will be
transparently called.

A wrapping function has also been added to the std.os to transform
errno returns to Zig errors.

@daurnimatordaurnimator left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should also add a prototype in std/c.zig so that libc's function is used when linking against libc.

Comment threadlib/std/os.zig Outdated
while (true) {
var rc: usize = undefined;
var err: usize = undefined;
if (builtin.os == .linux) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should just be an unconditional system.sendfile. If someone attempts to call this function on a system without it then they will get a compile error indicating as much.

@daurnimatordaurnimator added os-linux Linux standard library This issue involves writing Zig code for the standard library. labels Jan 10, 2020
@terinjokes

Copy link
Copy Markdown
ContributorAuthor

@daurnimator I had added it to c.zig locally, but building anything linking against C fails with an unrelated error, so I can't test if my changes are good.

@terinjokes

Copy link
Copy Markdown
ContributorAuthor
/usr/lib/zig/std/os.zig:3301:60: error: cast discards const qualifier
switch (errno(system.setsockopt(fd, level, optname, opt.ptr, @intCast(socklen_t, opt.len)))) {

@terinjokes

terinjokes commented Jan 10, 2020

Copy link
Copy Markdown
ContributorAuthor

Per discussion on IRC, this PR can likely be extended with macOS and FreeBSD support:

  • Extend the os.zig wrapper to accept hdr, sbytes, and flags parameters.
  • Handle writing headers and trailers on systems where this isn't the default. Document what systems they're written atomically.
  • The BSD and Linux handle updates to the offset pointer different, so I may need to also document the behavior and what would be portable.

Windows has TransmitFile as part of mswsock, which looks similar. Will have to investigate farther.

Comment threadlib/std/os.zig Outdated
Comment on lines +3118 to +3119
/// There was insufficient memory for reading from infd.
NoMem,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm surprised (and disappointed) this error is even possible; the kernel should be able to make this "just work" even if it is forced to use a small stack-based buffer due to heap memory pressure.

By convention, ENOMEM in zig turns into one of these two things:

  • error.OutOfMemory if it is userspace heap memory that is exhausted
  • error.SystemResources if it is kernel space memory or other resources that are unavailable.

In this case I believe it would be error.SystemResources.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reading through the kernel sources, this actually comes from files that have a mandatory lock, and the underlying splice() cannot return ENOMEM.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@shawnl Thanks, I can update the comment. I'll likely take @andrewrk's recommendation of using error.SystemResources in this case.

@terinjokes

Copy link
Copy Markdown
ContributorAuthor

I've pushed updates to the Linux support to accept the wider *BSD parameters, and to send the header and trailer iovecs. I doubt I have implemented the behavior to match correctly.

Next up to to add support sendfile(2) from FreeBSD libc. Then I'll be in a better place to verify the behavior is the same.

This changset adds a `sendfile(2)` syscall bindings to the linux bits
component. Where available, the `sendfile64(2)` syscall will be
transparently called.
A wrapping function has also been added to the std.os to transform
errno returns to Zig errors.
Change-Id: I86769fc4382c0771e3656e7b21137bafd99a4411
Comment threadlib/std/c/freebsd.zig
trailers: [*]iovec_const,
trl_cnt: c_int,
};
pub extern "c" fn sendfile(fd: c_int, s: c_int, offset: u64, nbytes: usize, sf_hdtr: ?*sf_hdtr, sbytes: ?*u64, flags: c_int) c_int;

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I need to double check that the offset parameters here should be u64 instead of off_t.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think zig should support 32-bit off_t, in which case they are the same, but yeah probably still use off_t even if it must be u64.

@andrewrk

Copy link
Copy Markdown
Member

Thanks! This is merged into #4611.

@andrewrkandrewrk closed this Mar 3, 2020
@terinjokes

Copy link
Copy Markdown
ContributorAuthor

Sorry for not getting this as polished as I liked. Thank you for taking the time to carry it through.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

os-linuxLinuxstandard libraryThis issue involves writing Zig code for the standard library.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@terinjokes@andrewrk@daurnimator@shawnl
, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); std: implement sendfile on linux by terinjokes · Pull Request #4131 · ziglang/zig · GitHub
Skip to content

std: implement sendfile on linux - #4131

Closed
terinjokes wants to merge 1 commit into
ziglang:masterfrom
terinjokes:patches/sendfile
Closed

std: implement sendfile on linux#4131
terinjokes wants to merge 1 commit into
ziglang:masterfrom
terinjokes:patches/sendfile

Conversation

@terinjokes

Copy link
Copy Markdown
Contributor

This changset adds a sendfile(2) syscall bindings to the linux bits
component. Where available, the sendfile64(2) syscall will be
transparently called.

A wrapping function has also been added to the std.os to transform
errno returns to Zig errors.

@daurnimatordaurnimator left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should also add a prototype in std/c.zig so that libc's function is used when linking against libc.

Comment threadlib/std/os.zig Outdated
while (true) {
var rc: usize = undefined;
var err: usize = undefined;
if (builtin.os == .linux) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should just be an unconditional system.sendfile. If someone attempts to call this function on a system without it then they will get a compile error indicating as much.

@daurnimatordaurnimator added os-linux Linux standard library This issue involves writing Zig code for the standard library. labels Jan 10, 2020
@terinjokes

Copy link
Copy Markdown
ContributorAuthor

@daurnimator I had added it to c.zig locally, but building anything linking against C fails with an unrelated error, so I can't test if my changes are good.

@terinjokes

Copy link
Copy Markdown
ContributorAuthor
/usr/lib/zig/std/os.zig:3301:60: error: cast discards const qualifier
switch (errno(system.setsockopt(fd, level, optname, opt.ptr, @intCast(socklen_t, opt.len)))) {

@terinjokes

terinjokes commented Jan 10, 2020

Copy link
Copy Markdown
ContributorAuthor

Per discussion on IRC, this PR can likely be extended with macOS and FreeBSD support:

  • Extend the os.zig wrapper to accept hdr, sbytes, and flags parameters.
  • Handle writing headers and trailers on systems where this isn't the default. Document what systems they're written atomically.
  • The BSD and Linux handle updates to the offset pointer different, so I may need to also document the behavior and what would be portable.

Windows has TransmitFile as part of mswsock, which looks similar. Will have to investigate farther.

Comment threadlib/std/os.zig Outdated
Comment on lines +3118 to +3119
/// There was insufficient memory for reading from infd.
NoMem,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm surprised (and disappointed) this error is even possible; the kernel should be able to make this "just work" even if it is forced to use a small stack-based buffer due to heap memory pressure.

By convention, ENOMEM in zig turns into one of these two things:

  • error.OutOfMemory if it is userspace heap memory that is exhausted
  • error.SystemResources if it is kernel space memory or other resources that are unavailable.

In this case I believe it would be error.SystemResources.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reading through the kernel sources, this actually comes from files that have a mandatory lock, and the underlying splice() cannot return ENOMEM.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@shawnl Thanks, I can update the comment. I'll likely take @andrewrk's recommendation of using error.SystemResources in this case.

@terinjokes

Copy link
Copy Markdown
ContributorAuthor

I've pushed updates to the Linux support to accept the wider *BSD parameters, and to send the header and trailer iovecs. I doubt I have implemented the behavior to match correctly.

Next up to to add support sendfile(2) from FreeBSD libc. Then I'll be in a better place to verify the behavior is the same.

This changset adds a `sendfile(2)` syscall bindings to the linux bits
component. Where available, the `sendfile64(2)` syscall will be
transparently called.
A wrapping function has also been added to the std.os to transform
errno returns to Zig errors.
Change-Id: I86769fc4382c0771e3656e7b21137bafd99a4411
Comment threadlib/std/c/freebsd.zig
trailers: [*]iovec_const,
trl_cnt: c_int,
};
pub extern "c" fn sendfile(fd: c_int, s: c_int, offset: u64, nbytes: usize, sf_hdtr: ?*sf_hdtr, sbytes: ?*u64, flags: c_int) c_int;

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I need to double check that the offset parameters here should be u64 instead of off_t.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think zig should support 32-bit off_t, in which case they are the same, but yeah probably still use off_t even if it must be u64.

@andrewrk

Copy link
Copy Markdown
Member

Thanks! This is merged into #4611.

@andrewrkandrewrk closed this Mar 3, 2020
@terinjokes

Copy link
Copy Markdown
ContributorAuthor

Sorry for not getting this as polished as I liked. Thank you for taking the time to carry it through.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

os-linuxLinuxstandard libraryThis issue involves writing Zig code for the standard library.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@terinjokes@andrewrk@daurnimator@shawnl