1 /* 2 * Copyright (c) 2016 Proofpoint, Inc. and its suppliers. 3 * All rights reserved. 4 * 5 * By using this file, you agree to the terms and conditions set 6 * forth in the LICENSE file which can be found at the top level of 7 * the sendmail distribution. 8 */ 9 10 #include <sm/gen.h> 11 12 #include <stdio.h> 13 14 #if _FFR_DMTRIGGER || _FFR_NOTIFY 15 # include <stdlib.h> 16 # include <unistd.h> 17 # include <errno.h> 18 # include <sm/heap.h> 19 # include <sm/string.h> 20 # include <sm/test.h> 21 # include <sm/notify.h> 22 # include <sm/conf.h> 23 24 /* 25 ** NOTIFY_WR -- test of notify feature 26 ** 27 ** Parameters: 28 ** pid -- pid of process 29 ** 30 ** Returns: 31 ** 0 on success 32 ** < 0 on failure 33 */ 34 35 static int 36 notify_wr(pid) 37 pid_t pid; 38 { 39 int r; 40 size_t len; 41 char buf[64]; 42 #define TSTSTR "qf0001" 43 44 r = sm_notify_start(false, 0); 45 if (r < 0) 46 { 47 perror("sm_notify_start failed"); 48 return -1; 49 } 50 51 len = sm_snprintf(buf, sizeof(buf), "%s-%ld", TSTSTR, (long) pid); 52 r = sm_notify_snd(buf, len); 53 SM_TEST(r >= 0); 54 return r; 55 } 56 57 /* 58 ** NOTIFY_RD -- test of notify feature 59 ** 60 ** Parameters: 61 ** 62 ** Returns: 63 ** 0 on success 64 ** < 0 on failure 65 */ 66 67 static int 68 notify_rd(nproc) 69 int nproc; 70 { 71 int r, i; 72 char buf[64]; 73 #define TSTSTR "qf0001" 74 75 r = sm_notify_start(true, 0); 76 if (r < 0) 77 { 78 perror("sm_notify_start failed"); 79 return -1; 80 } 81 82 for (i = 0; i < nproc; i++) 83 { 84 r = sm_notify_rcv(buf, sizeof(buf), 5 * SM_MICROS); 85 SM_TEST(r >= 0); 86 if (r < 0) 87 { 88 fprintf(stderr, "rcv=%d\n", r); 89 return r; 90 } 91 if (r > 0 && r < sizeof(buf)) 92 buf[r] = '\0'; 93 buf[sizeof(buf) - 1] = '\0'; 94 SM_TEST(strncmp(buf, TSTSTR, sizeof(TSTSTR) - 1) == 0); 95 SM_TEST(r > sizeof(TSTSTR)); 96 fprintf(stderr, "buf=\"%s\"\n", buf); 97 } 98 return 0; 99 } 100 101 int 102 main(argc, argv) 103 int argc; 104 char *argv[]; 105 { 106 int i; 107 int r = 0; 108 int nproc = 1; 109 pid_t pid; 110 111 # define OPTIONS "p:" 112 while ((i = getopt(argc, argv, OPTIONS)) != -1) 113 { 114 switch ((char) i) 115 { 116 case 'p': 117 nproc = atoi(optarg); 118 if (nproc < 1) 119 { 120 errno = EINVAL; 121 perror("-p: must be >0\n"); 122 return r; 123 } 124 break; 125 default: 126 break; 127 } 128 } 129 130 sm_test_begin(argc, argv, "test notify"); 131 r = sm_notify_init(0); 132 SM_TEST(r >= 0); 133 if (r < 0) 134 { 135 perror("sm_notify_init failed\n"); 136 return r; 137 } 138 139 pid = 0; 140 for (i = 0; i < nproc; i++) 141 { 142 if ((pid = fork()) < 0) 143 { 144 perror("fork failed\n"); 145 return -1; 146 } 147 148 if (pid == 0) 149 { 150 /* give the parent the chance to set up data */ 151 sleep(1); 152 r = notify_wr(getpid()); 153 break; 154 } 155 } 156 if (pid > 0) 157 r = notify_rd(nproc); 158 SM_TEST(r >= 0); 159 return sm_test_end(); 160 } 161 #else /* _FFR_DMTRIGGER */ 162 int 163 main(argc, argv) 164 int argc; 165 char *argv[]; 166 { 167 printf("SKIPPED: no _FFR_DMTRIGGER\n"); 168 return 0; 169 } 170 #endif /* _FFR_DMTRIGGER */ 171