Как я могу получить локаль пользователя при работе с правами root?

Я работаю как root, но имею uid пользователя (например, 504). Как определить локаль пользователя (в моем случае en_GB)? Не работает следующее:

setuid(user_uid);
fprintf(stderr,
        CFStringGetCStringPtr(CFLocaleGetIdentifier(CFLocaleCopyCurrent()),
                              kCFStringEncodingMacRoman);
setuid(0);

Это выводит en_US для меня.


person fredley    schedule 24.11.2011    source источник
comment
У пользователя нет локали. Только среда имеет языковой стандарт. Однако среда зависит от многих факторов и обычно настраивается серией сценариев оболочки, когда пользователь входит в систему.   -  person Kerrek SB    schedule 24.11.2011
comment
@KerrekSB Хороший вопрос. Любая идея, как начать в этой ситуации?   -  person fredley    schedule 24.11.2011
comment
@ Просканируйте каталог пользователя, просканируйте все файлы на предмет вхождений локали exports и ожидайте, что пользователь введет в свою командную строку! Эксгумация файла bash_history может дать вам статистическую информацию о прошлом поведении; например если вы видите много LC_ALL=en_AU.utf8 ./myprog, вы знаете, что пользователю могут понравиться кенгуру...   -  person Kerrek SB    schedule 24.11.2011
comment
Если это действительно так много усилий, почему setuid(0) изменяет результат CFLocaleCopyCurrent(), а setuid(user_uid) нет?   -  person fredley    schedule 24.11.2011
comment
Как setuid(0) меняет его? Обычно, когда вы получаете повышенные привилегии, ОС должна сбросить или очистить всю среду, чтобы непривилегированные пользователи не могли ничего вводить в привилегированный контекст. Я предполагаю, что это установит локаль на C или что-то в этом роде.   -  person Kerrek SB    schedule 24.11.2011
comment
@KerrekSB Он меняет его на en_US, я не знаю, почему. Mac моего коллеги меняет его на en_GB, что кажется странным.   -  person fredley    schedule 24.11.2011
comment
Хм, MacOSX может иметь некоторые дополнительные нестандартные функции, которые отслеживают своего рода системную локаль по умолчанию. В таком случае я бы не знал; нам придется подождать некоторых Macsperts.   -  person Kerrek SB    schedule 24.11.2011


Ответы (2)


Эта информация содержится в GlobalPreferences.plist, поэтому выполняется:

$ defaults read /Library/Preferences/.GlobalPreferences AppleLocale

дает желаемый результат.

person fredley    schedule 29.11.2011

Вы не можете, потому что его не существует. Локаль управляется переменными среды и может меняться динамически, от окна к окну и даже от приложения к приложению (т.е. если пользователь запустил программу с:

env LC_LANG=fr_FR program_name ...

.) В Unix вы можете получить локаль пользователя по умолчанию, выполнив что-то вроде:

FILE* in = popen( "su -c 'env | grep ^LC_ ; env | grep ^LANG' - user", "r" );

, затем чтение и разбор ввода, но я не думаю, что есть что-то проще.

person James Kanze    schedule 24.11.2011