Quando você chama open com O_CREAT, ele espera um terceiro argumento para o modo do arquivo. O umask é então mascarado do modo que você solicita. Então, por exemplo:
umask(S_IWGRP | S_IWOTH /* == 0022 */);
fd = open(file, O_CREAT|O_WRONLY, 0777);
criaria um arquivo com sinalizadores 0777 & (~ 0022) = 0755, i.e., rwxr-xr-x, enquanto:
umask(S_IWGRP | S_IWOTH);
fd = open(file, O_CREAT|O_WRONLY, 0666);
criaria um arquivo com sinalizadores 0666 & (~ 0022) = 0644, isto é, rw-r - r--. No seu caso, porque você não forneceu um argumento de modo, a função de abertura pega dados aleatórios da pilha, então a única coisa que você sabe é que os bits mascarados com umask estarão desligados. Tente fornecer o seu modo desejado para a chamada aberta; 0777 é uma boa escolha para arquivos executáveis e 0666 é bom para arquivos não executáveis.