- switch (l_whence) {
- case SEEK_SET: break;
- case SEEK_CUR: l_start += s.pos(); break;
- case SEEK_END: l_start += s.length(); break;
- default: return -1;
- }
-
- if (cmd != F_GETLK && cmd != F_SETLK) return -EINVAL;
-
- if (cmd == F_GETLK) {
- // Check if an l_type lock can be aquired. The only way to
- // do this within the Java API is to try and create a lock.
- Seekable.Lock lock = s.lock(l_start, l_len, l_type == F_RDLCK);
-
- if (lock != null) {
- // no lock exists
- memWrite(arg, SEEK_SET|(F_UNLCK<<16));
- lock.release();
- }
-
- return 0;
- }
-
- // now processing F_SETLK
- if (cmd != F_SETLK) return -EINVAL;
-
- if (l_type == F_UNLCK) {
- // release all locks that fall within the boundaries given
- for (int i=0; i < LOCK_MAX; i++) {
- if (locks[i] == null || !s.equals(locks[i].seekable()))
- continue;
-
- int pos = (int)locks[i].position();
- if (pos < l_start) continue;
- if (l_start != 0 && l_len != 0) // start/len 0 means unlock all
- if (pos + locks[i].size() > l_start + l_len)
- continue;
-
- locks[i].release();
- locks[i] = null;
- }
- return 0;
-
- } else if (l_type == F_RDLCK || l_type == F_WRLCK) {
- // first see if a lock already exists
- for (int i=0; i < LOCK_MAX; i++) {
- if (locks[i] == null || !s.equals(locks[i].seekable()))
- continue;
- int pos = (int)locks[i].position();
- int size = (int)locks[i].size();
- if (l_start < pos && pos + size < l_start + l_len) {
- // found a lock contained in the new requested lock
- locks[i].release();
- locks[i] = null;
-
- } else if (l_start >= pos && pos + size >= l_start + l_len) {
- // found a lock that contains the requested lock
- if (locks[i].isShared() == (l_type == F_RDLCK)) {
- memWrite(arg+4, pos);
- memWrite(arg+8, size);
- return 0;
- } else {
- locks[i].release();
- locks[i] = null;
- }
- }
- }
-
- // create the lock
- Seekable.Lock lock = s.lock(l_start, l_len, l_type == F_RDLCK);
- if (lock == null) return -EAGAIN;
-
- int i;
- for (i=0; i < LOCK_MAX; i++)
- if (locks[i] == null) break;
- if (i == LOCK_MAX) return -ENOLCK;
- locks[i] = lock;