+
+/**
+ * util_encode_string:
+ * @str: input string to be encoded
+ * @str_enc: output string to store the encoded input string
+ * @len: maximum size of the output string, which may be
+ * four times as long as the input string
+ *
+ * Encode all potentially unsafe characters of a string to the
+ * corresponding hex value prefixed by '\x'.
+ *
+ * Returns: 0 if the entire string was copied, non-zero otherwise.
+ **/
+int udev_util_encode_string(const char *str, char *str_enc, size_t len)
+{
+ size_t i, j;
+
+ if (str == NULL || str_enc == NULL || len == 0)
+ return -1;
+
+ str_enc[0] = '\0';
+ for (i = 0, j = 0; str[i] != '\0'; i++) {
+ int seqlen;
+
+ seqlen = utf8_encoded_valid_unichar(&str[i]);
+ if (seqlen > 1) {
+ memcpy(&str_enc[j], &str[i], seqlen);
+ j += seqlen;
+ i += (seqlen-1);
+ } else if (str[i] == '\\' || !is_whitelisted(str[i], NULL)) {
+ sprintf(&str_enc[j], "\\x%02x", (unsigned char) str[i]);
+ j += 4;
+ } else {
+ str_enc[j] = str[i];
+ j++;
+ }
+ if (j+3 >= len)
+ goto err;
+ }
+ str_enc[j] = '\0';
+ return 0;
+err:
+ return -1;
+}
+
+void util_set_fd_cloexec(int fd)
+{
+ int flags;
+
+ flags = fcntl(fd, F_GETFD);
+ if (flags < 0)
+ flags = FD_CLOEXEC;
+ else
+ flags |= FD_CLOEXEC;
+ fcntl(fd, F_SETFD, flags);
+}
+
+unsigned int util_string_hash32(const char *str)
+{
+ unsigned int hash = 0;
+
+ while (str[0] != '\0') {
+ hash += str[0] << 4;
+ hash += str[0] >> 4;
+ hash *= 11;
+ str++;
+ }
+ return hash;
+}