Skip to content

Commit 687f45a

Browse files
gh-48511: Make pwd and grp expose inner errors
Distinguish between the case when the user/group does not exist and error conditions. If the user does not exit, raise KeyError as now, for errors raise OSError.
1 parent 7e5227f commit 687f45a

3 files changed

Lines changed: 63 additions & 45 deletions

File tree

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
The Unix user (:func:`pwd.getpwuid`, :func:`pwd.getpwnam`) and group
2+
(:func:`grp.getgrgid`, :func:`grp.getgrnam`) database functions now
3+
differentiate between a lack of record (:exc:`KeyError` is risen, the current behaviour)
4+
and a database access error (:exc:`OSError` is risen).
5+
6+
Based on a patch by Oleg Iarygin.

‎Modules/grpmodule.c‎

Lines changed: 28 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -176,24 +176,29 @@ grp_getgrgid_impl(PyObject *module, gid_t gid)
176176
p = getgrgid(gid);
177177
#endif
178178
if (p == NULL) {
179-
#ifndef HAVE_GETGRGID_R
180-
PyMutex_Unlock(&group_db_mutex);
181-
#endif
182-
PyMem_RawFree(buf);
183179
if (nomem == 1) {
184-
return PyErr_NoMemory();
180+
retval = PyErr_NoMemory();
181+
}
182+
else if (errno == 0) {
183+
PyObject *gid_obj = _PyLong_FromGid(gid);
184+
if (gid_obj == NULL) {
185+
retval = NULL;
186+
}
187+
else {
188+
retval = PyErr_Format(PyExc_KeyError,
189+
"getgrgid(): gid not found: %S", gid_obj);
190+
Py_DECREF(gid_obj);
191+
}
192+
}
193+
else {
194+
retval = PyErr_SetFromErrno(PyExc_OSError);
185195
}
186-
PyObject *gid_obj = _PyLong_FromGid(gid);
187-
if (gid_obj == NULL)
188-
return NULL;
189-
PyErr_Format(PyExc_KeyError, "getgrgid(): gid not found: %S", gid_obj);
190-
Py_DECREF(gid_obj);
191-
return NULL;
192196
}
193-
retval = mkgrent(module, p);
194-
#ifdef HAVE_GETGRGID_R
197+
else {
198+
retval = mkgrent(module, p);
199+
}
195200
PyMem_RawFree(buf);
196-
#else
201+
#ifndef HAVE_GETGRGID_R
197202
PyMutex_Unlock(&group_db_mutex);
198203
#endif
199204
return retval;
@@ -265,18 +270,20 @@ grp_getgrnam_impl(PyObject *module, PyObject *name)
265270
p = getgrnam(name_chars);
266271
#endif
267272
if (p == NULL) {
268-
#ifndef HAVE_GETGRNAM_R
269-
PyMutex_Unlock(&group_db_mutex);
270-
#endif
271273
if (nomem == 1) {
272-
PyErr_NoMemory();
274+
retval = PyErr_NoMemory();
275+
}
276+
else if (errno == 0) {
277+
retval = PyErr_Format(PyExc_KeyError,
278+
"getgrnam(): name not found: %R", name);
273279
}
274280
else {
275-
PyErr_Format(PyExc_KeyError, "getgrnam(): name not found: %R", name);
281+
retval = PyErr_SetFromErrno(PyExc_OSError);
276282
}
277-
goto out;
278283
}
279-
retval = mkgrent(module, p);
284+
else {
285+
retval = mkgrent(module, p);
286+
}
280287
#ifndef HAVE_GETGRNAM_R
281288
PyMutex_Unlock(&group_db_mutex);
282289
#endif

‎Modules/pwdmodule.c‎

Lines changed: 29 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -180,27 +180,31 @@ pwd_getpwuid_impl(PyObject *module, uid_t uid)
180180
p = getpwuid(uid);
181181
#endif
182182
if (p == NULL) {
183-
#ifndef HAVE_GETPWUID_R
184-
PyMutex_Unlock(&pwd_db_mutex);
185-
#endif
186-
PyMem_RawFree(buf);
187183
if (nomem == 1) {
188-
return PyErr_NoMemory();
184+
retval = PyErr_NoMemory();
185+
}
186+
else if (errno == 0) {
187+
PyObject *uid_obj = _PyLong_FromUid(uid);
188+
if (uid_obj == NULL) {
189+
retval = NULL;
190+
}
191+
else {
192+
retval = PyErr_Format(PyExc_KeyError,
193+
"getpwuid(): uid not found: %S", uid_obj);
194+
Py_DECREF(uid_obj);
195+
}
196+
}
197+
else {
198+
retval = PyErr_SetFromErrno(PyExc_OSError);
189199
}
190-
PyObject *uid_obj = _PyLong_FromUid(uid);
191-
if (uid_obj == NULL)
192-
return NULL;
193-
PyErr_Format(PyExc_KeyError,
194-
"getpwuid(): uid not found: %S", uid_obj);
195-
Py_DECREF(uid_obj);
196-
return NULL;
197200
}
198-
retval = mkpwent(module, p);
199-
#ifdef HAVE_GETPWUID_R
200-
PyMem_RawFree(buf);
201-
#else
201+
else {
202+
retval = mkpwent(module, p);
203+
}
204+
#ifndef HAVE_GETPWUID_R
202205
PyMutex_Unlock(&pwd_db_mutex);
203206
#endif
207+
PyMem_RawFree(buf);
204208
return retval;
205209
}
206210

@@ -271,19 +275,20 @@ pwd_getpwnam_impl(PyObject *module, PyObject *name)
271275
p = getpwnam(name_chars);
272276
#endif
273277
if (p == NULL) {
274-
#ifndef HAVE_GETPWNAM_R
275-
PyMutex_Unlock(&pwd_db_mutex);
276-
#endif
277278
if (nomem == 1) {
278-
PyErr_NoMemory();
279+
retval = PyErr_NoMemory();
280+
}
281+
else if (errno == 0) {
282+
retval = PyErr_Format(PyExc_KeyError,
283+
"getpwnam(): name not found: %R", name);
279284
}
280285
else {
281-
PyErr_Format(PyExc_KeyError,
282-
"getpwnam(): name not found: %R", name);
286+
retval = PyErr_SetFromErrno(PyExc_OSError);
283287
}
284-
goto out;
285288
}
286-
retval = mkpwent(module, p);
289+
else {
290+
retval = mkpwent(module, p);
291+
}
287292
#ifndef HAVE_GETPWNAM_R
288293
PyMutex_Unlock(&pwd_db_mutex);
289294
#endif

0 commit comments

Comments
 (0)