1 /* source: xiolockfile.c */
2 /* Copyright Gerhard Rieger and contributors (see file CHANGES) */
3 /* Published under the GNU General Public License V.2, see file COPYING */
5 /* this file contains socats explicit locking mechanisms */
7 #include "xiosysincludes.h"
18 #include "xiolockfile.h"
21 /* returns 0 if it could create lock; 1 if the lock exists; -1 on error */
22 int xiogetlock(const char *lockfile
) {
27 char pidbuf
[3*sizeof(pid_t
)+1];
30 if (Lstat(lockfile
, &strat
) == 0) {
36 Error3("Lstat(\"%s\", %p): %s", lockfile
, &strat
, strerror(errno
));
39 /* in this moment, the file did not exist */
41 if ((s
= Malloc(strlen(lockfile
)+8)) == NULL
) {
48 if ((fd
= Mkstemp(s
)) < 0) {
49 Error2("mkstemp(\"%s\"): %s", s
, strerror(errno
));
54 bytes
= sprintf(pidbuf
, F_pid
, pid
);
55 if (writefull(fd
, pidbuf
, bytes
) < 0) {
56 Error4("write(%d, %p, "F_Zu
"): %s", fd
, pidbuf
, bytes
, strerror(errno
));
61 /* Chmod(lockfile, 0600); */
62 if (Link(s
, lockfile
) < 0) {
64 Error3("link(\"%s\", \"%s\"): %s", s
, lockfile
, strerror(errno
));
74 int xiounlock(const char *lockfile
) {
75 return Unlink(lockfile
);
79 /* returns 0 when it could create lock, or -1 on error */
80 int xiowaitlock(const char *lockfile
, struct timespec
*intervall
) {
82 int level
= E_NOTICE
; /* first print a notice */
84 while ((rc
= xiogetlock(lockfile
)) == 1) {
85 Msg1(level
, "waiting for lock \"%s\"", lockfile
);
86 level
= E_INFO
; /* afterwards only make info */
87 Nanosleep(intervall
, NULL
);
93 /* returns 0 when it could obtain lock or the lock is not valid
94 (lockfile==NULL), 1 if it could not obtain the lock, or -1 on error */
95 int xiolock(xiolock_t
*lock
) {
98 if (lock
->lockfile
== NULL
) {
101 if (lock
->waitlock
) {
102 result
= xiowaitlock(lock
->lockfile
, &lock
->intervall
);
104 result
= xiogetlock(lock
->lockfile
);
107 Info1("obtained lock \"%s\"", lock
->lockfile
);
113 int xiofiledroplock(xiofile_t
*xfd
) {
114 if (xfd
->tag
== XIO_TAG_DUAL
) {
115 xiofiledroplock((xiofile_t
*)xfd
->dual
.stream
[0]);
116 xiofiledroplock((xiofile_t
*)xfd
->dual
.stream
[1]);
118 xfd
->stream
.havelock
= false;