⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 syscalls.cc

📁 cygwin, 著名的在win32下模拟unix操作系统的东东
💻 CC
📖 第 1 页 / 共 4 页
字号:
    }  if (real_b.exists ())    {      syscall_printf ("file '%s' exists?", (char *) real_b);      set_errno (EEXIST);      goto done;    }  if (real_b[strlen (real_b) - 1] == '.')    {      syscall_printf ("trailing dot, bailing out");      set_errno (EINVAL);      goto done;    }  /* Try to make hard link first on Windows NT */  if (wincap.has_hard_links ())    {      if (CreateHardLinkA (real_b, real_a, NULL))	{	  res = 0;	  goto done;	}      HANDLE hFileSource;      WIN32_STREAM_ID StreamId;      DWORD dwBytesWritten;      LPVOID lpContext;      DWORD cbPathLen;      DWORD StreamSize;      WCHAR wbuf[MAX_PATH];      BOOL bSuccess;      hFileSource = CreateFile (real_a, FILE_WRITE_ATTRIBUTES,				FILE_SHARE_READ | FILE_SHARE_WRITE /*| FILE_SHARE_DELETE*/,				&sec_none_nih, // sa				OPEN_EXISTING, 0, NULL);      if (hFileSource == INVALID_HANDLE_VALUE)	{	  syscall_printf ("cannot open source, %E");	  goto docopy;	}      cbPathLen = sys_mbstowcs (wbuf, real_b, MAX_PATH) * sizeof (WCHAR);      StreamId.dwStreamId = BACKUP_LINK;      StreamId.dwStreamAttributes = 0;      StreamId.dwStreamNameSize = 0;      StreamId.Size.HighPart = 0;      StreamId.Size.LowPart = cbPathLen;      StreamSize = sizeof (WIN32_STREAM_ID) - sizeof (WCHAR**) +		   StreamId.dwStreamNameSize;      lpContext = NULL;      /* Write the WIN32_STREAM_ID */      bSuccess = BackupWrite (	hFileSource,	 (LPBYTE) &StreamId,	// buffer to write	StreamSize,		// number of bytes to write	&dwBytesWritten,	FALSE,			// don't abort yet	FALSE,			// don't process security	&lpContext);      if (bSuccess)	{	  /* write the buffer containing the path */	  /* FIXME: BackupWrite sometimes traps if linkname is invalid.	     Need to handle. */	  bSuccess = BackupWrite (		hFileSource,		 (LPBYTE) wbuf,	// buffer to write		cbPathLen,	// number of bytes to write		&dwBytesWritten,		FALSE,		// don't abort yet		FALSE,		// don't process security		&lpContext		);	  if (!bSuccess)	    syscall_printf ("cannot write linkname, %E");	  /* Free context */	  BackupWrite (	    hFileSource,	    NULL,		// buffer to write	    0,			// number of bytes to write	    &dwBytesWritten,	    TRUE,		// abort	    FALSE,		// don't process security	    &lpContext);	}      else	syscall_printf ("cannot write streamId, %E");      CloseHandle (hFileSource);      if (!bSuccess)	goto docopy;      res = 0;      goto done;    }docopy:  /* do this with a copy */  if (CopyFileA (real_a, real_b, 1))    res = 0;  else    __seterrno ();done:  syscall_printf ("%d = link (%s, %s)", res, a, b);  return res;}/* chown: POSIX 5.6.5.1 *//* * chown () is only implemented for Windows NT.  Under other operating * systems, it is only a stub that always returns zero. */static intchown_worker (const char *name, unsigned fmode, __uid32_t uid, __gid32_t gid){  int res;  if (check_null_empty_str_errno (name))    return -1;  if (!wincap.has_security ())  // real chown only works on NT    res = 0;			// return zero (and do nothing) under Windows 9x  else    {      /* we need Win32 path names because of usage of Win32 API functions */      path_conv win32_path (PC_NONULLEMPTY, name, fmode);      if (win32_path.error)	{	  set_errno (win32_path.error);	  res = -1;	  goto done;	}      /* FIXME: This makes chown on a device succeed always.  Someday we'll want	 to actually allow chown to work properly on devices. */      if (win32_path.is_device ())	{	  res = 0;	  goto done;	}      DWORD attrib = 0;      if (win32_path.isdir ())	attrib |= S_IFDIR;      res = get_file_attribute (win32_path.has_acls (),				win32_path.get_win32 (),				(int *) &attrib);      if (!res)         res = set_file_attribute (win32_path.has_acls (), win32_path, uid,				   gid, attrib);      if (res != 0 && (!win32_path.has_acls () || !allow_ntsec))	{	  /* fake - if not supported, pretend we're like win95	     where it just works */	  res = 0;	}    }done:  syscall_printf ("%d = %schown (%s,...)",		  res, (fmode & PC_SYM_NOFOLLOW) ? "l" : "", name);  return res;}extern "C" intchown32 (const char * name, __uid32_t uid, __gid32_t gid){  sigframe thisframe (mainthread);  return chown_worker (name, PC_SYM_FOLLOW, uid, gid);}extern "C" intchown (const char * name, __uid16_t uid, __gid16_t gid){  sigframe thisframe (mainthread);  return chown_worker (name, PC_SYM_FOLLOW,		       uid16touid32 (uid), gid16togid32 (gid));}extern "C" intlchown32 (const char * name, __uid32_t uid, __gid32_t gid){  sigframe thisframe (mainthread);  return chown_worker (name, PC_SYM_NOFOLLOW, uid, gid);}extern "C" intlchown (const char * name, __uid16_t uid, __gid16_t gid){  sigframe thisframe (mainthread);  return chown_worker (name, PC_SYM_NOFOLLOW,		       uid16touid32 (uid), gid16togid32 (gid));}extern "C" intfchown32 (int fd, __uid32_t uid, __gid32_t gid){  sigframe thisframe (mainthread);  cygheap_fdget cfd (fd);  if (cfd < 0)    {      syscall_printf ("-1 = fchown (%d,...)", fd);      return -1;    }  const char *path = cfd->get_name ();  if (path == NULL)    {      syscall_printf ("-1 = fchown (%d,...) (no name)", fd);      set_errno (ENOSYS);      return -1;    }  syscall_printf ("fchown (%d,...): calling chown_worker (%s,FOLLOW,...)",		  fd, path);  return chown_worker (path, PC_SYM_FOLLOW, uid, gid);}extern "C" intfchown (int fd, __uid16_t uid, __gid16_t gid){  return fchown32 (fd, uid16touid32 (uid), gid16togid32 (gid));}/* umask: POSIX 5.3.3.1 */extern "C" mode_tumask (mode_t mask){  mode_t oldmask;  oldmask = cygheap->umask;  cygheap->umask = mask & 0777;  return oldmask;}/* chmod: POSIX 5.6.4.1 */extern "C" intchmod (const char *path, mode_t mode){  int res = -1;  sigframe thisframe (mainthread);  path_conv win32_path (path);  if (win32_path.error)    {      set_errno (win32_path.error);      goto done;    }  /* FIXME: This makes chmod on a device succeed always.  Someday we'll want     to actually allow chmod to work properly on devices. */  if (win32_path.is_device ())    {      res = 0;      goto done;    }  if (!win32_path.exists ())    __seterrno ();  else    {      /* temporary erase read only bit, to be able to set file security */      SetFileAttributes (win32_path, (DWORD) win32_path & ~FILE_ATTRIBUTE_READONLY);      if (win32_path.isdir ())	mode |= S_IFDIR;      if (!set_file_attribute (win32_path.has_acls (), win32_path,			       ILLEGAL_UID, ILLEGAL_GID, mode)	  && allow_ntsec)	res = 0;      /* if the mode we want has any write bits set, we can't	 be read only. */      if (mode & (S_IWUSR | S_IWGRP | S_IWOTH))	(DWORD) win32_path &= ~FILE_ATTRIBUTE_READONLY;      else	(DWORD) win32_path |= FILE_ATTRIBUTE_READONLY;      if (S_ISLNK (mode) || S_ISSOCK (mode))	(DWORD) win32_path |= FILE_ATTRIBUTE_SYSTEM;      if (!SetFileAttributes (win32_path, win32_path))	__seterrno ();      else if (!allow_ntsec)	/* Correct NTFS security attributes have higher priority */	res = 0;    }done:  syscall_printf ("%d = chmod (%s, %p)", res, path, mode);  return res;}/* fchmod: P96 5.6.4.1 */extern "C" intfchmod (int fd, mode_t mode){  sigframe thisframe (mainthread);  cygheap_fdget cfd (fd);  if (cfd < 0)    {      syscall_printf ("-1 = fchmod (%d, 0%o)", fd, mode);      return -1;    }  const char *path = cfd->get_name ();  if (path == NULL)    {      syscall_printf ("-1 = fchmod (%d, 0%o) (no name)", fd, mode);      set_errno (ENOSYS);      return -1;    }  syscall_printf ("fchmod (%d, 0%o): calling chmod (%s, 0%o)",		  fd, mode, path, mode);  return chmod (path, mode);}static voidstat64_to_stat32 (struct __stat64 *src, struct __stat32 *dst){  dst->st_dev = ((src->st_dev >> 8) & 0xff00) | (src->st_dev & 0xff);  dst->st_ino = src->st_ino;  dst->st_mode = src->st_mode;  dst->st_nlink = src->st_nlink;  dst->st_uid = src->st_uid;  dst->st_gid = src->st_gid;  dst->st_rdev = ((src->st_rdev >> 8) & 0xff00) | (src->st_rdev & 0xff);  dst->st_size = src->st_size;  dst->st_atim = src->st_atim;  dst->st_mtim = src->st_mtim;  dst->st_ctim = src->st_ctim;  dst->st_blksize = src->st_blksize;  dst->st_blocks = src->st_blocks;}extern "C" intfstat64 (int fd, struct __stat64 *buf){  int res;  sigframe thisframe (mainthread);  cygheap_fdget cfd (fd);  if (cfd < 0)    res = -1;  else    {      path_conv pc (cfd->get_win32_name (), PC_SYM_NOFOLLOW);      memset (buf, 0, sizeof (struct __stat64));      res = cfd->fstat (buf, &pc);      if (!res)	{	  if (!buf->st_ino)	    buf->st_ino = hash_path_name (0, cfd->get_win32_name ());	  if (!buf->st_dev)	    buf->st_dev = (cfd->get_device () << 16) | cfd->get_unit ();	  if (!buf->st_rdev)	    buf->st_rdev = buf->st_dev;	}    }  syscall_printf ("%d = fstat (%d, %p)", res, fd, buf);  return res;}extern "C" int_fstat (int fd, struct __stat32 *buf){  struct __stat64 buf64;  int ret = fstat64 (fd, &buf64);  if (!ret)    stat64_to_stat32 (&buf64, buf);  return ret;}/* fsync: P96 6.6.1.1 */extern "C" intfsync (int fd){  sigframe thisframe (mainthread);  cygheap_fdget cfd (fd);  if (cfd < 0)    {      syscall_printf ("-1 = fsync (%d)", fd);      return -1;    }  if (FlushFileBuffers (cfd->get_handle ()) == 0)    {      __seterrno ();      return -1;    }  return 0;}/* sync: standards? */extern "C" intsync (){  return 0;}suffix_info stat_suffixes[] ={  suffix_info ("", 1),  suffix_info (".exe", 1),  suffix_info (NULL)};/* Cygwin internal */int __stdcallstat_worker (const char *name, struct __stat64 *buf, int nofollow,	     path_conv *pc){  int res = -1;  path_conv real_path;  fhandler_base *fh = NULL;  if (check_null_invalid_struct_errno (buf))    goto done;  if (!pc)    pc = &real_path;  fh = cygheap->fdtab.build_fhandler_from_name (-1, name, NULL, *pc,						(nofollow ? PC_SYM_NOFOLLOW							  : PC_SYM_FOLLOW)						| PC_FULL, stat_suffixes);  if (pc->error)    {      debug_printf ("got %d error from build_fhandler_from_name", pc->error);      set_errno (pc->error);    }  else    {      debug_printf ("(%s, %p, %d, %p), file_attributes %d", name, buf, nofollow,		    pc, (DWORD) real_path);      memset (buf, 0, sizeof (*buf));      res = fh->fstat (buf, pc);      if (!res)	{	  if (!buf->st_ino)	    buf->st_ino = hash_path_name (0, fh->get_win32_name ());	  if (!buf->st_dev)	    buf->st_dev = (fh->get_device () << 16) | fh->get_unit ();	  if (!buf->st_rdev)	    buf->st_rdev = buf->st_dev;	}    } done:  if (fh)    delete fh;  MALLOC_CHECK;  syscall_printf ("%d = (%s, %p)", res, name, buf);  return res;}extern "C" intstat64 (const char *name, struct __stat64 *buf){  sigframe thisframe (mainthread);  syscall_printf ("entering");  return stat_worker (name, buf, 0);}extern "C" int_stat (const char *name, struct __stat32 *buf){  struct __stat64 buf64;  int ret = stat64 (name, &buf64);  if (!ret)    stat64_to_stat32 (&buf64, buf);  return ret;}/* lstat: Provided by SVR4 and 4.3+BSD, POSIX? */extern "C" intlstat64 (const char *name, struct __stat64 *buf){  sigframe thisframe (mainthread);  syscall_printf ("entering");  return stat_worker (name, buf, 1);}/* lstat: Provided by SVR4 and 4.3+BSD, POSIX? */extern "C" intcygwin_lstat (const char *name, struct __stat32 *buf){  struct __stat64 buf64;  int ret = lstat64 (name, &buf64);  if (!ret)    stat64_to_stat32 (&buf64, buf);  return ret;}extern int acl_access (const char *, int);extern "C" intaccess (const char *fn, int flags){  sigframe thisframe (mainthread);  // flags were incorrectly specified  if (flags & ~(F_OK|R_OK|W_OK|X_OK))    {      set_errno (EINVAL);      return -1;    }  if (allow_ntsec)    return acl_access (fn, flags);  struct __stat64 st;  int r = stat_worker (fn, &st, 0);  if (r)    return -1;  r = -1;  if (flags & R_OK)    {      if (st.st_uid == myself->uid)	{	  if (!(st.st_mode & S_IRUSR))	    goto done;	}      else if (st.st_gid == myself->gid)	{	  if (!(st.st_mode & S_IRGRP))	    goto done;	}      else if (!(st.st_mode & S_IROTH))	goto done;    }  if (flags & W_OK)    {      if (st.st_uid == myself->uid)	{	  if (!(st.st_mode & S_IWUSR))	    goto done;	}      else if (st.st_gid == myself->gid)	{	  if (!(st.st_mode & S_IWGRP))	    goto done;	}      else if (!(st.st_mode & S_IWOTH))	goto done;    }  if (flags & X_OK)    {      if (st.st_uid == myself->uid)	{	  if (!(st.st_mode & S_IXUSR))	    goto done;	}      else if (st.st_gid == myself->gid)	{	  if (!(st.st_mode & S_IXGRP))	    goto done;	}      else if (!(st.st_mode & S_IXOTH))	goto done;    }  r = 0;done:  if (r)    set_errno (EACCES);  return r;}extern "C" intrename (const char *oldpath, const char *newpath){  sigframe thisframe (mainthread);  int res = 0;  char *lnk_suffix = NULL;  path_conv real_old (oldpath, PC_SYM_NOFOLLOW);  if (real_old.error)    {      syscall_printf ("-1 = rename (%s, %s)", oldpath, newpath);      set_errno (real_old.error);      return -1;    }  path_conv real_new (newpath, PC_SYM_NOFOLLOW);  /* Shortcut hack. */  char new_lnk_buf[MAX_PATH + 5];  if (real_old.issymlink () && !real_new.error && !real_new.case_clash)    {      int len_old = strlen (real_old.get_win32 ());      if (strcasematch (real_old.get_win32 () + len_old - 4, ".lnk"))	{	  strcpy (new_lnk_buf, newpath);	  strcat (new_lnk_buf, ".lnk");	  newpath = new_lnk_buf;	  real_new.check (newpath, PC_SYM_NOFOLLOW);	}    }  if (real_new.error || real_new.case_clash)    {      syscall_printf ("-1 = rename (%s, %s)", oldpath, newpath);      set_errno (real_new.case_clash ? ECASECLASH : real_new.error);      return -1;    }  if (!writable_directory (real_old) || !writable_directory (real_new))    {      syscall_printf ("-1 = rename (%s, %s)", oldpath, newpath);      set_errno (EACCES);      return -1;    }  if (!real_old.exists ()) /* file to move doesn't exist */    {       syscall_printf ("file to move doesn't exist");       set_errno (ENOENT);       return (-1);    }  /* Destination file exists and is read only, change that or else     the rename won't work. */  if (real_new.has_attribute (FILE_ATTRIBUTE_READONLY))    SetFileAttributes (real_new, (DWORD) real_new & ~FILE_ATTRIBUTE_READONLY);  /* Shortcut hack No. 2, part 1 */  if (!real_old.issymlink () && !real_new.error && real_new.issymlink () &&      real_new.known_suffix && strcasematch (real_new.known_suffix, ".lnk") &&

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -