mirror of
git://git.musl-libc.org/musl
synced 2025-01-30 10:32:04 +00:00
refactor group file access code
this allows getgrnam and getgrgid to share code with the _r versions in preparation for alternate backend support.
This commit is contained in:
parent
4e8a356165
commit
7c5f0a5212
@ -5,6 +5,8 @@ struct group *fgetgrent(FILE *f)
|
||||
{
|
||||
static char *line, **mem;
|
||||
static struct group gr;
|
||||
struct group *res;
|
||||
size_t size=0, nmem=0;
|
||||
return __getgrent_a(f, &gr, &line, &size, &mem, &nmem);
|
||||
__getgrent_a(f, &gr, &line, &size, &mem, &nmem, &res);
|
||||
return res;
|
||||
}
|
||||
|
32
src/passwd/getgr_a.c
Normal file
32
src/passwd/getgr_a.c
Normal file
@ -0,0 +1,32 @@
|
||||
#include <pthread.h>
|
||||
#include "pwf.h"
|
||||
|
||||
int __getgr_a(const char *name, gid_t gid, struct group *gr, char **buf, size_t *size, char ***mem, size_t *nmem, struct group **res)
|
||||
{
|
||||
FILE *f;
|
||||
int rv = 0;
|
||||
int cs;
|
||||
|
||||
*res = 0;
|
||||
|
||||
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
|
||||
|
||||
f = fopen("/etc/group", "rbe");
|
||||
if (!f) {
|
||||
rv = errno;
|
||||
goto done;
|
||||
}
|
||||
|
||||
while (!(rv = __getgrent_a(f, gr, buf, size, mem, nmem, res)) && *res) {
|
||||
if (name && !strcmp(name, (*res)->gr_name)
|
||||
|| !name && (*res)->gr_gid == gid) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
fclose(f);
|
||||
|
||||
done:
|
||||
pthread_setcancelstate(cs, 0);
|
||||
if (rv) errno = rv;
|
||||
return rv;
|
||||
}
|
@ -5,7 +5,6 @@
|
||||
|
||||
static int getgr_r(const char *name, gid_t gid, struct group *gr, char *buf, size_t size, struct group **res)
|
||||
{
|
||||
FILE *f;
|
||||
char *line = 0;
|
||||
size_t len = 0;
|
||||
char **mem = 0;
|
||||
@ -16,37 +15,24 @@ static int getgr_r(const char *name, gid_t gid, struct group *gr, char *buf, siz
|
||||
|
||||
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
|
||||
|
||||
f = fopen("/etc/group", "rbe");
|
||||
if (!f) {
|
||||
rv = errno;
|
||||
goto done;
|
||||
rv = __getgr_a(name, gid, gr, &line, &len, &mem, &nmem, res);
|
||||
if (!rv && size < len + (nmem+1)*sizeof(char *) + 32) {
|
||||
*res = 0;
|
||||
rv = ERANGE;
|
||||
}
|
||||
|
||||
*res = 0;
|
||||
while (__getgrent_a(f, gr, &line, &len, &mem, &nmem)) {
|
||||
if (name && !strcmp(name, gr->gr_name)
|
||||
|| !name && gr->gr_gid == gid) {
|
||||
if (size < len + (nmem+1)*sizeof(char *) + 32) {
|
||||
rv = ERANGE;
|
||||
break;
|
||||
}
|
||||
*res = gr;
|
||||
buf += (16-(uintptr_t)buf)%16;
|
||||
gr->gr_mem = (void *)buf;
|
||||
buf += (nmem+1)*sizeof(char *);
|
||||
memcpy(buf, line, len);
|
||||
FIX(name);
|
||||
FIX(passwd);
|
||||
for (i=0; mem[i]; i++)
|
||||
gr->gr_mem[i] = mem[i]-line+buf;
|
||||
gr->gr_mem[i] = 0;
|
||||
break;
|
||||
}
|
||||
if (!rv) {
|
||||
buf += (16-(uintptr_t)buf)%16;
|
||||
gr->gr_mem = (void *)buf;
|
||||
buf += (nmem+1)*sizeof(char *);
|
||||
memcpy(buf, line, len);
|
||||
FIX(name);
|
||||
FIX(passwd);
|
||||
for (i=0; mem[i]; i++)
|
||||
gr->gr_mem[i] = mem[i]-line+buf;
|
||||
gr->gr_mem[i] = 0;
|
||||
}
|
||||
free(mem);
|
||||
free(line);
|
||||
fclose(f);
|
||||
done:
|
||||
pthread_setcancelstate(cs, 0);
|
||||
return rv;
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
#include "pwf.h"
|
||||
|
||||
static FILE *f;
|
||||
static char *line, **mem;
|
||||
static struct group gr;
|
||||
|
||||
void setgrent()
|
||||
{
|
||||
@ -12,34 +14,26 @@ weak_alias(setgrent, endgrent);
|
||||
|
||||
struct group *getgrent()
|
||||
{
|
||||
static char *line, **mem;
|
||||
static struct group gr;
|
||||
struct group *res;
|
||||
size_t size=0, nmem=0;
|
||||
if (!f) f = fopen("/etc/group", "rbe");
|
||||
if (!f) return 0;
|
||||
return __getgrent_a(f, &gr, &line, &size, &mem, &nmem);
|
||||
__getgrent_a(f, &gr, &line, &size, &mem, &nmem, &res);
|
||||
return res;
|
||||
}
|
||||
|
||||
struct group *getgrgid(gid_t gid)
|
||||
{
|
||||
struct group *gr;
|
||||
int errno_saved;
|
||||
setgrent();
|
||||
while ((gr=getgrent()) && gr->gr_gid != gid);
|
||||
errno_saved = errno;
|
||||
endgrent();
|
||||
errno = errno_saved;
|
||||
return gr;
|
||||
struct group *res;
|
||||
size_t size=0, nmem=0;
|
||||
__getgr_a(0, gid, &gr, &line, &size, &mem, &nmem, &res);
|
||||
return res;
|
||||
}
|
||||
|
||||
struct group *getgrnam(const char *name)
|
||||
{
|
||||
struct group *gr;
|
||||
int errno_saved;
|
||||
setgrent();
|
||||
while ((gr=getgrent()) && strcmp(gr->gr_name, name));
|
||||
errno_saved = errno;
|
||||
endgrent();
|
||||
errno = errno_saved;
|
||||
return gr;
|
||||
struct group *res;
|
||||
size_t size=0, nmem=0;
|
||||
__getgr_a(name, 0, &gr, &line, &size, &mem, &nmem, &res);
|
||||
return res;
|
||||
}
|
||||
|
@ -8,15 +8,17 @@ static unsigned atou(char **s)
|
||||
return x;
|
||||
}
|
||||
|
||||
struct group *__getgrent_a(FILE *f, struct group *gr, char **line, size_t *size, char ***mem, size_t *nmem)
|
||||
int __getgrent_a(FILE *f, struct group *gr, char **line, size_t *size, char ***mem, size_t *nmem, struct group **res)
|
||||
{
|
||||
ssize_t l;
|
||||
char *s, *mems;
|
||||
size_t i;
|
||||
int rv = 0;
|
||||
int cs;
|
||||
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
|
||||
for (;;) {
|
||||
if ((l=getline(line, size, f)) < 0) {
|
||||
rv = errno;
|
||||
free(*line);
|
||||
*line = 0;
|
||||
gr = 0;
|
||||
@ -43,6 +45,7 @@ struct group *__getgrent_a(FILE *f, struct group *gr, char **line, size_t *size,
|
||||
free(*mem);
|
||||
*mem = calloc(sizeof(char *), *nmem+1);
|
||||
if (!*mem) {
|
||||
rv = errno;
|
||||
free(*line);
|
||||
*line = 0;
|
||||
return 0;
|
||||
@ -58,5 +61,7 @@ struct group *__getgrent_a(FILE *f, struct group *gr, char **line, size_t *size,
|
||||
gr->gr_mem = *mem;
|
||||
end:
|
||||
pthread_setcancelstate(cs, 0);
|
||||
return gr;
|
||||
*res = gr;
|
||||
if(rv) errno = rv;
|
||||
return rv;
|
||||
}
|
||||
|
@ -10,5 +10,6 @@
|
||||
|
||||
int __getpwent_a(FILE *f, struct passwd *pw, char **line, size_t *size, struct passwd **res);
|
||||
int __getpw_a(const char *name, uid_t uid, struct passwd *pw, char **buf, size_t *size, struct passwd **res);
|
||||
struct group *__getgrent_a(FILE *f, struct group *gr, char **line, size_t *size, char ***mem, size_t *nmem);
|
||||
int __getgrent_a(FILE *f, struct group *gr, char **line, size_t *size, char ***mem, size_t *nmem, struct group **res);
|
||||
int __getgr_a(const char *name, gid_t gid, struct group *gr, char **buf, size_t *size, char ***mem, size_t *nmem, struct group **res);
|
||||
int __parsespent(char *s, struct spwd *sp);
|
||||
|
Loading…
Reference in New Issue
Block a user