2

I am not sure what the filedescriptor number 3 means here? Is this descriptor some kind of pointer to the connection made to the harddrive to get the file datlog.txt? I guess so because the subroutine close() takes this integer as an argument further down in the code. Or is de descriptor pointing to a buffer in the memory where the file is stored?

 open("datalog.txt", O_RDONLY)              = 3
 read(3, "Hello World!!!!!!\n", 250)     = 18
 fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 3), ...}) = 0
 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1,   0) = 0x7f3f71a10000
 write(1, "Read Hello World!!!!!!\n", 23) = 23
 write(1, "\n", 1)                       = 1
 close(3)                                = 0
 exit_group(0)                           = ?
 +++ exited with 0 +++

1 Answer 1

4

Strace shows system calls, which on GNU/Linux are C functions. These are issued by the native C library which every executable process needs to make use of in some way. Actual C code can call them directly, or use an API wrapper function, which usually corresponds very directly to the system call itself.

This means you can decipher most sys calls by looking at the documentation for the corresponding API function, since the signatures are usually identical. For example:

open("datalog.txt", O_RDONLY)

Below is the signature for GNU C open(), from man 2 open. Section 2 of the manual is all system calls1:

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

In case you don't speak C, this takes a string path, an integer flag (in this case O_RDONLY which means, read only) and returns an integer.

That integer is a file descriptor and it is used with other low level C input/output functions, such as read(). Strace shows the value after the = for the open(), in this case, 3. Here's the signature for POSIX/GNU C read():

ssize_t read(int fd, void *buf, size_t count);

The first argument is an integer file descriptor.


1. Note the term "system call" refers ambiguously to either the real system calls from the library, or the API wrapper functions, since again, they are usually identical. Section 2 is really the latter documentation. Technically it's the GNU API, but it conforms closely to POSIX, which also has official docs -- e.g., here's open(). Not all *nix systems use the GNU C library, but they all have some equivalent and the logic above will still apply.

2
  • Ok - so one could possibly state that the API (POSIX) wrapper (user mode) calls a system-call (kernel mode). ?
    – java
    Jul 26, 2015 at 16:13
  • Not quite. They are both userland actions, but the actual system call invokes invokes the kernel. For example, if you run a debugger on C code that uses open() on GNU/Linux and try to step through it, there's almost nothing there (it ends at a line in an asm source, T_PSEUDO (SYSCALL_SYMBOL, SYSCALL_NAME, SYSCALL_NARGS)). That's the point where execution switches from user to kernel mode. The API wrappers are actually a wrapper on this, written to conform to the linux kernel API. So they are a bridge between a portable, *nix wide standard (POSIX) and a particular implementation (linux).
    – goldilocks
    Jul 26, 2015 at 16:43

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .