0

Where is the code for the this _write() used in stdio?

A wiki page says that every syscall must be registered in a master file and in the a libc's Symbol.map, it also says that for every entry in the Symbol.map three symbols are generated: symbol, _symbol, and sys_symbol.

I found where the sysent for the write syscall, the _write symbol in the Symbol.map but I can't find the actual code for _write.

Augusto Hack
  • 2,032
  • 18
  • 35
  • If anyone is also interested on linux syscall's, lwn has some great posts about it https://lwn.net/Articles/604287/ – Augusto Hack Feb 07 '15 at 14:55

1 Answers1

0

Keep in mind that _write is a /very/ complicated syscall. Since it functions on a file handle which may be file on any type of filesystem or even a network socket, it basically forks off to places all over the kernel.

The wiki page you link to is the right place to start to understand FreeBSD syscalls. write is probably not the best syscall to use to understand them, if that's what you're trying to do.

The implementation of the write syscall (from FreeBSD 10.0-RELEASE):

/usr/src/sys/kern/sys_generic.c:358

#ifndef _SYS_SYSPROTO_H_
struct write_args {
    int fd;
    const void *buf;
    size_t  nbyte;
};
#endif
int
sys_write(td, uap)
    struct thread *td;
    struct write_args *uap;
{
    struct uio auio;
    struct iovec aiov;
    int error;

    if (uap->nbyte > IOSIZE_MAX)
        return (EINVAL);
    aiov.iov_base = (void *)(uintptr_t)uap->buf;
    aiov.iov_len = uap->nbyte;
    auio.uio_iov = &aiov;
    auio.uio_iovcnt = 1;
    auio.uio_resid = uap->nbyte;
    auio.uio_segflg = UIO_USERSPACE;
    error = kern_writev(td, uap->fd, &auio);
    return(error);
}
D'Nabre
  • 2,226
  • 16
  • 13
  • BTW, while syscalls sometimes have wrappers in libc, the raw syscall isn't inside of libc, it's in the kernel itself. – D'Nabre Dec 31 '14 at 05:03
  • Your guess is right, I'm trying to understand how the system call works. I just picked `puts` at random because I guessed IO needs a system call. I understand that on a x86 it will eventually use `int $0x80`, as defined in `libc/i386/SYS.h`, at the moment of the system call all arguments will be in the stack with `SYS_write` in a register, but I can't find where the system call is actually done, I mean, where is the code that uses the interrupt? Also, I guess the system call will eventually endup in `i386/i386/trap.c`, is that right? – Augusto Hack Dec 31 '14 at 22:51
  • On my phone, so I can't look at the src, but that sounds right. The getpid() syscall is generally the best first one to trace through the kernel. It steps into the kernel, grabs a single value, and hands it back to userspace. I/O is ugly, and I try to avoid it when I can – D'Nabre Dec 31 '14 at 23:02