Skip to content

Commit bae90cd

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 0274d83 commit bae90cd

File tree

3 files changed

+63
-45
lines changed

3 files changed

+63
-45
lines changed
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
@@ -179,24 +179,29 @@ grp_getgrgid_impl(PyObject *module, PyObject *id)
179179
p = getgrgid(gid);
180180
#endif
181181
if (p == NULL) {
182-
#ifndef HAVE_GETGRGID_R
183-
PyMutex_Unlock(&group_db_mutex);
184-
#endif
185-
PyMem_RawFree(buf);
186182
if (nomem == 1) {
187-
return PyErr_NoMemory();
183+
retval = PyErr_NoMemory();
184+
}
185+
else if (errno == 0) {
186+
PyObject *gid_obj = _PyLong_FromGid(gid);
187+
if (gid_obj == NULL) {
188+
retval = NULL;
189+
}
190+
else {
191+
retval = PyErr_Format(PyExc_KeyError,
192+
"getgrgid(): gid not found: %S", gid_obj);
193+
Py_DECREF(gid_obj);
194+
}
195+
}
196+
else {
197+
retval = PyErr_SetFromErrno(PyExc_OSError);
188198
}
189-
PyObject *gid_obj = _PyLong_FromGid(gid);
190-
if (gid_obj == NULL)
191-
return NULL;
192-
PyErr_Format(PyExc_KeyError, "getgrgid(): gid not found: %S", gid_obj);
193-
Py_DECREF(gid_obj);
194-
return NULL;
195199
}
196-
retval = mkgrent(module, p);
197-
#ifdef HAVE_GETGRGID_R
200+
else {
201+
retval = mkgrent(module, p);
202+
}
198203
PyMem_RawFree(buf);
199-
#else
204+
#ifndef HAVE_GETGRGID_R
200205
PyMutex_Unlock(&group_db_mutex);
201206
#endif
202207
return retval;
@@ -268,18 +273,20 @@ grp_getgrnam_impl(PyObject *module, PyObject *name)
268273
p = getgrnam(name_chars);
269274
#endif
270275
if (p == NULL) {
271-
#ifndef HAVE_GETGRNAM_R
272-
PyMutex_Unlock(&group_db_mutex);
273-
#endif
274276
if (nomem == 1) {
275-
PyErr_NoMemory();
277+
retval = PyErr_NoMemory();
278+
}
279+
else if (errno == 0) {
280+
retval = PyErr_Format(PyExc_KeyError,
281+
"getgrnam(): name not found: %R", name);
276282
}
277283
else {
278-
PyErr_Format(PyExc_KeyError, "getgrnam(): name not found: %R", name);
284+
retval = PyErr_SetFromErrno(PyExc_OSError);
279285
}
280-
goto out;
281286
}
282-
retval = mkgrent(module, p);
287+
else {
288+
retval = mkgrent(module, p);
289+
}
283290
#ifndef HAVE_GETGRNAM_R
284291
PyMutex_Unlock(&group_db_mutex);
285292
#endif

Modules/pwdmodule.c

Lines changed: 29 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -187,27 +187,31 @@ pwd_getpwuid(PyObject *module, PyObject *uidobj)
187187
p = getpwuid(uid);
188188
#endif
189189
if (p == NULL) {
190-
#ifndef HAVE_GETPWUID_R
191-
PyMutex_Unlock(&pwd_db_mutex);
192-
#endif
193-
PyMem_RawFree(buf);
194190
if (nomem == 1) {
195-
return PyErr_NoMemory();
191+
retval = PyErr_NoMemory();
192+
}
193+
else if (errno == 0) {
194+
PyObject *uid_obj = _PyLong_FromUid(uid);
195+
if (uid_obj == NULL) {
196+
retval = NULL;
197+
}
198+
else {
199+
retval = PyErr_Format(PyExc_KeyError,
200+
"getpwuid(): uid not found: %S", uid_obj);
201+
Py_DECREF(uid_obj);
202+
}
203+
}
204+
else {
205+
retval = PyErr_SetFromErrno(PyExc_OSError);
196206
}
197-
PyObject *uid_obj = _PyLong_FromUid(uid);
198-
if (uid_obj == NULL)
199-
return NULL;
200-
PyErr_Format(PyExc_KeyError,
201-
"getpwuid(): uid not found: %S", uid_obj);
202-
Py_DECREF(uid_obj);
203-
return NULL;
204207
}
205-
retval = mkpwent(module, p);
206-
#ifdef HAVE_GETPWUID_R
207-
PyMem_RawFree(buf);
208-
#else
208+
else {
209+
retval = mkpwent(module, p);
210+
}
211+
#ifndef HAVE_GETPWUID_R
209212
PyMutex_Unlock(&pwd_db_mutex);
210213
#endif
214+
PyMem_RawFree(buf);
211215
return retval;
212216
}
213217

@@ -278,19 +282,20 @@ pwd_getpwnam_impl(PyObject *module, PyObject *name)
278282
p = getpwnam(name_chars);
279283
#endif
280284
if (p == NULL) {
281-
#ifndef HAVE_GETPWNAM_R
282-
PyMutex_Unlock(&pwd_db_mutex);
283-
#endif
284285
if (nomem == 1) {
285-
PyErr_NoMemory();
286+
retval = PyErr_NoMemory();
287+
}
288+
else if (errno == 0) {
289+
retval = PyErr_Format(PyExc_KeyError,
290+
"getpwnam(): name not found: %R", name);
286291
}
287292
else {
288-
PyErr_Format(PyExc_KeyError,
289-
"getpwnam(): name not found: %R", name);
293+
retval = PyErr_SetFromErrno(PyExc_OSError);
290294
}
291-
goto out;
292295
}
293-
retval = mkpwent(module, p);
296+
else {
297+
retval = mkpwent(module, p);
298+
}
294299
#ifndef HAVE_GETPWNAM_R
295300
PyMutex_Unlock(&pwd_db_mutex);
296301
#endif

0 commit comments

Comments
 (0)