VirtualBox

source: kBuild/trunk/src/lib/restartable-syscall-wrappers.c@ 2444

Last change on this file since 2444 was 2444, checked in by bird, 14 years ago

Attempt at curing EINTR problems with recent S11 builds.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 4.1 KB
Line 
1/* $Id: restartable-syscall-wrappers.c 2444 2011-07-06 13:48:18Z bird $ */
2/** @file
3 * restartable-syscall-wrappers.c - Workaround for annoying S11 "features".
4 *
5 * The symptoms are that open or mkdir occationally fails with EINTR when
6 * receiving SIGCHLD at the wrong time. With a enough cores, this start
7 * happening on a regular basis.
8 *
9 * The workaround here is to create our own wrappers for these syscalls which
10 * will restart the syscall when appropriate. This depends on the libc
11 * providing alternative names for the syscall entry points.
12 */
13
14/*
15 * Copyright (c) 2011 knut st. osmundsen <[email protected]>
16 *
17 * This file is part of kBuild.
18 *
19 * kBuild is free software; you can redistribute it and/or modify
20 * it under the terms of the GNU General Public License as published by
21 * the Free Software Foundation; either version 3 of the License, or
22 * (at your option) any later version.
23 *
24 * kBuild is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 * GNU General Public License for more details.
28 *
29 * You should have received a copy of the GNU General Public License
30 * along with kBuild. If not, see <http://www.gnu.org/licenses/>
31 *
32 */
33
34
35/*******************************************************************************
36* Header Files *
37*******************************************************************************/
38#include <sys/types.h>
39#include <sys/stat.h>
40#include <fcntl.h>
41#include <errno.h>
42#include <stdarg.h>
43
44
45/*******************************************************************************
46* Defined Constants And Macros *
47*******************************************************************************/
48/** Mangle a syscall name to it's weak alias. */
49#ifdef KBUILD_OS_SOLARIS
50# define WRAP(a_name) _##a_name
51#elif defined(KBUILD_OS_LINUX)
52# define WRAP(a_name) __##a_name
53#else
54# error "Port Me"
55#endif
56
57/** Mangle a syscall name with optional '64' suffix. */
58#if !defined(_LP64) && _FILE_OFFSET_BITS == 64
59# define WRAP64(a_name) WRAP(a_name)##64
60#else
61# define WRAP64(a_name) WRAP(a_name)
62#endif
63
64/** Check whether errno indicates restart. */
65#ifdef ERESTART
66# define SHOULD_RESTART() (errno == EINTR || errno == ERESTART)
67#else
68# define SHOULD_RESTART() (errno == EINTR)
69#endif
70
71
72extern int WRAP64(open)(const char *pszName, int fFlags, ...);
73int open(const char *pszName, int fFlags, ...)
74{
75 mode_t fMode;
76 va_list va;
77 int fd;
78
79 va_start(va, fFlags);
80 fMode = va_arg(va, mode_t);
81 va_end(va);
82
83 do
84 fd = WRAP64(open)(pszName, fFlags, fMode);
85 while (fd == -1 && SHOULD_RESTART());
86 return fd;
87}
88
89
90#if !defined(KBUILD_OS_LINUX) /* no wrapper */
91extern int WRAP(mkdir)(const char *pszName, mode_t fMode);
92int mkdir(const char *pszName, mode_t fMode)
93{
94 int rc;
95 do
96 rc = WRAP(mkdir)(pszName, fMode);
97 while (rc == -1 && SHOULD_RESTART());
98 return rc;
99}
100#endif
101
102extern int WRAP64(stat)(const char *pszName, struct stat *pStBuf);
103int stat(const char *pszName, struct stat *pStBuf)
104{
105 int rc;
106 do
107 rc = WRAP64(stat)(pszName, pStBuf);
108 while (rc == -1 && SHOULD_RESTART());
109 return rc;
110}
111
112extern int WRAP64(lstat)(const char *pszName, struct stat *pStBuf);
113int lstat(const char *pszName, struct stat *pStBuf)
114{
115 int rc;
116 do
117 rc = WRAP64(lstat)(pszName, pStBuf);
118 while (rc == -1 && SHOULD_RESTART());
119 return rc;
120}
121
122extern ssize_t WRAP(read)(int fd, void *pvBuf, size_t cbBuf);
123ssize_t read(int fd, void *pvBuf, size_t cbBuf)
124{
125 ssize_t cbRead;
126 do
127 cbRead = WRAP(read)(fd, pvBuf, cbBuf);
128 while (cbRead == -1 && SHOULD_RESTART());
129 return cbRead;
130}
131
132extern ssize_t WRAP(write)(int fd, void *pvBuf, size_t cbBuf);
133ssize_t write(int fd, void *pvBuf, size_t cbBuf)
134{
135 ssize_t cbWritten;
136 do
137 cbWritten = WRAP(write)(fd, pvBuf, cbBuf);
138 while (cbWritten == -1 && SHOULD_RESTART());
139 return cbWritten;
140}
141
142/** @todo chmod, chown, chgrp, times, and possible some more. */
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette