Tanto quanto eu posso dizer, isso é embutido em utilitários padrão. Eu strace d ambos touch criando um novo arquivo e mkdir criando um novo diretório.
O touch trace produziu isso:
open("newfile", O_WRONLY|O_CREAT|O_NOCTTY|O_NONBLOCK, 0666) = 3
enquanto o mkdir trace produziu isto:
mkdir("newdir", 0777) = 0
Faltando codificar o processo de criação de arquivos / diretórios em C, não vejo uma maneira de modificar as permissões padrão. Parece-me, no entanto, que não fazer arquivos executáveis por padrão faz sentido: você não quer que nenhum texto aleatório seja acidentalmente interpretado erroneamente como comandos shell.
Atualizar
Para dar um exemplo de como os bits de permissão são codificados nos utilitários padrão. Aqui estão algumas linhas relevantes de dois arquivos no pacote coreutils que contém o código-fonte para touch(1) e mkdir(1) , entre outros:
mkdir.c :
if (specified_mode)
{
struct mode_change *change = mode_compile (specified_mode);
if (!change)
error (EXIT_FAILURE, 0, _("invalid mode %s"),
quote (specified_mode));
options.mode = mode_adjust (S_IRWXUGO, true, umask_value, change,
&options.mode_bits);
free (change);
}
else
options.mode = S_IRWXUGO & ~umask_value;
}
Em outras palavras, se o modo não for especificado, defina-o como S_IRWXUGO (leia-se: 0777) modificado pelo umask_value .
touch.c é ainda mais claro:
int default_permissions =
S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
Ou seja, conceda permissões de leitura e gravação a todos (leia-se: 0666), o que será modificado pelo processo umask na criação do arquivo, é claro.
Você pode contornar isso apenas programaticamente: ou seja, ao criar arquivos de dentro de um programa em C, onde você faz chamadas do sistema diretamente ou de dentro de um idioma que permite fazer um syscall de baixo nível (consulte exemplo sysopen de Perl sob perldoc -f sysopen ).