summaryrefslogtreecommitdiff
path: root/lib/libc/gen
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libc/gen')
-rw-r--r--lib/libc/gen/setmode.36
-rw-r--r--lib/libc/gen/setmode.c29
2 files changed, 21 insertions, 14 deletions
diff --git a/lib/libc/gen/setmode.3 b/lib/libc/gen/setmode.3
index d6f49df1122..ef87d927a26 100644
--- a/lib/libc/gen/setmode.3
+++ b/lib/libc/gen/setmode.3
@@ -1,4 +1,4 @@
-.\" $OpenBSD: setmode.3,v 1.11 2004/07/02 16:10:52 jmc Exp $
+.\" $OpenBSD: setmode.3,v 1.12 2005/10/26 20:37:13 otto Exp $
.\"
.\" Copyright (c) 1989, 1991, 1993
.\" The Regents of the University of California. All rights reserved.
@@ -91,7 +91,9 @@ for any of the errors specified for the library routine
.Xr malloc 3
or to
.Er ERANGE
-if an invalid octal value was specified.
+if an invalid octal value was specified, or
+.Er EINVAL
+if an invalid symbolic value was specified.
.Sh SEE ALSO
.Xr chmod 1 ,
.Xr stat 2 ,
diff --git a/lib/libc/gen/setmode.c b/lib/libc/gen/setmode.c
index 22353badbde..e0b6dfc1a1d 100644
--- a/lib/libc/gen/setmode.c
+++ b/lib/libc/gen/setmode.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: setmode.c,v 1.17 2005/08/08 08:05:34 espie Exp $ */
+/* $OpenBSD: setmode.c,v 1.18 2005/10/26 20:37:13 otto Exp $ */
/* $NetBSD: setmode.c,v 1.15 1997/02/07 22:21:06 christos Exp $ */
/*
@@ -161,16 +161,17 @@ common: if (set->cmd2 & CMD2_CLR) {
void *
setmode(const char *p)
{
- int perm, who;
char op, *ep;
- BITCMD *set, *saveset, *endset;
+ BITCMD *set, *saveset = NULL, *endset;
sigset_t sigset, sigoset;
- mode_t mask;
- int equalopdone, permXbits, setlen;
+ mode_t mask, perm, permXbits, who;
+ int equalopdone, setlen, serrno;
u_long perml;
- if (!*p)
- return (NULL);
+ if (!*p) {
+ errno = EINVAL;
+ goto out;
+ }
/*
* Get a copy of the mask for the permissions that are mask relative.
@@ -187,7 +188,7 @@ setmode(const char *p)
setlen = SET_LEN + 2;
if ((set = malloc((u_int)(sizeof(BITCMD) * setlen))) == NULL)
- return (NULL);
+ goto out;
saveset = set;
endset = set + (setlen - 2);
@@ -199,9 +200,8 @@ setmode(const char *p)
perml = strtoul(p, &ep, 8);
/* The test on perml will also catch overflow. */
if (*ep != '\0' || (perml & ~(STANDARD_BITS|S_ISTXT))) {
- free(saveset);
errno = ERANGE;
- return (NULL);
+ goto out;
}
perm = (mode_t)perml;
ADDCMD('=', (STANDARD_BITS|S_ISTXT), perm, mask);
@@ -235,8 +235,8 @@ setmode(const char *p)
}
getop: if ((op = *p++) != '+' && op != '-' && op != '=') {
- free(saveset);
- return (NULL);
+ errno = EINVAL;
+ goto out;
}
if (op == '=')
equalopdone = 0;
@@ -331,6 +331,11 @@ apply: if (!*p)
dumpmode(saveset);
#endif
return (saveset);
+out:
+ serrno = errno;
+ free(saveset);
+ errno = serrno;
+ return (NULL);
}
static BITCMD *