summaryrefslogtreecommitdiff
path: root/os2/os2.c
diff options
context:
space:
mode:
authorIlya Zakharevich <ilya@math.ohio-state.edu>1997-06-09 16:52:06 +1200
committerTim Bunce <Tim.Bunce@ig.co.uk>1997-08-07 00:00:00 +1200
commit367f3c247e808d76465803ec861b19fd55ffd90d (patch)
tree4ca58250b62dedd5b9ff9bae8d8a993b3debb769 /os2/os2.c
parent17fd57d4d5d145d80aa9549b4fb89625b31a4148 (diff)
downloadperl-367f3c247e808d76465803ec861b19fd55ffd90d.tar.gz
Assorted OS/2 fixes
In article <9706131709.AA05526@toad.ig.co.uk>, Tim Bunce <Tim.Bunce@ig.co.uk> wrote: > It give me great pleasure to announce the arrival of perl5.004_01. Thank you for a great job! You even corrected os2/diff.configure! Unfortunately, several sections of os2/diff.configure were erroneously removed, so it will not create a valid config.sh any more (ar used instead of $ar, and one extra method to extract symbols is not tried). Unfortunately, I was away from my development machine, so could not try it earlier. A patch to correct this problem, and some other ones, follows. a) Missing sections restored; os2/diff.configure b) my_flock added to os2/os2.c (libc contains a dummy implementation only) (switchable off in case CRT DLL is fixed in this respect); os2/os2ish.h os2/Makefile.SHs os2/os2.c c) depending on architecture, waitpid may be implemented or not. New define HAS_WAITPID_RUNTIME is added and wait4pid corrected correspondingly; os2/os2ish.h util.c d) if -S was given and the file name contained \ , it was nevertheless searched on path; perl.c e) updated: os2/Changes README.os2 f) by default use better gcc optimization options (as mbeattie advices): hints/os2.sh [editor's note: this was applied in the reverse order to one a couple of commits ago] p5p-msgid: 1997Jun16.163234.2091727@hmivax.humgen.upenn.edu
Diffstat (limited to 'os2/os2.c')
-rw-r--r--os2/os2.c113
1 files changed, 113 insertions, 0 deletions
diff --git a/os2/os2.c b/os2/os2.c
index c45dfecd1e..80742429be 100644
--- a/os2/os2.c
+++ b/os2/os2.c
@@ -1196,3 +1196,116 @@ my_tmpfile ()
return fopen(my_tmpnam(NULL), "w+b"); /* Race condition, but
grants TMP. */
}
+
+#undef flock
+
+/* This code was contributed by Rocco Caputo. */
+int
+my_flock(int handle, int op)
+{
+ FILELOCK rNull, rFull;
+ ULONG timeout, handle_type, flag_word;
+ APIRET rc;
+ int blocking, shared;
+ static int use_my = -1;
+
+ if (use_my == -1) {
+ char *s = getenv("USE_PERL_FLOCK");
+ if (s)
+ use_my = atoi(s);
+ else
+ use_my = 1;
+ }
+ if (!(_emx_env & 0x200) || !use_my)
+ return flock(handle, op); /* Delegate to EMX. */
+
+ // is this a file?
+ if ((DosQueryHType(handle, &handle_type, &flag_word) != 0) ||
+ (handle_type & 0xFF))
+ {
+ errno = EBADF;
+ return -1;
+ }
+ // set lock/unlock ranges
+ rNull.lOffset = rNull.lRange = rFull.lOffset = 0;
+ rFull.lRange = 0x7FFFFFFF;
+ // set timeout for blocking
+ timeout = ((blocking = !(op & LOCK_NB))) ? 100 : 1;
+ // shared or exclusive?
+ shared = (op & LOCK_SH) ? 1 : 0;
+ // do not block the unlock
+ if (op & (LOCK_UN | LOCK_SH | LOCK_EX)) {
+ rc = DosSetFileLocks(handle, &rFull, &rNull, timeout, shared);
+ switch (rc) {
+ case 0:
+ errno = 0;
+ return 0;
+ case ERROR_INVALID_HANDLE:
+ errno = EBADF;
+ return -1;
+ case ERROR_SHARING_BUFFER_EXCEEDED:
+ errno = ENOLCK;
+ return -1;
+ case ERROR_LOCK_VIOLATION:
+ break; // not an error
+ case ERROR_INVALID_PARAMETER:
+ case ERROR_ATOMIC_LOCK_NOT_SUPPORTED:
+ case ERROR_READ_LOCKS_NOT_SUPPORTED:
+ errno = EINVAL;
+ return -1;
+ case ERROR_INTERRUPT:
+ errno = EINTR;
+ return -1;
+ default:
+ errno = EINVAL;
+ return -1;
+ }
+ }
+ // lock may block
+ if (op & (LOCK_SH | LOCK_EX)) {
+ // for blocking operations
+ for (;;) {
+ rc =
+ DosSetFileLocks(
+ handle,
+ &rNull,
+ &rFull,
+ timeout,
+ shared
+ );
+ switch (rc) {
+ case 0:
+ errno = 0;
+ return 0;
+ case ERROR_INVALID_HANDLE:
+ errno = EBADF;
+ return -1;
+ case ERROR_SHARING_BUFFER_EXCEEDED:
+ errno = ENOLCK;
+ return -1;
+ case ERROR_LOCK_VIOLATION:
+ if (!blocking) {
+ errno = EWOULDBLOCK;
+ return -1;
+ }
+ break;
+ case ERROR_INVALID_PARAMETER:
+ case ERROR_ATOMIC_LOCK_NOT_SUPPORTED:
+ case ERROR_READ_LOCKS_NOT_SUPPORTED:
+ errno = EINVAL;
+ return -1;
+ case ERROR_INTERRUPT:
+ errno = EINTR;
+ return -1;
+ default:
+ errno = EINVAL;
+ return -1;
+ }
+ // give away timeslice
+ DosSleep(1);
+ }
+ }
+
+ errno = 0;
+ return 0;
+}