Make sure that setmode sets errno on failure (it used to return a random
errno) and document it.
This commit is contained in:
parent
d15fb24907
commit
fbd01002b3
|
@ -1,4 +1,4 @@
|
|||
.\" $NetBSD: setmode.3,v 1.17 2005/06/04 00:39:26 wiz Exp $
|
||||
.\" $NetBSD: setmode.3,v 1.18 2005/10/01 20:08:01 christos Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 1989, 1991, 1993
|
||||
.\" The Regents of the University of California. All rights reserved.
|
||||
|
@ -29,7 +29,7 @@
|
|||
.\"
|
||||
.\" @(#)setmode.3 8.2 (Berkeley) 4/28/95
|
||||
.\"
|
||||
.Dd May 17, 2005
|
||||
.Dd October 1, 2005
|
||||
.Dt SETMODE 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
|
@ -95,6 +95,17 @@ for any of the errors specified for the library routines
|
|||
.Xr malloc 3
|
||||
or
|
||||
.Xr strtol 3 .
|
||||
In addition,
|
||||
.Fn setmode
|
||||
will fail and set
|
||||
.Va errno
|
||||
to:
|
||||
.Bl -tag -width Er
|
||||
.It Bq Er EINVAL
|
||||
The
|
||||
.Fa mode
|
||||
argument does not represent a valid mode.
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr chmod 1 ,
|
||||
.Xr stat 2 ,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: setmode.c,v 1.30 2003/08/07 16:42:56 agc Exp $ */
|
||||
/* $NetBSD: setmode.c,v 1.31 2005/10/01 20:08:01 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1989, 1993, 1994
|
||||
|
@ -37,7 +37,7 @@
|
|||
#if 0
|
||||
static char sccsid[] = "@(#)setmode.c 8.2 (Berkeley) 3/25/94";
|
||||
#else
|
||||
__RCSID("$NetBSD: setmode.c,v 1.30 2003/08/07 16:42:56 agc Exp $");
|
||||
__RCSID("$NetBSD: setmode.c,v 1.31 2005/10/01 20:08:01 christos Exp $");
|
||||
#endif
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
|
@ -50,6 +50,7 @@ __RCSID("$NetBSD: setmode.c,v 1.30 2003/08/07 16:42:56 agc Exp $");
|
|||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <stdlib.h>
|
||||
#include <limits.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifdef SETMODE_DEBUG
|
||||
|
@ -76,7 +77,7 @@ typedef struct bitcmd {
|
|||
#define CMD2_OBITS 0x08
|
||||
#define CMD2_UBITS 0x10
|
||||
|
||||
static BITCMD *addcmd __P((BITCMD *, int, int, int, u_int));
|
||||
static BITCMD *addcmd __P((BITCMD *, mode_t, mode_t, mode_t, mode_t));
|
||||
static void compress_mode __P((BITCMD *));
|
||||
#ifdef SETMODE_DEBUG
|
||||
static void dumpmode __P((BITCMD *));
|
||||
|
@ -165,15 +166,13 @@ common: if (set->cmd2 & CMD2_CLR) {
|
|||
BITCMD *newset; \
|
||||
setlen += SET_LEN_INCR; \
|
||||
newset = realloc(saveset, sizeof(BITCMD) * setlen); \
|
||||
if (newset == NULL) { \
|
||||
free(saveset); \
|
||||
return (NULL); \
|
||||
} \
|
||||
if (newset == NULL) \
|
||||
goto out; \
|
||||
set = newset + (set - saveset); \
|
||||
saveset = newset; \
|
||||
endset = newset + (setlen - 2); \
|
||||
} \
|
||||
set = addcmd(set, (a), (b), (c), (d)); \
|
||||
set = addcmd(set, (mode_t)(a), (mode_t)(b), (mode_t)(c), (d)); \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
#define STANDARD_BITS (S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO)
|
||||
|
@ -182,16 +181,19 @@ void *
|
|||
setmode(p)
|
||||
const char *p;
|
||||
{
|
||||
int perm, who;
|
||||
int serrno;
|
||||
char op, *ep;
|
||||
BITCMD *set, *saveset, *endset;
|
||||
sigset_t signset, sigoset;
|
||||
mode_t mask;
|
||||
mode_t mask, perm, permXbits, who;
|
||||
long lval;
|
||||
int equalopdone = 0; /* pacify gcc */
|
||||
int permXbits, setlen;
|
||||
int setlen;
|
||||
|
||||
if (!*p)
|
||||
return (NULL);
|
||||
if (!*p) {
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get a copy of the mask for the permissions that are mask relative.
|
||||
|
@ -217,11 +219,19 @@ setmode(p)
|
|||
* or illegal bits.
|
||||
*/
|
||||
if (isdigit((unsigned char)*p)) {
|
||||
perm = (mode_t)strtol(p, &ep, 8);
|
||||
if (*ep || perm & ~(STANDARD_BITS|S_ISTXT)) {
|
||||
free(saveset);
|
||||
return (NULL);
|
||||
errno = 0;
|
||||
lval = strtol(p, &ep, 8);
|
||||
if (*ep) {
|
||||
errno = EINVAL;
|
||||
goto out;
|
||||
}
|
||||
if (errno == ERANGE && (lval == LONG_MAX || lval == LONG_MIN))
|
||||
goto out;
|
||||
if (lval & ~(STANDARD_BITS|S_ISTXT)) {
|
||||
errno = EINVAL;
|
||||
goto out;
|
||||
}
|
||||
perm = (mode_t)lval;
|
||||
ADDCMD('=', (STANDARD_BITS|S_ISTXT), perm, mask);
|
||||
set->cmd = 0;
|
||||
return (saveset);
|
||||
|
@ -253,8 +263,8 @@ setmode(p)
|
|||
}
|
||||
|
||||
getop: if ((op = *p++) != '+' && op != '-' && op != '=') {
|
||||
free(saveset);
|
||||
return (NULL);
|
||||
errno = EINVAL;
|
||||
goto out;
|
||||
}
|
||||
if (op == '=')
|
||||
equalopdone = 0;
|
||||
|
@ -349,14 +359,17 @@ apply: if (!*p)
|
|||
dumpmode(saveset);
|
||||
#endif
|
||||
return (saveset);
|
||||
out:
|
||||
serrno = errno;
|
||||
free(saveset);
|
||||
errno = serrno;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static BITCMD *
|
||||
addcmd(set, op, who, oparg, mask)
|
||||
BITCMD *set;
|
||||
int oparg, who;
|
||||
int op;
|
||||
u_int mask;
|
||||
mode_t oparg, who, op, mask;
|
||||
{
|
||||
|
||||
_DIAGASSERT(set != NULL);
|
||||
|
|
Loading…
Reference in New Issue