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
|
.\" Copyright (c) 1989, 1991, 1993
|
||||||
.\" The Regents of the University of California. All rights reserved.
|
.\" The Regents of the University of California. All rights reserved.
|
||||||
|
@ -29,7 +29,7 @@
|
||||||
.\"
|
.\"
|
||||||
.\" @(#)setmode.3 8.2 (Berkeley) 4/28/95
|
.\" @(#)setmode.3 8.2 (Berkeley) 4/28/95
|
||||||
.\"
|
.\"
|
||||||
.Dd May 17, 2005
|
.Dd October 1, 2005
|
||||||
.Dt SETMODE 3
|
.Dt SETMODE 3
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
|
@ -95,6 +95,17 @@ for any of the errors specified for the library routines
|
||||||
.Xr malloc 3
|
.Xr malloc 3
|
||||||
or
|
or
|
||||||
.Xr strtol 3 .
|
.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
|
.Sh SEE ALSO
|
||||||
.Xr chmod 1 ,
|
.Xr chmod 1 ,
|
||||||
.Xr stat 2 ,
|
.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
|
* Copyright (c) 1989, 1993, 1994
|
||||||
|
@ -37,7 +37,7 @@
|
||||||
#if 0
|
#if 0
|
||||||
static char sccsid[] = "@(#)setmode.c 8.2 (Berkeley) 3/25/94";
|
static char sccsid[] = "@(#)setmode.c 8.2 (Berkeley) 3/25/94";
|
||||||
#else
|
#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
|
||||||
#endif /* LIBC_SCCS and not lint */
|
#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 <errno.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <limits.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#ifdef SETMODE_DEBUG
|
#ifdef SETMODE_DEBUG
|
||||||
|
@ -76,7 +77,7 @@ typedef struct bitcmd {
|
||||||
#define CMD2_OBITS 0x08
|
#define CMD2_OBITS 0x08
|
||||||
#define CMD2_UBITS 0x10
|
#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 *));
|
static void compress_mode __P((BITCMD *));
|
||||||
#ifdef SETMODE_DEBUG
|
#ifdef SETMODE_DEBUG
|
||||||
static void dumpmode __P((BITCMD *));
|
static void dumpmode __P((BITCMD *));
|
||||||
|
@ -165,15 +166,13 @@ common: if (set->cmd2 & CMD2_CLR) {
|
||||||
BITCMD *newset; \
|
BITCMD *newset; \
|
||||||
setlen += SET_LEN_INCR; \
|
setlen += SET_LEN_INCR; \
|
||||||
newset = realloc(saveset, sizeof(BITCMD) * setlen); \
|
newset = realloc(saveset, sizeof(BITCMD) * setlen); \
|
||||||
if (newset == NULL) { \
|
if (newset == NULL) \
|
||||||
free(saveset); \
|
goto out; \
|
||||||
return (NULL); \
|
|
||||||
} \
|
|
||||||
set = newset + (set - saveset); \
|
set = newset + (set - saveset); \
|
||||||
saveset = newset; \
|
saveset = newset; \
|
||||||
endset = newset + (setlen - 2); \
|
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)
|
} while (/*CONSTCOND*/0)
|
||||||
|
|
||||||
#define STANDARD_BITS (S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO)
|
#define STANDARD_BITS (S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO)
|
||||||
|
@ -182,16 +181,19 @@ void *
|
||||||
setmode(p)
|
setmode(p)
|
||||||
const char *p;
|
const char *p;
|
||||||
{
|
{
|
||||||
int perm, who;
|
int serrno;
|
||||||
char op, *ep;
|
char op, *ep;
|
||||||
BITCMD *set, *saveset, *endset;
|
BITCMD *set, *saveset, *endset;
|
||||||
sigset_t signset, sigoset;
|
sigset_t signset, sigoset;
|
||||||
mode_t mask;
|
mode_t mask, perm, permXbits, who;
|
||||||
|
long lval;
|
||||||
int equalopdone = 0; /* pacify gcc */
|
int equalopdone = 0; /* pacify gcc */
|
||||||
int permXbits, setlen;
|
int setlen;
|
||||||
|
|
||||||
if (!*p)
|
if (!*p) {
|
||||||
return (NULL);
|
errno = EINVAL;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get a copy of the mask for the permissions that are mask relative.
|
* Get a copy of the mask for the permissions that are mask relative.
|
||||||
|
@ -217,11 +219,19 @@ setmode(p)
|
||||||
* or illegal bits.
|
* or illegal bits.
|
||||||
*/
|
*/
|
||||||
if (isdigit((unsigned char)*p)) {
|
if (isdigit((unsigned char)*p)) {
|
||||||
perm = (mode_t)strtol(p, &ep, 8);
|
errno = 0;
|
||||||
if (*ep || perm & ~(STANDARD_BITS|S_ISTXT)) {
|
lval = strtol(p, &ep, 8);
|
||||||
free(saveset);
|
if (*ep) {
|
||||||
return (NULL);
|
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);
|
ADDCMD('=', (STANDARD_BITS|S_ISTXT), perm, mask);
|
||||||
set->cmd = 0;
|
set->cmd = 0;
|
||||||
return (saveset);
|
return (saveset);
|
||||||
|
@ -253,8 +263,8 @@ setmode(p)
|
||||||
}
|
}
|
||||||
|
|
||||||
getop: if ((op = *p++) != '+' && op != '-' && op != '=') {
|
getop: if ((op = *p++) != '+' && op != '-' && op != '=') {
|
||||||
free(saveset);
|
errno = EINVAL;
|
||||||
return (NULL);
|
goto out;
|
||||||
}
|
}
|
||||||
if (op == '=')
|
if (op == '=')
|
||||||
equalopdone = 0;
|
equalopdone = 0;
|
||||||
|
@ -349,14 +359,17 @@ apply: if (!*p)
|
||||||
dumpmode(saveset);
|
dumpmode(saveset);
|
||||||
#endif
|
#endif
|
||||||
return (saveset);
|
return (saveset);
|
||||||
|
out:
|
||||||
|
serrno = errno;
|
||||||
|
free(saveset);
|
||||||
|
errno = serrno;
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static BITCMD *
|
static BITCMD *
|
||||||
addcmd(set, op, who, oparg, mask)
|
addcmd(set, op, who, oparg, mask)
|
||||||
BITCMD *set;
|
BITCMD *set;
|
||||||
int oparg, who;
|
mode_t oparg, who, op, mask;
|
||||||
int op;
|
|
||||||
u_int mask;
|
|
||||||
{
|
{
|
||||||
|
|
||||||
_DIAGASSERT(set != NULL);
|
_DIAGASSERT(set != NULL);
|
||||||
|
|
Loading…
Reference in New Issue