-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[libc] Add the implementation of the fdopen function #94186
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
15834c5
7eee9b3
0251116
a926d0f
9dd1429
a535a9d
5f70faa
0f7bdf2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
//===-- Implementation header of internal fcntl function ------------------===// | ||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
// See https://llvm.org/LICENSE.txt for license information. | ||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_FCNTL_H | ||
#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_FCNTL_H | ||
|
||
namespace LIBC_NAMESPACE::internal { | ||
|
||
int fcntl(int fd, int cmd, void *arg = nullptr); | ||
|
||
} // namespace LIBC_NAMESPACE::internal | ||
|
||
#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_FCNTL_H |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
//===-- Implementation of internal fcntl ----------------------------------===// | ||
// | ||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
// See https://llvm.org/LICENSE.txt for license information. | ||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#include "src/__support/OSUtil/fcntl.h" | ||
|
||
#include "hdr/fcntl_macros.h" | ||
#include "hdr/types/struct_f_owner_ex.h" | ||
#include "hdr/types/struct_flock.h" | ||
#include "hdr/types/struct_flock64.h" | ||
#include "src/__support/OSUtil/syscall.h" // For internal syscall function. | ||
#include "src/__support/common.h" | ||
#include "src/errno/libc_errno.h" | ||
|
||
#include <stdarg.h> | ||
#include <sys/syscall.h> // For syscall numbers. | ||
|
||
namespace LIBC_NAMESPACE::internal { | ||
|
||
int fcntl(int fd, int cmd, void *arg) { | ||
switch (cmd) { | ||
case F_OFD_SETLKW: { | ||
struct flock *flk = reinterpret_cast<struct flock *>(arg); | ||
// convert the struct to a flock64 | ||
struct flock64 flk64; | ||
flk64.l_type = flk->l_type; | ||
flk64.l_whence = flk->l_whence; | ||
flk64.l_start = flk->l_start; | ||
flk64.l_len = flk->l_len; | ||
flk64.l_pid = flk->l_pid; | ||
// create a syscall | ||
return LIBC_NAMESPACE::syscall_impl<int>(SYS_fcntl, fd, cmd, &flk64); | ||
} | ||
case F_OFD_GETLK: | ||
case F_OFD_SETLK: { | ||
struct flock *flk = reinterpret_cast<struct flock *>(arg); | ||
// convert the struct to a flock64 | ||
struct flock64 flk64; | ||
flk64.l_type = flk->l_type; | ||
flk64.l_whence = flk->l_whence; | ||
flk64.l_start = flk->l_start; | ||
flk64.l_len = flk->l_len; | ||
flk64.l_pid = flk->l_pid; | ||
// create a syscall | ||
int retVal = LIBC_NAMESPACE::syscall_impl<int>(SYS_fcntl, fd, cmd, &flk64); | ||
// On failure, return | ||
if (retVal == -1) | ||
return -1; | ||
// Check for overflow, i.e. the offsets are not the same when cast | ||
// to off_t from off64_t. | ||
if (static_cast<off_t>(flk64.l_len) != flk64.l_len || | ||
static_cast<off_t>(flk64.l_start) != flk64.l_start) { | ||
libc_errno = EOVERFLOW; | ||
return -1; | ||
} | ||
// Now copy back into flk, in case flk64 got modified | ||
flk->l_type = flk64.l_type; | ||
flk->l_whence = flk64.l_whence; | ||
flk->l_start = flk64.l_start; | ||
flk->l_len = flk64.l_len; | ||
Comment on lines
+63
to
+64
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thank you for this patch. Note though that it did break the 32b ARM build bot:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
flk->l_pid = flk64.l_pid; | ||
return retVal; | ||
} | ||
case F_GETOWN: { | ||
struct f_owner_ex fex; | ||
int retVal = | ||
LIBC_NAMESPACE::syscall_impl<int>(SYS_fcntl, fd, F_GETOWN_EX, &fex); | ||
if (retVal == -EINVAL) | ||
return LIBC_NAMESPACE::syscall_impl<int>(SYS_fcntl, fd, cmd, | ||
reinterpret_cast<void *>(arg)); | ||
if (static_cast<unsigned long>(retVal) <= -4096UL) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Michael seems to have asked the same question, see #89507 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm confused by this logic. If the return result is negative but malformed, should we return errors instead? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. also we should use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Frankly, I'm also puzzled by this code. I found the same code in GLIBC, yet I'm also uncertain as to why the GLIBC's authors chose this way. Perhaps we could set it aside for now, and I'll open a new issue to address it after I delve into it. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since you're only moving the function to different location, it's fine for me to leave it as-is. But please create an issue for further investigation / fixing and add a TODO here. Thanks, There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Please help assign #95570 to me. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We really should not be copying code from ANY libc which we do not understand. |
||
return fex.type == F_OWNER_PGRP ? -fex.pid : fex.pid; | ||
|
||
libc_errno = -retVal; | ||
return -1; | ||
} | ||
// The general case | ||
default: { | ||
int retVal = LIBC_NAMESPACE::syscall_impl<int>( | ||
SYS_fcntl, fd, cmd, reinterpret_cast<void *>(arg)); | ||
if (retVal >= 0) { | ||
return retVal; | ||
} | ||
libc_errno = -retVal; | ||
return -1; | ||
} | ||
} | ||
} | ||
|
||
} // namespace LIBC_NAMESPACE::internal |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
//===-- Implementation header of open ---------------------------*- C++ -*-===// | ||
// | ||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
// See https://llvm.org/LICENSE.txt for license information. | ||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#ifndef LLVM_LIBC_SRC_STDIO_FDOPEN_H | ||
#define LLVM_LIBC_SRC_STDIO_FDOPEN_H | ||
|
||
#include <stdio.h> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @michaelrj-google : shall we create an issue to add proxy header for |
||
|
||
namespace LIBC_NAMESPACE { | ||
|
||
FILE *fdopen(int fd, const char *mode); | ||
|
||
} // namespace LIBC_NAMESPACE | ||
|
||
#endif // LLVM_LIBC_SRC_STDIO_FDOPEN_H |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fcntl
should be a separate target.