bpo-33625: Release GIL for grp.getgr{nam,gid} and pwd.getpw{nam,uid} … · python/cpython@23e65b2 (original) (raw)

`@@ -50,6 +50,8 @@ exception is raised if the entry asked for cannot be found.");

`

50

50

`static int initialized;

`

51

51

`static PyTypeObject StructPwdType;

`

52

52

``

``

53

`+

#define DEFAULT_BUFFER_SIZE 1024

`

``

54

+

53

55

`static void

`

54

56

`sets(PyObject v, int i, const char val)

`

55

57

`{

`

`@@ -116,16 +118,59 @@ static PyObject *

`

116

118

`pwd_getpwuid(PyObject *module, PyObject *uidobj)

`

117

119

`/[clinic end generated code: output=c4ee1d4d429b86c4 input=ae64d507a1c6d3e8]/

`

118

120

`{

`

``

121

`+

PyObject *retval = NULL;

`

119

122

`uid_t uid;

`

``

123

`+

int nomem = 0;

`

120

124

`struct passwd *p;

`

``

125

`+

char *buf = NULL, *buf2 = NULL;

`

121

126

``

122

127

`if (!_Py_Uid_Converter(uidobj, &uid)) {

`

123

128

`if (PyErr_ExceptionMatches(PyExc_OverflowError))

`

124

129

`PyErr_Format(PyExc_KeyError,

`

125

130

`"getpwuid(): uid not found");

`

126

131

`return NULL;

`

127

132

` }

`

128

``

`-

if ((p = getpwuid(uid)) == NULL) {

`

``

133

`+

#ifdef HAVE_GETPWUID_R

`

``

134

`+

Py_BEGIN_ALLOW_THREADS

`

``

135

`+

int status;

`

``

136

`+

Py_ssize_t bufsize;

`

``

137

`+

struct passwd pwd;

`

``

138

+

``

139

`+

bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);

`

``

140

`+

if (bufsize == -1) {

`

``

141

`+

bufsize = DEFAULT_BUFFER_SIZE;

`

``

142

`+

}

`

``

143

+

``

144

`+

while(1) {

`

``

145

`+

buf2 = PyMem_RawRealloc(buf, bufsize);

`

``

146

`+

if (buf2 == NULL) {

`

``

147

`+

nomem = 1;

`

``

148

`+

break;

`

``

149

`+

}

`

``

150

`+

buf = buf2;

`

``

151

`+

status = getpwuid_r(uid, &pwd, buf, bufsize, &p);

`

``

152

`+

if (status != 0) {

`

``

153

`+

p = NULL;

`

``

154

`+

}

`

``

155

`+

if (p != NULL || status != ERANGE) {

`

``

156

`+

break;

`

``

157

`+

}

`

``

158

`+

if (bufsize > (PY_SSIZE_T_MAX >> 1)) {

`

``

159

`+

nomem = 1;

`

``

160

`+

break;

`

``

161

`+

}

`

``

162

`+

bufsize <<= 1;

`

``

163

`+

}

`

``

164

+

``

165

`+

Py_END_ALLOW_THREADS

`

``

166

`+

#else

`

``

167

`+

p = getpwuid(uid);

`

``

168

`+

#endif

`

``

169

`+

if (p == NULL) {

`

``

170

`+

PyMem_RawFree(buf);

`

``

171

`+

if (nomem == 1) {

`

``

172

`+

return PyErr_NoMemory();

`

``

173

`+

}

`

129

174

`PyObject *uid_obj = _PyLong_FromUid(uid);

`

130

175

`if (uid_obj == NULL)

`

131

176

`return NULL;

`

`@@ -134,7 +179,11 @@ pwd_getpwuid(PyObject *module, PyObject *uidobj)

`

134

179

`Py_DECREF(uid_obj);

`

135

180

`return NULL;

`

136

181

` }

`

137

``

`-

return mkpwent(p);

`

``

182

`+

retval = mkpwent(p);

`

``

183

`+

#ifdef HAVE_GETPWUID_R

`

``

184

`+

PyMem_RawFree(buf);

`

``

185

`+

#endif

`

``

186

`+

return retval;

`

138

187

`}

`

139

188

``

140

189

`/*[clinic input]

`

`@@ -152,7 +201,8 @@ static PyObject *

`

152

201

`pwd_getpwnam_impl(PyObject *module, PyObject *arg)

`

153

202

`/[clinic end generated code: output=6abeee92430e43d2 input=d5f7e700919b02d3]/

`

154

203

`{

`

155

``

`-

char *name;

`

``

204

`+

char *buf = NULL, *buf2 = NULL, *name;

`

``

205

`+

int nomem = 0;

`

156

206

`struct passwd *p;

`

157

207

`PyObject *bytes, *retval = NULL;

`

158

208

``

`@@ -161,13 +211,55 @@ pwd_getpwnam_impl(PyObject *module, PyObject *arg)

`

161

211

`/* check for embedded null bytes */

`

162

212

`if (PyBytes_AsStringAndSize(bytes, &name, NULL) == -1)

`

163

213

` goto out;

`

164

``

`-

if ((p = getpwnam(name)) == NULL) {

`

165

``

`-

PyErr_Format(PyExc_KeyError,

`

166

``

`-

"getpwnam(): name not found: %s", name);

`

``

214

`+

#ifdef HAVE_GETPWNAM_R

`

``

215

`+

Py_BEGIN_ALLOW_THREADS

`

``

216

`+

int status;

`

``

217

`+

Py_ssize_t bufsize;

`

``

218

`+

struct passwd pwd;

`

``

219

+

``

220

`+

bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);

`

``

221

`+

if (bufsize == -1) {

`

``

222

`+

bufsize = DEFAULT_BUFFER_SIZE;

`

``

223

`+

}

`

``

224

+

``

225

`+

while(1) {

`

``

226

`+

buf2 = PyMem_RawRealloc(buf, bufsize);

`

``

227

`+

if (buf2 == NULL) {

`

``

228

`+

nomem = 1;

`

``

229

`+

break;

`

``

230

`+

}

`

``

231

`+

buf = buf2;

`

``

232

`+

status = getpwnam_r(name, &pwd, buf, bufsize, &p);

`

``

233

`+

if (status != 0) {

`

``

234

`+

p = NULL;

`

``

235

`+

}

`

``

236

`+

if (p != NULL || status != ERANGE) {

`

``

237

`+

break;

`

``

238

`+

}

`

``

239

`+

if (bufsize > (PY_SSIZE_T_MAX >> 1)) {

`

``

240

`+

nomem = 1;

`

``

241

`+

break;

`

``

242

`+

}

`

``

243

`+

bufsize <<= 1;

`

``

244

`+

}

`

``

245

+

``

246

`+

Py_END_ALLOW_THREADS

`

``

247

`+

#else

`

``

248

`+

p = getpwnam(name);

`

``

249

`+

#endif

`

``

250

`+

if (p == NULL) {

`

``

251

`+

if (nomem == 1) {

`

``

252

`+

PyErr_NoMemory();

`

``

253

`+

}

`

``

254

`+

else {

`

``

255

`+

PyErr_Format(PyExc_KeyError,

`

``

256

`+

"getpwnam(): name not found: %s", name);

`

``

257

`+

}

`

167

258

` goto out;

`

168

259

` }

`

169

260

`retval = mkpwent(p);

`

170

261

`out:

`

``

262

`+

PyMem_RawFree(buf);

`

171

263

`Py_DECREF(bytes);

`

172

264

`return retval;

`

173

265

`}

`