-1

Aside from using popen() (as was discussed in this question) is this a valid way of doing it ?


Say we had a program who's name is hexdump_dup and wanted the program to output the exact output of the hexdump command.


#include <fcntl.h>
#include <unistd.h>

int main(void)
{
    int fd;

    fd = open("hexdump_dup", O_CREAT | O_TRUNC | O_WRONLY, 0755);    // (line 8)
    write(fd, "/usr/bin/hexdump $@;", 20);                           // (line 9)
    close(fd);
    return (0);
}

Also could someone briefly explain what line 8 and 9 do, and how afterwards the command gets executed ? Like when, where does it say to execute the command or what makes the command execute ?

AymenTM
  • 529
  • 2
  • 5
  • 17
  • I think this is a similar question https://stackoverflow.com/questions/5237482/how-do-i-execute-external-program-within-c-code-in-linux-with-arguments – solomonope Sep 14 '18 at 05:18
  • In the line #8, The system call used is `int open(const char *pathname, int flags, mode_t mode);` The first argument is the file name to be opened, the second argument is set of flags. In your case, you have used `O_CREAT O_TRUNC O_WRONLY`. First creates the file if the file does not exist. O_TRUNC - If the file already exists and is a regular file and the access mode allows writing (i.e., is O_RDWR or O_WRONLY) it will be truncated to length 0. If the file is a FIFO or terminal device file, the O_TRUNC flag is ignored. Otherwise, the effect of O_TRUNC is unspecified. – Gunasekar Sep 14 '18 at 05:23
  • What does this bit do `write(fd, "/usr/bin/hexdump $@;", 20);` . If I had to guess; this writes to the newly created file, the binary source code of the system's hexdump command... Please correct me if I'm wrong. And what does `$@` that do ? @Gunasekar – AymenTM Sep 14 '18 at 05:26
  • @Lion I am not sure about `$@`. The number 20 represents the number of bytes to be written. – Gunasekar Sep 14 '18 at 05:32
  • The line `write(fd, "/usr/bin/hexdump $@;", 20);` writes `"/usr/bin/hexdump $@;"` to the file given with the file descriptor `fd` up to 20 bytes. You may have noticed that the string has 20 characters too (excluding the terminating `NULL`). `$@` in the string refers to all parameters passed into a script. See https://stackoverflow.com/questions/9994295/what-does-mean-in-a-shell-script for more about it. – Motun Sep 14 '18 at 05:39
  • @Motun .... ok, I see now. So basically the executable file `ft_hexdump` is first (created if doesn't exist) truncated to 0 bytes, then we write to it the 20 byte string `"/usr/bin/hexdump"`... now hold on what does that do exactly, does it write the binary source code of the unix system's `hexdump` command ? or does it tell the program 'ft_hexdump' to go to that file ?.... and we also write to it `$@` which are the arguments passed to the program `ft_hexdump` in the command line when we ran the program. Is that correct ? – AymenTM Sep 14 '18 at 05:50
  • @Motun I still don't understand though, how does the hexdump command get run ? Like ok we wrote a string to the source file, but when is it that we run the command.. ? Right after the writing, we close the file descriptor then return.. can someone explain ? – AymenTM Sep 14 '18 at 06:00
  • `hexdump` command is not being called in any way here. You just create a file named `"hexdump_dup"` and write the string `"/usr/bin/hexdump $@;"` into it just like writing something to a text file. If you then call `./hexdump_dup` from the command line, you'd be calling the commands inside the file `"hexdump_dup"`. It's not very clear what sort of call process you want from this but my humble suggestion is that you use `popen` if you want to issue commands from a C source. – Motun Sep 14 '18 at 06:07
  • Possible duplicate of [How do I execute external program within C code in linux with arguments?](https://stackoverflow.com/questions/5237482/how-do-i-execute-external-program-within-c-code-in-linux-with-arguments) – OrdoFlammae Sep 18 '18 at 12:59

1 Answers1

0

After this

fd = open("hexdump_dup", O_CREAT | O_TRUNC | O_WRONLY, 0755);    // (line 8)
write(fd, "/usr/bin/hexdump $@;", 20);  

you need to execute hexdump_dup executable, for that you need to use either system() or exec() family function. For e.g

system("./hexdump_dup 1 2 3"); /* after creating binary file(hexdump_dup) & writing command into it, you need to run it, for that use system() or exec() */

This

fd = open("hexdump_dup", O_CREAT | O_TRUNC | O_WRONLY, 0755);

will create the hexdump_dup binary if it doesn't exist before & if exists before it will truncate its content to 0. You can refer the man page of open() , it says

 int open(const char *pathname, int flags, mode_t mode);

The argument flags must include one of the following access modes: O_RDONLY, O_WRONLY, or O_RDWR. These request opening the file read-only, write-only, or read/write, respectively.

O_CREAT If the file does not exist it will be created. The owner (user ID) of the file is set to the effective user ID of the process.

O_TRUNC If the file already exists and is a regular file and the open mode allows writing (i.e., is O_RDWR or O_WRONLY) it will be truncated to length 0. If the file is a FIFO or terminal device file, the O_TRUNC flag is ignored.

Lastly this

write(fd, "/usr/bin/hexdump $@;", 20); 

writes 20 bytes containing array of characters /usr/bin/hexdump $@; in this case into a file where fd points i.e it will put this into hexdump_dup file.

Here $@ means when you execute hexdump_dup like

./hexdump_dup 1 2 3

it will take all the parameters to be passed.

Achal
  • 11,821
  • 2
  • 15
  • 37