file.c revision 9acbbeaf2a1ffe5c14b244867d427714fab43c5c
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <errno.h>
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <utime.h>
#include <atomic.h>
#include <sys/lx_syscall.h>
#include <sys/lx_types.h>
#include <sys/lx_debug.h>
static int
{
int saved_errno = errno;
char path[MAXPATHLEN];
/*
*
* act as if it succeded.
*/
return (-errno);
return (0);
errno = saved_errno;
return (-errno);
}
/*
* Miscellaneous file-related system calls.
*/
/*
* Linux creates half-duplex unnamed pipes and Solaris creates full-duplex
* pipes. Thus, to get the correct semantics, our simple pipe() system
* call actually needs to create a named pipe, do three opens, a close, and
* an unlink. This is woefully expensive. If performance becomes a real
* issue, we can implement a half-duplex pipe() in the brand module.
*/
int
{
int cnt;
char pipename[PIPENAMESZ];
int fds[3];
int r = 0;
fds[0] = -1;
/*
* Construct a name for the named pipe: /tmp/.pipe.<pid>.<++cnt>
*/
return (-errno);
/*
* To prevent either the read-only or write-only open from
* blocking, we first need to open the pipe for both reading and
* writing.
*/
r = errno;
} else {
/*
* Copy the two one-way fds back to the app's address
* space.
*/
r = errno;
}
if (fds[2] >= 0)
if (r != 0) {
if (fds[0] >= 0)
if (fds[1] >= 0)
}
return (-r);
}
/*
* On Linux, even root cannot create a link to a directory, so we have to
* add an explicit check.
*/
int
{
return (-EPERM);
}
/*
* On Linux, an unlink of a directory returns EISDIR, not EPERM.
*/
int
{
char *pathname = (char *)p;
return (-EISDIR);
}
/*
* fsync() and fdatasync() - On Solaris, these calls translate into a common
* fsync() syscall with a different parameter, so we layer on top of the librt
* functions instead.
*/
int
{
}
int
{
}
/*
* Linux, unlike Solaris, ALWAYS resets the setuid and setgid bits on a
*/
/*
*/
int
{
return (-errno);
}
return (0);
}
int
{
return (-errno);
}
return (0);
}
int
{
}
int
{
int ret;
if (ret < 0) {
/*
* If chown() failed and we're in install mode, return success
* if the the reason we failed was because the source file
*/
if ((lx_install != 0) &&
return (0);
return (-errno);
}
}
return (0);
}
int
{
return (-errno);
}
return (0);
}
int
{
int ret;
if (ret < 0) {
/*
* If chown() failed and we're in install mode, return success
* if the the reason we failed was because the source file
*/
if ((lx_install != 0) &&
return (0);
return (-errno);
}
return (0);
}
int
{
int ret;
if (ret < 0) {
/*
* If chown() failed and we're in install mode, return success
* if the the reason we failed was because the source file
*/
if ((lx_install != 0) &&
return (0);
return (-errno);
}
return (0);
}
/*
* llseek() - The Linux implementation takes an additional parameter, which is
* the resulting position in the file.
*/
int
{
/* SEEK_DATA and SEEK_HOLE are only valid in Solaris */
return (-EINVAL);
return (-errno);
return (0);
}
/*
* seek() - When the resultant file offset cannot be represented in 32 bits,
* Linux performs the seek but Solaris doesn't, though both set EOVERFLOW. We
* call llseek() and then check to see if we need to return EOVERFLOW.
*/
int
{
/* SEEK_DATA and SEEK_HOLE are only valid in Solaris */
return (-EINVAL);
return (-errno);
return (ret32);
else
return (-EOVERFLOW);
}
/*
* Neither Solaris nor Linux actually returns anything to the caller, but glibc
* expects to see SOME value returned, so placate it and return 0.
*/
int
lx_sync(void)
{
sync();
return (0);
}
int
{
int r;
if (r < 0)
return (0);
}
/*
* Exactly the same as Solaris' sysfs(2), except Linux numbers their fs indices
* starting at 0, and Solaris starts at 1.
*/
int
{
int res;
/*
* Linux actually doesn't have #defines for these; their sysfs(2)
* man page literally defines the "option" field as being 1, 2 or 3,
* corresponding to Solaris' GETFSIND, GETFSTYP and GETNFSTYP,
* respectively.
*/
switch (option) {
case 1:
return (-errno);
return (res - 1);
case 2:
(char *)p3)) < 0)
return (-errno);
return (0);
case 3:
return (-errno);
return (res);
default:
break;
}
return (-EINVAL);
}