As far as I can tell, this is hard-coded into standard utilities. I straced both a touch creating a new file and a mkdir creating a new directory.
The touch trace produced this:
open("newfile", O_WRONLY|O_CREAT|O_NOCTTY|O_NONBLOCK, 0666) = 3
while the mkdir trace produced this:
mkdir("newdir", 0777)
Short of coding the file/directory creation process in C, I don't see a way of modifying the default permissions. It seems to me, though, that not making files executable by default makes sense: you don't want any random text to be accidentally misconstrued as shell commands.
Update
To give you an example of how the permission bits are hard-coded into the standard utilities. Here are some relevant lines from two files in the coreutils package that contains the source code for both
touch(1)
and mkdir(1)
, among others: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;
}
In other words, if the mode is not specified, set it to S_IRWXUGO (read:
0777
) modified by the umask_value.touch.c is even clearer:
int default_permissions =
S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
That is, give read and write permissions to everyone (read:
0666
), which will be modified by the process umask on file creation, of course.You may be able to get around this programmatically only: i.e. while creating files from within either a C program, where you make the system calls directly or from within a language that allows you to make a low-level syscall (see for example Perl's sysopen under perldoc -f sysopen).