A explicação em
http://man7.org/linux/man-pages/man2/open.2.html
sobre por que openat
é necessário, lê-se em parte:
openat() allows an application to avoid race conditions that
could occur when using open() to open files in directories other than
the current working directory. These race conditions result from the
fact that some component of the directory prefix given to open()
could be changed in parallel with the call to open(). Suppose, for
example, that we wish to create the file path/to/xxx.dep if the file
path/to/xxx exists. The problem is that between the existence check
and the file creation step, path or to (which might be symbolic
links) could be modified to point to a different location.
Não entendo por que essa corrida é um problema. Se um aplicativo quiser verificar a existência de algum arquivo e, em caso afirmativo, crie umdiferentearquivo, então, é claro, essas são duas etapas, e o aplicativo deve e pode garantir que nada interfira entre elas. Somente se uma única chamada open()
puder causar uma condição de corrida, algum outro syscall, como o, poderá openat()
ser necessário. Caso contrário, isso não cabe aos syscalls resolver, mas é responsabilidade do aplicativo.
O que não estou entendendo aqui?
Responder1
A corrida refere-se apenas a arquivos que não estão no diretório atual. O caminho relativo que você está passando para openat() pode conter um link simbólico que aponta para um diretório diferente daquele que você espera.
Se você usar open() apenas com arquivos no diretório atual (depois de ter certeza de que está onde deseja), você evitará esse problema.