Merge branch 'master' of ssh://git.claws-mail.org/home/git/claws
[claws.git] / src / common / claws_io.c
1 /*
2  * Claws Mail -- a GTK+ based, lightweight, and fast e-mail client
3  * Copyright (C) 1999-2018 Colin Leroy and the Claws Mail team
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
17  */
18
19 #ifdef HAVE_CONFIG_H
20 #  include "config.h"
21 #include "claws-features.h"
22 #endif
23
24 #include <stdio.h>
25 #include <unistd.h>
26
27 #include "timing.h"
28 #include "claws_io.h"
29
30 gboolean prefs_common_get_flush_metadata(void);
31
32 /* FIXME make static once every file I/O is done using claws_* wrappers */
33 int safe_fclose(FILE *fp)
34 {
35         int r;
36         START_TIMING("");
37
38         if (fflush(fp) != 0) {
39                 return EOF;
40         }
41         if (prefs_common_get_flush_metadata() && fsync(fileno(fp)) != 0) {
42                 return EOF;
43         }
44
45         r = fclose(fp);
46         END_TIMING();
47
48         return r;
49 }
50
51 #if HAVE_FGETS_UNLOCKED
52
53 /* Open a file and locks it once
54  * so subsequent I/O is faster
55  */
56 FILE *claws_fopen(const char *file, const char *mode)
57 {
58         FILE *fp = fopen(file, mode);
59         if (!fp)
60                 return NULL;
61         flockfile(fp);
62         return fp;
63 }
64
65 FILE *claws_fdopen(int fd, const char *mode)
66 {
67         FILE *fp = fdopen(fd, mode);
68         if (!fp)
69                 return NULL;
70         flockfile(fp);
71         return fp;
72 }
73
74 /* Unlocks and close a file pointer
75  */
76
77 int claws_fclose(FILE *fp)
78 {
79         funlockfile(fp);
80         return fclose(fp);
81 }
82
83 /* Unlock, then safe-close a file pointer
84  * Safe close is done using fflush + fsync
85  * if the according preference says so.
86  */
87 int claws_safe_fclose(FILE *fp)
88 {
89         funlockfile(fp);
90         return safe_fclose(fp);
91 }
92
93 #endif