File: main.c

package info (click to toggle)
libexplain 0.52.D002-1
  • links: PTS
  • area: main
  • in suites: wheezy
  • size: 34,656 kB
  • sloc: ansic: 138,224; makefile: 36,642; sh: 15,448; yacc: 1,442; awk: 246
file content (214 lines) | stat: -rw-r--r-- 4,973 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
/*
 * libexplain - Explain errno values returned by libc functions
 * Copyright (C) 2011 Peter Miller
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation; either version 3 of the License, or (at your
 * option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program. If not, see <http://www.gnu.org/licenses/>.
 */

#include <libexplain/ac/errno.h>
#include <libexplain/ac/stdio.h>
#include <libexplain/ac/stdlib.h>
#include <libexplain/ac/unistd.h>
#include <libexplain/ac/sys/shm.h>

#include <libexplain/buffer/shmctl_command.h>
#include <libexplain/buffer/shmid_ds.h>
#include <libexplain/buffer/shm_info.h>
#include <libexplain/buffer/shminfo.h>
#include <libexplain/output.h>
#include <libexplain/shmctl.h>
#include <libexplain/string_buffer.h>
#include <libexplain/string_to_thing.h>
#include <libexplain/version_print.h>
#include <libexplain/wrap_and_print.h>


static void
usage(void)
{
    fprintf(stderr, "Usage: test_shmctl <shmid> <command> <data>\n");
    fprintf(stderr, "       test_shmctl -V\n");
    exit(EXIT_FAILURE);
}


static void
print_shm_info(const struct shm_info *data)
{
    char            result[2000];
    explain_string_buffer_t result_sb;

    explain_string_buffer_init(&result_sb, result, sizeof(result));
    explain_buffer_shm_info(&result_sb, data);
    explain_wrap_and_print(stdout, result);
}


static void
print_shminfo(const struct shminfo *data)
{
    char            result[2000];
    explain_string_buffer_t result_sb;

    explain_string_buffer_init(&result_sb, result, sizeof(result));
    explain_buffer_shminfo(&result_sb, data);
    explain_wrap_and_print(stdout, result);
}


static void
print_shmid_ds(int shmid, const struct shmid_ds *data)
{
    char            result[2000];
    explain_string_buffer_t result_sb;

    explain_string_buffer_init(&result_sb, result, sizeof(result));
    if (shmid >= 0)
        explain_string_buffer_printf(&result_sb, "shmid = %d, ", shmid);
    explain_buffer_shmid_ds(&result_sb, data, 1);
    explain_wrap_and_print(stdout, result);
}


static void
list(void)
{
    struct shminfo  shminfo;
    struct shm_info shm_info;
    int             maxid;
    int             id;

    maxid = explain_shmctl_or_die(0, SHM_INFO, (void *)&shm_info);
    print_shm_info(&shm_info);
    explain_shmctl_or_die(0, IPC_INFO, (void *)&shminfo);
    print_shminfo(&shminfo);
    for (id = 0; id < maxid; ++id)
    {
        int             shmid;
        struct shmid_ds shmseg;

        shmid = shmctl(id, SHM_STAT, &shmseg);
        if (shmid < 0)
        {
            if (errno != EINVAL && errno != EIDRM)
            {
                explain_output_error_and_die
                (
                    "%s",
                    explain_shmctl(id, SHM_STAT, &shmseg)
                );
            }
            continue;
        }
        print_shmid_ds(shmid, &shmseg);
    }
}


int
main(int argc, char **argv)
{
    int             shmid;
    int             command;
    struct shmid_ds *data;

    union dummy_t
    {
        int u0;
#ifdef HAVE_SYS_SHM_H
        struct shmid_ds u1;
#endif
#ifdef SHM_INFO
        struct shm_info u2;
#endif
#ifdef IPC_INFO
        struct shminfo u3;
#endif

    };

    union dummy_t   dummy;

    data = (void *)&dummy;
    for (;;)
    {
        int c = getopt(argc, argv, "lV");
        if (c == EOF)
            break;
        switch (c)
        {
        case 'l':
            /* list everything */
            list();
            return 0;

        case 'V':
            explain_version_print();
            return EXIT_SUCCESS;

        default:
            usage();
        }
    }
    switch (argc - optind)
    {
    default:
        usage();

    case 3:
        data = explain_string_to_pointer(argv[optind + 2]);
    case 2:
        command =
            explain_parse_shmctl_command_or_die(argv[optind + 1], "arg 1");
        shmid = explain_string_to_int(argv[optind]);
        break;
    }

    explain_shmctl_or_die(shmid, command, data);

    if (data == (void *)&dummy)
    {
        switch (command)
        {
#ifdef IPC_STAT
        case IPC_STAT:
#endif
#ifdef SHM_STAT
        case SHM_STAT:
#endif
            print_shmid_ds(-1, data);
            break;

#ifdef IPC_INFO
        case IPC_INFO:
            print_shminfo((void *)data);
            break;
#endif

#ifdef SHM_INFO
        case SHM_INFO:
            print_shm_info((void *)data);
            break;
#endif

        default:
            break;
        }
    }

    return EXIT_SUCCESS;
}


/* vim: set ts=8 sw=4 et */