Fawkes API  Fawkes Development Version
file.cpp
1 
2 /***************************************************************************
3  * file.cpp - file utils
4  *
5  * Generated: Wed Aug 30 22:47:11 2006
6  * Copyright 2006 Tim Niemueller [www.niemueller.de]
7  * 2007 Daniel Beck
8  *
9  ****************************************************************************/
10 
11 /* This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 2 of the License, or
14  * (at your option) any later version. A runtime exception applies to
15  * this software (see LICENSE.GPL_WRE file mentioned below for details).
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20  * GNU Library General Public License for more details.
21  *
22  * Read the full text in the LICENSE.GPL_WRE file in the doc directory.
23  */
24 
25 #include <core/exceptions/system.h>
26 #include <sys/stat.h>
27 #include <sys/types.h>
28 #include <utils/system/file.h>
29 
30 #include <cstdio>
31 #include <errno.h>
32 #include <fcntl.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #include <unistd.h>
36 
37 namespace fawkes {
38 
39 /** @class UnableToOpenFileException file.h <utils/system/file.h>
40  * Opening a file failed for some reason.
41  * @ingroup Exceptions
42  */
43 /** Constructor
44  * @param filename the name of the file which couldn't be opened
45  * @param error the errno
46  */
47 UnableToOpenFileException::UnableToOpenFileException(const char *filename, int error)
48 : Exception(error, "Unable to open file")
49 {
50  append("File that could not be opened: %s", filename);
51 }
52 
53 /** @class File file.h <utils/system/file.h>
54  * File utility methods.
55  * Allows for opening a file and provides utilities to check if a file exists
56  * or whether it is a regular file (and not a symbolic link/directory).
57  * @author Tim Niemueller
58  * @author Daniel Beck
59  */
60 
61 /** Constructor.
62  * Independent of the FileOpenMethod files are created with
63  * permissions 660
64  * @param filename the filename
65  * @param method the method determines what is done if a file with the
66  * specified name already exists
67  */
68 File::File(const char *filename, FileOpenMethod method)
69 {
70  fd = -1;
71 
72  switch (method) {
73  case OVERWRITE:
74  fd = open(filename, O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
75  fn = strdup(filename);
76  break;
77 
78  case APPEND:
79  fd = open(filename, O_RDWR | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
80  fn = strdup(filename);
81  break;
82 
83  case ADD_SUFFIX: {
84  char *filename_ext = strdup(filename);
85  int index = 0;
86  while (File::exists(filename_ext)) {
87  free(filename_ext);
88  if (asprintf(&filename_ext, "%s.%d", filename, ++index) == -1) {
89  throw OutOfMemoryException("Could not allocate filename string");
90  }
91  }
92  fd = open(filename_ext, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
93  fn = filename_ext;
94  } break;
95 
96  default: printf("%s [line %d]: Unkown method.\n", __FILE__, __LINE__);
97  }
98 
99  if (-1 == fd) {
100  throw UnableToOpenFileException(filename, errno);
101  }
102 
103  fp = fdopen(fd, "r+");
104 }
105 
106 /** Destructor. */
107 File::~File()
108 {
109  // this also closes the underlying file descritptor fd
110  fclose(fp);
111  free(fn);
112 }
113 
114 /** Get access to the file stream.
115  * @return a pointer to the file stream
116  */
117 FILE *
118 File::stream() const
119 {
120  return fp;
121 }
122 
123 /** Get the file's name.
124  * @return a pointer to a char array where the filename is stored
125  */
126 const char *
127 File::filename() const
128 {
129  return fn;
130 }
131 
132 /** Check if a file exists.
133  * @param filename the name of the file to check
134  * @return true, if the file exists, false otherwise
135  */
136 bool
137 File::exists(const char *filename)
138 {
139  return (access(filename, F_OK) == 0);
140 }
141 
142 /** Check if a file is a regular file
143  * @param filename the name of the file to check
144  * @return true, if the given path points to a regular file, false otherwise
145  */
146 bool
147 File::is_regular(const char *filename)
148 {
149  struct stat s;
150 
151  if (stat(filename, &s) == 0) {
152  return S_ISREG(s.st_mode);
153  } else {
154  return false;
155  }
156 }
157 
158 } // end namespace fawkes
fawkes::File::exists
static bool exists(const char *filename)
Check if a file exists.
Definition: file.cpp:142
fawkes::File::is_regular
static bool is_regular(const char *filename)
Check if a file is a regular file.
Definition: file.cpp:152
fawkes::UnableToOpenFileException::UnableToOpenFileException
UnableToOpenFileException(const char *filename, int error)
Constructor.
Definition: file.cpp:52
fawkes::File::ADD_SUFFIX
add a suffix (starting with ".1") to the given filename
Definition: file.h:54
fawkes::File::~File
~File()
Destructor.
Definition: file.cpp:112
fawkes::File::filename
const char * filename() const
Get the file's name.
Definition: file.cpp:132
fawkes::File::OVERWRITE
overwrite the existing file
Definition: file.h:52
fawkes::File::File
File(const char *filename, FileOpenMethod method=APPEND)
Constructor.
Definition: file.cpp:73
fawkes
fawkes::File::APPEND
append data at the end of the existing file
Definition: file.h:53
fawkes::File::stream
FILE * stream() const
Get access to the file stream.
Definition: file.cpp:123
fawkes::OutOfMemoryException
Definition: system.h:35