Crossfire Server, Trunk
output_file.cpp
Go to the documentation of this file.
1 /*
2  * Crossfire -- cooperative multi-player graphical RPG and adventure game
3  *
4  * Copyright (c) 1999-2014 Mark Wedel and the Crossfire Development Team
5  * Copyright (c) 1992 Frank Tore Johansen
6  *
7  * Crossfire is free software and comes with ABSOLUTELY NO WARRANTY. You are
8  * welcome to redistribute it under certain conditions. For details, please
9  * see COPYING and LICENSE.
10  *
11  * The authors can be reached via e-mail at <crossfire@metalforge.org>.
12  */
13 
14 #include <errno.h>
15 #include <stdlib.h>
16 #include <string.h>
17 
18 #include "global.h"
19 #include "logger.h"
20 #include "output_file.h"
21 
22 
27 #define TMP_EXT ".tmp"
28 
29 
30 FILE *of_open(OutputFile *of, const char *fname) {
31  char *fname_tmp;
32  FILE *f;
33 
34  fname_tmp = static_cast<char *>(malloc(strlen(fname)+sizeof(TMP_EXT)));
35  if (fname_tmp == NULL) {
36  LOG(llevError, "%s: out of memory\n", fname);
37  return NULL;
38  }
39 
40  sprintf(fname_tmp, "%s%s", fname, TMP_EXT);
41  remove(fname_tmp);
42  f = fopen(fname_tmp, "w");
43  if (f == NULL) {
44  LOG(llevError, "could not open %s: %s\n", fname_tmp, strerror(errno));
45  free(fname_tmp);
46  return NULL;
47  }
48 
49  of->fname = strdup_local(fname);
50  if (of->fname == NULL) {
51  LOG(llevError, "%s: out of memory\n", fname);
52  free(fname_tmp);
53  fclose(f);
54  return NULL;
55  }
56  of->fname_tmp = fname_tmp;
57  of->file = f;
58  return f;
59 }
60 
61 int of_close(OutputFile *of) {
62  if (ferror(of->file)) {
63  LOG(llevError, "%s: write error\n", of->fname);
64  fclose(of->file);
65  remove(of->fname_tmp);
66  free(of->fname_tmp);
67  free(of->fname);
68  return 0;
69  }
70  if (fclose(of->file) != 0) {
71  LOG(llevError, "could not write %s: %s\n", of->fname, strerror(errno));
72  remove(of->fname_tmp);
73  free(of->fname_tmp);
74  free(of->fname);
75  return 0;
76  }
77  if (rename(of->fname_tmp, of->fname) != 0) {
78  LOG(llevError, "%s: cannot rename from %s: %s\n", of->fname, of->fname_tmp, strerror(errno));
79  remove(of->fname_tmp);
80  free(of->fname_tmp);
81  free(of->fname);
82  return 0;
83  }
84  free(of->fname_tmp);
85  free(of->fname);
86  return 1;
87 }
88 
90 {
91  fclose(of->file);
92  remove(of->fname_tmp);
93  free(of->fname_tmp);
94  free(of->fname);
95 }
OutputFile::fname
char * fname
Definition: output_file.h:46
output_file.h
global.h
OutputFile::file
FILE * file
Definition: output_file.h:57
llevError
@ llevError
Definition: logger.h:11
LOG
void LOG(LogLevel logLevel, const char *format,...)
Definition: logger.cpp:58
of_close
int of_close(OutputFile *of)
Definition: output_file.cpp:61
TMP_EXT
#define TMP_EXT
Definition: output_file.cpp:27
of_open
FILE * of_open(OutputFile *of, const char *fname)
Definition: output_file.cpp:30
strdup_local
#define strdup_local
Definition: compat.h:29
logger.h
of_cancel
void of_cancel(OutputFile *of)
Definition: output_file.cpp:89
OutputFile::fname_tmp
char * fname_tmp
Definition: output_file.h:52
OutputFile
Definition: output_file.h:41