12fb4f839SGregory Neil Shapiro /*
22fb4f839SGregory Neil Shapiro * Copyright (c) 2005 Proofpoint, Inc. and its suppliers.
32fb4f839SGregory Neil Shapiro * All rights reserved.
42fb4f839SGregory Neil Shapiro *
52fb4f839SGregory Neil Shapiro * By using this file, you agree to the terms and conditions set
62fb4f839SGregory Neil Shapiro * forth in the LICENSE file which can be found at the top level of
72fb4f839SGregory Neil Shapiro * the sendmail distribution.
82fb4f839SGregory Neil Shapiro *
92fb4f839SGregory Neil Shapiro */
102fb4f839SGregory Neil Shapiro
112fb4f839SGregory Neil Shapiro #include <sm/gen.h>
122fb4f839SGregory Neil Shapiro SM_IDSTR(id, "@(#)$Id: t-lockfile.c,v 1.2 2013-11-22 20:51:50 ca Exp $")
132fb4f839SGregory Neil Shapiro #include <stdlib.h>
142fb4f839SGregory Neil Shapiro #include <stdio.h>
152fb4f839SGregory Neil Shapiro #include <sendmail.h>
162fb4f839SGregory Neil Shapiro
172fb4f839SGregory Neil Shapiro #define IOBUFSZ 64
182fb4f839SGregory Neil Shapiro char iobuf[IOBUFSZ];
192fb4f839SGregory Neil Shapiro #define FIRSTLINE "first line\n"
202fb4f839SGregory Neil Shapiro #define LASTLINE "last line\n"
212fb4f839SGregory Neil Shapiro static int noio, chk;
222fb4f839SGregory Neil Shapiro static pid_t pid;
232fb4f839SGregory Neil Shapiro
24*d39bd2c1SGregory Neil Shapiro /*
25*d39bd2c1SGregory Neil Shapiro ** OPENFILE -- open a file
26*d39bd2c1SGregory Neil Shapiro **
27*d39bd2c1SGregory Neil Shapiro ** Parameters:
28*d39bd2c1SGregory Neil Shapiro ** owner -- create file?
29*d39bd2c1SGregory Neil Shapiro ** filename -- name of file.
30*d39bd2c1SGregory Neil Shapiro ** flags -- flags for open(2)
31*d39bd2c1SGregory Neil Shapiro **
32*d39bd2c1SGregory Neil Shapiro ** Returns:
33*d39bd2c1SGregory Neil Shapiro ** >=0 fd
34*d39bd2c1SGregory Neil Shapiro ** <0 on failure.
35*d39bd2c1SGregory Neil Shapiro */
36*d39bd2c1SGregory Neil Shapiro
37*d39bd2c1SGregory Neil Shapiro static int
openfile(owner,filename,flags)382fb4f839SGregory Neil Shapiro openfile(owner, filename, flags)
392fb4f839SGregory Neil Shapiro int owner;
402fb4f839SGregory Neil Shapiro char *filename;
412fb4f839SGregory Neil Shapiro int flags;
422fb4f839SGregory Neil Shapiro {
432fb4f839SGregory Neil Shapiro int fd;
442fb4f839SGregory Neil Shapiro
452fb4f839SGregory Neil Shapiro if (owner)
462fb4f839SGregory Neil Shapiro flags |= O_CREAT;
472fb4f839SGregory Neil Shapiro fd = open(filename, flags, 0640);
482fb4f839SGregory Neil Shapiro if (fd >= 0)
492fb4f839SGregory Neil Shapiro return fd;
502fb4f839SGregory Neil Shapiro fprintf(stderr, "%d: %ld: owner=%d, open(%s) failed\n",
512fb4f839SGregory Neil Shapiro (int) pid, (long) time(NULL), owner, filename);
52*d39bd2c1SGregory Neil Shapiro return -1;
532fb4f839SGregory Neil Shapiro }
542fb4f839SGregory Neil Shapiro
55*d39bd2c1SGregory Neil Shapiro /*
56*d39bd2c1SGregory Neil Shapiro ** WRBUF -- write iobuf to fd
57*d39bd2c1SGregory Neil Shapiro **
58*d39bd2c1SGregory Neil Shapiro ** Parameters:
59*d39bd2c1SGregory Neil Shapiro ** fd -- file descriptor.
60*d39bd2c1SGregory Neil Shapiro **
61*d39bd2c1SGregory Neil Shapiro ** Returns:
62*d39bd2c1SGregory Neil Shapiro ** ==0 write was ok
63*d39bd2c1SGregory Neil Shapiro ** !=0 on failure.
64*d39bd2c1SGregory Neil Shapiro */
65*d39bd2c1SGregory Neil Shapiro
66*d39bd2c1SGregory Neil Shapiro static int
wrbuf(fd)672fb4f839SGregory Neil Shapiro wrbuf(fd)
682fb4f839SGregory Neil Shapiro int fd;
692fb4f839SGregory Neil Shapiro {
702fb4f839SGregory Neil Shapiro int r;
712fb4f839SGregory Neil Shapiro
722fb4f839SGregory Neil Shapiro if (noio)
732fb4f839SGregory Neil Shapiro return 0;
742fb4f839SGregory Neil Shapiro r = write(fd, iobuf, sizeof(iobuf));
752fb4f839SGregory Neil Shapiro if (sizeof(iobuf) == r)
762fb4f839SGregory Neil Shapiro return 0;
772fb4f839SGregory Neil Shapiro fprintf(stderr, "%d: %ld: owner=1, write(%s)=fail\n",
782fb4f839SGregory Neil Shapiro (int) pid, (long) time(NULL), iobuf);
792fb4f839SGregory Neil Shapiro return 1;
802fb4f839SGregory Neil Shapiro }
812fb4f839SGregory Neil Shapiro
82*d39bd2c1SGregory Neil Shapiro /*
83*d39bd2c1SGregory Neil Shapiro ** RDBUF -- read from fd
84*d39bd2c1SGregory Neil Shapiro **
85*d39bd2c1SGregory Neil Shapiro ** Parameters:
86*d39bd2c1SGregory Neil Shapiro ** fd -- file descriptor.
87*d39bd2c1SGregory Neil Shapiro ** xbuf -- expected content.
88*d39bd2c1SGregory Neil Shapiro **
89*d39bd2c1SGregory Neil Shapiro ** Returns:
90*d39bd2c1SGregory Neil Shapiro ** ==0 read was ok and content matches
91*d39bd2c1SGregory Neil Shapiro ** !=0 otherwise
92*d39bd2c1SGregory Neil Shapiro */
93*d39bd2c1SGregory Neil Shapiro
94*d39bd2c1SGregory Neil Shapiro static int
rdbuf(fd,xbuf)952fb4f839SGregory Neil Shapiro rdbuf(fd, xbuf)
962fb4f839SGregory Neil Shapiro int fd;
972fb4f839SGregory Neil Shapiro const char *xbuf;
982fb4f839SGregory Neil Shapiro {
992fb4f839SGregory Neil Shapiro int r;
1002fb4f839SGregory Neil Shapiro
1012fb4f839SGregory Neil Shapiro if (noio)
1022fb4f839SGregory Neil Shapiro return 0;
1032fb4f839SGregory Neil Shapiro r = read(fd, iobuf, sizeof(iobuf));
1042fb4f839SGregory Neil Shapiro if (sizeof(iobuf) != r)
1052fb4f839SGregory Neil Shapiro {
1062fb4f839SGregory Neil Shapiro fprintf(stderr, "%d: %ld: owner=0, read()=fail\n",
1072fb4f839SGregory Neil Shapiro (int) pid, (long) time(NULL));
1082fb4f839SGregory Neil Shapiro return 1;
1092fb4f839SGregory Neil Shapiro }
1102fb4f839SGregory Neil Shapiro if (strncmp(iobuf, xbuf, strlen(xbuf)))
1112fb4f839SGregory Neil Shapiro {
1122fb4f839SGregory Neil Shapiro fprintf(stderr, "%d: %ld: owner=0, read=%s expected=%s\n",
1132fb4f839SGregory Neil Shapiro (int) pid, (long) time(NULL), iobuf, xbuf);
1142fb4f839SGregory Neil Shapiro return 1;
1152fb4f839SGregory Neil Shapiro }
1162fb4f839SGregory Neil Shapiro return 0;
1172fb4f839SGregory Neil Shapiro }
1182fb4f839SGregory Neil Shapiro
1192fb4f839SGregory Neil Shapiro /*
120*d39bd2c1SGregory Neil Shapiro ** LOCKTESTWR -- test WR/EX file locking
1212fb4f839SGregory Neil Shapiro **
1222fb4f839SGregory Neil Shapiro ** Parameters:
1232fb4f839SGregory Neil Shapiro ** owner -- create file?
1242fb4f839SGregory Neil Shapiro ** filename -- name of file.
1252fb4f839SGregory Neil Shapiro ** flags -- flags for open(2)
1262fb4f839SGregory Neil Shapiro ** delay -- how long to keep file locked?
1272fb4f839SGregory Neil Shapiro **
1282fb4f839SGregory Neil Shapiro ** Returns:
1292fb4f839SGregory Neil Shapiro ** 0 on success
1302fb4f839SGregory Neil Shapiro ** != 0 on failure.
1312fb4f839SGregory Neil Shapiro */
1322fb4f839SGregory Neil Shapiro
1332fb4f839SGregory Neil Shapiro #define DBGPRINTR(str) \
1342fb4f839SGregory Neil Shapiro do \
1352fb4f839SGregory Neil Shapiro { \
1362fb4f839SGregory Neil Shapiro fprintf(stderr, "%d: %ld: owner=0, ", (int) pid, \
1372fb4f839SGregory Neil Shapiro (long) time(NULL)); \
1382fb4f839SGregory Neil Shapiro fprintf(stderr, str, filename, shared ? "RD" : "EX"); \
1392fb4f839SGregory Neil Shapiro } while (0)
1402fb4f839SGregory Neil Shapiro
141*d39bd2c1SGregory Neil Shapiro static int
locktestwr(filename,flags,delay)1422fb4f839SGregory Neil Shapiro locktestwr(filename, flags, delay)
1432fb4f839SGregory Neil Shapiro char *filename;
1442fb4f839SGregory Neil Shapiro int flags;
1452fb4f839SGregory Neil Shapiro int delay;
1462fb4f839SGregory Neil Shapiro {
1472fb4f839SGregory Neil Shapiro int fd;
1482fb4f839SGregory Neil Shapiro bool locked;
1492fb4f839SGregory Neil Shapiro
1502fb4f839SGregory Neil Shapiro fd = openfile(1, filename, flags);
1512fb4f839SGregory Neil Shapiro if (fd < 0)
1522fb4f839SGregory Neil Shapiro return errno;
1532fb4f839SGregory Neil Shapiro locked = lockfile(fd, filename, "[owner]", LOCK_EX);
1542fb4f839SGregory Neil Shapiro if (!locked)
1552fb4f839SGregory Neil Shapiro {
1562fb4f839SGregory Neil Shapiro fprintf(stderr, "%d: %ld: owner=1, lock(%s) failed\n",
1572fb4f839SGregory Neil Shapiro (int) pid, (long) time(NULL), filename);
1582fb4f839SGregory Neil Shapiro return 1;
1592fb4f839SGregory Neil Shapiro }
1602fb4f839SGregory Neil Shapiro else
1612fb4f839SGregory Neil Shapiro fprintf(stderr, "%d: %ld: owner=1, lock(%s) ok\n",
1622fb4f839SGregory Neil Shapiro (int) pid, (long) time(NULL), filename);
1632fb4f839SGregory Neil Shapiro
1642fb4f839SGregory Neil Shapiro sm_strlcpy(iobuf, FIRSTLINE, sizeof(iobuf));
1652fb4f839SGregory Neil Shapiro if (wrbuf(fd))
1662fb4f839SGregory Neil Shapiro return 1;
167*d39bd2c1SGregory Neil Shapiro if (delay > 0)
1682fb4f839SGregory Neil Shapiro sleep(delay);
1692fb4f839SGregory Neil Shapiro sm_strlcpy(iobuf, LASTLINE, sizeof(iobuf));
1702fb4f839SGregory Neil Shapiro if (wrbuf(fd))
1712fb4f839SGregory Neil Shapiro return 1;
1722fb4f839SGregory Neil Shapiro locked = lockfile(fd, filename, "[owner]", LOCK_UN);
1732fb4f839SGregory Neil Shapiro if (!locked)
1742fb4f839SGregory Neil Shapiro {
1752fb4f839SGregory Neil Shapiro fprintf(stderr, "%d: %ld: owner=1, unlock(%s) failed\n",
1762fb4f839SGregory Neil Shapiro (int) pid, (long) time(NULL), filename);
1772fb4f839SGregory Neil Shapiro return 1;
1782fb4f839SGregory Neil Shapiro }
1792fb4f839SGregory Neil Shapiro fprintf(stderr, "%d: %ld: owner=1, unlock(%s) done\n",
1802fb4f839SGregory Neil Shapiro (int) pid, (long) time(NULL), filename);
1812fb4f839SGregory Neil Shapiro if (fd > 0)
1822fb4f839SGregory Neil Shapiro {
1832fb4f839SGregory Neil Shapiro close(fd);
1842fb4f839SGregory Neil Shapiro fd = -1;
1852fb4f839SGregory Neil Shapiro }
1862fb4f839SGregory Neil Shapiro return 0;
1872fb4f839SGregory Neil Shapiro }
1882fb4f839SGregory Neil Shapiro
189*d39bd2c1SGregory Neil Shapiro /*
190*d39bd2c1SGregory Neil Shapiro ** CHKLCK -- check whether fd is locked (only for fcntl())
191*d39bd2c1SGregory Neil Shapiro **
192*d39bd2c1SGregory Neil Shapiro ** Parameters:
193*d39bd2c1SGregory Neil Shapiro ** owner -- create file?
194*d39bd2c1SGregory Neil Shapiro ** filename -- name of file.
195*d39bd2c1SGregory Neil Shapiro ** flags -- flags for open(2)
196*d39bd2c1SGregory Neil Shapiro ** delay -- how long to keep file locked?
197*d39bd2c1SGregory Neil Shapiro **
198*d39bd2c1SGregory Neil Shapiro ** Returns:
199*d39bd2c1SGregory Neil Shapiro ** 0 if not locked
200*d39bd2c1SGregory Neil Shapiro ** >0 pid of process which holds a WR lock
201*d39bd2c1SGregory Neil Shapiro ** <0 error
202*d39bd2c1SGregory Neil Shapiro */
203*d39bd2c1SGregory Neil Shapiro
204*d39bd2c1SGregory Neil Shapiro static long
chklck(fd)2052fb4f839SGregory Neil Shapiro chklck(fd)
2062fb4f839SGregory Neil Shapiro int fd;
2072fb4f839SGregory Neil Shapiro {
2082fb4f839SGregory Neil Shapiro #if !HASFLOCK
2092fb4f839SGregory Neil Shapiro int action, i;
2102fb4f839SGregory Neil Shapiro struct flock lfd;
2112fb4f839SGregory Neil Shapiro
2122fb4f839SGregory Neil Shapiro (void) memset(&lfd, '\0', sizeof lfd);
2132fb4f839SGregory Neil Shapiro lfd.l_type = F_RDLCK;
2142fb4f839SGregory Neil Shapiro action = F_GETLK;
2152fb4f839SGregory Neil Shapiro while ((i = fcntl(fd, action, &lfd)) < 0 && errno == EINTR)
2162fb4f839SGregory Neil Shapiro continue;
2172fb4f839SGregory Neil Shapiro if (i < 0)
2182fb4f839SGregory Neil Shapiro return (long)i;
2192fb4f839SGregory Neil Shapiro if (F_WRLCK == lfd.l_type)
2202fb4f839SGregory Neil Shapiro return (long)lfd.l_pid;
2212fb4f839SGregory Neil Shapiro return 0L;
2222fb4f839SGregory Neil Shapiro #else /* !HASFLOCK */
223*d39bd2c1SGregory Neil Shapiro fprintf(stderr, "%d: %ld: flock(): no lock test\n",
2242fb4f839SGregory Neil Shapiro (int) pid, (long) time(NULL));
2252fb4f839SGregory Neil Shapiro return -1L;
2262fb4f839SGregory Neil Shapiro #endif /* !HASFLOCK */
2272fb4f839SGregory Neil Shapiro }
2282fb4f839SGregory Neil Shapiro
229*d39bd2c1SGregory Neil Shapiro /*
230*d39bd2c1SGregory Neil Shapiro ** LOCKTESTRD -- test file locking for reading
231*d39bd2c1SGregory Neil Shapiro **
232*d39bd2c1SGregory Neil Shapiro ** Parameters:
233*d39bd2c1SGregory Neil Shapiro ** filename -- name of file.
234*d39bd2c1SGregory Neil Shapiro ** flags -- flags for open(2)
235*d39bd2c1SGregory Neil Shapiro ** delay -- how long is file locked by owner?
236*d39bd2c1SGregory Neil Shapiro ** shared -- LOCK_{EX/SH}
237*d39bd2c1SGregory Neil Shapiro **
238*d39bd2c1SGregory Neil Shapiro ** Returns:
239*d39bd2c1SGregory Neil Shapiro ** 0 on success
240*d39bd2c1SGregory Neil Shapiro ** != 0 on failure.
241*d39bd2c1SGregory Neil Shapiro */
242*d39bd2c1SGregory Neil Shapiro
243*d39bd2c1SGregory Neil Shapiro static int
locktestrd(filename,flags,delay,shared)2442fb4f839SGregory Neil Shapiro locktestrd(filename, flags, delay, shared)
2452fb4f839SGregory Neil Shapiro char *filename;
2462fb4f839SGregory Neil Shapiro int flags;
2472fb4f839SGregory Neil Shapiro int delay;
2482fb4f839SGregory Neil Shapiro int shared;
2492fb4f839SGregory Neil Shapiro {
2502fb4f839SGregory Neil Shapiro int fd, cnt;
2512fb4f839SGregory Neil Shapiro int lt;
2522fb4f839SGregory Neil Shapiro bool locked;
2532fb4f839SGregory Neil Shapiro
2542fb4f839SGregory Neil Shapiro fd = openfile(0, filename, flags);
2552fb4f839SGregory Neil Shapiro if (fd < 0)
2562fb4f839SGregory Neil Shapiro return errno;
2572fb4f839SGregory Neil Shapiro if (chk)
2582fb4f839SGregory Neil Shapiro {
2592fb4f839SGregory Neil Shapiro long locked;
2602fb4f839SGregory Neil Shapiro
2612fb4f839SGregory Neil Shapiro locked = chklck(fd);
2622fb4f839SGregory Neil Shapiro if (locked > 0)
2632fb4f839SGregory Neil Shapiro fprintf(stderr, "%d: %ld: file=%s status=locked pid=%ld\n",
2642fb4f839SGregory Neil Shapiro (int) pid, (long) time(NULL), filename, locked);
2652fb4f839SGregory Neil Shapiro else if (0 == locked)
2662fb4f839SGregory Neil Shapiro fprintf(stderr, "%d: %ld: file=%s status=not_locked\n",
2672fb4f839SGregory Neil Shapiro (int) pid, (long) time(NULL), filename);
2682fb4f839SGregory Neil Shapiro else
2692fb4f839SGregory Neil Shapiro fprintf(stderr, "%d: %ld: file=%s status=unknown\n",
2702fb4f839SGregory Neil Shapiro (int) pid, (long) time(NULL), filename);
2712fb4f839SGregory Neil Shapiro goto end;
2722fb4f839SGregory Neil Shapiro }
2732fb4f839SGregory Neil Shapiro
2742fb4f839SGregory Neil Shapiro if (shared)
2752fb4f839SGregory Neil Shapiro lt = LOCK_SH;
2762fb4f839SGregory Neil Shapiro else
2772fb4f839SGregory Neil Shapiro lt = LOCK_EX;
2782fb4f839SGregory Neil Shapiro
2792fb4f839SGregory Neil Shapiro for (cnt = 0; cnt < delay - 2; cnt++)
2802fb4f839SGregory Neil Shapiro {
2812fb4f839SGregory Neil Shapiro /* try to get lock: should fail (nonblocking) */
2822fb4f839SGregory Neil Shapiro locked = lockfile(fd, filename, "[client]", lt|LOCK_NB);
2832fb4f839SGregory Neil Shapiro if (locked)
2842fb4f839SGregory Neil Shapiro {
2852fb4f839SGregory Neil Shapiro DBGPRINTR("lock(%s)=%s succeeded\n");
2862fb4f839SGregory Neil Shapiro return 1;
2872fb4f839SGregory Neil Shapiro }
2882fb4f839SGregory Neil Shapiro sleep(1);
2892fb4f839SGregory Neil Shapiro }
2902fb4f839SGregory Neil Shapiro if (delay > 0)
2912fb4f839SGregory Neil Shapiro sleep(2);
2922fb4f839SGregory Neil Shapiro locked = lockfile(fd, filename, "[client]", lt);
2932fb4f839SGregory Neil Shapiro if (!locked)
2942fb4f839SGregory Neil Shapiro {
2952fb4f839SGregory Neil Shapiro DBGPRINTR("lock(%s)=%s failed\n");
2962fb4f839SGregory Neil Shapiro return 1;
2972fb4f839SGregory Neil Shapiro }
2982fb4f839SGregory Neil Shapiro DBGPRINTR("lock(%s)=%s ok\n");
2992fb4f839SGregory Neil Shapiro if (rdbuf(fd, FIRSTLINE))
3002fb4f839SGregory Neil Shapiro return 1;
3012fb4f839SGregory Neil Shapiro if (rdbuf(fd, LASTLINE))
3022fb4f839SGregory Neil Shapiro return 1;
3032fb4f839SGregory Neil Shapiro sleep(1);
3042fb4f839SGregory Neil Shapiro locked = lockfile(fd, filename, "[client]", LOCK_UN);
3052fb4f839SGregory Neil Shapiro if (!locked)
3062fb4f839SGregory Neil Shapiro {
3072fb4f839SGregory Neil Shapiro DBGPRINTR("unlock(%s)=%s failed\n");
3082fb4f839SGregory Neil Shapiro return 1;
3092fb4f839SGregory Neil Shapiro }
3102fb4f839SGregory Neil Shapiro DBGPRINTR("unlock(%s)=%s done\n");
3112fb4f839SGregory Neil Shapiro
3122fb4f839SGregory Neil Shapiro end:
3132fb4f839SGregory Neil Shapiro if (fd > 0)
3142fb4f839SGregory Neil Shapiro {
3152fb4f839SGregory Neil Shapiro close(fd);
3162fb4f839SGregory Neil Shapiro fd = -1;
3172fb4f839SGregory Neil Shapiro }
3182fb4f839SGregory Neil Shapiro return 0;
3192fb4f839SGregory Neil Shapiro }
3202fb4f839SGregory Neil Shapiro
321*d39bd2c1SGregory Neil Shapiro /*
322*d39bd2c1SGregory Neil Shapiro ** USAGE -- show usage
323*d39bd2c1SGregory Neil Shapiro **
324*d39bd2c1SGregory Neil Shapiro ** Parameters:
325*d39bd2c1SGregory Neil Shapiro ** prg -- name of program
326*d39bd2c1SGregory Neil Shapiro **
327*d39bd2c1SGregory Neil Shapiro ** Returns:
328*d39bd2c1SGregory Neil Shapiro ** nothing.
329*d39bd2c1SGregory Neil Shapiro */
330*d39bd2c1SGregory Neil Shapiro
3312fb4f839SGregory Neil Shapiro static void
usage(prg)3322fb4f839SGregory Neil Shapiro usage(prg)
3332fb4f839SGregory Neil Shapiro const char *prg;
3342fb4f839SGregory Neil Shapiro {
3352fb4f839SGregory Neil Shapiro fprintf(stderr, "usage: %s [options]\n"
3362fb4f839SGregory Neil Shapiro "-f filename use filename\n"
3372fb4f839SGregory Neil Shapiro "-i do not perform I/O\n"
3382fb4f839SGregory Neil Shapiro "-n do not try non-blocking locking first\n"
3392fb4f839SGregory Neil Shapiro "-R only start reader process\n"
3402fb4f839SGregory Neil Shapiro "-r use shared locking for reader\n"
3412fb4f839SGregory Neil Shapiro "-s delay sleep delay seconds before unlocking\n"
3422fb4f839SGregory Neil Shapiro "-W only start writer process\n"
343*d39bd2c1SGregory Neil Shapiro #if !HASFLOCK
344*d39bd2c1SGregory Neil Shapiro "uses fcntl()\n"
345*d39bd2c1SGregory Neil Shapiro #else
346*d39bd2c1SGregory Neil Shapiro "uses flock()\n"
347*d39bd2c1SGregory Neil Shapiro #endif
348*d39bd2c1SGregory Neil Shapiro
3492fb4f839SGregory Neil Shapiro , prg);
3502fb4f839SGregory Neil Shapiro }
3512fb4f839SGregory Neil Shapiro
3522fb4f839SGregory Neil Shapiro int
main(argc,argv)3532fb4f839SGregory Neil Shapiro main(argc, argv)
3542fb4f839SGregory Neil Shapiro int argc;
3552fb4f839SGregory Neil Shapiro char *argv[];
3562fb4f839SGregory Neil Shapiro {
3572fb4f839SGregory Neil Shapiro int ch, delay, r, status, flags, shared, nb, reader, writer;
3582fb4f839SGregory Neil Shapiro char *filename;
3592fb4f839SGregory Neil Shapiro pid_t fpid;
3602fb4f839SGregory Neil Shapiro extern char *optarg;
3612fb4f839SGregory Neil Shapiro
3622fb4f839SGregory Neil Shapiro delay = 5;
3632fb4f839SGregory Neil Shapiro filename = "testlock";
3642fb4f839SGregory Neil Shapiro flags = O_RDWR;
3652fb4f839SGregory Neil Shapiro shared = nb = noio = reader = writer = chk = 0;
3662fb4f839SGregory Neil Shapiro #define OPTIONS "cf:inRrs:W"
3672fb4f839SGregory Neil Shapiro while ((ch = getopt(argc, argv, OPTIONS)) != -1)
3682fb4f839SGregory Neil Shapiro {
3692fb4f839SGregory Neil Shapiro switch ((char) ch)
3702fb4f839SGregory Neil Shapiro {
3712fb4f839SGregory Neil Shapiro case 'c':
3722fb4f839SGregory Neil Shapiro chk = 1;
3732fb4f839SGregory Neil Shapiro break;
3742fb4f839SGregory Neil Shapiro
3752fb4f839SGregory Neil Shapiro case 'f':
3762fb4f839SGregory Neil Shapiro filename = optarg;
3772fb4f839SGregory Neil Shapiro break;
3782fb4f839SGregory Neil Shapiro
3792fb4f839SGregory Neil Shapiro case 'i':
3802fb4f839SGregory Neil Shapiro noio = 1;
3812fb4f839SGregory Neil Shapiro break;
3822fb4f839SGregory Neil Shapiro
3832fb4f839SGregory Neil Shapiro case 'n':
3842fb4f839SGregory Neil Shapiro nb = 0;
3852fb4f839SGregory Neil Shapiro break;
3862fb4f839SGregory Neil Shapiro
3872fb4f839SGregory Neil Shapiro case 'R':
3882fb4f839SGregory Neil Shapiro reader = 1;
3892fb4f839SGregory Neil Shapiro break;
3902fb4f839SGregory Neil Shapiro
3912fb4f839SGregory Neil Shapiro case 'r':
3922fb4f839SGregory Neil Shapiro shared = 1;
3932fb4f839SGregory Neil Shapiro break;
3942fb4f839SGregory Neil Shapiro
3952fb4f839SGregory Neil Shapiro case 's':
3962fb4f839SGregory Neil Shapiro delay = atoi(optarg);
3972fb4f839SGregory Neil Shapiro break;
3982fb4f839SGregory Neil Shapiro
3992fb4f839SGregory Neil Shapiro case 'W':
4002fb4f839SGregory Neil Shapiro writer = 1;
4012fb4f839SGregory Neil Shapiro break;
4022fb4f839SGregory Neil Shapiro
4032fb4f839SGregory Neil Shapiro default:
4042fb4f839SGregory Neil Shapiro usage(argv[0]);
4052fb4f839SGregory Neil Shapiro exit(69);
4062fb4f839SGregory Neil Shapiro break;
4072fb4f839SGregory Neil Shapiro }
4082fb4f839SGregory Neil Shapiro }
4092fb4f839SGregory Neil Shapiro
4102fb4f839SGregory Neil Shapiro fpid = -1;
4112fb4f839SGregory Neil Shapiro if (0 == reader && 0 == writer && (fpid = fork()) < 0)
4122fb4f839SGregory Neil Shapiro {
4132fb4f839SGregory Neil Shapiro perror("fork failed\n");
4142fb4f839SGregory Neil Shapiro return 1;
4152fb4f839SGregory Neil Shapiro }
4162fb4f839SGregory Neil Shapiro
4172fb4f839SGregory Neil Shapiro r = 0;
4182fb4f839SGregory Neil Shapiro if (reader || fpid == 0)
4192fb4f839SGregory Neil Shapiro {
4202fb4f839SGregory Neil Shapiro /* give the parent the chance to set up data */
4212fb4f839SGregory Neil Shapiro pid = getpid();
4222fb4f839SGregory Neil Shapiro sleep(1);
4232fb4f839SGregory Neil Shapiro r = locktestrd(filename, flags, nb ? delay : 0, shared);
4242fb4f839SGregory Neil Shapiro }
4252fb4f839SGregory Neil Shapiro if (writer || fpid > 0)
4262fb4f839SGregory Neil Shapiro {
4272fb4f839SGregory Neil Shapiro fpid = getpid();
4282fb4f839SGregory Neil Shapiro r = locktestwr(filename, flags, delay);
4292fb4f839SGregory Neil Shapiro (void) wait(&status);
4302fb4f839SGregory Neil Shapiro }
4312fb4f839SGregory Neil Shapiro /* (void) unlink(filename); */
4322fb4f839SGregory Neil Shapiro return r;
4332fb4f839SGregory Neil Shapiro }
434