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 
26 #include <utils/system/file.h>
27 #include <core/exceptions/system.h>
28 
29 #include <sys/types.h>
30 #include <sys/stat.h>
31 #include <unistd.h>
32 #include <fcntl.h>
33 #include <string.h>
34 #include <errno.h>
35 #include <stdlib.h>
36 #include <cstdio>
37 
38 namespace fawkes {
39 
40 /** @class UnableToOpenFileException file.h <utils/system/file.h>
41  * Opening a file failed for some reason.
42  * @ingroup Exceptions
43  */
44 /** Constructor
45  * @param filename the name of the file which couldn't be opened
46  * @param error the errno
47  */
49  : Exception(error, "Unable to open file")
50 {
51  append("File that could not be opened: %s", filename);
52 }
53 
54 
55 /** @class File file.h <utils/system/file.h>
56  * File utility methods.
57  * Allows for opening a file and provides utilities to check if a file exists
58  * or whether it is a regular file (and not a symbolic link/directory).
59  * @author Tim Niemueller
60  * @author Daniel Beck
61  */
62 
63 
64 /** Constructor.
65  * Independent of the FileOpenMethod files are created with
66  * permissions 660
67  * @param filename the filename
68  * @param method the method determines what is done if a file with the
69  * specified name already exists
70  */
71 File::File(const char *filename, FileOpenMethod method)
72 {
73  fd = -1;
74 
75  switch (method)
76  {
77  case OVERWRITE:
78  fd = open(filename, O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
79  fn = strdup(filename);
80  break;
81 
82  case APPEND:
83  fd = open(filename, O_RDWR | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
84  fn = strdup(filename);
85  break;
86 
87  case ADD_SUFFIX:
88  {
89  char *filename_ext = strdup(filename);
90  int index = 0;
91  while (File::exists(filename_ext)) {
92  free(filename_ext);
93  if ( asprintf(&filename_ext, "%s.%d", filename, ++index) == -1 ) {
94  throw OutOfMemoryException("Could not allocate filename string");
95  }
96 
97  }
98  fd = open(filename_ext, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
99  fn = filename_ext;
100  }
101  break;
102 
103  default:
104  printf("%s [line %d]: Unkown method.\n", __FILE__, __LINE__);
105  }
106 
107  if (-1 == fd)
108  {
109  throw UnableToOpenFileException(filename, errno);
110  }
111 
112  fp = fdopen(fd, "r+");
113 }
114 
115 
116 /** Destructor. */
118 {
119  // this also closes the underlying file descritptor fd
120  fclose(fp);
121  free(fn);
122 }
123 
124 
125 /** Get access to the file stream.
126  * @return a pointer to the file stream
127  */
128 FILE *
130 {
131  return fp;
132 }
133 
134 /** Get the file's name.
135  * @return a pointer to a char array where the filename is stored
136  */
137 const char *
139 {
140  return fn;
141 }
142 
143 
144 /** Check if a file exists.
145  * @param filename the name of the file to check
146  * @return true, if the file exists, false otherwise
147  */
148 bool
149 File::exists(const char *filename)
150 {
151  return (access(filename, F_OK) == 0);
152 }
153 
154 
155 /** Check if a file is a regular file
156  * @param filename the name of the file to check
157  * @return true, if the given path points to a regular file, false otherwise
158  */
159 bool
160 File::is_regular(const char *filename)
161 {
162  struct stat s;
163 
164  if ( stat(filename, &s) == 0 ) {
165  return S_ISREG(s.st_mode);
166  } else {
167  return false;
168  }
169 }
170 
171 
172 } // end namespace fawkes
File(const char *filename, FileOpenMethod method=APPEND)
Constructor.
Definition: file.cpp:71
const char * filename() const
Get the file&#39;s name.
Definition: file.cpp:138
Fawkes library namespace.
UnableToOpenFileException(const char *filename, int error)
Constructor.
Definition: file.cpp:48
FileOpenMethod
What to do when a file with the same name already exists.
Definition: file.h:44
Base class for exceptions in Fawkes.
Definition: exception.h:36
FILE * stream() const
Get access to the file stream.
Definition: file.cpp:129
static bool exists(const char *filename)
Check if a file exists.
Definition: file.cpp:149
static bool is_regular(const char *filename)
Check if a file is a regular file.
Definition: file.cpp:160
~File()
Destructor.
Definition: file.cpp:117
System ran out of memory and desired operation could not be fulfilled.
Definition: system.h:32
void append(const char *format,...)
Append messages to the message list.
Definition: exception.cpp:341