summaryrefslogtreecommitdiff
path: root/doio.c
diff options
context:
space:
mode:
authorJarkko Hietaniemi <jhi@iki.fi>2002-01-27 17:37:54 +0000
committerJarkko Hietaniemi <jhi@iki.fi>2002-01-27 17:37:54 +0000
commit3dccc55c6f7c2628aaa90e6f846f1f28d1834fac (patch)
tree6f8b004cbda1c20733d281336bb2f256de0934df /doio.c
parent07229bbd38a40809e9122ae72c3fd635b9fe18eb (diff)
downloadperl-3dccc55c6f7c2628aaa90e6f846f1f28d1834fac.tar.gz
O_RDONLY/O_WRONLY/O_RDWR portability.
p4raw-id: //depot/perl@14445
Diffstat (limited to 'doio.c')
-rw-r--r--doio.c42
1 files changed, 34 insertions, 8 deletions
diff --git a/doio.c b/doio.c
index ca15cd745d..ab74d4a21c 100644
--- a/doio.c
+++ b/doio.c
@@ -140,18 +140,44 @@ Perl_do_openn(pTHX_ GV *gv, register char *name, I32 len, int as_raw,
if (as_raw) {
/* sysopen style args, i.e. integer mode and permissions */
STRLEN ix = 0;
- if (num_svs != 0) {
- Perl_croak(aTHX_ "panic: sysopen with multiple args");
- }
- if (rawmode & (O_WRONLY|O_RDWR|O_CREAT
+ int appendtrunc =
+ 0
#ifdef O_APPEND /* Not fully portable. */
- |O_APPEND
+ |O_APPEND
#endif
#ifdef O_TRUNC /* Not fully portable. */
- |O_TRUNC
+ |O_TRUNC
#endif
- ))
- TAINT_PROPER("sysopen");
+ ;
+ int modifyingmode =
+ O_WRONLY|O_RDWR|O_CREAT|appendtrunc;
+ int ismodifying;
+
+ if (num_svs != 0) {
+ Perl_croak(aTHX_ "panic: sysopen with multiple args");
+ }
+ /* It's not always
+
+ O_RDONLY 0
+ O_WRONLY 1
+ O_RDWR 2
+
+ It might be (in OS/390 and Mac OS Classic it is)
+
+ O_WRONLY 1
+ O_RDONLY 2
+ O_RDWR 3
+
+ This means that simple & with O_RDWR would look
+ like O_RDONLY is present. Therefore we have to
+ be more careful.
+ */
+ if ((ismodifying = (rawmode & modifyingmode))) {
+ if ((ismodifying & O_WRONLY) == O_WRONLY ||
+ (ismodifying & O_RDWR) == O_RDWR ||
+ (ismodifying & (O_CREAT|appendtrunc)))
+ TAINT_PROPER("sysopen");
+ }
mode[ix++] = '#'; /* Marker to openn to use numeric "sysopen" */
#if defined(USE_64_BIT_RAWIO) && defined(O_LARGEFILE)