}
/**
- * Pparaslash's version of strdup().
+ * Paraslash's version of strdup().
*
* \param s The string to be duplicated.
*
return make_message("%08i", rand());
}
-/**
- * Create unique temporary file.
- *
- * \param template The template to be passed to mkstemp().
- * \param mode The desired mode of the tempfile.
- *
- * This wrapper for mkstemp additionally uses fchmod() to
- * set the given mode of the tempfile if mkstemp() returned success.
- *
- * \return The file descriptor of the temp file just created on success.
- * On errors, a negative value is returned.
- */
-__must_check int para_mkstemp(char *template, mode_t mode)
-{
- int tmp, fd = mkstemp(template);
-
- if (fd < 0)
- return -ERRNO_TO_PARA_ERROR(errno);
- tmp = fchmod(fd, mode);
- if (tmp >= 0)
- return fd;
- tmp = errno;
- close(fd);
- unlink(template);
- return -ERRNO_TO_PARA_ERROR(tmp);
-}
-
/**
* Get the logname of the current user.
*
*
* This function prints into the buffer given by \a b at the offset which is
* also given by \a b. If there is not enough space to hold the result, the
- * buffer size is doubled until the underlying call to vsnprintf() succeeds.
+ * buffer size is doubled until the underlying call to vsnprintf() succeeds
+ * or the size of the buffer exceeds the maximal size specified in \a pb.
+ *
+ * In the latter case the unmodified \a buf and \a offset values as well as the
+ * private_data pointer of \a b are passed to the \a max_size_handler of \a b.
+ * If this function succeeds, i.e. returns a non-negative value, the offset of
+ * \a b is reset to zero and the given data is written to the beginning of the
+ * buffer.
+ *
* Upon return, the offset of \a b is adjusted accordingly so that subsequent
* calls to this function append data to what is already contained in the
* buffer.
b->buf = para_malloc(128);
b->size = 128;
b->offset = 0;
- } else if (b->size <= b->offset + 1) {
- b->size *= 2;
- b->buf = para_realloc(b->buf, b->size);
}
while (1) {
char *p = b->buf + b->offset;
size_t size = b->size - b->offset;
va_list ap;
- va_start(ap, fmt);
- ret = vsnprintf(p, size, fmt, ap);
- va_end(ap);
- if (ret > -1 && ret < size) { /* success */
- b->offset += ret;
- break;
+ if (size) {
+ va_start(ap, fmt);
+ ret = vsnprintf(p, size, fmt, ap);
+ va_end(ap);
+ if (ret > -1 && ret < size) { /* success */
+ b->offset += ret;
+ return ret;
+ }
+ }
+ /* check if we may grow the buffer */
+ if (!b->max_size || 2 * b->size < b->max_size) { /* yes */
+ /* try again with more space */
+ b->size *= 2;
+ b->buf = para_realloc(b->buf, b->size);
+ continue;
}
- /* try again with more space */
- b->size *= 2;
- b->buf = para_realloc(b->buf, b->size);
+ /* can't grow buffer */
+ if (!b->offset || !b->max_size_handler) /* message too large */
+ return -ERRNO_TO_PARA_ERROR(ENOSPC);
+ ret = b->max_size_handler(b->buf, b->offset, b->private_data);
+ if (ret < 0)
+ return ret;
+ b->offset = 0;
}
- return ret;
}
/** \cond LLONG_MAX and LLONG_LIN might not be defined. */