xref: /freebsd/contrib/ntp/util/sht.c (revision aa0a1e58)
1 /*
2  * sht.c - Testprogram for shared memory refclock
3  * read/write shared memory segment; see usage
4  */
5 #ifndef SYS_WINNT
6 #include <sys/types.h>
7 #include <sys/ipc.h>
8 #include <sys/shm.h>
9 #include <stdio.h>
10 #include <time.h>
11 #include <unistd.h>
12 #include <stdlib.h>
13 #else
14 #include <windows.h>
15 #include <time.h>
16 #include <stdlib.h>
17 #include <stdio.h>
18 #include <iostream.h>
19 #define sleep(x) Sleep(x*1000)
20 #endif
21 #include <assert.h>
22 struct shmTime {
23 	int    mode; /* 0 - if valid set
24 		      *       use values,
25 		      *       clear valid
26 		      * 1 - if valid set
27 		      *       if count before and after read of values is equal,
28 		      *         use values
29 		      *       clear valid
30 		      */
31 	int    count;
32 	time_t clockTimeStampSec;
33 	int    clockTimeStampUSec;
34 	time_t receiveTimeStampSec;
35 	int    receiveTimeStampUSec;
36 	int    leap;
37 	int    precision;
38 	int    nsamples;
39 	int    valid;
40 };
41 
42 struct shmTime *
43 getShmTime (
44 	int unit
45 	)
46 {
47 #ifndef SYS_WINNT
48 	int shmid=shmget (0x4e545030+unit, sizeof (struct shmTime), IPC_CREAT|0777);
49 	if (shmid==-1) {
50 		perror ("shmget");
51 		exit (1);
52 	}
53 	else {
54 		struct shmTime *p=(struct shmTime *)shmat (shmid, 0, 0);
55 		if ((int)(long)p==-1) {
56 			perror ("shmat");
57 			p=0;
58 		}
59 		assert (p!=0);
60 		return p;
61 	}
62 #else
63 	char buf[10];
64 	LPSECURITY_ATTRIBUTES psec=0;
65 	sprintf (buf,"NTP%d",unit);
66 	SECURITY_DESCRIPTOR sd;
67 	SECURITY_ATTRIBUTES sa;
68 	HANDLE shmid;
69 
70 	assert (InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION));
71 	assert (SetSecurityDescriptorDacl(&sd,1,0,0));
72 	sa.nLength=sizeof (SECURITY_ATTRIBUTES);
73 	sa.lpSecurityDescriptor=&sd;
74 	sa.bInheritHandle=0;
75 	shmid=CreateFileMapping ((HANDLE)0xffffffff, 0, PAGE_READWRITE,
76 				 psec, sizeof (struct shmTime),buf);
77 	if (!shmid) {
78 		shmid=CreateFileMapping ((HANDLE)0xffffffff, 0, PAGE_READWRITE,
79 					 0, sizeof (struct shmTime),buf);
80 		cout <<"CreateFileMapping with psec!=0 failed"<<endl;
81 	}
82 
83 	if (!shmid) {
84 		char mbuf[1000];
85 		FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM,
86 			       0, GetLastError (), 0, mbuf, sizeof (mbuf), 0);
87 		int x=GetLastError ();
88 		cout <<"CreateFileMapping "<<buf<<":"<<mbuf<<endl;
89 		exit (1);
90 	}
91 	else {
92 		struct shmTime *p=(struct shmTime *) MapViewOfFile (shmid,
93 								    FILE_MAP_WRITE, 0, 0, sizeof (struct shmTime));
94 		if (p==0) {
95 			char mbuf[1000];
96 			FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM,
97 				       0, GetLastError (), 0, mbuf, sizeof (mbuf), 0);
98 			cout <<"MapViewOfFile "<<buf<<":"<<mbuf<<endl;
99 			exit (1);
100 		}
101 		return p;
102 	}
103 	return 0;
104 #endif
105 }
106 
107 
108 int
109 main (
110 	int argc,
111 	char *argv[]
112 	)
113 {
114 	volatile struct shmTime *p=getShmTime(2);
115 	if (argc<=1) {
116 		printf ("usage: %s r[c][l]|w|snnn\n",argv[0]);
117 		printf ("       r read shared memory\n");
118 		printf ("        c clear valid-flag\n");
119 		printf ("        l loop (so, rcl will read and clear in a loop\n");
120 		printf ("       w write shared memory with current time\n");
121 		printf ("       snnnn set nsamples to nnn\n");
122 		printf ("       lnnnn set leap to nnn\n");
123 		printf ("       pnnnn set precision to -nnn\n");
124 		exit (0);
125 	}
126 	switch (argv[1][0]) {
127 	    case 's': {
128 		    p->nsamples=atoi(&argv[1][1]);
129 	    }
130 	    break;
131 	    case 'l': {
132 		    p->leap=atoi(&argv[1][1]);
133 	    }
134 	    break;
135 	    case 'p': {
136 		    p->precision=-atoi(&argv[1][1]);
137 	    }
138 	    break;
139 	    case 'r': {
140 		    char *ap=&argv[1][1];
141 		    int clear=0;
142 		    int loop=0;
143 		    printf ("reader\n");
144 		    while (*ap) {
145 			    switch (*ap) {
146 				case 'l' : loop=1; break;
147 				case 'c' : clear=1; break;
148 			    }
149 			    ap++;
150 		    }
151 		    do {
152 			    printf ("mode=%d, count=%d, clock=%d.%d, rec=%d.%d,\n",
153 				    p->mode,p->count,p->clockTimeStampSec,p->clockTimeStampUSec,
154 				    p->receiveTimeStampSec,p->receiveTimeStampUSec);
155 			    printf ("  leap=%d, precision=%d, nsamples=%d, valid=%d\n",
156 				    p->leap, p->precision, p->nsamples, p->valid);
157 			    if (!p->valid)
158 				printf ("***\n");
159 			    if (clear) {
160 				    p->valid=0;
161 				    printf ("cleared\n");
162 			    }
163 			    if (loop)
164 				sleep (1);
165 		    } while (loop);
166 	    }
167 	    break;
168 	    case 'w': {
169 		    printf ("writer\n");
170 		    p->mode=0;
171 		    if (!p->valid) {
172 			    p->clockTimeStampSec=time(0)-20;
173 			    p->clockTimeStampUSec=0;
174 			    p->receiveTimeStampSec=time(0)-1;
175 			    p->receiveTimeStampUSec=0;
176 			    printf ("%d %d\n",p->clockTimeStampSec, p->receiveTimeStampSec);
177 			    p->valid=1;
178 		    }
179 		    else {
180 			    printf ("p->valid still set\n"); /* not an error! */
181 		    }
182 	    }
183 	    break;
184 	}
185 }
186