Ответ 1
Основываясь на ваших комментариях, вы хотите что-то по строкам этой функции:
/* return the fd or negative on error (check errno);
how is 1 if created, or 0 if opened */
int create_or_open (const char *path, int create_flags, int open_flags,
int *how) {
int fd;
create_flags |= (O_CREAT|O_EXCL);
open_flags &= ~(O_CREAT|O_EXCL);
for (;;) {
*how = 1;
fd = open(path, create_flags);
if (fd >= 0) break;
if (errno != EEXIST) break;
*how = 0;
fd = open(path, open_flags);
if (fd >= 0) break;
if (errno != ENOENT) break;
}
return fd;
}
Это решение не является доказательством пули. Могут быть случаи (возможно, символические ссылки?), Которые заставили бы его зацикливаться навсегда. Кроме того, он может работать в режиме реального времени в определенных сценариях параллелизма. Я оставлю решение таких вопросов, как упражнение. :-)
В вашем отредактированном вопросе вы ставите:
У меня есть 10 процессов, которые пытаются открыть один и тот же файл более или менее одновременно с помощью открытого (O_CREAT) вызова, а затем удалить его.
Хак-иш, но более пуленепробиваемым решением было бы дать каждому процессу другой идентификатор пользователя. Затем просто используйте обычный open(path, O_CREAT|...)
вызов. Затем вы можете запросить файл с помощью fstat()
в файловом дескрипторе и проверить поле st_uid
структуры stat
. Если поле равно идентификатору пользователя процессов, то это был создатель. В противном случае это был нож. Это работает, так как каждый процесс удаляет файл после открытия.