From 9b82e42a473189f96c65526eece686da72fbf338 Mon Sep 17 00:00:00 2001 From: David Fries Date: Sat, 10 Dec 2011 11:28:45 -0600 Subject: [PATCH] Set close on exec flag FD_CLOEXEC Set the close on exec flag when opening dri character devices, so they will be closed and free any resouces allocated in exec. Signed-off-by: David Fries Reviewed-by: Adam Jackson --- src/egl/drivers/dri2/platform_wayland.c | 11 ++++++++++- src/egl/drivers/dri2/platform_x11.c | 9 +++++++++ src/gallium/state_trackers/egl/drm/native_drm.c | 11 ++++++++++- .../state_trackers/egl/fbdev/native_fbdev.c | 11 ++++++++++- .../state_trackers/egl/wayland/native_drm.c | 10 +++++++++- src/gallium/state_trackers/egl/x11/x11_screen.c | 10 +++++++++- src/glx/dri2_glx.c | 10 +++++++++- 7 files changed, 66 insertions(+), 6 deletions(-) diff --git a/src/egl/drivers/dri2/platform_wayland.c b/src/egl/drivers/dri2/platform_wayland.c index 7a70d8d..2dfde69 100644 --- a/src/egl/drivers/dri2/platform_wayland.c +++ b/src/egl/drivers/dri2/platform_wayland.c @@ -747,7 +747,16 @@ drm_handle_device(void *data, struct wl_drm *drm, const char *device) if (!dri2_dpy->device_name) return; - dri2_dpy->fd = open(dri2_dpy->device_name, O_RDWR); +#ifdef O_CLOEXEC + dri2_dpy->fd = open(dri2_dpy->device_name, O_RDWR | O_CLOEXEC); + if (dri2_dpy->fd == -1 && errno == EINVAL) +#endif + { + dri2_dpy->fd = open(dri2_dpy->device_name, O_RDWR); + if (dri2_dpy->fd != -1) + fcntl(dri2_dpy->fd, F_SETFD, fcntl(dri2_dpy->fd, F_GETFD) | + FD_CLOEXEC); + } if (dri2_dpy->fd == -1) { _eglLog(_EGL_WARNING, "wayland-egl: could not open %s (%s)", dri2_dpy->device_name, strerror(errno)); diff --git a/src/egl/drivers/dri2/platform_x11.c b/src/egl/drivers/dri2/platform_x11.c index 8dd231a..a31a587 100644 --- a/src/egl/drivers/dri2/platform_x11.c +++ b/src/egl/drivers/dri2/platform_x11.c @@ -998,7 +998,16 @@ dri2_initialize_x11_dri2(_EGLDriver *drv, _EGLDisplay *disp) if (!dri2_load_driver(disp)) goto cleanup_conn; +#ifdef O_CLOEXEC dri2_dpy->fd = open(dri2_dpy->device_name, O_RDWR | O_CLOEXEC); + if (dri2_dpy->fd == -1 && errno == EINVAL) +#endif + { + dri2_dpy->fd = open(dri2_dpy->device_name, O_RDWR); + if (dri2_dpy->fd != -1) + fcntl(dri2_dpy->fd, F_SETFD, fcntl(dri2_dpy->fd, F_GETFD) | + FD_CLOEXEC); + } if (dri2_dpy->fd == -1) { _eglLog(_EGL_WARNING, "DRI2: could not open %s (%s)", dri2_dpy->device_name, diff --git a/src/gallium/state_trackers/egl/drm/native_drm.c b/src/gallium/state_trackers/egl/drm/native_drm.c index c013769..a762f8f 100644 --- a/src/gallium/state_trackers/egl/drm/native_drm.c +++ b/src/gallium/state_trackers/egl/drm/native_drm.c @@ -312,7 +312,16 @@ native_create_display(void *dpy, boolean use_sw) gbm = dpy; if (gbm == NULL) { - fd = open("/dev/dri/card0", O_RDWR); + const char *device_name="/dev/dri/card0"; +#ifdef O_CLOEXEC + fd = open(device_name, O_RDWR | O_CLOEXEC); + if (fd == -1 && errno == EINVAL) +#endif + { + fd = open(device_name, O_RDWR); + if (fd != -1) + fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC); + } /* FIXME: Use an internal constructor to create a gbm * device with gallium backend directly, without setenv */ setenv("GBM_BACKEND", "gbm_gallium_drm.so", 1); diff --git a/src/gallium/state_trackers/egl/fbdev/native_fbdev.c b/src/gallium/state_trackers/egl/fbdev/native_fbdev.c index e126888..b45ab5c 100644 --- a/src/gallium/state_trackers/egl/fbdev/native_fbdev.c +++ b/src/gallium/state_trackers/egl/fbdev/native_fbdev.c @@ -515,7 +515,16 @@ native_create_display(void *dpy, boolean use_sw) /* well, this makes fd 0 being ignored */ if (!dpy) { - fd = open("/dev/fb0", O_RDWR); + const char *device_name="/dev/fb0"; +#ifdef O_CLOEXEC + fd = open(device_name, O_RDWR | O_CLOEXEC); + if (fd == -1 && errno == EINVAL) +#endif + { + fd = open(device_name, O_RDWR); + if (fd != -1) + fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC); + } } else { fd = dup((int) pointer_to_intptr(dpy)); diff --git a/src/gallium/state_trackers/egl/wayland/native_drm.c b/src/gallium/state_trackers/egl/wayland/native_drm.c index 5618f3e..92e73ed 100644 --- a/src/gallium/state_trackers/egl/wayland/native_drm.c +++ b/src/gallium/state_trackers/egl/wayland/native_drm.c @@ -134,7 +134,15 @@ drm_handle_device(void *data, struct wl_drm *drm, const char *device) if (!drmdpy->device_name) return; - drmdpy->fd = open(drmdpy->device_name, O_RDWR); +#ifdef O_CLOEXEC + drmdpy->fd = open(drmdpy->device_name, O_RDWR | O_CLOEXEC); + if (drmdpy->fd == -1 && errno == EINVAL) +#endif + { + drmdpy->fd = open(drmdpy->device_name, O_RDWR); + if (drmdpy->fd != -1) + fcntl(drmdpy->fd, F_SETFD, fcntl(drmdpy->fd, F_GETFD) | FD_CLOEXEC); + } if (drmdpy->fd == -1) { _eglLog(_EGL_WARNING, "wayland-egl: could not open %s (%s)", drmdpy->device_name, strerror(errno)); diff --git a/src/gallium/state_trackers/egl/x11/x11_screen.c b/src/gallium/state_trackers/egl/x11/x11_screen.c index 6155b4d..140668f 100644 --- a/src/gallium/state_trackers/egl/x11/x11_screen.c +++ b/src/gallium/state_trackers/egl/x11/x11_screen.c @@ -265,7 +265,15 @@ x11_screen_enable_dri2(struct x11_screen *xscr, if (!x11_screen_probe_dri2(xscr, NULL, NULL)) return -1; - fd = open(xscr->dri_device, O_RDWR); +#ifdef O_CLOEXEC + fd = open(xscr->dri_device, O_RDWR | O_CLOEXEC); + if (fd == -1 && errno == EINVAL) +#endif + { + fd = open(xscr->dri_device, O_RDWR); + if (fd != -1) + fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC); + } if (fd < 0) { _eglLog(_EGL_WARNING, "failed to open %s", xscr->dri_device); return -1; diff --git a/src/glx/dri2_glx.c b/src/glx/dri2_glx.c index 553869a..b931a7b 100644 --- a/src/glx/dri2_glx.c +++ b/src/glx/dri2_glx.c @@ -914,7 +914,15 @@ dri2CreateScreen(int screen, struct glx_display * priv) goto handle_error; } - psc->fd = open(deviceName, O_RDWR); +#ifdef O_CLOEXEC + psc->fd = open(deviceName, O_RDWR | O_CLOEXEC); + if (psc->fd == -1 && errno == EINVAL) +#endif + { + psc->fd = open(deviceName, O_RDWR); + if (psc->fd != -1) + fcntl(psc->fd, F_SETFD, fcntl(psc->fd, F_GETFD) | FD_CLOEXEC); + } if (psc->fd < 0) { ErrorMessageF("failed to open drm device: %s\n", strerror(errno)); goto handle_error; -- 1.7.7.1