mkdir не работает с тильдой в OS X в C?

Я переношу библиотеку C на OSX, что до сих пор не доставляло мне особых головных болей. В следующей функции:

int createDirectory( char *directory ){

    int error;

    error = mkdir(directory, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);

    if( error < 0 ){

        if( errno != EEXIST ){       

            return errno;                           
        }            
    }

    return error;        
}

Независимо от того, что такое directory, mkdir() всегда терпит неудачу с EPERM (операция не разрешена). Я не уверен, что исполняемый файл xcode находится в песочнице или я что-то упускаю, но каждый путь, который я передаю функции, терпит неудачу.

Я пробовал mkdir из терминала, и папки создаются без проблем, поэтому я не уверен, в чем проблема. Эта функция прекрасно работает в Linux и Solaris.

Примеры путей:

"~/Library/Application\\ Support/myApp"
"~/Desktop/myApp"

Первый — реальный пример каталога, который должна создать библиотека.


person whtlnv    schedule 17.05.2015    source источник
comment
~-расширение — это оболочка. Попробуйте без этого.   -  person Mat    schedule 17.05.2015
comment
Получите содержимое переменной окружения $HOME и замените ею ~.   -  person trojanfoe    schedule 17.05.2015
comment
EPERM? Действительно? Это интересно, поскольку этот код ошибки не является документом для mkdir(): developer.apple.com/library/mac/documentation/Darwin/Reference/ Я ожидал ENOENT.   -  person alk    schedule 17.05.2015
comment
И вы должны использовать API для получения местоположения каталогов, и это будет означать, что приложение будет работать как в режиме песочницы, так и в режиме без песочницы.   -  person trojanfoe    schedule 17.05.2015
comment
В дополнение к ~, попытка экранировать пробел с обратной косой чертой, а затем экранировать обратную косую черту является неправильной. Первый относится к оболочке и не подходит для программы на C (если только аргументы форматирования не передаются в оболочку). Путь с пробелом должен быть просто написан нормально: "/a/path/with some spaces/in/it".   -  person Ken Thomases    schedule 17.05.2015
comment
согласно справочной странице: EPERM: файловая система, содержащая имя пути, не поддерживает создание каталогов. Существует также вероятность того, что разрешения для родительского каталога не установлены, чтобы позволить программе создавать каталоги.   -  person user3629249    schedule 18.05.2015


Ответы (1)


OSX не расширяет символ '~', как это делает bash (хотя и использует bash).

Учитывая эту программу, работающую в /tmp:

#include <stdlib.h>
#include <sys/stat.h>
#include <stdio.h>

int main(void)
{
    char *given = "~/Library";
    char result[1024];
    char *s;
    mkdir("~", 0755);
    mkdir("~/Library", 0755);
    if ((s = realpath(given, result)) != 0) {
        printf ("%s\n", s);
    } else {
        perror("realpath");
    }
    return 0;
}

Я получаю этот результат на OSX:

/private/tmp/~/Library

Я получаю этот результат в Linux (Debian), а также в Solaris 10:

/tmp/~/Library

Как отмечено в Почему тильда (~ ) раскрыть в двойных кавычках?, изначально это была функция csh оболочки, которая bash включена давно (со ссылкой на страницу 1994 года). Он не реализован ни в одной из библиотек времени выполнения данных систем.

person Thomas Dickey    schedule 17.05.2015
comment
Эээ... и как это ответит на вопрос ОП о EPERM? - person alk; 17.05.2015
comment
Основной причиной проблемы является непонимание проблемы OP - EPERM интересно, но не имеет отношения к решению проблемы. - person Thomas Dickey; 17.05.2015
comment
Спасибо, проблема действительно была в '~'. Ни одна из других реализаций не использовала ~, но когда я писал файл конфигурации, я ошибся, думая, что разговариваю с терминалом оболочки. Кроме того, как сказал @alk, я до сих пор понятия не имею, почему я получаю EPERM, а не ENOENT. - person whtlnv; 17.05.2015