Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'winsup/cygwin/syscalls.cc')
-rw-r--r--winsup/cygwin/syscalls.cc278
1 files changed, 80 insertions, 198 deletions
diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc
index 1b047aaff..a14774e1a 100644
--- a/winsup/cygwin/syscalls.cc
+++ b/winsup/cygwin/syscalls.cc
@@ -31,7 +31,7 @@ details. */
#include <sys/statvfs.h> /* needed for statvfs */
#include <stdlib.h>
#include <stdio.h>
-#include <process.h>
+#include <cygwin/process.h>
#include <utmp.h>
#include <utmpx.h>
#include <sys/uio.h>
@@ -39,7 +39,6 @@ details. */
#include <wctype.h>
#include <unistd.h>
#include <sys/wait.h>
-#include <dirent.h>
#include "ntdll.h"
#undef fstat
@@ -95,7 +94,7 @@ close_all_files (bool norelease)
for (int i = 0; i < (int) cygheap->fdtab.size; i++)
{
- cygheap_fdget cfd (i, false, false);
+ cygheap_fdget cfd (i);
if (cfd >= 0)
{
debug_only_printf ("closing fd %d", i);
@@ -126,18 +125,6 @@ dup (int fd)
return res;
}
-inline int
-dup_finish (int oldfd, int newfd, int flags)
-{
- int res;
- if ((res = cygheap->fdtab.dup3 (oldfd, newfd, flags | O_EXCL)) == newfd)
- {
- cygheap_fdget (newfd)->inc_refcnt ();
- cygheap->fdtab.unlock (); /* dup3 exits with lock set on success */
- }
- return res;
-}
-
extern "C" int
dup2 (int oldfd, int newfd)
{
@@ -152,8 +139,8 @@ dup2 (int oldfd, int newfd)
cygheap_fdget cfd (oldfd);
res = (cfd >= 0) ? oldfd : -1;
}
- else
- res = dup_finish (oldfd, newfd, 0);
+ else if ((res = cygheap->fdtab.dup3 (oldfd, newfd, 0)) == newfd)
+ cygheap->fdtab[newfd]->refcnt (1);
syscall_printf ("%R = dup2(%d, %d)", res, oldfd, newfd);
return res;
@@ -174,8 +161,8 @@ dup3 (int oldfd, int newfd, int flags)
set_errno (cfd < 0 ? EBADF : EINVAL);
res = -1;
}
- else
- res = dup_finish (oldfd, newfd, flags);
+ else if ((res = cygheap->fdtab.dup3 (oldfd, newfd, flags)) == newfd)
+ cygheap->fdtab[newfd]->refcnt (1);
syscall_printf ("%R = dup3(%d, %d, %p)", res, oldfd, newfd, flags);
return res;
@@ -212,12 +199,7 @@ stop_transaction (NTSTATUS status, HANDLE old_trans, HANDLE trans)
}
static char desktop_ini[] =
- "[.ShellClassInfo]\r\n"
- "CLSID={645FF040-5081-101B-9F08-00AA002F954E}\r\n";
-
-static char desktop_ini_ext[] =
- "LocalizedResourceName=@%SystemRoot%\\system32\\shell32.dll,-8964\r\n";
-
+ "[.ShellClassInfo]\r\nCLSID={645FF040-5081-101B-9F08-00AA002F954E}\r\n";
static BYTE info2[] =
{
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -228,8 +210,7 @@ enum bin_status
{
dont_move,
move_to_bin,
- has_been_moved,
- dir_not_empty
+ has_been_moved
};
static bin_status
@@ -246,9 +227,7 @@ try_to_bin (path_conv &pc, HANDLE &fh, ACCESS_MASK access)
PFILE_NAME_INFORMATION pfni;
PFILE_INTERNAL_INFORMATION pfii;
PFILE_RENAME_INFORMATION pfri;
- ULONG frisiz;
FILE_DISPOSITION_INFORMATION disp = { TRUE };
- bool fs_has_per_user_recycler = pc.fs_is_ntfs () || pc.fs_is_refs ();
tmp_pathbuf tp;
PBYTE infobuf = (PBYTE) tp.w_get ();
@@ -273,8 +252,8 @@ try_to_bin (path_conv &pc, HANDLE &fh, ACCESS_MASK access)
RtlInitEmptyUnicodeString (&recycler, recyclerbuf, sizeof recyclerbuf);
if (!pc.isremote ())
{
- if (wincap.has_recycle_dot_bin ()) /* NTFS and FAT since Vista, ReFS */
- RtlAppendUnicodeToString (&recycler, L"\\$RECYCLE.BIN\\");
+ if (wincap.has_recycle_dot_bin ()) /* NTFS and FAT since Vista */
+ RtlAppendUnicodeToString (&recycler, L"\\$Recycle.Bin\\");
else if (pc.fs_is_ntfs ()) /* NTFS up to 2K3 */
RtlAppendUnicodeToString (&recycler, L"\\RECYCLER\\");
else if (pc.fs_is_fat ()) /* FAT up to 2K3 */
@@ -311,10 +290,10 @@ try_to_bin (path_conv &pc, HANDLE &fh, ACCESS_MASK access)
recycler.Length -= sizeof (WCHAR);
/* Store length of recycler base dir, if it's necessary to create it. */
recycler_base_len = recycler.Length;
- /* On NTFS or ReFS the recycler dir contains user specific subdirs, which
- are the actual recycle bins per user. The name if this dir is the
- string representation of the user SID. */
- if (fs_has_per_user_recycler)
+ /* On NTFS the recycler dir contains user specific subdirs, which are the
+ actual recycle bins per user. The name if this dir is the string
+ representation of the user SID. */
+ if (pc.fs_is_ntfs ())
{
UNICODE_STRING sid;
WCHAR sidbuf[128];
@@ -341,10 +320,7 @@ try_to_bin (path_conv &pc, HANDLE &fh, ACCESS_MASK access)
pc.fs_flags () & FILE_UNICODE_ON_DISK
? L".\xdc63\xdc79\xdc67" : L".cyg");
pfii = (PFILE_INTERNAL_INFORMATION) infobuf;
- /* Note: Modern Samba versions apparently don't like buffer sizes of more
- than 65535 in some NtQueryInformationFile/NtSetInformationFile calls.
- Therefore we better use exact buffer sizes from now on. */
- status = NtQueryInformationFile (fh, &io, pfii, sizeof *pfii,
+ status = NtQueryInformationFile (fh, &io, pfii, 65536,
FileInternalInformation);
if (!NT_SUCCESS (status))
{
@@ -361,15 +337,12 @@ try_to_bin (path_conv &pc, HANDLE &fh, ACCESS_MASK access)
pfri->RootDirectory = pc.isremote () ? NULL : rootdir;
pfri->FileNameLength = recycler.Length;
memcpy (pfri->FileName, recycler.Buffer, recycler.Length);
- frisiz = sizeof *pfri + pfri->FileNameLength - sizeof (WCHAR);
- status = NtSetInformationFile (fh, &io, pfri, frisiz, FileRenameInformation);
+ status = NtSetInformationFile (fh, &io, pfri, 65536, FileRenameInformation);
if (status == STATUS_OBJECT_PATH_NOT_FOUND && !pc.isremote ())
{
/* Ok, so the recycler and/or the recycler/SID directory don't exist.
First reopen root dir with permission to create subdirs. */
NtClose (rootdir);
- InitializeObjectAttributes (&attr, &root, OBJ_CASE_INSENSITIVE,
- NULL, NULL);
status = NtOpenFile (&rootdir, FILE_ADD_SUBDIRECTORY, &attr, &io,
FILE_SHARE_VALID_FLAGS, FILE_OPEN_FOR_BACKUP_INTENT);
if (!NT_SUCCESS (status))
@@ -380,17 +353,14 @@ try_to_bin (path_conv &pc, HANDLE &fh, ACCESS_MASK access)
}
/* Then check if recycler exists by opening and potentially creating it.
Yes, we can really do that. Typically the recycle bin is created
- by the first user actually using the bin. Pre-Vista, the permissions
- are the default permissions propagated from the root directory.
- Since Vista the top-level recycle dir has explicit permissions. */
+ by the first user actually using the bin. The permissions are the
+ default permissions propagated from the root directory. */
InitializeObjectAttributes (&attr, &recycler, OBJ_CASE_INSENSITIVE,
- rootdir,
- wincap.has_recycle_dot_bin ()
- ? recycler_sd (true, true) : NULL);
+ rootdir, NULL);
recycler.Length = recycler_base_len;
status = NtCreateFile (&recyclerdir,
READ_CONTROL
- | (fs_has_per_user_recycler ? 0 : FILE_ADD_FILE),
+ | (pc.fs_is_ntfs () ? 0 : FILE_ADD_FILE),
&attr, &io, NULL,
FILE_ATTRIBUTE_DIRECTORY
| FILE_ATTRIBUTE_SYSTEM
@@ -405,12 +375,10 @@ try_to_bin (path_conv &pc, HANDLE &fh, ACCESS_MASK access)
}
/* Next, if necessary, check if the recycler/SID dir exists and
create it if not. */
- if (fs_has_per_user_recycler)
+ if (pc.fs_is_ntfs ())
{
NtClose (recyclerdir);
recycler.Length = recycler_user_len;
- InitializeObjectAttributes (&attr, &recycler, OBJ_CASE_INSENSITIVE,
- rootdir, recycler_sd (false, true));
status = NtCreateFile (&recyclerdir, READ_CONTROL | FILE_ADD_FILE,
&attr, &io, NULL, FILE_ATTRIBUTE_DIRECTORY
| FILE_ATTRIBUTE_SYSTEM
@@ -431,7 +399,7 @@ try_to_bin (path_conv &pc, HANDLE &fh, ACCESS_MASK access)
{
RtlInitUnicodeString (&fname, L"desktop.ini");
InitializeObjectAttributes (&attr, &fname, OBJ_CASE_INSENSITIVE,
- recyclerdir, recycler_sd (false, false));
+ recyclerdir, NULL);
status = NtCreateFile (&tmp_fh, FILE_GENERIC_WRITE, &attr, &io, NULL,
FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN,
FILE_SHARE_VALID_FLAGS, FILE_CREATE,
@@ -447,15 +415,6 @@ try_to_bin (path_conv &pc, HANDLE &fh, ACCESS_MASK access)
if (!NT_SUCCESS (status))
debug_printf ("NtWriteFile (%S) failed, status = %p",
&fname, status);
- else if (wincap.has_recycle_dot_bin ())
- {
- status = NtWriteFile (tmp_fh, NULL, NULL, NULL, &io,
- desktop_ini_ext,
- sizeof desktop_ini_ext - 1, NULL, NULL);
- if (!NT_SUCCESS (status))
- debug_printf ("NtWriteFile (%S) failed, status = %p",
- &fname, status);
- }
NtClose (tmp_fh);
}
if (!wincap.has_recycle_dot_bin ()) /* No INFO2 file since Vista */
@@ -483,7 +442,7 @@ try_to_bin (path_conv &pc, HANDLE &fh, ACCESS_MASK access)
}
NtClose (recyclerdir);
/* Shoot again. */
- status = NtSetInformationFile (fh, &io, pfri, frisiz,
+ status = NtSetInformationFile (fh, &io, pfri, 65536,
FileRenameInformation);
}
if (!NT_SUCCESS (status))
@@ -499,26 +458,6 @@ try_to_bin (path_conv &pc, HANDLE &fh, ACCESS_MASK access)
Otherwise the below code closes the handle to allow replacing the file. */
status = NtSetInformationFile (fh, &io, &disp, sizeof disp,
FileDispositionInformation);
- if (status == STATUS_DIRECTORY_NOT_EMPTY)
- {
- /* Uh oh! This was supposed to be avoided by the check_dir_not_empty
- test in unlink_nt, but given that the test isn't atomic, this *can*
- happen. Try to move the dir back ASAP. */
- pfri->RootDirectory = NULL;
- pfri->FileNameLength = pc.get_nt_native_path ()->Length;
- memcpy (pfri->FileName, pc.get_nt_native_path ()->Buffer,
- pc.get_nt_native_path ()->Length);
- frisiz = sizeof *pfri + pfri->FileNameLength - sizeof (WCHAR);
- if (NT_SUCCESS (NtSetInformationFile (fh, &io, pfri, frisiz,
- FileRenameInformation)))
- {
- /* Give notice to unlink_nt and leave immediately. This avoids
- closing the handle, which might still be used if called from
- the rm -r workaround code. */
- bin_stat = dir_not_empty;
- goto out;
- }
- }
/* In case of success, restore R/O attribute to accommodate hardlinks.
That leaves potentially hardlinks around with the R/O bit suddenly
off if setting the delete disposition failed, but please, keep in
@@ -550,7 +489,7 @@ try_to_bin (path_conv &pc, HANDLE &fh, ACCESS_MASK access)
status);
goto out;
}
- status = NtSetInformationFile (tmp_fh, &io, pfri, frisiz,
+ status = NtSetInformationFile (tmp_fh, &io, pfri, 65536,
FileRenameInformation);
NtClose (tmp_fh);
if (!NT_SUCCESS (status))
@@ -717,45 +656,46 @@ unlink_nt (path_conv &pc)
if a file is already open elsewhere for other purposes than
reading and writing data. */
status = NtOpenFile (&fh, access, &attr, &io, FILE_SHARE_DELETE, flags);
- /* STATUS_SHARING_VIOLATION is what we expect. STATUS_LOCK_NOT_GRANTED can
- be generated under not quite clear circumstances when trying to open a
- file on NFS with FILE_SHARE_DELETE only. This has been observed with
- SFU 3.5 if the NFS share has been mounted under a drive letter. It's
- not generated for all files, but only for some. If it's generated once
- for a file, it will be generated all the time. It looks as if wrong file
- state information is stored within the NFS client which never times out.
- Opening the file with FILE_SHARE_VALID_FLAGS will work, though, and it
- is then possible to delete the file quite normally. */
if (status == STATUS_SHARING_VIOLATION || status == STATUS_LOCK_NOT_GRANTED)
{
- debug_printf ("Sharing violation when opening %S",
- pc.get_nt_native_path ());
- /* We never call try_to_bin on NFS and NetApp for the follwing reasons:
-
- NFS implements its own mechanism to remove in-use files, which looks
- quite similar to what we do in try_to_bin for remote files.
+ /* STATUS_LOCK_NOT_GRANTED can be generated under not quite clear
+ circumstances when trying to open a file on NFS with FILE_SHARE_DELETE
+ only. This has been observed with SFU 3.5 if the NFS share has been
+ mounted under a drive letter. It's not generated for all files, but
+ only for some. If it's generated once for a file, it will be
+ generated all the time. It looks like wrong file state information
+ is stored within the NFS client, for no apparent reason, which never
+ times out. Opening the file with FILE_SHARE_VALID_FLAGS will work,
+ though, and it is then possible to delete the file quite normally.
+
+ NFS implements its own mechanism to remove in-use files which
+ looks quite similar to what we do in try_to_bin for remote files.
+ That's why we don't call try_to_bin on NFS.
Netapp filesystems don't understand the "move and delete" method
at all and have all kinds of weird effects. Just setting the delete
dispositon usually works fine, though. */
+ debug_printf ("Sharing violation when opening %S",
+ pc.get_nt_native_path ());
if (!pc.fs_is_nfs () && !pc.fs_is_netapp ())
bin_stat = move_to_bin;
- /* If the file is not a directory, of if we didn't set the move_to_bin
- flag, just proceed with the FILE_SHARE_VALID_FLAGS set. */
- if (!pc.isdir () || bin_stat == dont_move)
+ if (!pc.isdir () || pc.isremote ())
status = NtOpenFile (&fh, access, &attr, &io,
FILE_SHARE_VALID_FLAGS, flags);
else
{
- /* Otherwise it's getting tricky. The directory is opened in some
- process, so we're supposed to move it to the recycler and mark it
- for deletion. But what if the directory is not empty? The move
+ /* It's getting tricky. The directory is opened in some process,
+ so we're supposed to move it to the recycler and mark it for
+ deletion. But what if the directory is not empty? The move
will work, but the subsequent delete will fail. So we would
- have to move it back. While we do that in try_to_bin, it's bad,
- because the move results in a temporary inconsistent state.
- So, we test first if the directory is empty. If not, we bail
- out with STATUS_DIRECTORY_NOT_EMPTY. This avoids most of the
- problems. */
+ have to move it back. That's bad, because the directory would
+ be moved around which results in a temporary inconsistent state.
+ So, what we do here is to test if the directory is empty. If
+ not, we bail out with STATUS_DIRECTORY_NOT_EMPTY. The below code
+ tests for at least three entries in the directory, ".", "..",
+ and another one. Three entries means, not empty. This doesn't
+ work for the root directory of a drive, but the root dir can
+ neither be deleted, nor moved anyway. */
status = NtOpenFile (&fh, access | FILE_LIST_DIRECTORY | SYNCHRONIZE,
&attr, &io, FILE_SHARE_VALID_FLAGS,
flags | FILE_SYNCHRONOUS_IO_NONALERT);
@@ -789,15 +729,9 @@ unlink_nt (path_conv &pc)
/* Try to move to bin if a sharing violation occured. If that worked,
we're done. */
if (bin_stat == move_to_bin
- && (bin_stat = try_to_bin (pc, fh, access)) >= has_been_moved)
+ && (bin_stat = try_to_bin (pc, fh, access)) == has_been_moved)
{
- if (bin_stat == has_been_moved)
- status = STATUS_SUCCESS;
- else
- {
- status = STATUS_DIRECTORY_NOT_EMPTY;
- NtClose (fh);
- }
+ status = STATUS_SUCCESS;
goto out;
}
@@ -862,7 +796,6 @@ try_again:
bin_stat = try_to_bin (pc, fh, access);
}
}
- /* Do NOT handle bin_stat == dir_not_empty here! */
if (bin_stat == has_been_moved)
status = STATUS_SUCCESS;
else
@@ -874,15 +807,12 @@ try_again:
}
}
}
- else if (status2 != STATUS_OBJECT_PATH_NOT_FOUND
- && status2 != STATUS_OBJECT_NAME_NOT_FOUND)
+ else
{
fh = NULL;
debug_printf ("Opening dir %S for check_dir_not_empty failed, "
"status = %p", pc.get_nt_native_path (), status2);
}
- else /* Directory disappeared between NtClose and NtOpenFile. */
- status = STATUS_SUCCESS;
}
/* Trying to delete a hardlink to a file in use by the system in some
way (for instance, font files) by setting the delete disposition fails
@@ -920,10 +850,8 @@ try_again:
unlinking didn't work. */
if (bin_stat == dont_move)
bin_stat = try_to_bin (pc, fh, access);
- if (bin_stat >= has_been_moved)
- status = bin_stat == has_been_moved
- ? STATUS_SUCCESS
- : STATUS_DIRECTORY_NOT_EMPTY;
+ if (bin_stat == has_been_moved)
+ status = STATUS_SUCCESS;
}
else
NtClose (fh2);
@@ -933,7 +861,7 @@ try_again:
{
if (access & FILE_WRITE_ATTRIBUTES)
{
- /* Restore R/O attribute if setting the delete disposition failed. */
+ /* Restore R/O attribute if setting the delete dispostion failed. */
if (!NT_SUCCESS (status))
NtSetAttributesFile (fh, pc.file_attributes ());
/* If we succeeded, restore R/O attribute to accommodate hardlinks.
@@ -1087,9 +1015,10 @@ setsid (void)
syscall_printf ("hmm. pgid %d pid %d", myself->pgid, myself->pid);
else
{
- myself->ctty = -2;
- myself->sid = myself->pid;
- myself->pgid = myself->pid;
+ myself->ctty = -1;
+ cygheap->manage_console_count ("setsid", 0);
+ myself->sid = getpid ();
+ myself->pgid = getpid ();
if (cygheap->ctty)
cygheap->close_ctty ();
syscall_printf ("sid %d, pgid %d, %s", myself->sid, myself->pgid, myctty ());
@@ -1347,7 +1276,7 @@ open (const char *unix_path, int flags, ...)
tty for the process. */
int opt = PC_OPEN | ((flags & (O_NOFOLLOW | O_EXCL))
? PC_SYM_NOFOLLOW : PC_SYM_FOLLOW);
- if (!(flags & O_NOCTTY) && fd > 2 && myself->ctty != -2)
+ if (!(flags & O_NOCTTY) && fd > 2)
{
flags |= O_NOCTTY;
opt |= PC_CTTY; /* flag that, if opened, this fhandler could
@@ -1415,10 +1344,7 @@ lseek64 (int fd, _off64_t pos, int dir)
else
res = -1;
}
- /* Can't use %R here since res is 8 bytes */
- syscall_printf (res == -1 ? "%D = lseek(%d, %D, %d), errno %d"
- : "%D = lseek(%d, %D, %d)",
- res, fd, pos, dir, get_errno ());
+ syscall_printf ("%R = lseek(%d, %D, %d)", res, fd, pos, dir);
return res;
}
@@ -1656,49 +1582,6 @@ stat64_to_stat32 (struct __stat64 *src, struct __stat32 *dst)
dst->st_blocks = src->st_blocks;
}
-static struct __stat64 dev_st;
-static bool dev_st_inited;
-
-void
-fhandler_base::stat_fixup (struct __stat64 *buf)
-{
- /* For devices, set inode number to device number. This gives us a valid,
- unique inode number without having to call hash_path_name. */
- if (!buf->st_ino)
- buf->st_ino = (get_major () == DEV_VIRTFS_MAJOR) ? get_ino ()
- : get_device ();
- /* For /dev-based devices, st_dev must be set to the device number of /dev,
- not it's own device major/minor numbers. What we do here to speed up
- the process is to fetch the device number of /dev only once, liberally
- assuming that /dev doesn't change over the lifetime of a process. */
- if (!buf->st_dev)
- {
- if (dev ().is_dev_resident ())
- {
- if (!dev_st_inited)
- {
- stat64 ("/dev", &dev_st);
- dev_st_inited = true;
- }
- buf->st_dev = dev_st.st_dev;
- }
- else
- buf->st_dev = get_device ();
- }
- /* Only set st_rdev if it's a device. */
- if (!buf->st_rdev && get_major () != DEV_VIRTFS_MAJOR)
- {
- buf->st_rdev = get_device ();
- /* consX, console, conin, and conout point to the same device.
- Make sure the link count is correct. */
- if (buf->st_rdev == (dev_t) myself->ctty && iscons_dev (myself->ctty))
- buf->st_nlink = 4;
- /* CD-ROM drives have two links, /dev/srX and /dev/scdX. */
- else if (gnu_dev_major (buf->st_rdev) == DEV_CDROM_MAJOR)
- buf->st_nlink = 2;
- }
-}
-
extern "C" int
fstat64 (int fd, struct __stat64 *buf)
{
@@ -1712,7 +1595,14 @@ fstat64 (int fd, struct __stat64 *buf)
memset (buf, 0, sizeof (struct __stat64));
res = cfd->fstat (buf);
if (!res)
- cfd->stat_fixup (buf);
+ {
+ if (!buf->st_ino)
+ buf->st_ino = cfd->get_ino ();
+ if (!buf->st_dev)
+ buf->st_dev = cfd->get_device ();
+ if (!buf->st_rdev)
+ buf->st_rdev = buf->st_dev;
+ }
}
syscall_printf ("%R = fstat(%d, %p)", res, fd, buf);
@@ -1851,7 +1741,14 @@ stat_worker (path_conv &pc, struct __stat64 *buf)
memset (buf, 0, sizeof (*buf));
res = fh->fstat (buf);
if (!res)
- fh->stat_fixup (buf);
+ {
+ if (!buf->st_ino)
+ buf->st_ino = fh->get_ino ();
+ if (!buf->st_dev)
+ buf->st_dev = fh->get_device ();
+ if (!buf->st_rdev)
+ buf->st_rdev = buf->st_dev;
+ }
delete fh;
}
else
@@ -2332,7 +2229,7 @@ retry:
{
debug_printf ("status %p", status);
if (status == STATUS_SHARING_VIOLATION
- && cygwait (10L) != WAIT_SIGNALED)
+ && WaitForSingleObject (signal_arrived, 10L) != WAIT_OBJECT_0)
{
/* Typical BLODA problem. Some virus scanners check newly generated
files and while doing that disallow DELETE access. That's really
@@ -4541,21 +4438,6 @@ renameat (int olddirfd, const char *oldpathname,
}
extern "C" int
-scandirat (int dirfd, const char *pathname, struct dirent ***namelist,
- int (*select) (const struct dirent *),
- int (*compar) (const struct dirent **, const struct dirent **))
-{
- tmp_pathbuf tp;
- myfault efault;
- if (efault.faulted (EFAULT))
- return -1;
- char *path = tp.c_get ();
- if (gen_full_path_at (path, dirfd, pathname))
- return -1;
- return scandir (pathname, namelist, select, compar);
-}
-
-extern "C" int
symlinkat (const char *oldpath, int newdirfd, const char *newpathname)
{
tmp_pathbuf tp;