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