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 <pthread.h>
17#include <stdio.h>
18#include <stdlib.h>
19#include <string.h>
20#include "test.h"
21
22const char *path = "/data/test.txt";
23
24void *child_func(void *p)
25{
26    char buf[64];
27
28    FILE *filep = fopen(path, "r+");
29    if (filep == NULL) {
30        t_error("%s fopen failed\n", __func__);
31    }
32
33    flockfile(filep);
34
35    if (fseek(filep, 0L, SEEK_SET) == -1) {
36        t_error("%s fseek failed\n", __func__);
37    }
38    int ret = fread(buf, 64, 1, filep);
39
40    int count = atoi(buf);
41    ++count;
42
43    sprintf(buf, "%d", count);
44    if (fseek(filep, 0L, SEEK_SET) == -1) {
45        t_error("%s fseek failed\n", __func__);
46    }
47    ret = fwrite(buf, strlen(buf), 1, filep);
48
49    funlockfile(filep);
50
51    fclose(filep);
52    return NULL;
53}
54
55/**
56 * @tc.name      : funlockfile_0100
57 * @tc.desc      : Mutual exclusion has been tested in the test case of flockfile, so this test case tests that threads
58 *                 cannot be mutually exclusive for the case where each thread fopens a descriptor
59 * @tc.level     : Level 0
60 */
61void funlockfile_0100(void)
62{
63    pthread_t tid[100];
64
65    for (int i = 0; i < 100; i++) {
66        if (pthread_create(tid + i, NULL, child_func, NULL) != 0) {
67            t_error("%s pthread_create failed\n", __func__);
68        }
69    }
70
71    for (int j = 0; j < 100; j++) {
72        if (pthread_join(tid[j], NULL) != 0) {
73            t_error("%s pthread_join failed\n", __func__);
74        }
75    }
76}
77
78int main(int argc, char *argv[])
79{
80    FILE *fp = fopen(path, "w+");
81    if (fp == NULL) {
82        t_error("%s fopen failed\n", __func__);
83    }
84    fclose(fp);
85
86    funlockfile_0100();
87
88    remove(path);
89    return t_status;
90}