LINUX.ORG.RU

tempnam, tmpnam, tmpfile, mktemp, mkstemp


0

0

Здравствуйте. Мне нужно сгенерировать временное имя файла, которое затем будет передано ассемблеру (as), как имя выходного файла. Какую из сабжевых функций лучше использовать? Как избежать возможности того, что кто-то угадает имя файла и создаст символическую ссылку с таким именем, указывающую на какие-нибудь важные файлы пользователя, запустившего программу? Правильно ли я понимаю, что в данном случае не получится использовать функции, которые возвращают FILE* или файл-дескриптор (int), решая предыдущий вопрос?

★★★

Ответ на: комментарий от execve

А как мне передать FILE* внешней программе (ассемблеру), чтобы он выводил результат (объектный код) в указанный файл?

kmeaw ★★★
() автор топика
Ответ на: комментарий от kmeaw

можно использовать сишные ф-ии из ассемблера, с этим, как правило нет проблем. + имхо лучше исползовать ф-ю, возвращающуу fd, а не FILE*, благо какая-то из tmp* ф-й это реализует(не помню какая именно, в маны лезть банально лень). если всё же упёрто хочется использовать FILE*, то передать его легко, благо это всего лишь поинтер. + есть в этом списке функций вроде бы и такая, которая генерит только имя в char*, можно использовать и её.

asgard
()
Ответ на: комментарий от asgard

Маны не рекомендуют использовать не одну из этих функций, кроме tmpfile.

Поскольку она возвращает FILE *, для получения дескриптора используем fileno:

int fd = fileno(tmpfile());

Если нужно именно имя файла, в Линуксе можно сделать так:

char linkpath[PATH_MAX];
char path[PATH_MAX];
snprintf(linkpath, PATH_MAX, "/proc/self/fd/%i", fd);
readlink(linkpath, path, PATH_MAX);

Но это не POSIX, то есть код непереносим на другие Unix-системы.

Sikon ★★★
()
Ответ на: комментарий от asgard

т.е. не изменяя ассемблер (в моё мслучае это GNU Assembler) безопасно задачу решить невозможно?

kmeaw ★★★
() автор топика
Ответ на: комментарий от kmeaw

На самом деле задача странная. Придумать имя файла, а потом отдать его ассемблеру, чтобы он его типа создал - это явный race. В чём заключается настоящая задача, в рамках решения которой ты думаешь, что тебе это надо?

Teak ★★★★★
()
Ответ на: комментарий от Teak

Задача следующая - мне не хочется заставлять пользователя запускать компилятор, ассемблер и линкер отдельно каждый раз. Это неудобно. Поэтому, если компилятору не были переданы особые ключи (не ассемблировать или не линковать), то результат компиляции (ассемблерный код) будет перенаправлен на stdin ассемблера. Мне не известно, как сделать так, чтобы ассемблер выводил результат своей работы (объектный код) на stdout и как заставить линкер (ld) принимать объектные файлы с stdin. Значит надо создавать промежуточный файл, в который будет записываться объектный код. Но для этого надо придумать имя, которое будет подставлено после ключа "-o" в параметрах ассемблера.

kmeaw ★★★
() автор топика
Ответ на: комментарий от kmeaw

Гм.

Создаешь временную директорию с помощью mkdtemp (не вполне портабельно, но в топике и *BSD есть, вроде бы), делаешь chdir в нее, далее можешь вообще не париться с безопасностью имен.

на системах без mkdtemp задача, наверное, не решается никак (если нужна 100% надежность). Разве что в начале исполнения требовать, чтобы cwd уже была директорией с 0700, принадлежащей юзеру, иначе вырубаться.

anonymous
()
Ответ на: комментарий от kmeaw

> Задача следующая - мне не хочется заставлять пользователя запускать компилятор, ассемблер и линкер отдельно каждый раз. Это неудобно.

1. Каждый раз когда что? Чем там таким у тебя пользователь занимается, что ему приходится вручную вызывать компилятор, ассемблер и линкер постоянно?

2. А почему бы пользователю не набрать команду make и не париться?

Teak ★★★★★
()
Ответ на: комментарий от Teak

Если gcc передать только имя исходника (gcc test.c), то он автоматически его откомпилирует (создаст /tmp/XXXXXXXX.s), потом отассемблирует (создаст /tmp/XXXXXXXX.o) и слинкует (создаст a.out), после чего всё подчистит за собой. Это удобно при компиляции небольших программ, состоящих всего из одного файла, писать для которых Makefile нет смысла. Я хочу сделать похожее поведение для своего компилятора.

anonymous
()
Ответ на: комментарий от anonymous

Вопрос: программа такая-то делает так-то, я хочу, чтобы моя программа делала точно так же.

Ответ: посмотри исходники этой программы и возьми, что тебе надо, оттуда.

Teak ★★★★★
()
Ответ на: комментарий от Teak

> Придумать имя файла, а потом отдать его ассемблеру, чтобы он его типа создал - это явный race.

Не обязательно. Если сам же его атомарно создаешь open+O_EXCL, то все будет хорошо.

anonymous
()
Ответ на: комментарий от anonymous

Перечитай то, что ты отквотировал, пожалуйста. Там нет места варианту, о котором ты говоришь. as создаёт без O_EXCL. Так трудно сначала подумать, а потом демонстрировать, что ты уже прочитал man 2 open?

Teak ★★★★★
()
Ответ на: комментарий от Teak

>Так трудно сначала подумать

>as создаёт без O_EXCL

Для медленно соображающих разжевываю :) Процесс может сгенерировать любое имя. Атомарно создать - с помощью open+O_EXCL. При коллизии имен - сгенерировать новое имя. Потом предложить as в него писать. Ни в каком месте тут race нет.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.