diff options
author | qchang <qing.chang1@huawei.com> | 2018-03-08 17:39:22 -0800 |
---|---|---|
committer | qchang <qing.chang1@huawei.com> | 2018-03-08 17:39:22 -0800 |
commit | 697ade6190b23c80e7f60963983786e679759393 (patch) | |
tree | dd9782d1e936b8342163b26795e23571d4b1b415 /src/framework/common/base/liblinuxapi | |
parent | 71a4e2f34afa8018426f0e830050e50a1de6d375 (diff) |
dmm initial commit
Change-Id: I049ee277cf4efdb83f9c2ac439365fcd421c159b
Signed-off-by: qchang <qing.chang1@huawei.com>
Diffstat (limited to 'src/framework/common/base/liblinuxapi')
4 files changed, 1308 insertions, 0 deletions
diff --git a/src/framework/common/base/liblinuxapi/base_linux_api_declare.h b/src/framework/common/base/liblinuxapi/base_linux_api_declare.h new file mode 100644 index 0000000..943ae04 --- /dev/null +++ b/src/framework/common/base/liblinuxapi/base_linux_api_declare.h @@ -0,0 +1,51 @@ +/* +* +* Copyright (c) 2018 Huawei Technologies Co.,Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at: +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +BASE_MK_DECL (int, socket, (int, int, int)); +BASE_MK_DECL (int, bind, (int, const struct sockaddr *, socklen_t)); +BASE_MK_DECL (int, listen, (int, int)); +BASE_MK_DECL (int, shutdown, (int, int)); +BASE_MK_DECL (int, getsockname, (int, struct sockaddr *, socklen_t *)); +BASE_MK_DECL (int, getpeername, (int, struct sockaddr *, socklen_t *)); +BASE_MK_DECL (int, getsockopt, (int, int, int, void *, socklen_t *)); +BASE_MK_DECL (int, setsockopt, (int, int, int, const void *, socklen_t)); +BASE_MK_DECL (int, accept, (int, struct sockaddr *, socklen_t *)); +BASE_MK_DECL (int, accept4, (int, struct sockaddr *, socklen_t *, int flags)); +BASE_MK_DECL (int, connect, (int, const struct sockaddr *, socklen_t)); +BASE_MK_DECL (ssize_t, recv, (int, void *, size_t, int)); +BASE_MK_DECL (ssize_t, send, (int, const void *, size_t, int)); +BASE_MK_DECL (ssize_t, read, (int, void *, size_t)); +BASE_MK_DECL (ssize_t, write, (int, const void *, size_t)); +BASE_MK_DECL (ssize_t, writev, (int, const struct iovec *, int)); +BASE_MK_DECL (ssize_t, readv, (int, const struct iovec *, int)); +BASE_MK_DECL (ssize_t, sendto, + (int, const void *, size_t, int, const struct sockaddr *, + socklen_t)); +BASE_MK_DECL (ssize_t, recvfrom, + (int, void *, size_t, int, struct sockaddr *, socklen_t *)); +BASE_MK_DECL (ssize_t, sendmsg, (int, const struct msghdr *, int flags)); +BASE_MK_DECL (ssize_t, recvmsg, (int, struct msghdr *, int flags)); +BASE_MK_DECL (int, close, (int)); +BASE_MK_DECL (int, select, + (int, fd_set *, fd_set *, fd_set *, struct timeval *)); +BASE_MK_DECL (int, ioctl, (int, unsigned long, unsigned long)); +BASE_MK_DECL (int, fcntl, (int, int, unsigned long)); +BASE_MK_DECL (int, epoll_create, (int)); +BASE_MK_DECL (int, epoll_create1, (int)); +BASE_MK_DECL (int, epoll_ctl, (int, int, int, struct epoll_event *)); +BASE_MK_DECL (int, epoll_wait, (int, struct epoll_event *, int, int)); +BASE_MK_DECL (pid_t, fork, (void)); +#undef BASE_MK_DECL diff --git a/src/framework/common/base/liblinuxapi/nsfw_base_linux_api.c b/src/framework/common/base/liblinuxapi/nsfw_base_linux_api.c new file mode 100644 index 0000000..de98877 --- /dev/null +++ b/src/framework/common/base/liblinuxapi/nsfw_base_linux_api.c @@ -0,0 +1,628 @@ +/* +* +* Copyright (c) 2018 Huawei Technologies Co.,Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at: +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#include "nsfw_base_linux_api.h" +#include "nstack_log.h" +#include <pthread.h> +#include <stdio.h> +#include <errno.h> +#include <dlfcn.h> + +#define NSFW_BASE_OK 0 +#define NSFW_BASE_FAIL (-1) + +#define nsfw_call_ret(symbol, para){ \ + if (NSFW_BASE_OK != nsfw_posix_api_init()) \ + { \ + return NSFW_BASE_FAIL; \ + } \ + if (g_nsfw_posix_api.pf##symbol) \ + { \ + return g_nsfw_posix_api.pf##symbol para;\ + } \ + errno = ENOSYS; \ + return NSFW_BASE_FAIL; \ +} + +typedef enum +{ + BASE_STATE_INIT, + BASE_STATE_SUCCESS, + BASE_STATE_FAIL +} nsfw_base_state; + +typedef struct __base_linux_api +{ +#define BASE_MK_DECL(ret, fn, args) ret (*pf##fn) args; +#include "base_linux_api_declare.h" +} base_linux_api; + +nsfw_base_state g_nsfw_mudule_state = BASE_STATE_INIT; +pthread_mutex_t g_nsfw_init_mutex = PTHREAD_MUTEX_INITIALIZER; +base_linux_api g_nsfw_posix_api = { 0 }; + +void *g_linux_lib_handle = (void *) 0; + +int +nsfw_posix_symbol_load () +{ + g_linux_lib_handle = dlopen ("libc.so.6", RTLD_NOW | RTLD_GLOBAL); + if ((void *) 0 == g_linux_lib_handle) + { + /* optimize dlopen err print */ + NSSOC_LOGERR ("cannot dlopen libc.so.6] err_string=%s", dlerror ()); + return NSFW_BASE_FAIL; + } +#define BASE_MK_DECL(ret, fn, args) \ + g_nsfw_posix_api.pf##fn = (typeof(g_nsfw_posix_api.pf##fn))dlsym(g_linux_lib_handle, #fn); +#include <base_linux_api_declare.h> + + return NSFW_BASE_OK; +} + +/***************************************************************** +Parameters : void +Return : +Description : linux posix api init with threadonce +*****************************************************************/ +static inline int +nsfw_posix_api_init () +{ + int iret = NSFW_BASE_OK; + + /*if init already, just return success, if init fail before, just return err */ + if (BASE_STATE_INIT != g_nsfw_mudule_state) + { + return (BASE_STATE_SUCCESS == + g_nsfw_mudule_state ? NSFW_BASE_OK : NSFW_BASE_FAIL); + } + + (void) pthread_mutex_lock (&g_nsfw_init_mutex); + + /*if init already, just return success, if init fail before, just return err */ + if (BASE_STATE_INIT != g_nsfw_mudule_state) + { + (void) pthread_mutex_unlock (&g_nsfw_init_mutex); + return (BASE_STATE_SUCCESS == + g_nsfw_mudule_state ? NSFW_BASE_OK : NSFW_BASE_FAIL); + } + + iret = nsfw_posix_symbol_load (); + if (NSFW_BASE_OK == iret) + { + g_nsfw_mudule_state = BASE_STATE_SUCCESS; + } + else + { + g_nsfw_mudule_state = BASE_STATE_FAIL; + } + + (void) pthread_mutex_unlock (&g_nsfw_init_mutex); + return iret; +} +/* *INDENT-OFF* */ +/***************************************************************************** +* Prototype : nsfw_base_socket +* Description : linux socket api +* Input : int a +* int b +* int c +* Output : None +* Return Value : int +* Calls : +* Called By : + +* +*****************************************************************************/ +int nsfw_base_socket(int a, int b, int c) +{ + nsfw_call_ret(socket, (a, b, c)) +} + +/***************************************************************************** +* Prototype : nsfw_base_bind +* Description : linux fd bind api +* Input : int a +* const struct sockaddr* b +* socklen_t c +* Output : None +* Return Value : int +* Calls : +* Called By : +* +*****************************************************************************/ +int nsfw_base_bind(int a, const struct sockaddr* b, socklen_t c) +{ + nsfw_call_ret(bind, (a, b, c)) +} + +/***************************************************************************** +* Prototype : nsfw_base_listen +* Description : linux fd listen api +* Input : int a +* int b +* Output : None +* Return Value : int +* Calls : +* Called By : +* +*****************************************************************************/ +int nsfw_base_listen(int a, int b) +{ + nsfw_call_ret(listen, (a, b)) +} + +/***************************************************************************** +* Prototype : nsfw_base_shutdown +* Description : linux shutdown api +* Input : int a +* int b +* Output : None +* Return Value : int +* Calls : +* Called By : +* +* +*****************************************************************************/ +int nsfw_base_shutdown(int a, int b) +{ + nsfw_call_ret(shutdown, (a, b)) +} + +/***************************************************************************** +* Prototype : nsfw_base_getsockname +* Description : linux getsockname api +* Input : int a +* struct sockaddr* b +* socklen_t* c +* Output : None +* Return Value : int +* Calls : +* Called By : +* +*****************************************************************************/ +int nsfw_base_getsockname(int a, struct sockaddr* b, socklen_t* c) +{ + nsfw_call_ret(getsockname, (a, b, c)) +} + +/***************************************************************************** +* Prototype : nsfw_base_getpeername +* Description : linux getpername api +* Input : int a +* struct sockaddr* b +* socklen_t* c +* Output : None +* Return Value : int +* Calls : +* Called By : +* +*****************************************************************************/ +int nsfw_base_getpeername(int a, struct sockaddr* b, socklen_t* c) +{ + nsfw_call_ret(getpeername, (a, b, c)) +} + +/***************************************************************************** +* Prototype : nsfw_base_getsockopt +* Description : linux getsockopt api +* Input : int a +* int b +* int c +* void* d +* socklen_t* e +* Output : None +* Return Value : int +* Calls : +* Called By : +* +*****************************************************************************/ +int nsfw_base_getsockopt(int a, int b, int c, void* d, socklen_t* e) +{ + nsfw_call_ret(getsockopt, (a, b, c, d, e)) +} + +/***************************************************************************** +* Prototype : nsfw_base_setsockopt +* Description : linux setsockopt api +* Input : int a +* int b +* int c +* const void* d +* socklen_t e +* Output : None +* Return Value : int +* Calls : +* Called By : +*****************************************************************************/ +int nsfw_base_setsockopt(int a, int b, int c, const void* d, socklen_t e) +{ + nsfw_call_ret(setsockopt, (a, b, c, d, e)) +} + +/***************************************************************************** +* Prototype : nsfw_base_accept +* Description : linux accept api +* Input : int a +* struct sockaddr* b +* socklen_t* c +* Output : None +* Return Value : int +* Calls : +* Called By : +*****************************************************************************/ +int nsfw_base_accept(int a, struct sockaddr* b, socklen_t* c) +{ + nsfw_call_ret(accept, (a, b, c)) +} + +/***************************************************************************** +* Prototype : nsfw_base_accept4 +* Description : linux accept4 api +* Input : int a +* struct sockaddr* b +* socklen_t* c +* int flags +* Output : None +* Return Value : int +* Calls : +* Called By : +*****************************************************************************/ +int nsfw_base_accept4(int a, struct sockaddr* b, socklen_t* c, int flags) +{ + nsfw_call_ret(accept4, (a, b, c, flags)) +} + +/***************************************************************************** +* Prototype : nsfw_base_connect +* Description : linux connect api +* Input : int a +* const struct sockaddr* b +* socklen_t c +* Output : None +* Return Value : int +* Calls : +* Called By : +* +*****************************************************************************/ +int nsfw_base_connect(int a, const struct sockaddr* b, socklen_t c) +{ + nsfw_call_ret(connect, (a, b, c)) +} + +/***************************************************************************** +* Prototype : nsfw_base_recv +* Description : linux recv api +* Input : int a +* void* b +* size_t c +* int d +* Output : None +* Return Value : ssize_t +* Calls : +* Called By : +* +*****************************************************************************/ +ssize_t nsfw_base_recv(int a, void* b, size_t c, int d) +{ + nsfw_call_ret(recv, (a, b, c, d)) +} + +/***************************************************************************** +* Prototype : nsfw_base_send +* Description : linux send api +* Input : int a +* const void* b +* size_t c +* int d +* Output : None +* Return Value : ssize_t +* Calls : +* Called By : +* +*****************************************************************************/ +ssize_t nsfw_base_send(int a, const void* b, size_t c, int d) +{ + nsfw_call_ret(send, (a, b, c, d)) +} + +/***************************************************************************** +* Prototype : nsfw_base_read +* Description : linux read api +* Input : int a +* void* b +* size_t c +* Output : None +* Return Value : ssize_t +* Calls : +* Called By : +* +*****************************************************************************/ +ssize_t nsfw_base_read(int a, void* b, size_t c) +{ + nsfw_call_ret(read, (a, b, c)) +} + +/***************************************************************************** +* Prototype : nsfw_base_write +* Description : linux write api +* Input : int a +* const void* b +* size_t c +* Output : None +* Return Value : ssize_t +* Calls : +* Called By : +* +*****************************************************************************/ +ssize_t nsfw_base_write(int a, const void* b, size_t c) +{ + nsfw_call_ret(write, (a, b, c)) +} + +/***************************************************************************** +* Prototype : nsfw_base_writev +* Description : linux writev api +* Input : int a +* const struct iovec * b +* int c +* Output : None +* Return Value : ssize_t +* Calls : +* Called By : +*****************************************************************************/ +ssize_t nsfw_base_writev(int a, const struct iovec * b, int c) +{ + nsfw_call_ret(writev, (a, b, c)) +} + +/***************************************************************************** +* Prototype : nsfw_base_readv +* Description : linux readv api +* Input : int a +* const struct iovec * b +* int c +* Output : None +* Return Value : ssize_t +* Calls : +* Called By : +* +*****************************************************************************/ +ssize_t nsfw_base_readv(int a, const struct iovec * b, int c) +{ + nsfw_call_ret(readv, (a, b, c)) +} + +/***************************************************************************** +* Prototype : nsfw_base_sendto +* Description : linux sendto api +* Input : int a +* const void * b +* size_t c +* int d +* const struct sockaddr *e +* socklen_t f +* Output : None +* Return Value : ssize_t +* Calls : +* Called By : +*****************************************************************************/ +ssize_t nsfw_base_sendto(int a, const void * b, size_t c, int d, const struct sockaddr *e, socklen_t f) +{ + nsfw_call_ret(sendto, (a, b, c, d, e, f)) +} + +/***************************************************************************** +* Prototype : nsfw_base_recvfrom +* Description : linux recvfrom api +* Input : int a +* void *b +* size_t c +* int d +* struct sockaddr *e +* socklen_t *f +* Output : None +* Return Value : ssize_t +* Calls : +* Called By : +*****************************************************************************/ +ssize_t nsfw_base_recvfrom(int a, void *b, size_t c, int d,struct sockaddr *e, socklen_t *f) +{ + nsfw_call_ret(recvfrom, (a, b, c, d, e, f)) +} + +/***************************************************************************** +* Prototype : nsfw_base_sendmsg +* Description : linux sendmsg api +* Input : int a +* const struct msghdr *b +* int flags +* Output : None +* Return Value : ssize_t +* Calls : +* Called By : +* +*****************************************************************************/ +ssize_t nsfw_base_sendmsg(int a, const struct msghdr *b, int flags) +{ + nsfw_call_ret(sendmsg, (a, b, flags)) +} + +/***************************************************************************** +* Prototype : nsfw_base_recvmsg +* Description : linux recvmsg api +* Input : int a +* struct msghdr *b +* int flags +* Output : None +* Return Value : ssize_t +* Calls : +* Called By : +* +*****************************************************************************/ +ssize_t nsfw_base_recvmsg(int a, struct msghdr *b, int flags) +{ + nsfw_call_ret(recvmsg, (a, b, flags)) +} + +/***************************************************************************** +* Prototype : nsfw_base_close +* Description : linux close api +* Input : int a +* Output : None +* Return Value : int +* Calls : +* Called By : +* +*****************************************************************************/ +int nsfw_base_close(int a) +{ + nsfw_call_ret(close, (a)) +} + +/***************************************************************************** +* Prototype : nsfw_base_select +* Description : linux select api +* Input : int a +* fd_set *b +* fd_set *c +* fd_set *d +* struct timeval *e +* Output : None +* Return Value : int +* Calls : +* Called By : +*****************************************************************************/ +int nsfw_base_select(int a, fd_set *b, fd_set *c, fd_set *d, struct timeval *e) +{ + nsfw_call_ret(select, (a, b, c, d, e)) +} + +/***************************************************************************** +* Prototype : nsfw_base_ioctl +* Description : linux ioctl api +* Input : int a +* unsigned long b +* unsigned long c +* Output : None +* Return Value : int +* Calls : +* Called By : +* +*****************************************************************************/ +int nsfw_base_ioctl(int a, unsigned long b, unsigned long c) +{ + nsfw_call_ret(ioctl, (a, b, c)) +} + +/***************************************************************************** +* Prototype : nsfw_base_fcntl +* Description : linux fcntl api +* Input : int a +* int b +* unsigned long c +* Output : None +* Return Value : int +* Calls : +* Called By : +* +*****************************************************************************/ +int nsfw_base_fcntl(int a, int b, unsigned long c) +{ + nsfw_call_ret(fcntl, (a, b, c)) +} + +/***************************************************************************** +* Prototype : nsfw_base_epoll_create +* Description : linux epoll_create api +* Input : int a +* Output : None +* Return Value : int +* Calls : +* Called By : +* +*****************************************************************************/ +int nsfw_base_epoll_create(int a) +{ + nsfw_call_ret(epoll_create, (a)) +} + +/***************************************************************************** +* Prototype : nsfw_base_epoll_create1 +* Description : linux epoll_create1 api +* Input : int a +* Output : None +* Return Value : int +* Calls : +* Called By : +* +*****************************************************************************/ +int nsfw_base_epoll_create1(int a) +{ + nsfw_call_ret(epoll_create1, (a)) +} + +/***************************************************************************** +* Prototype : nsfw_base_epoll_ctl +* Description : linux epoll_ctl api +* Input : int a +* int b +* int c +* struct epoll_event *d +* Output : None +* Return Value : int +* Calls : +* Called By : +* +*****************************************************************************/ +int nsfw_base_epoll_ctl(int a, int b, int c, struct epoll_event *d) +{ + nsfw_call_ret(epoll_ctl, (a, b, c, d)) +} + +/***************************************************************************** +* Prototype : nsfw_base_epoll_wait +* Description : linux epoll_wait api +* Input : int a +* struct epoll_event *b +* int c +* int d +* Output : None +* Return Value : int +* Calls : +* Called By : +* +*****************************************************************************/ +int nsfw_base_epoll_wait(int a, struct epoll_event *b, int c, int d) +{ + nsfw_call_ret(epoll_wait, (a, b, c, d)) +} + +/***************************************************************************** +* Prototype : nsfw_base_fork +* Description : linux fork api +* Input : void +* Output : None +* Return Value : pid_t +* Calls : +* Called By : +* +*****************************************************************************/ +pid_t nsfw_base_fork(void) +{ + nsfw_call_ret(fork, ()) +} +/* *INDENT-ON* */ diff --git a/src/framework/common/base/liblinuxapi/nsfw_getopt.c b/src/framework/common/base/liblinuxapi/nsfw_getopt.c new file mode 100644 index 0000000..ac7d6bf --- /dev/null +++ b/src/framework/common/base/liblinuxapi/nsfw_getopt.c @@ -0,0 +1,455 @@ +/* +* +* Copyright (c) 2018 Huawei Technologies Co.,Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at: +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#include <stdio.h> +#include <stdarg.h> +#include <stdlib.h> +#include <string.h> +#include "nsfw_getopt.h" +#include "nstack_log.h" + +char *nsfw_optarg = NULL; +int nsfw_optind = 1; +int nsfw_opterr = 1; +int nsfw_optopt = '?'; +NSTACK_STATIC char *nsfw_optnext = NULL; +NSTACK_STATIC int posixly_correct = -1; +NSTACK_STATIC int handle_nonopt_argv = 0; +NSTACK_STATIC int start = 0; +NSTACK_STATIC int end = 0; + +NSTACK_STATIC void check_gnu_extension (const char *optstring); +NSTACK_STATIC int nsfw_getopt_internal (int argc, char *const argv[], + const char *optstring, + const struct option *longopts, + int *longindex, int long_only); +NSTACK_STATIC int nsfw_getopt_shortopts (int argc, char *const argv[], + const char *optstring, + int long_only); +NSTACK_STATIC int nsfw_getopt_longopts (int argc, char *const argv[], + char *arg, const char *optstring, + const struct option *longopts, + int *longindex, int *long_only_flag); +NSTACK_STATIC inline int nsfw_getopt_internal_check_opts (const char + *optstring); +NSTACK_STATIC inline int nsfw_getopt_check_optind (); +NSTACK_STATIC inline int nsfw_getopt_internal_init (char *const argv[]); +NSTACK_STATIC inline int nsfw_getopt_longopts_check_longonly (int + *long_only_flag, + const char + *optstring, + char *const + argv[]); + +NSTACK_STATIC void +check_gnu_extension (const char *optstring) +{ + if (optstring[0] == '+' || getenv ("POSIXLY_CORRECT") != NULL) + { + posixly_correct = 1; + } + else + { + posixly_correct = 0; + } + if (optstring[0] == '-') + { + handle_nonopt_argv = 1; + } + else + { + handle_nonopt_argv = 0; + } +} + +int +nsfw_getopt_long (int argc, char *const argv[], const char *optstring, + const struct option *longopts, int *longindex) +{ + return nsfw_getopt_internal (argc, argv, optstring, longopts, longindex, 0); +} + +NSTACK_STATIC inline int +nsfw_getopt_internal_check_opts (const char *optstring) +{ + if (NULL == optstring) + { + return -1; + } + + if (nsfw_optopt == '?') + { + nsfw_optopt = 0; + } + + if (posixly_correct == -1) + { + check_gnu_extension (optstring); + } + + if (nsfw_optind == 0) + { + check_gnu_extension (optstring); + nsfw_optind = 1; + nsfw_optnext = NULL; + } + + switch (optstring[0]) + { + case '+': + case '-': + optstring++; + break; + default: + break; + } + return 0; +} + +NSTACK_STATIC inline int +nsfw_getopt_check_optind () +{ + if (nsfw_optind <= 0) + nsfw_optind = 1; + return 0; +} + +NSTACK_STATIC inline int +nsfw_getopt_internal_init (char *const argv[]) +{ + if (nsfw_optnext == NULL && start != 0) + { + int last_pos = nsfw_optind - 1; + + nsfw_optind -= end - start; + (void) nsfw_getopt_check_optind (); + + while (start < end--) + { + int i; + char *arg = argv[end]; + + for (i = end; i < last_pos; i++) + { + int j = i + 1; + ((char **) argv)[i] = argv[j]; + } + ((char const **) argv)[i] = arg; + last_pos--; + } + start = 0; + } + return 0; +} + +NSTACK_STATIC int +nsfw_getopt_internal (int argc, char *const argv[], const char *optstring, + const struct option *longopts, int *longindex, + int long_only) +{ + + (void) nsfw_getopt_internal_check_opts (optstring); + + (void) nsfw_getopt_internal_init (argv); + + if (nsfw_optind >= argc) + { + nsfw_optarg = NULL; + return -1; + } + if (nsfw_optnext == NULL) + { + const char *arg = argv[nsfw_optind]; + if (*arg != '-') + { + if (handle_nonopt_argv) + { + nsfw_optarg = argv[nsfw_optind++]; + start = 0; + return 1; + } + else if (posixly_correct) + { + nsfw_optarg = NULL; + return -1; + } + else + { + int i; + + start = nsfw_optind; + for (i = nsfw_optind + 1; i < argc; i++) + { + if (argv[i][0] == '-') + { + end = i; + break; + } + } + if (i == argc) + { + nsfw_optarg = NULL; + return -1; + } + nsfw_optind = i; + arg = argv[nsfw_optind]; + } + } + if (strcmp (arg, "--") == 0) + { + nsfw_optind++; + return -1; + } + if (longopts != NULL && arg[1] == '-') + { + return nsfw_getopt_longopts (argc, argv, argv[nsfw_optind] + 2, + optstring, longopts, longindex, NULL); + } + } + + if (nsfw_optnext == NULL) + { + nsfw_optnext = argv[nsfw_optind] + 1; + } + if (long_only) + { + int long_only_flag = 0; + int rv = + nsfw_getopt_longopts (argc, argv, nsfw_optnext, optstring, longopts, + longindex, &long_only_flag); + if (!long_only_flag) + { + nsfw_optnext = NULL; + return rv; + } + } + + return nsfw_getopt_shortopts (argc, argv, optstring, long_only); +} + +NSTACK_STATIC int +nsfw_getopt_shortopts (int argc, char *const argv[], const char *optstring, + int long_only) +{ + int opt = *nsfw_optnext; + const char *os; + if (optstring != NULL) + { + os = strchr (optstring, opt); + } + else + { + /* here try to keep same with below behavior */ + return '?'; + } + + if (os == NULL) + { + nsfw_optarg = NULL; + if (long_only) + { + if (':' != optstring[0]) + { + NSFW_LOGERR ("unrecognized option] argv_0=%s, netopt=%s", + argv[0], nsfw_optnext); + } + nsfw_optind++; + nsfw_optnext = NULL; + } + else + { + nsfw_optopt = opt; + if (':' != optstring[0]) + { + NSFW_LOGERR ("invalid option] argv_0=%s, opt=%c", argv[0], opt); + } + if (*(++nsfw_optnext) == 0) + { + nsfw_optind++; + nsfw_optnext = NULL; + } + } + return '?'; + } + if (os[1] == ':') + { + if (nsfw_optnext[1] == 0) + { + nsfw_optind++; + if (os[2] == ':') + { + nsfw_optarg = NULL; + } + else + { + if (nsfw_optind == argc) + { + nsfw_optarg = NULL; + nsfw_optopt = opt; + if (':' != optstring[0]) + { + NSFW_LOGERR + ("option requires an argument] argv_0=%s, opt=%c", + argv[0], opt); + } + return optstring[0] == ':' ? ':' : '?'; + } + nsfw_optarg = argv[nsfw_optind]; + nsfw_optind++; + } + } + else + { + nsfw_optarg = nsfw_optnext + 1; + nsfw_optind++; + } + nsfw_optnext = NULL; + } + else + { + nsfw_optarg = NULL; + if (nsfw_optnext[1] == 0) + { + nsfw_optnext = NULL; + nsfw_optind++; + } + else + { + nsfw_optnext++; + } + } + return opt; +} + +NSTACK_STATIC inline int +nsfw_getopt_longopts_check_longonly (int *long_only_flag, + const char *optstring, + char *const argv[]) +{ + if (long_only_flag) + { + *long_only_flag = 1; + } + else + { + if (':' != optstring[0]) + { + NSFW_LOGERR ("unrecognized option] argv_0=%s, option=%s", argv[0], + argv[nsfw_optind]); + } + nsfw_optind++; + } + return 0; +} + +NSTACK_STATIC int +nsfw_getopt_longopts (int argc, char *const argv[], char *arg, + const char *optstring, const struct option *longopts, + int *longindex, int *long_only_flag) +{ + char *val = NULL; + const struct option *opt; + size_t namelen; + int idx; + + if ((longopts == NULL) || (arg == NULL)) + { + return -1; + } + + for (idx = 0; longopts[idx].name != NULL; idx++) + { + opt = &longopts[idx]; + namelen = strlen (opt->name); + + if (strncmp (arg, opt->name, namelen) == 0) + { + switch (arg[namelen]) + { + case '\0': + switch (opt->has_arg) + { + case nsfw_required_argument: + nsfw_optind++; + + if (nsfw_optind == argc) + { + nsfw_optarg = NULL; + nsfw_optopt = opt->val; + if (':' != optstring[0]) + { + NSFW_LOGERR + ("requires an argument] argv_0=%s, opt name=%s", + argv[0], opt->name); + } + return optstring[0] == ':' ? ':' : '?'; + } + + val = argv[nsfw_optind]; + break; + + default: + break; + } + + goto found; + + case '=': + if (opt->has_arg == nsfw_no_argument) + { + const char *hyphens = + (argv[nsfw_optind][1] == '-') ? "--" : "-"; + nsfw_optind++; + nsfw_optarg = NULL; + nsfw_optopt = opt->val; + if (':' != optstring[0]) + { + NSFW_LOGERR + ("doesn't allow an argument] argv_0=%s, hyphens=%s, opt name=%s", + argv[0], hyphens, opt->name); + } + return '?'; + } + + val = arg + namelen + 1; + goto found; + + default: + break; + } + } + } + + (void) nsfw_getopt_longopts_check_longonly (long_only_flag, optstring, + argv); + return '?'; + +found: + nsfw_optarg = val; + nsfw_optind++; + + if (opt->flag) + { + *opt->flag = opt->val; + } + + if (longindex) + { + *longindex = idx; + } + + return opt->flag ? 0 : opt->val; +} diff --git a/src/framework/common/base/liblinuxapi/nsfw_lock_file.c b/src/framework/common/base/liblinuxapi/nsfw_lock_file.c new file mode 100644 index 0000000..0ec196f --- /dev/null +++ b/src/framework/common/base/liblinuxapi/nsfw_lock_file.c @@ -0,0 +1,174 @@ +/* +* +* Copyright (c) 2018 Huawei Technologies Co.,Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at: +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#include <stdio.h> +#include <stdlib.h> +#include <errno.h> +#include <fcntl.h> +#include <unistd.h> + +#include "types.h" +#include "nstack_securec.h" +#include "nsfw_init.h" +#include "common_mem_api.h" + +#include "nstack_log.h" +#include "nsfw_maintain_api.h" +#include "nsfw_mgr_com_api.h" + +#include "nsfw_base_linux_api.h" +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C"{ +/* *INDENT-ON* */ +#endif /* __cplusplus */ + +#define NSFW_FILE_PATH_LEN 128 +#define LOCK_FOLDER "/ip_module/" +#define LOCK_SUFFIX ".pid" + +#define read_lock(fd, offset, whence, len) nsfw_lock_reg((fd), F_SETLK, F_RDLCK, (offset), (whence), (len)) +#define readw_lock(fd, offset, whence, len) nsfw_lock_reg((fd), F_SETLKW, F_RDLCK, (offset), (whence), (len)) +#define write_lock(fd, offset, whence, len) nsfw_lock_reg((fd), F_SETLK, F_WRLCK, (offset), (whence), (len)) +#define writew_lock(fd, offset, whence, len) nsfw_lock_reg((fd), F_SETLKW, F_WRLCK, (offset), (whence), (len)) +#define un_lock(fd, offset, whence, len) nsfw_lock_reg((fd), F_SETLK, F_UNLCK, (offset), (whence), (len)) + +i32 +nsfw_lock_reg (i32 fd, i32 cmd, i32 type, off_t offset, i32 whence, off_t len) +{ + struct flock lock_file; + lock_file.l_type = type; + lock_file.l_start = offset; + lock_file.l_whence = whence; + lock_file.l_len = len; + return (fcntl (fd, cmd, &lock_file)); +} + +/***************************************************************************** +* Prototype : nsfw_proc_start_with_lock +* Description : lock file start +* Input : u8 proc_type +* Output : None +* Return Value : i32 +* Calls : +* Called By : +*****************************************************************************/ +i32 +nsfw_proc_start_with_lock (u8 proc_type) +{ + NSFW_LOGINF ("lock_file init]type=%u", proc_type); + char *module_name = nsfw_get_proc_name (proc_type); + if (NULL == module_name) + { + NSFW_LOGERR ("proc type error]proc_type=%u", proc_type); + return 0; + } + + const char *directory = NSFW_DOMAIN_DIR; + const char *home_dir = getenv ("HOME"); + + if (getuid () != 0 && home_dir != NULL) + { + directory = home_dir; + } + + int ret; + char lock_fpath[NSFW_FILE_PATH_LEN] = { 0 }; + ret = STRCPY_S (lock_fpath, NSFW_FILE_PATH_LEN, directory); + if (EOK != ret) + { + NSFW_LOGERR ("lock init STRCPY_S failed]ret=%d", ret); + return -1; + } + + ret = STRCAT_S (lock_fpath, NSFW_FILE_PATH_LEN, LOCK_FOLDER); + if (EOK != ret) + { + NSFW_LOGERR ("lock init STRCAT_S failed]ret=%d", ret); + return -1; + } + + ret = STRCAT_S (lock_fpath, NSFW_FILE_PATH_LEN, module_name); + if (EOK != ret) + { + NSFW_LOGERR ("lock init STRCAT_S failed]ret=%d", ret); + return -1; + } + + ret = STRCAT_S (lock_fpath, NSFW_FILE_PATH_LEN, LOCK_SUFFIX); + if (EOK != ret) + { + NSFW_LOGERR ("lock init STRCAT_S failed]ret=%d", ret); + return -1; + } + + i32 fd; + if ((fd = open (lock_fpath, O_RDWR | O_CREAT, 0640)) == -1) + { /* file permission no large than 0640 */ + NSFW_LOGERR ("open lock file error!]path=%s,error = %d", lock_fpath, + errno); + return -1; + } + + int rc = nsfw_set_close_on_exec (fd); + if (rc == -1) + { + (void) nsfw_base_close (fd); + NSFW_LOGERR ("set exec err]fd=%d, errno=%d", fd, errno); + return -1; + } + + if (write_lock (fd, 0, SEEK_SET, 0) < 0) + { + (void) nsfw_base_close (fd); + NSFW_LOGERR ("get lock file error!]path=%s,error = %d", lock_fpath, + errno); + return -1; + } + + char buf[32] = { 0 }; + if (ftruncate (fd, 0) < 0) + { + (void) nsfw_base_close (fd); + NSFW_LOGERR ("ftruncate file error!]path=%s,error = %d", lock_fpath, + errno); + return -1; + } + + ret = + SNPRINTF_S (buf, sizeof (buf), sizeof (buf) - 1, "%ld", (long) getpid ()); + if (-1 == ret) + { + NSTCP_LOGERR ("SNPRINTF_S failed]ret=%d", ret); + (void) nsfw_base_close (fd); + return -1; + } + + if (write (fd, buf, strlen (buf) + 1) < 0) + { + (void) nsfw_base_close (fd); + NSFW_LOGERR ("write file error!]path=%s,error = %d", lock_fpath, errno); + return -1; + } + + return 0; +} + +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif /* __cplusplus */ |