X-Git-Url: http://git.tuebingen.mpg.de/?p=adu.git;a=blobdiff_plain;f=fd.c;h=7040b87865b3965f3a7eff7963b8584294d637b8;hp=cfef4d9a663268d24c130ecf11fee71fac0864a9;hb=5738935ef1e34d1a82e9b4fcdb741f2b06667b96;hpb=a4cf08e8062d1d73c343a628563acf4d9f454742 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). *