What do you recommend me to do? to change this to execve approach?
The alternatives of system()
vs. execve()
are choices for how to run another process. The latter would be combined with fork()
. Given that you must use one of these, it is apparent that you are supposed to use an external command to perform the I/O to the eventual destination. An essential question to answer, then, is which external command to use.
As you have discovered, there are limits to the size of a shell command, and if you pursued a direct conversion to using execve()
instead of system()
then you would likely discover that there are corresponding limits at that level. Therefore, your basic approach of passing the data to be printed as an argument to the command is not viable if the possible size of the data is not suitably bounded. Thus a second, related, essential question is how the data to write are to be conveyed to the external command.
Allow me to suggest using the cat
command in place of printf
. With no arguments, cat
simply copies its standard input to its standard output. This solves the problem of providing the data to write to the file: you will arrange for cat
to read it from its standard input. To arrange for the data to go to the destination file, you will need to connect cat
's standard output to that file.
As far as the standard input goes, it looks like you would want to establish a pipe()
between the main process and its fork()
ed child, and to dup2()
the read end of that pipe onto the child's standard input. The child would close the write end of the pipe (important), and the parent would close the read end.
The clean way to handle the output would be for the child to open()
the destination file, and to dup2()
its file descriptor on to its standard output.
Having performed those redirections, the child would then execve()
/usr/bin/cat
with no arguments, and the parent would write()
or fwrite()
the data to the write end of the pipe, then close()
the pipe and wait()
s for the child to finish.