xref: /llvm-project/libc/src/sys/socket/linux/bind.cpp (revision 13dd2fd1e0ad428331ccbb65871574f9c1e3546f)
1*13dd2fd1SMichael Jones //===-- Linux implementation of bind --------------------------------------===//
2*13dd2fd1SMichael Jones //
3*13dd2fd1SMichael Jones // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*13dd2fd1SMichael Jones // See https://llvm.org/LICENSE.txt for license information.
5*13dd2fd1SMichael Jones // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*13dd2fd1SMichael Jones //
7*13dd2fd1SMichael Jones //===----------------------------------------------------------------------===//
8*13dd2fd1SMichael Jones 
9*13dd2fd1SMichael Jones #include "src/sys/socket/bind.h"
10*13dd2fd1SMichael Jones 
11*13dd2fd1SMichael Jones #include "src/__support/OSUtil/syscall.h" // For internal syscall function.
12*13dd2fd1SMichael Jones #include "src/__support/common.h"
13*13dd2fd1SMichael Jones 
14*13dd2fd1SMichael Jones #include "src/__support/macros/config.h"
15*13dd2fd1SMichael Jones #include "src/errno/libc_errno.h"
16*13dd2fd1SMichael Jones 
17*13dd2fd1SMichael Jones #include <linux/net.h>   // For SYS_SOCKET socketcall number.
18*13dd2fd1SMichael Jones #include <sys/syscall.h> // For syscall numbers.
19*13dd2fd1SMichael Jones 
20*13dd2fd1SMichael Jones namespace LIBC_NAMESPACE_DECL {
21*13dd2fd1SMichael Jones 
22*13dd2fd1SMichael Jones LLVM_LIBC_FUNCTION(int, bind,
23*13dd2fd1SMichael Jones                    (int socket, const struct sockaddr *address,
24*13dd2fd1SMichael Jones                     socklen_t address_len)) {
25*13dd2fd1SMichael Jones #ifdef SYS_bind
26*13dd2fd1SMichael Jones   int ret =
27*13dd2fd1SMichael Jones       LIBC_NAMESPACE::syscall_impl<int>(SYS_bind, socket, address, address_len);
28*13dd2fd1SMichael Jones #elif defined(SYS_socketcall)
29*13dd2fd1SMichael Jones   unsigned long sockcall_args[3] = {static_cast<unsigned long>(socket),
30*13dd2fd1SMichael Jones                                     reinterpret_cast<unsigned long>(address),
31*13dd2fd1SMichael Jones                                     static_cast<unsigned long>(address_len)};
32*13dd2fd1SMichael Jones   int ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_socketcall, SYS_BIND,
33*13dd2fd1SMichael Jones                                               sockcall_args);
34*13dd2fd1SMichael Jones #else
35*13dd2fd1SMichael Jones #error "socket and socketcall syscalls unavailable for this platform."
36*13dd2fd1SMichael Jones #endif
37*13dd2fd1SMichael Jones   if (ret < 0) {
38*13dd2fd1SMichael Jones     libc_errno = -ret;
39*13dd2fd1SMichael Jones     return -1;
40*13dd2fd1SMichael Jones   }
41*13dd2fd1SMichael Jones   return ret;
42*13dd2fd1SMichael Jones }
43*13dd2fd1SMichael Jones 
44*13dd2fd1SMichael Jones } // namespace LIBC_NAMESPACE_DECL
45