xref: /llvm-project/libc/src/stdio/gpu/fgets.cpp (revision a1be5d69dff0ff9bdf0329370a3ce724bcd25ed2)
1 //===-- GPU implementation of fgets ---------------------------------------===//
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/fgets.h"
10 #include "file.h"
11 #include "src/stdio/feof.h"
12 #include "src/stdio/ferror.h"
13 
14 #include <stddef.h>
15 #include <stdio.h>
16 
17 namespace __llvm_libc {
18 
19 LLVM_LIBC_FUNCTION(char *, fgets,
20                    (char *__restrict str, int count,
21                     ::FILE *__restrict stream)) {
22   if (count < 1)
23     return nullptr;
24 
25   // This implementation is very slow as it makes multiple RPC calls.
26   unsigned char c = '\0';
27   int i = 0;
28   for (; i < count - 1 && c != '\n'; ++i) {
29     auto r = file::read(stream, &c, 1);
30     if (r != 1)
31       break;
32 
33     str[i] = c;
34   }
35 
36   bool has_error = __llvm_libc::ferror(stream);
37   bool has_eof = __llvm_libc::feof(stream);
38 
39   if (has_error || (i == 0 && has_eof))
40     return nullptr;
41 
42   str[i] = '\0';
43   return str;
44 }
45 
46 } // namespace __llvm_libc
47