Ruby  2.0.0p247(2013-06-27revision41674)
missing/flock.c
Go to the documentation of this file.
00001 #include "ruby/config.h"
00002 #include "ruby/ruby.h"
00003 
00004 #if defined _WIN32
00005 #elif defined HAVE_FCNTL && defined HAVE_FCNTL_H && !defined(__native_client__)
00006 
00007 /* These are the flock() constants.  Since this sytems doesn't have
00008    flock(), the values of the constants are probably not available.
00009 */
00010 # ifndef LOCK_SH
00011 #  define LOCK_SH 1
00012 # endif
00013 # ifndef LOCK_EX
00014 #  define LOCK_EX 2
00015 # endif
00016 # ifndef LOCK_NB
00017 #  define LOCK_NB 4
00018 # endif
00019 # ifndef LOCK_UN
00020 #  define LOCK_UN 8
00021 # endif
00022 
00023 #include <fcntl.h>
00024 #include <unistd.h>
00025 #include <errno.h>
00026 
00027 int
00028 flock(int fd, int operation)
00029 {
00030     struct flock lock;
00031 
00032     switch (operation & ~LOCK_NB) {
00033     case LOCK_SH:
00034         lock.l_type = F_RDLCK;
00035         break;
00036     case LOCK_EX:
00037         lock.l_type = F_WRLCK;
00038         break;
00039     case LOCK_UN:
00040         lock.l_type = F_UNLCK;
00041         break;
00042     default:
00043         errno = EINVAL;
00044         return -1;
00045     }
00046     lock.l_whence = SEEK_SET;
00047     lock.l_start = lock.l_len = 0L;
00048 
00049     return fcntl(fd, (operation & LOCK_NB) ? F_SETLK : F_SETLKW, &lock);
00050 }
00051 
00052 #elif defined(HAVE_LOCKF)
00053 
00054 #include <unistd.h>
00055 #include <errno.h>
00056 
00057 /*  Emulate flock() with lockf() or fcntl().  This is just to increase
00058     portability of scripts.  The calls might not be completely
00059     interchangeable.  What's really needed is a good file
00060     locking module.
00061 */
00062 
00063 # ifndef F_ULOCK
00064 #  define F_ULOCK       0       /* Unlock a previously locked region */
00065 # endif
00066 # ifndef F_LOCK
00067 #  define F_LOCK        1       /* Lock a region for exclusive use */
00068 # endif
00069 # ifndef F_TLOCK
00070 #  define F_TLOCK       2       /* Test and lock a region for exclusive use */
00071 # endif
00072 # ifndef F_TEST
00073 #  define F_TEST        3       /* Test a region for other processes locks */
00074 # endif
00075 
00076 /* These are the flock() constants.  Since this sytems doesn't have
00077    flock(), the values of the constants are probably not available.
00078 */
00079 # ifndef LOCK_SH
00080 #  define LOCK_SH 1
00081 # endif
00082 # ifndef LOCK_EX
00083 #  define LOCK_EX 2
00084 # endif
00085 # ifndef LOCK_NB
00086 #  define LOCK_NB 4
00087 # endif
00088 # ifndef LOCK_UN
00089 #  define LOCK_UN 8
00090 # endif
00091 
00092 int
00093 flock(int fd, int operation)
00094 {
00095     switch (operation) {
00096 
00097         /* LOCK_SH - get a shared lock */
00098       case LOCK_SH:
00099         rb_notimplement();
00100         return -1;
00101         /* LOCK_EX - get an exclusive lock */
00102       case LOCK_EX:
00103         return lockf (fd, F_LOCK, 0);
00104 
00105         /* LOCK_SH|LOCK_NB - get a non-blocking shared lock */
00106       case LOCK_SH|LOCK_NB:
00107         rb_notimplement();
00108         return -1;
00109         /* LOCK_EX|LOCK_NB - get a non-blocking exclusive lock */
00110       case LOCK_EX|LOCK_NB:
00111         return lockf (fd, F_TLOCK, 0);
00112 
00113         /* LOCK_UN - unlock */
00114       case LOCK_UN:
00115         return lockf (fd, F_ULOCK, 0);
00116 
00117         /* Default - can't decipher operation */
00118       default:
00119         errno = EINVAL;
00120         return -1;
00121     }
00122 }
00123 #else
00124 int
00125 flock(int fd, int operation)
00126 {
00127     rb_notimplement();
00128     return -1;
00129 }
00130 #endif
00131