Подскажите как получить внутри программы домашнюю папку запустившего программу пользователя.Причем использовать glib нельзя (его нет в зависимостях). Используя язык C .
В исходниках питона вот такое. По большому счёту там проверяется сначала наличие переменной $HOME, и, если не получилось, то getpwuid, читаем из /etc/passwd.
Твой способ не совсем правильный. $HOME в любом случае приоритетнее, а если даже его нет, то я не уверен, что лучше: читать из passwd или принять home = / (и получать ошибки при попытках в него что-то записать).
Ну уж нет, тащить эту чушь за пределы гуи точно не надо.
Вопрос в пустоту - чем GUI принципиально отличается от не GUI?
В контексте топика речь про XDG’шные каталоги ~/.config/appname и /.local/share/appname вместо помойки из дотфайлов в ~. Это правильный подход независимо от GUI’шности.
В общем случае это невозможно. Программа запущена в контейнере с euid 100500. В /etc/passwd внутри контейнера пользователя с таким uid нет. Переменная окружения HOME содержит путь к несуществующей директории
Тут вот в чём фишка: запустившего программу пользователя Т.ч. getenv даст неправильный ответ.
С чего это он даст неправильный? Хотя тут есть некоторая двусмысленность терминологии, но всё-таки записи в passwd это не «запустивший пользователь» а «логинящийся пользователь». И, учитывая контекст, пользователь тут - вовсе не uid, а текущее рабочее окружение. У uid-а homedir-а вообще нет и быть не может, а то, что ты ищешь - «homedir первого логина в списке, у которого uid совпадает с текущим». Да, их может быть больше одного, и это полностью нормальная ситуация. Предыдущий вариант с getpwnam был более адекватен в этом плане, но и он неправильный по той же причине.
tmp % sudo ./h
Тут проблема не в том, что ты неправильно получаешь home, а в том, что ты запустил дефективный софт по названием sudo, который устраивает всякую чушь. Да, home там должен быть именно /Users/dima.
Вопрос в пустоту - чем GUI принципиально отличается от не GUI?
Под гуи имелся ввиду оплот гномеров, вайландеров и прочих некомпетентных личностей, устроивших там помойку. А «негуи» - пока ещё свободную от этой инфекции территорию.
Возможно, конечно. Эта самая несуществующая директория и будет home. То, что её нет, в целом ситуацию не меняет. В passwd смотреть не надо, я уже выше писал почему.
то я не уверен, что лучше: читать из passwd или принять home = / (и получать ошибки при попытках в него что-то записать).
Ничего из вышеперечисленного. Хомдир задаётся исключительно $HOME, никаких дефолтов у него нет и придумывать их не надо. Если хочется читать/писать в HOME, а $HOME не установлен, просто не читай/пиши. Если нужно читать/писать, то падай.
Ну уж нет, тащить эту чушь за пределы гуи точно не надо.
Какая разница GUI или что-то другое. $XDG_DATA_HOME, $XDG_CONFIG_HOME, $XDG_CACHE_HOME – база для хранения данных ПО. Любой кто хранит данные в ~/.myapp – говнюк полный. Остальное не менее важно.
Что значит «неправильный»? Если программа хочет узнать где домашний каталог пользователя, то по-уму ей сначала надо проверить существует ли в окружении переменная HOME. Если есть — использовать её значение, и только если переменной HOME нет, то вызывать getpwuid(). Какой user id указывать — реальный или эффективный — зависит от программы. Большинству обычных программ (которые не меняют user id по ходу исполнения) — пофигу, они совпадают. Если программа меняет user id — то надо разбираться а чего именно хочет добиться автор программы — получить каталог того пользователя, который запустил программу, или того пользователя, от имени которого программа работает в данный момент. Но в любом случае, начинать надо с HOME.
Но я бы начал с вопроса: а зачем ТС домашний каталог пользователя? Если для поиска конфигов или сохранения кеша/данных, то надо для начала курить XDG, а уж там явно написано, что если XDG_??? переменная не установлена, то дефолтное значение конструируется из переменной HOME.
У меня уже давно есть rule of thumb: если программа мусорит своим барахлом прямо в ~/, то лучше её поскорее удалить. Есть исключения, конечно, вроде Firefox, в котором скоро должны доделать поддержку XDG Base Directory, или cargo, который нечем заменить (и там можно переопределить каталог).
Всё наоборот, тот же mc раньше очень удобно всё складывал в .mc, а теперь раскидан по этим дурацким .local итд, крайне неудобно. Файрфокс хорошо что до сих пор пишет в .mozilla, если они хотят это испортить - осуждаю. Впрочем, частично уже испортили, как я какое-то время назад заметил - оно ещё в .cache что-то создаёт, и из-за этого для удаления профиля недостаточно удалить одну директорию, надо лазить где оно ещё наспамить успело.
Всё наоборот, тот же mc раньше очень удобно всё складывал в .mc, а теперь раскидан по этим дурацким .local итд, крайне неудобно.
Это разделение конфигурации и данных, не представляю, как оно может быть неудобным. Конкретно в MC тебе вообще не надо лезть в ~/.local/share/mc, там чисто служебные файлы.
Файрфокс хорошо что до сих пор пишет в .mozilla, если они хотят это испортить - осуждаю.
Насколько я помню, старый вариант будет тоже поддерживаться. Поддержка XDG тоже будет, вероятно, в стиле Chromium, когда в $XDG_CONFIG_HOME валяются вместе конфигурация и данные, но не слежу особо, возможно, и сумеют разделить как-то.
Впрочем, частично уже испортили, как я какое-то время назад заметил - оно ещё в .cache что-то создаёт, и из-за этого для удаления профиля недостаточно удалить одну директорию, надо лазить где оно ещё наспамить успело.
Любишь включать в резервные копии всякий мусор? ~/.cache легко и игнорировать, и просто грохнуться целиком без опасений потерять что-то сломать.
Конкретно в MC тебе вообще не надо лезть в ~/.local/share/mc, там чисто служебные файлы.
Это тебе не надо а я там редактировал схемы подсветки. И вообще, .local/share это двойной идиотизм, мало того что из удобного корня убрали в какую-то директорию второй вложенности с непонятным бессмысленным названием, так там ещё и каша внутри из тех же конфигов, кешей и файлов данных (речь не про конкретно mc, это у всех), только, в отличие от схемы «всё в корне», когда на втором уровне вложенности оно было структурировано по категории файлов, тут оно лежит просто в виде каши.
Это тебе не надо а я там редактировал схемы подсветки
Так и знал, что про это скажешь. Странно вообще, что схемы не в ~/.config, но тут MC не одинок, у nano такая же логика.
Ну, я частично соглашусь, что разделение на конфигурацию и данные подходит не любым программам, и иногда выглядит усложнением. Например, те же браузеры с их профилями. Игры туда же (но эти и не заморачиваются, обычно выбирают один каталог). В целом не всегда очевидно, где именно будет лежать то-то у такой-то программы, потому что стандарт понимается по-разному.
убрали в какую-то директорию второй вложенности
С одной стороны, эта вложенность используется, поскольку там рядом прописались всякие bin, state, у многих ещё lib. Но тогда было бы логично и config туда закинуть. С другой стороны, если хочешь переопределить расположение ~/.local/share, то надо оставить симлинк для кривых приложений, и эта вложенность становится неудобством.
В общем, не всё гладко, но стандарт есть стандарт, он прижился, и это уже не та помойка из скрытых файлов в домашнем каталоге. Я бы ещё сделал все эти каталоги не скрытыми, потому что дот-файлы — это просто рак, который появился не от большого ума.
А причина на самом деле вот какая. Само ~/.local планировалось как юзерский аналог /usr (оттуда и bin/lib). Но вот какое дело, /usr/share это место для хранения, в том числе, дефолтных конфигов, а место для хранения настроенных конфигов - /etc (которому аналог ~/.config). В контексте системы разделение понятно - дефолтные конфиги ставит пакетный менеджер, а настроенные - могут редактироваться администратором. В контексте юзера это разделение выглядит сомнительно - дефолты всё так же хранятся в /usr/share, дублировать их в ~/.local/share незачем. Остаётся одно единственное вменяемое применение: класть в ~/.local/share дефолты софта, установленного самим юзером себе в $HOME с префиксом $HOME/.local (например, через ./configure --prefix=$HOME/.local && make install). Собственно, ~/.local/bin и ~/.local/lib аналогично. То, что туда что-то пишут проги про запуске (не инсталляторы) - некорректное поведение. То, что установленные общесистемно проги оттуда что-то читают - ну, наверно допустимо (хотя я не уверен), но только если юзер сам решил таким образом подменить /usr/share. То есть, дефолтно никакого ~/.local/share существовать не должно, он может появиться только при явном на то желании юзера.
Если бы он существовал именно в таком виде - я бы его не осуждал, более того у меня было ~/usr/ для аналогичной цели когда-то (распаковывал туда deb-пакеты), а сейчас есть ~/DEV/{lib|include|man|src}/ для локальной компиляции при разработке.
Программы, установленные системным пакетным менеджером, вполне могли бы обойтись двумя директориями, какими-нить ~/.state/NAME и ~/.cache/NAME, причём большинству - только первая. И незачем делать всякие $XDG_XXX_DIR, это только добавляет лишнюю логику в куче мест системы, вполне нормально обращаться к ним через $HOME. Тогда можно точно знать, что вот есть максимум два места, где можно искать автосозданные прогой файлы. А кому надо другое место - есть симлинки.
Впрочем, некоторые я бы всё равно оставил в корне например ~/.ssh.
Нет, /etc/passwd это список логинов. А источник данных о текущем юзере это getuid() и похожие функции, а также getenv(). Юзер совершенно не обязательно логинился через штатные способы, он может быть синтетическим, сделанным на лету какой-то рутовой прогой. Да и не только рутовой, я иногда запускаю что-то в виде
HOME=$HOME/subdir /path/to/executable
И все нормальные программы, как и положено, считают home-ом указанную директорию и не устраивают самодеятельность с парсингом passwd.