1/*
2 * Copyright (c) 2022 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 <errno.h>
17#include <fcntl.h>
18#include <string.h>
19#include <sys/sem.h>
20
21#include "filepath_util.h"
22
23extern int __semtimedop_time64(int, struct sembuf *, size_t, const struct timespec *);
24
25/**
26 * @tc.name      : semtimedop_0100
27 * @tc.desc      : System V semaphore operations
28 * @tc.level     : Level 0
29 */
30void semtimedop_0100(void)
31{
32    char path[PATH_MAX] = {0};
33    FILE_ABSOLUTE_PATH(STR_FILE_TXT, path);
34    int fd = open(path, O_RDWR | O_CREAT, TEST_MODE);
35    if (fd < 0) {
36        t_error("%s failed: fd = %d\n", __func__, fd);
37    }
38
39    char str[] = "hello";
40    write(fd, str, sizeof(str));
41    close(fd);
42
43    // create a semaphore
44    key_t key = ftok(path, 1);
45    int id = semget(key, 1, IPC_CREAT | 0666);
46
47    // check semaphore info
48    struct semid_ds ds;
49    memset(&ds, 0, sizeof(ds));
50
51    semctl(id, 0, IPC_STAT, &ds);
52    semctl(id, 0, GETVAL);
53
54    // increment
55    struct sembuf ops[] = {{.sem_num = 0, .sem_op = 1, .sem_flg = 0}};
56    semop(id, ops, 1);
57    semctl(id, 0, GETVAL);
58
59    // test timeouts
60    struct timespec ts = {.tv_sec = 0, .tv_nsec = 100};
61    ops[0].sem_num = 0;
62    ops[0].sem_op = 0;
63    ops[0].sem_flg = 0;
64
65    errno = 0;
66    int result = semtimedop(id, ops, sizeof(ops) / sizeof(struct sembuf), &ts);
67    if (result != -1) {
68        t_error("%s failed: result = %d\n", __func__, result);
69    }
70
71    if (errno != EAGAIN) {
72        t_error("%s failed: errno = %d\n", __func__, errno);
73    }
74
75    semctl(id, 0, GETVAL);
76
77    // decrement.
78    ops[0].sem_num = 0;
79    ops[0].sem_op = -1;
80    ops[0].sem_flg = 0;
81
82    semop(id, ops, 1);
83    semctl(id, 0, GETVAL);
84
85    // destroy the semaphore
86    semctl(id, 0, IPC_RMID);
87}
88
89/**
90 * @tc.name      : semtimedop_0200
91 * @tc.desc      : System V semaphore operations with invalid parameters
92 * @tc.level     : Level 2
93 */
94void semtimedop_0200(void)
95{
96    errno = 0;
97    int result = semtimedop(-1, NULL, -1, NULL);
98    if (result == 0) {
99        t_error("%s failed: result = %d\n", __func__, result);
100    }
101
102    if (errno == 0) {
103        t_error("%s failed: errno = %d\n", __func__, errno);
104    }
105}
106
107/**
108 * @tc.name      : semtimedop_time64_0200
109 * @tc.desc      : System V semaphore operations with invalid parameters
110 * @tc.level     : Level 2
111 */
112void semtimedop_time64_0200(void)
113{
114    errno = 0;
115    int result = __semtimedop_time64(-1, NULL, -1, NULL);
116    if (result == 0) {
117        t_error("%s failed: result = %d\n", __func__, result);
118    }
119
120    if (errno == 0) {
121        t_error("%s failed: errno = %d\n", __func__, errno);
122    }
123}
124
125int main(int argc, char *argv[])
126{
127    // semtimedop_0100();
128    // semtimedop_0200();
129    // semtimedop_time64_0200();
130
131    return t_status;
132}
133