* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+/** @file
+ * @brief ANSI FILE* clone API implementation.
+ * @version $Id$
+ */
+#include "config.h"
+
#include "fileio.h"
-#include "runmalloc.h" /* RunMalloc, RunFree */
-#include <stdio.h> /* BUFSIZ, EOF */
-#include <fcntl.h> /* O_RDONLY, O_WRONLY, ... */
-#include <unistd.h> /* read, write, open, close */
-#include <assert.h> /* assert */
+#include "ircd_alloc.h" /* MyMalloc, MyFree */
+#include "ircd_log.h" /* assert */
-#define FB_EOF 0x01
-#define FB_FAIL 0x02
+/* #include <assert.h> -- Now using assert in ircd_log.h */ /* assert */
+#include <fcntl.h> /* O_RDONLY, O_WRONLY, ... */
+#include <stdio.h> /* BUFSIZ, EOF */
+#include <sys/stat.h> /* struct stat */
+#include <unistd.h> /* read, write, open, close */
+#include <string.h>
+#define FB_EOF 0x01 /**< File has reached EOF. */
+#define FB_FAIL 0x02 /**< File operation failed. */
+
+/** Tracks status and buffer for a file on disk. */
struct FileBuf {
- int fd; /* file descriptor */
- char *endp; /* one past the end */
- char *ptr; /* current read pos */
- int flags; /* file state */
- char buf[BUFSIZ]; /* buffer */
+ int fd; /**< file descriptor */
+ char *endp; /**< one past the end */
+ char *ptr; /**< current read pos */
+ int flags; /**< file state */
+ char buf[BUFSIZ]; /**< buffer */
};
-FBFILE *fbopen(const char *filename, const char *mode)
+/** Open a new FBFILE.
+ * @param[in] filename Name of file to open.
+ * @param[in] mode fopen()-style mode string.
+ * @return Pointer to newly allocated FBFILE.
+ */
+FBFILE* fbopen(const char *filename, const char *mode)
{
int openmode = 0;
int pmode = 0;
assert(filename);
assert(mode);
- while (*mode)
- {
- switch (*mode)
- {
- case 'r':
- openmode = O_RDONLY;
- break;
- case 'w':
- openmode = O_WRONLY | O_CREAT | O_TRUNC;
- pmode = S_IREAD | S_IWRITE;
- break;
- case 'a':
- openmode = O_WRONLY | O_CREAT | O_APPEND;
- pmode = S_IREAD | S_IWRITE;
- break;
- case '+':
- openmode &= ~(O_RDONLY | O_WRONLY);
- openmode |= O_RDWR;
- break;
- default:
- break;
+ while (*mode) {
+ switch (*mode) {
+ case 'r':
+ openmode = O_RDONLY;
+ break;
+ case 'w':
+ openmode = O_WRONLY | O_CREAT | O_TRUNC;
+ pmode = S_IRUSR | S_IWUSR;
+ break;
+ case 'a':
+ openmode = O_WRONLY | O_CREAT | O_APPEND;
+ pmode = S_IRUSR | S_IWUSR;
+ break;
+ case '+':
+ openmode &= ~(O_RDONLY | O_WRONLY);
+ openmode |= O_RDWR;
+ break;
+ default:
+ break;
}
++mode;
}
/*
* stop NFS hangs...most systems should be able to open a file in
- * 3 seconds. -avalon (curtesy of wumpus)
+ * 3 seconds. -avalon (courtesy of wumpus)
*/
alarm(3);
- if ((fd = open(filename, openmode, pmode)) == -1)
- {
+ if ((fd = open(filename, openmode, pmode)) == -1) {
alarm(0);
return fb;
}
return fb;
}
-FBFILE *fdbopen(int fd, const char *mode)
+/** Open a FBFILE from a file descriptor.
+ * @param[in] fd File descriptor to use.
+ * @param[in] mode fopen()-style mode string (ignored).
+ */
+FBFILE* fdbopen(int fd, const char *mode)
{
/*
* ignore mode, if file descriptor hasn't been opened with the
* correct mode, the first use will fail
*/
- FBFILE *fb = (FBFILE *) RunMalloc(sizeof(FBFILE));
- if (NULL != fb)
- {
- fb->ptr = fb->endp = fb->buf;
- fb->fd = fd;
- fb->flags = 0;
- }
+ FBFILE *fb = (FBFILE *) MyMalloc(sizeof(FBFILE));
+ assert(0 != fb);
+ fb->ptr = fb->endp = fb->buf;
+ fb->fd = fd;
+ fb->flags = 0;
+
return fb;
}
-void fbclose(FBFILE * fb)
+/** Close a FBFILE.
+ * @param[in] fb File buffer to close.
+ */
+void fbclose(FBFILE* fb)
{
assert(fb);
close(fb->fd);
- RunFree(fb);
+ MyFree(fb);
}
+/** Attempt to fill a file's buffer.
+ * @param[in] fb File to operate on.
+ * @return Number of bytes read into buffer, or a negative number on error.
+ */
static int fbfill(FBFILE * fb)
{
int n;
return n;
}
+/** Get a single character from a file.
+ * @param[in] fb File to fetch from.
+ * @return Character value read, or EOF on error or end-of-file.
+ */
int fbgetc(FBFILE * fb)
{
assert(fb);
return EOF;
}
+/** Get a line of input from a file.
+ * @param[out] buf Output buffer to read to.
+ * @param[in] len Maximum number of bytes to write to buffer
+ * (including terminating NUL).
+ * @param[in] fb File to read from.
+ */
char *fbgets(char *buf, size_t len, FBFILE * fb)
{
char *p = buf;
if (fb->ptr == fb->endp && fbfill(fb) < 1)
return 0;
--len;
- while (len--)
- {
+ while (len--) {
*p = *fb->ptr++;
if ('\n' == *p)
{
/*
* deal with CR's
*/
- else if ('\r' == *p)
- {
- if (fb->ptr < fb->endp || fbfill(fb) > 0)
- {
- if ('\n' == *fb->ptr)
- ++fb->ptr;
+ else if ('\r' == *p) {
+ if (fb->ptr < fb->endp || fbfill(fb) > 0) {
+ if ('\n' == *fb->ptr)
+ ++fb->ptr;
}
*p++ = '\n';
break;
return buf;
}
+/** Write a string to a file.
+ * @param[in] str String to write to file.
+ * @param[in] fb File to write to.
+ * @return Number of bytes written, or -1 on error.
+ */
int fbputs(const char *str, FBFILE * fb)
{
int n = -1;
assert(str);
assert(fb);
- if (0 == fb->flags)
- {
+ if (0 == fb->flags) {
n = write(fb->fd, str, strlen(str));
if (-1 == n)
fb->flags |= FB_FAIL;
return n;
}
+/** Get file status.
+ * @param[out] sb Receives file status.
+ * @param[in] fb File to get status for.
+ * @return Zero on success, -1 on error.
+ */
int fbstat(struct stat *sb, FBFILE * fb)
{
assert(sb);
assert(fb);
return fstat(fb->fd, sb);
}
+