return ret;
}
+/**
+ * Determines the current working directory.
+ *
+ * @return the current working directory (must be free()'d)
+ * or NULL on error
+ */
+char *vlc_getcwd (void)
+{
+ /* Try $PWD */
+ const char *pwd = getenv ("PWD");
+ if (pwd != NULL)
+ {
+ struct stat s1, s2;
+ /* Make sure $PWD is correct */
+ if (stat (pwd, &s1) == 0 && stat (".", &s2) == 0
+ && s1.st_dev == s2.st_dev && s1.st_ino == s2.st_ino)
+ return ToLocaleDup (pwd);
+ }
+
+ /* Otherwise iterate getcwd() until the buffer is big enough */
+ long path_max = pathconf (".", _PC_PATH_MAX);
+ size_t size = (path_max == -1 || path_max > 4096) ? 4096 : path_max;
+
+ for (;; size *= 2)
+ {
+ char *buf = malloc (size);
+ if (unlikely(buf == NULL))
+ break;
+
+ if (getcwd (buf, size) != NULL)
+#ifdef ASSUME_UTF8
+ return buf;
+#else
+ {
+ char *ret = ToLocaleDup (buf);
+ free (buf);
+ return ret; /* success */
+ }
+#endif
+ free (buf);
+
+ if (errno != ERANGE)
+ break;
+ }
+ return NULL;
+}
+
/**
* Duplicates a file descriptor. The new file descriptor has the close-on-exec
* descriptor flag set.
{
int newfd;
-#ifdef HAVE_DUP3
- /* Unfortunately, dup3() works like dup2(), not like plain dup(). So we
- * need such contortion to find the new file descriptor while preserving
- * thread safety of the file descriptor table. */
- newfd = vlc_open ("/dev/null", O_RDONLY);
- if (likely(newfd != -1))
+#ifdef F_DUPFD_CLOEXEC
+ newfd = fcntl (oldfd, F_DUPFD_CLOEXEC);
+ if (unlikely(newfd == -1 && errno == EINVAL))
+#endif
{
- if (likely(dup3 (oldfd, newfd, O_CLOEXEC) == newfd))
- return newfd;
- close (newfd);
+ newfd = dup (oldfd);
+ if (likely(newfd != -1))
+ fcntl (newfd, F_SETFD, FD_CLOEXEC);
}
-#endif
-
- newfd = dup (oldfd);
- if (likely(newfd != -1))
- fcntl (newfd, F_SETFD, FD_CLOEXEC);
return newfd;
}
+#ifdef __ANDROID__ /* && we support android < 2.3 */
+/* pipe2() is declared and available since android-9 NDK,
+ * although it is available in libc.a since android-3
+ * We redefine the function here in order to be able to run
+ * on versions of Android older than 2.3
+ */
+#include <sys/syscall.h>
+//#include <sys/linux-syscalls.h> // fucking brokeness
+int pipe2(int fds[2], int flags)
+{
+ return syscall(/*__NR_pipe2 */ 359, fds, flags);
+}
+#endif /* __ANDROID__ */
+
/**
* Creates a pipe (see "man pipe" for further reference).
*/