1 /*
2  * Copyright 2016-2021 The Regents of the University of California
3  * All rights reserved.
4  *
5  * This file is part of Spoofer.
6  *
7  * Spoofer is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * Spoofer is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with Spoofer.  If not, see <http://www.gnu.org/licenses/>.
19  */
20 
21 /****************************************************************************
22    Program:     $Id: spoofer_stdio.h,v 1.12 2021/04/28 17:39:07 kkeys Exp $
23    Date:        $Date: 2021/04/28 17:39:07 $
24    Description: stdio thread safety
25 ****************************************************************************/
26 
27 #ifndef COMMON_SPOOFER_STDIO_H
28 #define COMMON_SPOOFER_STDIO_H 1
29 
30 #include <cstdio>
31 
32 #ifdef _WIN32
33 // define a POSIX-compatible flockfile()
34 #define flockfile(f)    _lock_file(f)
35 #define funlockfile(f)  _unlock_file(f)
36 #endif
37 
38 // RAII-style FILE lock
39 class FileGuard {
40     FileGuard(const FileGuard&) NO_METHOD;
41     FileGuard operator=(const FileGuard&) NO_METHOD;
42     FILE *f;
43 public:
FileGuard(FILE * file)44     FileGuard(FILE *file) : f(file) { flockfile(f); }
~FileGuard()45     ~FileGuard() { funlockfile(f); }
46 };
47 
48 namespace spoofer_stdio {
49 
50 int fflush(FILE *f);
51 int fputc(int c, FILE *f);
52 int fputs(const char *s, FILE *f);
53 size_t fwrite(const void *p, size_t sz, size_t n, FILE *f);
54 int vfprintf(FILE *f, const char *fmt, va_list ap) FORMAT_PRINTF(2, 0);
55 int vprintf(const char *fmt, va_list ap) FORMAT_PRINTF(1, 0);
56 int printf(const char *fmt, ...) FORMAT_PRINTF(1, 2);
57 int fprintf(FILE *f, const char *fmt, ...) FORMAT_PRINTF(2, 3);
58 int puts(const char *s);
59 int overwritable_puts(const char *s);
60 
61 } // namespace spoofer_stdio
62 
63 #define fflush(f)            (spoofer_stdio::fflush)(f)
64 #define fputc(c,f)           (spoofer_stdio::fputc)(c,f)
65 #define fputs(s,f)           (spoofer_stdio::fputs)(s,f)
66 #define fwrite(p,sz,n,f)     (spoofer_stdio::fwrite)(p,sz,n,f)
67 #define vfprintf(f,fmt,ap)   (spoofer_stdio::vfprintf)(f,fmt,ap)
68 #define vprintf(fmt,ap)      (spoofer_stdio::vprintf)(fmt,ap)
69 #define fprintf(f,...)       (spoofer_stdio::fprintf)(f,__VA_ARGS__)
70 #define printf(...)          (spoofer_stdio::printf)(__VA_ARGS__)
71 #define putc(c, f)           (spoofer_stdio::fputc)(c, f)
72 #define putchar(c)           (spoofer_stdio::fputc)(c, stdout)
73 #define puts(s)              (spoofer_stdio::puts)(s)
74 #define overwritable_puts(s) (spoofer_stdio::overwritable_puts)(s)
75 
76 #endif // COMMON_SPOOFER_STDIO_H
77