- if(which != DIRHELPER_USER_LOCAL) {
- res = mkdir(path, modes[which]);
- if(res != 0 && errno != EEXIST)
- return NULL;
+#if !TARGET_OS_EMBEDDED
+ if (!_xpc_runtime_is_app_sandboxed())
+#endif
+ if(mkdir(path, modes[which]) != 0 && errno != EEXIST)
+ return NULL;
+
+#if !TARGET_OS_EMBEDDED
+ if (_xpc_runtime_is_app_sandboxed()) {
+ /*
+ * if xpchelper didn't make the subdir for us, bail since we don't have
+ * permission to create it ourselves.
+ */
+ if(stat(path, &sb) < 0) {
+ errno = EPERM;
+ return NULL;
+ }
+
+ /*
+ * sandboxed applications get per-application directories named
+ * after the container
+ */
+ char *container_id = getenv(XPC_ENV_SANDBOX_CONTAINER_ID);
+ if(!container_id) {
+ errno = EINVAL;
+ return NULL;
+ }
+
+ /*
+ * container ID doesn't end in a slash, so +2 is for slash and \0
+ */
+ if (pathlen < strlen(path) + strlen(container_id) + 2) {
+ errno = EINVAL;
+ return NULL; /* buffer too small */
+ }
+
+ strcat(path, container_id);
+ strcat(path, "/");
+
+ /*
+ * create per-app subdirectory with the appropriate permissions
+ * if it doesn't already exist.
+ */
+ if(mkdir(path, modes[which]) != 0 && errno != EEXIST)
+ return NULL;