From e5aaa1a1401f5cc39b1816608b69d41237f2a689 Mon Sep 17 00:00:00 2001 From: Andre Noll Date: Tue, 27 May 2008 01:25:52 +0200 Subject: [PATCH] Add missing functions to fd.c. These were previously exported by osl but don't really belong there. --- Makefile | 2 +- fd.c | 141 ++++++++++++++++++++++++++++++++++++++++--------------- fd.h | 1 + 3 files changed, 104 insertions(+), 40 deletions(-) diff --git a/Makefile b/Makefile index b590b29..ef94fcc 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -objects := adu.o string.o cmdline.o +objects := adu.o string.o cmdline.o fd.o all: adu DEBUG_CPPFLAGS += -Wno-sign-compare -g -Wunused -Wundef -W diff --git a/fd.c b/fd.c index cfef4d9..7040b87 100644 --- a/fd.c +++ b/fd.c @@ -16,30 +16,116 @@ #include "error.h" /** - * Write a buffer to a file descriptor, re-write on short writes. + * Wrapper for the write system call. * - * \param fd The file descriptor. - * \param buf The buffer to be sent. - * \param len The length of \a buf. + * \param fd The file descriptor to write to. + * \param buf The buffer to write. + * \param size The length of \a buf in bytes. + * + * This function writes out the given buffer and retries if an interrupt + * occurred during the write. + * + * \return On success, the number of bytes written is returned, otherwise, the + * function returns \p -E_WRITE. * - * \return Standard. In any case, the number of bytes that have been written is - * stored in \a len. + * \sa write(2). */ -int write_all(int fd, const char *buf, size_t *len) +ssize_t para_write(int fd, const void *buf, size_t size) { - size_t total = *len; - - assert(total); - *len = 0; - while (*len < total) { - int ret = write(fd, buf + *len, total - *len); - if (ret == -1) - return -ERRNO_TO_ERROR(errno); - *len += ret; + ssize_t ret; + + for (;;) { + ret = write(fd, buf, size); + if ((ret < 0) && (errno == EAGAIN || errno == EINTR)) + continue; + return ret >= 0? ret : -E_WRITE; + } +} + + +/** + * Write the whole buffer to a file descriptor. + * + * \param fd The file descriptor to write to. + * \param buf The buffer to write. + * \param size The length of \a buf in bytes. + * + * This function writes the given buffer and continues on short writes and + * when interrupted by a signal. + * + * \return Positive on success, negative on errors. Possible errors: any + * errors returned by para_write(). + * + * \sa para_write(). + */ +ssize_t write_all(int fd, const void *buf, size_t size) +{ +// DEBUG_LOG("writing %zu bytes\n", size); + const char *b = buf; + while (size) { + ssize_t ret = para_write(fd, b, size); +// DEBUG_LOG("ret: %zd\n", ret); + if (ret < 0) + return ret; + b += ret; + size -= ret; } return 1; } +/** + * Wrapper for the open(2) system call. + * + * \param path The filename. + * \param flags The usual open(2) flags. + * \param mode Specifies the permissions to use. + * + * The mode parameter must be specified when O_CREAT is in the flags, and is + * ignored otherwise. + * + * \return The file descriptor on success, negative on errors. + * + * \sa open(2). + */ +int para_open(const char *path, int flags, mode_t mode) +{ + int ret = open(path, flags, mode); + + if (ret >= 0) + return ret; + return -ERRNO_TO_ERROR(errno); +} + +/** + * Open a file, write the given buffer and close the file. + * + * \param filename Full path to the file to open. + * \param buf The buffer to write to the file. + * \param size The size of \a buf. + * + * \return Positive on success, negative on errors. Possible errors include: + * any errors from para_open() or para_write(). + * + * \sa para_open(), para_write(). + */ +int para_write_file(const char *filename, const void *buf, size_t size) +{ + int ret, fd; + + ret = para_open(filename, O_WRONLY | O_CREAT | O_EXCL, 0644); + if (ret < 0) + return ret; + fd = ret; + ret = write_all(fd, buf, size); + if (ret < 0) + goto out; + ret = 1; +out: + close(fd); + return ret; +} + + /** * Check whether a file exists. * @@ -205,29 +291,6 @@ void *para_mmap(size_t length, int prot, int flags, int fd, off_t offset) exit(EXIT_FAILURE); } -/** - * Wrapper for the open(2) system call. - * - * \param path The filename. - * \param flags The usual open(2) flags. - * \param mode Specifies the permissions to use. - * - * The mode parameter must be specified when O_CREAT is in the flags, and is - * ignored otherwise. - * - * \return The file descriptor on success, negative on errors. - * - * \sa open(2). - */ -int para_open(const char *path, int flags, mode_t mode) -{ - int ret = open(path, flags, mode); - - if (ret >= 0) - return ret; - return -ERRNO_TO_ERROR(errno); -} - /** * Wrapper for chdir(2). * diff --git a/fd.h b/fd.h index 22141be..da0d349 100644 --- a/fd.h +++ b/fd.h @@ -24,3 +24,4 @@ int mmap_full_file(const char *filename, int open_mode, void **map, size_t *size, int *fd_ptr); int para_munmap(void *start, size_t length); int write_ok(int fd); +int para_write_file(const char *filename, const void *buf, size_t size); -- 2.39.5