Skip to content

Commit 19a6dd3

Browse files
author
Siva Chandra Reddy
committed
[libc] Add the implementation of the GNU extension function fopencookie.
Reviewed By: lntue, michaelrj Differential Revision: https://reviews.llvm.org/D124141
1 parent df18e37 commit 19a6dd3

File tree

13 files changed

+420
-4
lines changed

13 files changed

+420
-4
lines changed

libc/config/linux/api.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ def StringAPI : PublicAPI<"string.h"> {
146146
}
147147

148148
def StdIOAPI : PublicAPI<"stdio.h"> {
149-
let Types = ["size_t", "FILE"];
149+
let Types = ["size_t", "FILE", "cookie_io_functions_t"];
150150
}
151151

152152
def StdlibAPI : PublicAPI<"stdlib.h"> {

libc/config/linux/x86_64/entrypoints.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,7 @@ if(LLVM_LIBC_FULL_BUILD)
255255
libc.src.stdio.flockfile
256256
libc.src.stdio.fflush
257257
libc.src.stdio.fopen
258+
libc.src.stdio.fopencookie
258259
libc.src.stdio.fread
259260
libc.src.stdio.fread_unlocked
260261
libc.src.stdio.fseek

libc/include/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ add_gen_header(
125125
DEPENDS
126126
.llvm_libc_common_h
127127
.llvm-libc-macros.file_seek_macros
128+
.llvm-libc-types.cookie_io_functions_t
128129
.llvm-libc-types.FILE
129130
.llvm-libc-types.size_t
130131
)

libc/include/llvm-libc-types/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ add_header(__mutex_type HDR __mutex_type.h)
55
add_header(__qsortcompare_t HDR __qsortcompare_t.h)
66
add_header(__sighandler_t HDR __sighandler_t.h)
77
add_header(cnd_t HDR cnd_t.h)
8+
add_header(cookie_io_functions_t HDR cookie_io_functions_t.h DEPENDS .off64_t)
89
add_header(double_t HDR double_t.h)
910
add_header(div_t HDR div_t.h)
1011
add_header(ldiv_t HDR ldiv_t.h)
@@ -17,6 +18,7 @@ add_header(imaxdiv_t HDR imaxdiv_t.h)
1718
add_header(mode_t HDR mode_t.h)
1819
add_header(mtx_t HDR mtx_t.h DEPENDS .__futex_word .__mutex_type)
1920
add_header(off_t HDR off_t.h)
21+
add_header(off64_t HDR off64_t.h)
2022
add_header(once_flag HDR once_flag.h DEPENDS .__futex_word)
2123
add_header(pthread_attr_t HDR pthread_attr_t.h)
2224
add_header(pthread_mutexattr_t HDR pthread_mutexattr_t.h)
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
//===-- Definition of type cookie_io_functions_t --------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef __LLVM_LIBC_TYPES_COOKIE_IO_FUNCTIONS_T_H
10+
#define __LLVM_LIBC_TYPES_COOKIE_IO_FUNCTIONS_T_H
11+
12+
#include <llvm-libc-types/off64_t.h>
13+
#include <llvm-libc-types/size_t.h>
14+
#include <llvm-libc-types/ssize_t.h>
15+
16+
typedef ssize_t cookie_read_function_t(void *, char *, size_t);
17+
typedef ssize_t cookie_write_function_t(void *, const char *, size_t);
18+
typedef int cookie_seek_function_t(void *, off64_t *, int);
19+
typedef int cookie_close_function_t(void *);
20+
21+
typedef struct {
22+
cookie_read_function_t *read;
23+
cookie_write_function_t *write;
24+
cookie_seek_function_t *seek;
25+
cookie_close_function_t *close;
26+
} cookie_io_functions_t;
27+
28+
#endif // __LLVM_LIBC_TYPES_COOKIE_IO_FUNCTIONS_T_H
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
//===-- Definition of off64_t type ----------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef __LLVM_LIBC_TYPES_OFF64_T_H__
10+
#define __LLVM_LIBC_TYPES_OFF64_T_H__
11+
12+
typedef __INT64_TYPE__ off64_t;
13+
14+
#endif // __LLVM_LIBC_TYPES_OFF64_T_H__

libc/spec/gnu_ext.td

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
def GnuExtensions : StandardSpec<"GNUExtensions"> {
2+
NamedType CookieIOFunctionsT = NamedType<"cookie_io_functions_t">;
23
HeaderSpec CType = HeaderSpec<
34
"ctype.h",
45
[], // Macros
@@ -68,9 +69,14 @@ def GnuExtensions : StandardSpec<"GNUExtensions"> {
6869
HeaderSpec StdIO = HeaderSpec<
6970
"stdio.h",
7071
[], // Macros
71-
[], // Types
72+
[CookieIOFunctionsT], // Types
7273
[], // Enumerations
7374
[
75+
FunctionSpec<
76+
"fopencookie",
77+
RetValSpec<FILEPtr>,
78+
[ArgSpec<VoidPtr>, ArgSpec<ConstCharPtr>, ArgSpec<CookieIOFunctionsT>]
79+
>,
7480
FunctionSpec<
7581
"fread_unlocked",
7682
RetValSpec<SizeTType>,
@@ -88,7 +94,7 @@ def GnuExtensions : StandardSpec<"GNUExtensions"> {
8894
ArgSpec<FILERestrictedPtr>]
8995
>,
9096
]
91-
>;
97+
>;
9298

9399
let Headers = [
94100
CType,

libc/spec/spec.td

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,6 @@ def FILERestrictedPtr : RestrictedPtrType<FILE>;
110110
//added because __assert_fail needs it.
111111
def UnsignedType : NamedType<"unsigned">;
112112

113-
114113
class Macro<string name> {
115114
string Name = name;
116115
}

libc/src/stdio/CMakeLists.txt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,3 +119,14 @@ add_entrypoint_object(
119119
libc.src.__support.File.file
120120
libc.src.__support.File.platform_file
121121
)
122+
123+
add_entrypoint_object(
124+
fopencookie
125+
SRCS
126+
fopencookie.cpp
127+
HDRS
128+
fopencookie.h
129+
DEPENDS
130+
libc.include.stdio
131+
libc.src.__support.File.file
132+
)

libc/src/stdio/fopencookie.cpp

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
//===-- Implementation of fopencookie -------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "src/stdio/fopencookie.h"
10+
#include "src/__support/File/file.h"
11+
12+
#include <errno.h>
13+
#include <stdio.h>
14+
#include <stdlib.h>
15+
16+
namespace __llvm_libc {
17+
18+
namespace {
19+
20+
class CookieFile : public __llvm_libc::File {
21+
public:
22+
void *cookie;
23+
cookie_io_functions_t ops;
24+
};
25+
26+
size_t write_func(File *f, const void *data, size_t size) {
27+
auto cookie_file = reinterpret_cast<CookieFile *>(f);
28+
if (cookie_file->ops.write == nullptr)
29+
return 0;
30+
return cookie_file->ops.write(cookie_file->cookie,
31+
reinterpret_cast<const char *>(data), size);
32+
}
33+
34+
size_t read_func(File *f, void *data, size_t size) {
35+
auto cookie_file = reinterpret_cast<CookieFile *>(f);
36+
if (cookie_file->ops.read == nullptr)
37+
return 0;
38+
return cookie_file->ops.read(cookie_file->cookie,
39+
reinterpret_cast<char *>(data), size);
40+
}
41+
42+
int seek_func(File *f, long offset, int whence) {
43+
auto cookie_file = reinterpret_cast<CookieFile *>(f);
44+
if (cookie_file->ops.seek == nullptr) {
45+
errno = EINVAL;
46+
return -1;
47+
}
48+
off64_t offset64 = offset;
49+
return cookie_file->ops.seek(cookie_file->cookie, &offset64, whence);
50+
}
51+
52+
int close_func(File *f) {
53+
auto cookie_file = reinterpret_cast<CookieFile *>(f);
54+
if (cookie_file->ops.close == nullptr)
55+
return 0;
56+
return cookie_file->ops.close(cookie_file->cookie);
57+
}
58+
59+
int flush_func(File *f) { return 0; }
60+
61+
} // anonymous namespace
62+
63+
LLVM_LIBC_FUNCTION(::FILE *, fopencookie,
64+
(void *cookie, const char *mode,
65+
cookie_io_functions_t ops)) {
66+
auto modeflags = File::mode_flags(mode);
67+
void *buffer = malloc(File::DEFAULT_BUFFER_SIZE);
68+
auto *file = reinterpret_cast<CookieFile *>(malloc(sizeof(CookieFile)));
69+
if (file == nullptr)
70+
return nullptr;
71+
72+
File::init(file, &write_func, &read_func, &seek_func, &close_func,
73+
&flush_func, buffer, File::DEFAULT_BUFFER_SIZE,
74+
0, // Default buffering style
75+
true, // Owned buffer
76+
modeflags);
77+
file->cookie = cookie;
78+
file->ops = ops;
79+
80+
return reinterpret_cast<::FILE *>(file);
81+
}
82+
83+
} // namespace __llvm_libc

libc/src/stdio/fopencookie.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
//===-- Implementation header of fopencookie --------------------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef LLVM_LIBC_SRC_STDIO_FOPENCOOKIE_H
10+
#define LLVM_LIBC_SRC_STDIO_FOPENCOOKIE_H
11+
12+
#include <stdio.h>
13+
14+
namespace __llvm_libc {
15+
16+
::FILE *fopencookie(void *cookie, const char *__restrict mode,
17+
cookie_io_functions_t desc);
18+
19+
} // namespace __llvm_libc
20+
21+
#endif // LLVM_LIBC_SRC_STDIO_FOPENCOOKIE_H

libc/test/src/stdio/CMakeLists.txt

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,28 @@ add_libc_unittest(
3030
libc.src.stdio.fwrite_unlocked
3131
)
3232

33+
add_libc_unittest(
34+
fopencookie_test
35+
SUITE
36+
libc_stdio_unittests
37+
SRCS
38+
fopencookie_test.cpp
39+
DEPENDS
40+
libc.include.errno
41+
libc.include.stdio
42+
libc.include.stdlib
43+
libc.src.stdio.fclose
44+
libc.src.stdio.fflush
45+
libc.src.stdio.fopencookie
46+
libc.src.stdio.fread
47+
libc.src.stdio.fseek
48+
libc.src.stdio.fwrite
49+
)
50+
51+
target_link_libraries(
52+
libc.test.src.stdio.fopencookie_test PRIVATE LibcMemoryHelpers
53+
)
54+
3355
add_subdirectory(printf_core)
3456

3557
add_subdirectory(testdata)

0 commit comments

Comments
 (0)