1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3  * License, v. 2.0. If a copy of the MPL was not distributed with this
4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 
6 #include "nspr.h"
7 #include "plgetopt.h"
8 
9 #include <stdio.h>
10 
11 #ifdef DEBUG
12 #define SEM_D "D"
13 #else
14 #define SEM_D
15 #endif
16 #ifdef IS_64
17 #define SEM_64 "64"
18 #else
19 #define SEM_64
20 #endif
21 
22 #define NO_SUCH_SEM_NAME "/tmp/nosuchsem.sem" SEM_D SEM_64
23 #define SEM_NAME1 "/tmp/foo.sem" SEM_D SEM_64
24 #define EXE_NAME "semaerr1"
25 #define SEM_MODE  0666
26 
27 static PRBool debug_mode = PR_FALSE;
28 
Help(void)29 static void Help(void)
30 {
31     fprintf(stderr, "semaerr test program usage:\n");
32     fprintf(stderr, "\t-d           debug mode         (FALSE)\n");
33     fprintf(stderr, "\t-h           this message\n");
34 }  /* Help */
35 
main(int argc,char ** argv)36 int main(int argc, char **argv)
37 {
38     PLOptStatus os;
39     PLOptState *opt = PL_CreateOptState(argc, argv, "dh");
40     PRSem *sem;
41     char *child_argv[32];
42     char **child_arg;
43     PRProcess *proc;
44     PRInt32 exit_code;
45 
46     while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) {
47         if (PL_OPT_BAD == os) {
48             continue;
49         }
50         switch (opt->option) {
51             case 'd':  /* debug mode */
52                 debug_mode = PR_TRUE;
53                 break;
54             case 'h':
55             default:
56                 Help();
57                 return 2;
58         }
59     }
60     PL_DestroyOptState(opt);
61 
62     /*
63      * Open a nonexistent semaphore without the PR_SEM_CREATE
64      * flag should fail with PR_FILE_NOT_FOUND_ERROR.
65      */
66     (void) PR_DeleteSemaphore(NO_SUCH_SEM_NAME);
67     sem = PR_OpenSemaphore(NO_SUCH_SEM_NAME, 0, 0, 0);
68     if (NULL != sem) {
69         fprintf(stderr, "Opening nonexistent semaphore %s "
70                 "without the PR_SEM_CREATE flag should fail "
71                 "but succeeded\n", NO_SUCH_SEM_NAME);
72         exit(1);
73     }
74     if (PR_GetError() != PR_FILE_NOT_FOUND_ERROR) {
75         fprintf(stderr, "Expected error is %ld (PR_FILE_NOT_FOUND_ERROR) but got (%d, %d)\n",
76                 PR_FILE_NOT_FOUND_ERROR, PR_GetError(), PR_GetOSError());
77         exit(1);
78     }
79 
80     /*
81      * Create a semaphore and let the another process
82      * try PR_SEM_CREATE and PR_SEM_CREATE|PR_SEM_EXCL.
83      */
84     if (PR_DeleteSemaphore(SEM_NAME1) == PR_SUCCESS) {
85         fprintf(stderr, "warning: deleted semaphore %s from previous "
86                 "run of the test\n", SEM_NAME1);
87     }
88     sem = PR_OpenSemaphore(SEM_NAME1, PR_SEM_CREATE, SEM_MODE, 0);
89     if (sem == NULL) {
90         fprintf(stderr, "PR_OpenSemaphore failed (%d, %d)\n",
91                 PR_GetError(), PR_GetOSError());
92         exit(1);
93     }
94     child_arg = child_argv;
95     *child_arg++ = EXE_NAME;
96     if (debug_mode) {
97         *child_arg++ = "-d";
98     }
99     *child_arg = NULL;
100     proc = PR_CreateProcess(child_argv[0], child_argv, NULL, NULL);
101     if (proc == NULL) {
102         fprintf(stderr, "PR_CreateProcess failed\n");
103         exit(1);
104     }
105     if (PR_WaitProcess(proc, &exit_code) == PR_FAILURE) {
106         fprintf(stderr, "PR_WaitProcess failed\n");
107         exit(1);
108     }
109     if (exit_code != 0) {
110         fprintf(stderr, "process semaerr1 failed\n");
111         exit(1);
112     }
113     if (PR_CloseSemaphore(sem) == PR_FAILURE) {
114         fprintf(stderr, "PR_CloseSemaphore failed\n");
115         exit(1);
116     }
117     if (PR_DeleteSemaphore(SEM_NAME1) == PR_FAILURE) {
118         fprintf(stderr, "PR_DeleteSemaphore failed\n");
119         exit(1);
120     }
121 
122     printf("PASS\n");
123     return 0;
124 }
125