1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "common/napi_helper.cpp"
17 #include "common/native_common.h"
18 #include "napi/native_api.h"
19 #include <sys/sem.h>
20 
21 #define PARAM_0 0
22 #define PARAM_1 1
23 #define ONEVAL 1
24 #define MINUSONE (-1)
25 #define TEST_MODE 0666
26 #define PARAM_EACCES 13
27 
Semop(napi_env env, napi_callback_info info)28 static napi_value Semop(napi_env env, napi_callback_info info)
29 {
30     static const char path[] = ".";
31     static const int id = 's';
32     struct sembuf sops = {PARAM_0};
33     key_t k = ftok(path, id);
34     sops.sem_num = PARAM_0;
35     sops.sem_op = MINUSONE;
36     sops.sem_flg = PARAM_0;
37     int semid = semget(k, PARAM_0, PARAM_0);
38     int semval = semop(semid, &sops, ONEVAL);
39     napi_value result = nullptr;
40     napi_create_int32(env, semval, &result);
41     return result;
42 }
Semtimedop(napi_env env, napi_callback_info info)43 static napi_value Semtimedop(napi_env env, napi_callback_info info)
44 {
45     static const char path[] = ".";
46     static const int id = 's';
47     struct sembuf sops = {PARAM_0};
48     key_t k = ftok(path, id);
49     sops.sem_num = PARAM_0;
50     sops.sem_op = MINUSONE;
51     sops.sem_flg = PARAM_0;
52     int semid = semget(k, PARAM_0, PARAM_0);
53     int semval = semtimedop(semid, &sops, ONEVAL, nullptr);
54     napi_value result = nullptr;
55     napi_create_int32(env, semval, &result);
56     return result;
57 }
58 
Semctl(napi_env env, napi_callback_info info)59 static napi_value Semctl(napi_env env, napi_callback_info info)
60 {
61     size_t argc = PARAM_1;
62     napi_value args[1] = {nullptr};
63     napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
64     int valueFirst;
65     napi_get_value_int32(env, args[0], &valueFirst);
66     static const char path[] = ".";
67     static const int id = 's';
68     key_t k = ftok(path, id);
69     int semid = semget(k, ONEVAL, IPC_CREAT | TEST_MODE);
70     if (valueFirst == PARAM_0) {
71         int semval = semctl(semid, PARAM_0, GETVAL);
72         if (semval == PARAM_EACCES) {
73             napi_value result;
74             napi_create_int32(env, semval, &result);
75             return result;
76         } else {
77             napi_value result;
78             napi_create_int32(env, ONEVAL, &result);
79             return result;
80         }
81     }
82     return nullptr;
83 }
84 
Semget(napi_env env, napi_callback_info info)85 static napi_value Semget(napi_env env, napi_callback_info info)
86 {
87     static const char path[] = ".";
88     static const int id = 's';
89     key_t k = ftok(path, id);
90     int semval = semget(k, ONEVAL, IPC_CREAT | TEST_MODE);
91     napi_value result;
92     napi_create_int32(env, semval, &result);
93     return result;
94 }
95 EXTERN_C_START
Init(napi_env env, napi_value exports)96 static napi_value Init(napi_env env, napi_value exports)
97 {
98     napi_property_descriptor desc[] = {
99         {"semop", nullptr, Semop, nullptr, nullptr, nullptr, napi_default, nullptr},
100         {"semtimedop", nullptr, Semtimedop, nullptr, nullptr, nullptr, napi_default, nullptr},
101         {"semctl", nullptr, Semctl, nullptr, nullptr, nullptr, napi_default, nullptr},
102         {"semget", nullptr, Semget, nullptr, nullptr, nullptr, napi_default, nullptr},
103     };
104     napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
105     return exports;
106 }
107 
108 EXTERN_C_END
109 
110 static napi_module demoModule = {
111     .nm_version = 1,
112     .nm_flags = 0,
113     .nm_filename = nullptr,
114     .nm_register_func = Init,
115     .nm_modname = "sem",
116     .nm_priv = ((void *)0),
117     .reserved = {0},
118 };
119 
RegisterEntryModule(void)120 extern "C" __attribute__((constructor)) void RegisterEntryModule(void) { napi_module_register(&demoModule); }
121