Re: user32: SetTimer should respect the minimum and maximum timeout limits (try 2).

2013-04-26 Thread Alexandre Julliard
"Erich E. Hoover"  writes:

> So, this particular patch fixes the minimum and maximum timeout limits
> for SetTimer, which has a significant impact on any application using
> SetTimer to render video (Bug #32489).  The old minimum timeout (55
> ms) is nowhere near short enough to render video at 24 FPS, causing
> "choppy" video behavior in a variety of Silverlight apps.  Even though
> MSDN indicates that the minimum timeout should be 10 ms, I'm using the
> value established from the included tests instead (15 ms).

That doesn't mean you can change the constant.

-- 
Alexandre Julliard
julli...@winehq.org




Re: msvcrt.h: Use inline function to forward hypot to _hypot.

2013-04-26 Thread Jacek Caban
On 04/26/13 16:18, Alexandre Julliard wrote:
> Jacek Caban  writes:
>
>> On 04/26/13 14:46, Alexandre Julliard wrote:
>>> Jacek Caban  writes:
>>>
 This fixes compiling msvcp* DLLs with recent mingw-w64 trunk version.
 Previous versions had a separated library that contained forwards from
 underscored functions to non-underscored, which I believe made using
 hypot work. Those were currently moved directly to msvcr* import libs,
 which we don't use in favour of our our own ones.
>>> Don't you need to do that for the other functions too?
>> With just this patch, the compilation works fine for me. There were not
>> that many functions affected by mingw-w64 change. Note that most msvcrt
>> functions are exported without underscore prefix. AFAICS, MSVC has such
>> inline wrapper in math.h only for hypot and hypotf. I checked why hypodf
>> was not affected so far and it seems like it's just because it uses
>> different way of forwarding in mingw-w64 crt, so that's also worth
>> changing in our math.h to be safe for the future changes.
> It looks to me like j0/j1/jn etc. would need it too.

We don't use them outside msvcrt, AFAICS. But yeah, we could have it for
sake of completeness.

Jacek




Re: msvcrt.h: Use inline function to forward hypot to _hypot.

2013-04-26 Thread Alexandre Julliard
Jacek Caban  writes:

> On 04/26/13 14:46, Alexandre Julliard wrote:
>> Jacek Caban  writes:
>>
>>> This fixes compiling msvcp* DLLs with recent mingw-w64 trunk version.
>>> Previous versions had a separated library that contained forwards from
>>> underscored functions to non-underscored, which I believe made using
>>> hypot work. Those were currently moved directly to msvcr* import libs,
>>> which we don't use in favour of our our own ones.
>> Don't you need to do that for the other functions too?
>
> With just this patch, the compilation works fine for me. There were not
> that many functions affected by mingw-w64 change. Note that most msvcrt
> functions are exported without underscore prefix. AFAICS, MSVC has such
> inline wrapper in math.h only for hypot and hypotf. I checked why hypodf
> was not affected so far and it seems like it's just because it uses
> different way of forwarding in mingw-w64 crt, so that's also worth
> changing in our math.h to be safe for the future changes.

It looks to me like j0/j1/jn etc. would need it too.

-- 
Alexandre Julliard
julli...@winehq.org




Re: [PATCH 1/2] gdi32: Clip font glyphs to fit within text metrics. (try 2)

2013-04-26 Thread Michael Stefaniuc

On 04/26/2013 05:54 AM, Sam Edwards wrote:


On 04/25/2013 12:28 PM, Alexandre Julliard wrote:

It doesn't work here:

../../../../wine/tools/runtest -q -P wine -M comctl32.dll -T ../../..
-p comctl32_test.exe.so
../../../../wine/dlls/comctl32/tests/listview.c && touch listview.ok
wine: Unhandled page fault on write access to 0x400053b34 at address
0x2b4c3d69e6b7 (thread 0398), starting debugger...
winedbg: Internal crash at 0x2b53f78066b7
make: *** [listview.ok] Error 84



Thanks for the heads-up, AJ.

I can't reproduce this problem, and it's strange that the debugger
itself suffered an internal crash as well. Can anyone else verify? Did
something mess up during AJ's build?

Sam, look at the size of the address. It is the 64bit build that crashes.

bye
michael




Re: msvcrt.h: Use inline function to forward hypot to _hypot.

2013-04-26 Thread Jacek Caban
On 04/26/13 14:46, Alexandre Julliard wrote:
> Jacek Caban  writes:
>
>> This fixes compiling msvcp* DLLs with recent mingw-w64 trunk version.
>> Previous versions had a separated library that contained forwards from
>> underscored functions to non-underscored, which I believe made using
>> hypot work. Those were currently moved directly to msvcr* import libs,
>> which we don't use in favour of our our own ones.
> Don't you need to do that for the other functions too?

With just this patch, the compilation works fine for me. There were not
that many functions affected by mingw-w64 change. Note that most msvcrt
functions are exported without underscore prefix. AFAICS, MSVC has such
inline wrapper in math.h only for hypot and hypotf. I checked why hypodf
was not affected so far and it seems like it's just because it uses
different way of forwarding in mingw-w64 crt, so that's also worth
changing in our math.h to be safe for the future changes.

Jacek




Re: msvcrt.h: Use inline function to forward hypot to _hypot.

2013-04-26 Thread Alexandre Julliard
Jacek Caban  writes:

> This fixes compiling msvcp* DLLs with recent mingw-w64 trunk version.
> Previous versions had a separated library that contained forwards from
> underscored functions to non-underscored, which I believe made using
> hypot work. Those were currently moved directly to msvcr* import libs,
> which we don't use in favour of our our own ones.

Don't you need to do that for the other functions too?

-- 
Alexandre Julliard
julli...@winehq.org




[PATCH v6 7/7] locks: Disable LOCK_MAND support for MS_SHARELOCK mounts

2013-04-26 Thread Pavel Shilovsky
Signed-off-by: Pavel Shilovsky 
---
 fs/locks.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/fs/locks.c b/fs/locks.c
index 25c3a49..7d67e0e 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -1756,6 +1756,12 @@ SYSCALL_DEFINE2(flock, unsigned int, fd, unsigned int, 
cmd)
goto out;
}
 
+   /* Disable LOCK_MAND support for FS mounted with MS_SHARELOCK */
+   if ((cmd & LOCK_MAND) && IS_SHARELOCK(f.file->f_path.dentry->d_inode)) {
+   error = -EPERM;
+   goto out;
+   }
+
can_sleep = !(cmd & LOCK_NB);
cmd &= ~LOCK_NB;
unlock = (cmd == LOCK_UN);
-- 
1.8.1.5





[PATCH v6 4/7] CIFS: Add O_DENY* open flags support

2013-04-26 Thread Pavel Shilovsky
Construct share_access value from O_DENY* flags and send it to
the server. Use NTCreateAndX command rather than Trans2
all the time we have any of O_DENY* flags regardless of unix
extensions support. Also change smb error mapping of
NT_STATUS_SHARING_VIOLATION to -ESHAREDENIED.

Signed-off-by: Pavel Shilovsky 
---
 fs/cifs/cifsfs.c   |  2 +-
 fs/cifs/cifsglob.h | 16 +++-
 fs/cifs/dir.c  |  4 
 fs/cifs/file.c | 15 +--
 fs/cifs/inode.c|  5 +++--
 fs/cifs/netmisc.c  |  2 +-
 fs/cifs/smb2maperror.c |  2 +-
 fs/locks.c | 11 ++-
 include/linux/fs.h |  1 +
 9 files changed, 49 insertions(+), 9 deletions(-)

diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 345fc89..92bd685 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -799,7 +799,7 @@ struct file_system_type cifs_fs_type = {
.name = "cifs",
.mount = cifs_do_mount,
.kill_sb = cifs_kill_sb,
-   /*  .fs_flags */
+   .fs_flags = FS_DOES_SHARELOCK,
 };
 MODULE_ALIAS_FS("cifs");
 const struct inode_operations cifs_dir_inode_ops = {
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index 80af61d..85703f6 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -465,7 +465,7 @@ struct smb_vol {
 CIFS_MOUNT_CIFS_BACKUPUID | CIFS_MOUNT_CIFS_BACKUPGID)
 
 #define CIFS_MS_MASK (MS_RDONLY | MS_MANDLOCK | MS_NOEXEC | MS_NOSUID | \
- MS_NODEV | MS_SYNCHRONOUS)
+ MS_NODEV | MS_SYNCHRONOUS | MS_SHARELOCK)
 
 struct cifs_mnt_data {
struct cifs_sb_info *cifs_sb;
@@ -947,6 +947,20 @@ struct cifsFileInfo {
struct work_struct oplock_break; /* work for oplock breaks */
 };
 
+static inline int
+cifs_get_share_flags(unsigned int flags)
+{
+   int share_access = 0;
+
+   if (!(flags & O_DENYREAD))
+   share_access |= FILE_SHARE_READ;
+   if (!(flags & O_DENYWRITE))
+   share_access |= FILE_SHARE_WRITE;
+   if (!(flags & O_DENYDELETE))
+   share_access |= FILE_SHARE_DELETE;
+   return share_access;
+}
+
 struct cifs_io_parms {
__u16 netfid;
 #ifdef CONFIG_CIFS_SMB2
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
index e5f6723..c03ad8c 100644
--- a/fs/cifs/dir.c
+++ b/fs/cifs/dir.c
@@ -216,7 +216,11 @@ cifs_do_create(struct inode *inode, struct dentry 
*direntry, unsigned int xid,
goto out;
}
 
+   if (IS_SHARELOCK(inode))
+   share_access = cifs_get_share_flags(oflags);
+
if (tcon->unix_ext && cap_unix(tcon->ses) && !tcon->broken_posix_open &&
+   (share_access == FILE_SHARE_ALL) &&
(CIFS_UNIX_POSIX_PATH_OPS_CAP &
le64_to_cpu(tcon->fsUnixInfo.Capability))) {
rc = cifs_posix_open(full_path, &newinode, inode->i_sb, mode,
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 7631b0c..febf807 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -216,6 +216,8 @@ cifs_nt_open(char *full_path, struct inode *inode, struct 
cifs_sb_info *cifs_sb,
  */
 
disposition = cifs_get_disposition(f_flags);
+   if (IS_SHARELOCK(inode))
+   share_access = cifs_get_share_flags(f_flags);
 
/* BB pass O_SYNC flag through on file attributes .. BB */
 
@@ -428,6 +430,7 @@ int cifs_open(struct inode *inode, struct file *file)
int rc = -EACCES;
unsigned int xid;
__u32 oplock;
+   int share_access = FILE_SHARE_ALL;
struct cifs_sb_info *cifs_sb;
struct TCP_Server_Info *server;
struct cifs_tcon *tcon;
@@ -463,8 +466,12 @@ int cifs_open(struct inode *inode, struct file *file)
else
oplock = 0;
 
-   if (!tcon->broken_posix_open && tcon->unix_ext &&
-   cap_unix(tcon->ses) && (CIFS_UNIX_POSIX_PATH_OPS_CAP &
+   if (IS_SHARELOCK(inode))
+   share_access = cifs_get_share_flags(file->f_flags);
+
+   if (!tcon->broken_posix_open && tcon->unix_ext && cap_unix(tcon->ses) &&
+   (share_access == FILE_SHARE_ALL) &&
+   (CIFS_UNIX_POSIX_PATH_OPS_CAP &
le64_to_cpu(tcon->fsUnixInfo.Capability))) {
/* can not refresh inode info since size could be stale */
rc = cifs_posix_open(full_path, &inode, inode->i_sb,
@@ -631,7 +638,11 @@ cifs_reopen_file(struct cifsFileInfo *cfile, bool 
can_flush)
else
oplock = 0;
 
+   if (IS_SHARELOCK(inode))
+   share_access = cifs_get_share_flags(cfile->f_flags);
+
if (tcon->unix_ext && cap_unix(tcon->ses) &&
+   (share_access == FILE_SHARE_ALL) &&
(CIFS_UNIX_POSIX_PATH_OPS_CAP &
le64_to_cpu(tcon->fsUnixInfo.Capability))) {
/*
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index ecb951f..f145971 100644
--- a/fs/cifs/inode.c
+++ b/

[PATCH v6 0/7] Add O_DENY* support for VFS and CIFS/NFS

2013-04-26 Thread Pavel Shilovsky
Main changes from v5:
1) O_DENYDELETE is now supported by VFS.
2) ESHAREDENIED erro code is introduced to be returned on sharelock conflicts.
3) forcemand dependancy is removed. CIFS module detects if it should use 
NTCreateAndX command according to existence of O_DENY flags.
4) Term 'deny lock' is replaced by 'sharelock' (function names, code comments, 
patch descriptions).

Main changes from v4:
1) deny_lock_file uses FS_DOES_SHARELOCK flag from fs_flags to determine 
whether to use VFS locks or not.
2) Make nfs code return -EBUSY for share conflicts (was -EACCESS).

Main changes from v3
1) O_DENYMAND is removed, sharelock mount option is introduced.
2) Patch fcntl.h and VFS patches are united into one.
3) flock/LOCK_MAND is disabled for sharelock mounts.

This patchset adds support of O_DENY* flags for Linux fs layer. These flags can 
be used by any application that needs share reservations to organize a file 
access. VFS already has some sort of this capability - now it's done through 
flock/LOCK_MAND mechanis, but that approach is non-atomic. This patchset build 
new capabilities on top of the existing one but doesn't bring any changes into 
the flock call semantic.

These flags can be used by NFS (built-in-kernel) and CIFS (Samba) servers and 
Wine applications through VFS (for local filesystems) or CIFS/NFS modules. This 
will help when e.g. Samba and NFS server share the same directory for Windows 
and Linux users or Wine applications use Samba/NFS share to access the same 
data from different clients.

According to the previous discussions the most problematic question is how to 
prevent situations like DoS attacks where e.g /lib/liba.so file can be open 
with DENYREAD, or smth like this. That's why extra mount option 'sharelock' is 
added for switching on/off O_DENY* flags processing. It allows us to avoid use 
of these flags on critical places (like /, /lib) and turn them on if we really 
want it proccessed that way.

So, we have 3 new flags:
O_DENYREAD - to prevent other opens with read access,
O_DENYWRITE - to prevent other opens with write access,
O_DENYDELETE - to prevent delete operations (this flag is not implemented in 
VFS and NFS part and only suitable for CIFS module),

The patchset avoid data races problem on newely created files: open with 
O_CREAT can return the -ETXTBSY error for a successfully created file if this 
files was locked with a sharelock by another task. Also, it turns 
flock/LOCK_MAND capability off for mounts with 'sharelock' option. This lets us 
not mix one share reservation approach with another.

The #1 patch adds flags to fcntl and implements VFS part. The patches #3, #4, 
#5 are related to CIFS-specific changes, #6 and #7 describe NFS and NFSD parts.

The preliminary patch for Samba that replaces the existing use of 
flock/LOCK_MAND mechanism with O_DENY* flags:
http://git.etersoft.ru/people/piastry/packages/?p=samba.git;a=commitdiff;h=173070262b7f29134ad6b2e49a760017c11aec4a

The future part of open man page patch:

-
O_DENYREAD, O_DENYWRIYE, O_DENYDELETE - used to inforce a mandatory share 
reservation scheme of the file access. If these flag is passed, the open fails 
with -ESHAREDENIED in following cases:
1) if O_DENYREAD flag is specified and there is another open with READ access 
to the file;
2) if O_DENYWRITE flag is specified and there is another open with WRITE access 
to the file;
3) if READ access is requested and there is another open with O_DENYREAD flags;
4) if WRITE access is requested and there is another open with O_DENYWRITE 
flags.

If O_DENYDELETE flag is specified and the open succeded, any further unlink 
operation will fail with -ESHAREDENIED untill this open is closed. Now this 
flag is processed by VFS and CIFS filesystem.

This mechanism is done through flocks. If O_DENY* flags are specified, flock 
syscall is processed after the open. The share modes are translated into flock 
according the following rules:
1) !O_DENYREAD   -> LOCK_READ   | LOCK_MAND
2) !O_DENYWRITE  -> LOCK_WRITE  | LOCK_MAND
3) !O_DENYDELETE -> LOCK_DELETE | LOCK_MAND
-

Pavel Shilovsky (7):
  VFS: Introduce new O_DENY* open flags
  VFS: Add O_DENYDELETE support for VFS
  CIFS: Add share_access parm to open request
  CIFS: Add O_DENY* open flags support
  NFSv4: Add O_DENY* open flags support
  NFSD: Pass share reservations flags to VFS
  locks: Disable LOCK_MAND support for MS_SHARELOCK mounts

 fs/cifs/cifsacl.c|   8 +-
 fs/cifs/cifsfs.c |   2 +-
 fs/cifs/cifsglob.h   |  18 -
 fs/cifs/cifsproto.h  |   8 +-
 fs/cifs/cifssmb.c|  50 +++--
 fs/cifs/dir.c|  16 ++--
 fs/cifs/file.c   |  25 +--
 fs/cifs/inode.c  |  21 +++---
 fs/cifs/link.c   |  25 ++-
 fs/cifs/netmisc.c|   2 +-
 fs/cifs/readdir.c|   5 +-
 fs/cifs/smb1ops.c|  16 ++--
 fs/cifs/smb2file.c  

[PATCH v6 6/7] NFSD: Pass share reservations flags to VFS

2013-04-26 Thread Pavel Shilovsky
that maps them into O_DENY* flags and make them visible for
applications on mounts with sharelock option.

Signed-off-by: Pavel Shilovsky 
---
 fs/locks.c  |  1 +
 fs/nfsd/nfs4state.c | 46 +-
 fs/nfsd/nfsproc.c   |  1 +
 3 files changed, 47 insertions(+), 1 deletion(-)

diff --git a/fs/locks.c b/fs/locks.c
index abe8986..25c3a49 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -897,6 +897,7 @@ sharelock_lock_file(struct file *filp)
locks_free_lock(lock);
return error;
 }
+EXPORT_SYMBOL(sharelock_lock_file);
 
 static int __posix_lock_file(struct inode *inode, struct file_lock *request, 
struct file_lock *conflock)
 {
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 2e27430..5043504 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -463,6 +463,19 @@ test_deny(u32 access, struct nfs4_ol_stateid *stp)
return test_bit(access, &stp->st_deny_bmap);
 }
 
+static int nfs4_deny_to_odeny(u32 access)
+{
+   switch (access & NFS4_SHARE_DENY_BOTH) {
+   case NFS4_SHARE_DENY_READ:
+   return O_DENYREAD;
+   case NFS4_SHARE_DENY_WRITE:
+   return O_DENYWRITE;
+   case NFS4_SHARE_DENY_BOTH:
+   return O_DENYREAD | O_DENYWRITE;
+   }
+   return 0;
+}
+
 static int nfs4_access_to_omode(u32 access)
 {
switch (access & NFS4_SHARE_ACCESS_BOTH) {
@@ -2786,6 +2799,21 @@ nfsd4_truncate(struct svc_rqst *rqstp, struct svc_fh *fh,
 }
 
 static __be32
+nfs4_vfs_set_deny(struct nfs4_file *fp, unsigned long share_access,
+ unsigned long deny_access)
+{
+   int oflag, rc;
+   __be32 status = nfs_ok;
+
+   oflag = nfs4_access_to_omode(share_access);
+   fp->fi_fds[oflag]->f_flags |= nfs4_deny_to_odeny(deny_access);
+   rc = sharelock_lock_file(fp->fi_fds[oflag]);
+   if (rc)
+   status = nfserrno(rc);
+   return status;
+}
+
+static __be32
 nfs4_upgrade_open(struct svc_rqst *rqstp, struct nfs4_file *fp, struct svc_fh 
*cur_fh, struct nfs4_ol_stateid *stp, struct nfsd4_open *open)
 {
u32 op_share_access = open->op_share_access;
@@ -2806,6 +2834,14 @@ nfs4_upgrade_open(struct svc_rqst *rqstp, struct 
nfs4_file *fp, struct svc_fh *c
}
return status;
}
+   status = nfs4_vfs_set_deny(fp, op_share_access, open->op_share_deny);
+   if (status) {
+   if (new_access) {
+   int oflag = nfs4_access_to_omode(op_share_access);
+   nfs4_file_put_access(fp, oflag);
+   }
+   return status;
+   }
/* remember the open */
set_access(op_share_access, stp);
set_deny(open->op_share_deny, stp);
@@ -3039,7 +3075,7 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh 
*current_fh, struct nf
 
/*
 * OPEN the file, or upgrade an existing OPEN.
-* If truncate fails, the OPEN fails.
+* If truncate or set_deny fails, the OPEN fails.
 */
if (stp) {
/* Stateid was found, this is an OPEN upgrade */
@@ -3053,6 +3089,10 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct 
svc_fh *current_fh, struct nf
status = nfsd4_truncate(rqstp, current_fh, open);
if (status)
goto out;
+   status = nfs4_vfs_set_deny(fp, open->op_share_access,
+  open->op_share_deny);
+   if (status)
+   goto out;
stp = open->op_stp;
open->op_stp = NULL;
init_open_stateid(stp, fp, open);
@@ -3751,6 +3791,10 @@ nfsd4_open_downgrade(struct svc_rqst *rqstp,
}
nfs4_stateid_downgrade(stp, od->od_share_access);
 
+   status = nfs4_vfs_set_deny(stp->st_file, od->od_share_access,
+  od->od_share_deny);
+   if (status)
+   goto out;
reset_union_bmap_deny(od->od_share_deny, stp);
 
update_stateid(&stp->st_stid.sc_stateid);
diff --git a/fs/nfsd/nfsproc.c b/fs/nfsd/nfsproc.c
index 54c6b3d..ff95544 100644
--- a/fs/nfsd/nfsproc.c
+++ b/fs/nfsd/nfsproc.c
@@ -743,6 +743,7 @@ nfserrno (int errno)
{ nfserr_notsupp, -EOPNOTSUPP },
{ nfserr_toosmall, -ETOOSMALL },
{ nfserr_serverfault, -ESERVERFAULT },
+   { nfserr_share_denied, -ESHAREDENIED },
};
int i;
 
-- 
1.8.1.5





[PATCH v6 5/7] NFSv4: Add O_DENY* open flags support

2013-04-26 Thread Pavel Shilovsky
by passing these flags to NFSv4 open request. Make it return
-ESHAREDENIED on share conflicts with other opens and disable
O_DENYDELETE support since NFSv4 doesn't support it.

Signed-off-by: Pavel Shilovsky 
---
 fs/nfs/dir.c   |  4 
 fs/nfs/internal.h  |  3 ++-
 fs/nfs/nfs4file.c  |  4 
 fs/nfs/nfs4proc.c  |  4 +++-
 fs/nfs/nfs4super.c |  9 ++---
 fs/nfs/nfs4xdr.c   | 21 +
 fs/nfs/super.c |  7 +--
 7 files changed, 41 insertions(+), 11 deletions(-)

diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index f23f455..fe3215c 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -1395,6 +1395,10 @@ int nfs_atomic_open(struct inode *dir, struct dentry 
*dentry,
dfprintk(VFS, "NFS: atomic_open(%s/%ld), %s\n",
dir->i_sb->s_id, dir->i_ino, dentry->d_name.name);
 
+   /* No support for O_DENYDELETE */
+   if (open_flags & O_DENYDELETE)
+   return -EINVAL;
+
/* NFS only supports OPEN on regular files */
if ((open_flags & O_DIRECTORY)) {
if (!d_unhashed(dentry)) {
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
index 541c9eb..70cd1b0 100644
--- a/fs/nfs/internal.h
+++ b/fs/nfs/internal.h
@@ -6,7 +6,8 @@
 #include 
 #include 
 
-#define NFS_MS_MASK (MS_RDONLY|MS_NOSUID|MS_NODEV|MS_NOEXEC|MS_SYNCHRONOUS)
+#define NFS_MS_MASK (MS_RDONLY | MS_NOSUID | MS_NODEV | MS_NOEXEC | \
+MS_SYNCHRONOUS | MS_SHARELOCK)
 
 struct nfs_string;
 
diff --git a/fs/nfs/nfs4file.c b/fs/nfs/nfs4file.c
index 13e6bb3..f5ec400 100644
--- a/fs/nfs/nfs4file.c
+++ b/fs/nfs/nfs4file.c
@@ -34,6 +34,10 @@ nfs4_file_open(struct inode *inode, struct file *filp)
dentry->d_parent->d_name.name,
dentry->d_name.name);
 
+   /* No support for O_DENYDELETE */
+   if (openflags & O_DENYDELETE)
+   return -EINVAL;
+
if ((openflags & O_ACCMODE) == 3)
openflags--;
 
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 0ad025e..fcf0d80 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -102,7 +102,7 @@ static int nfs4_map_errors(int err)
case -NFS4ERR_BADNAME:
return -EINVAL;
case -NFS4ERR_SHARE_DENIED:
-   return -EACCES;
+   return -ESHAREDENIED;
case -NFS4ERR_MINOR_VERS_MISMATCH:
return -EPROTONOSUPPORT;
case -NFS4ERR_ACCESS:
@@ -795,6 +795,8 @@ static struct nfs4_opendata *nfs4_opendata_alloc(struct 
dentry *dentry,
atomic_inc(&sp->so_count);
p->o_arg.fh = NFS_FH(dir);
p->o_arg.open_flags = flags;
+   if (!IS_SHARELOCK(dir))
+   p->o_arg.open_flags &= ~(O_DENYREAD | O_DENYWRITE);
p->o_arg.fmode = fmode & (FMODE_READ|FMODE_WRITE);
/* don't put an ACCESS op in OPEN compound if O_EXCL, because ACCESS
 * will return permission denied for all bits until close */
diff --git a/fs/nfs/nfs4super.c b/fs/nfs/nfs4super.c
index 569b166..a25a929 100644
--- a/fs/nfs/nfs4super.c
+++ b/fs/nfs/nfs4super.c
@@ -28,7 +28,8 @@ static struct file_system_type nfs4_remote_fs_type = {
.name   = "nfs4",
.mount  = nfs4_remote_mount,
.kill_sb= nfs_kill_super,
-   .fs_flags   = FS_RENAME_DOES_D_MOVE|FS_BINARY_MOUNTDATA,
+   .fs_flags   = FS_RENAME_DOES_D_MOVE | FS_BINARY_MOUNTDATA |
+ FS_DOES_SHARELOCK,
 };
 
 static struct file_system_type nfs4_remote_referral_fs_type = {
@@ -36,7 +37,8 @@ static struct file_system_type nfs4_remote_referral_fs_type = 
{
.name   = "nfs4",
.mount  = nfs4_remote_referral_mount,
.kill_sb= nfs_kill_super,
-   .fs_flags   = FS_RENAME_DOES_D_MOVE|FS_BINARY_MOUNTDATA,
+   .fs_flags   = FS_RENAME_DOES_D_MOVE | FS_BINARY_MOUNTDATA |
+ FS_DOES_SHARELOCK,
 };
 
 struct file_system_type nfs4_referral_fs_type = {
@@ -44,7 +46,8 @@ struct file_system_type nfs4_referral_fs_type = {
.name   = "nfs4",
.mount  = nfs4_referral_mount,
.kill_sb= nfs_kill_super,
-   .fs_flags   = FS_RENAME_DOES_D_MOVE|FS_BINARY_MOUNTDATA,
+   .fs_flags   = FS_RENAME_DOES_D_MOVE | FS_BINARY_MOUNTDATA |
+ FS_DOES_SHARELOCK,
 };
 
 static const struct super_operations nfs4_sops = {
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index e3edda5..cb0e8de 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -1325,7 +1325,8 @@ static void encode_lookup(struct xdr_stream *xdr, const 
struct qstr *name, struc
encode_string(xdr, name->len, name->name);
 }
 
-static void encode_share_access(struct xdr_stream *xdr, fmode_t fmode)
+static void encode_share_access(struct xdr_stream *xdr, fmode_t fmode,
+   int open_flags)
 {
__be32 *p;
 
@@ -1343,7 +1344,19 @@ static void encode_share_access(struct xdr_stream *xdr, 
fmode_t fmode)
   

[PATCH v6 3/7] CIFS: Add share_access parm to open request

2013-04-26 Thread Pavel Shilovsky
and simplify CIFSSMBOpen params.

Signed-off-by: Pavel Shilovsky 
---
 fs/cifs/cifsacl.c   |  8 
 fs/cifs/cifsglob.h  |  2 +-
 fs/cifs/cifsproto.h |  8 
 fs/cifs/cifssmb.c   | 50 +++---
 fs/cifs/dir.c   | 12 ++--
 fs/cifs/file.c  | 10 ++
 fs/cifs/inode.c | 16 ++--
 fs/cifs/link.c  | 25 -
 fs/cifs/readdir.c   |  5 ++---
 fs/cifs/smb1ops.c   | 16 +++-
 fs/cifs/smb2file.c  | 10 +-
 fs/cifs/smb2inode.c |  4 ++--
 fs/cifs/smb2ops.c   | 10 ++
 fs/cifs/smb2pdu.c   |  6 +++---
 fs/cifs/smb2proto.h | 14 --
 15 files changed, 95 insertions(+), 101 deletions(-)

diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c
index f1e3f25..56bdae2 100644
--- a/fs/cifs/cifsacl.c
+++ b/fs/cifs/cifsacl.c
@@ -908,8 +908,8 @@ static struct cifs_ntsd *get_cifs_acl_by_path(struct 
cifs_sb_info *cifs_sb,
create_options |= CREATE_OPEN_BACKUP_INTENT;
 
rc = CIFSSMBOpen(xid, tcon, path, FILE_OPEN, READ_CONTROL,
-   create_options, &fid, &oplock, NULL, cifs_sb->local_nls,
-   cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
+   FILE_SHARE_ALL, create_options, &fid, &oplock,
+   NULL, cifs_sb);
if (!rc) {
rc = CIFSSMBGetCIFSACL(xid, tcon, fid, &pntsd, pacllen);
CIFSSMBClose(xid, tcon, fid);
@@ -969,8 +969,8 @@ int set_cifs_acl(struct cifs_ntsd *pnntsd, __u32 acllen,
access_flags = WRITE_DAC;
 
rc = CIFSSMBOpen(xid, tcon, path, FILE_OPEN, access_flags,
-   create_options, &fid, &oplock, NULL, cifs_sb->local_nls,
-   cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
+   FILE_SHARE_ALL, create_options, &fid, &oplock,
+   NULL, cifs_sb);
if (rc) {
cERROR(1, "Unable to open file to set ACL");
goto out;
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index 4f07f6f..80af61d 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -310,7 +310,7 @@ struct smb_version_operations {
   struct cifs_sb_info *);
/* open a file for non-posix mounts */
int (*open)(const unsigned int, struct cifs_tcon *, const char *, int,
-   int, int, struct cifs_fid *, __u32 *, FILE_ALL_INFO *,
+   int, int, int, struct cifs_fid *, __u32 *, FILE_ALL_INFO *,
struct cifs_sb_info *);
/* set fid protocol-specific info */
void (*set_fid)(struct cifsFileInfo *, struct cifs_fid *, __u32);
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index f450f06..d285b81 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -362,10 +362,10 @@ extern int CIFSSMBQueryReparseLinkInfo(const unsigned int 
xid,
const struct nls_table *nls_codepage);
 #endif /* temporarily unused until cifs_symlink fixed */
 extern int CIFSSMBOpen(const unsigned int xid, struct cifs_tcon *tcon,
-   const char *fileName, const int disposition,
-   const int access_flags, const int omode,
-   __u16 *netfid, int *pOplock, FILE_ALL_INFO *,
-   const struct nls_table *nls_codepage, int remap);
+   const char *file_name, const int disposition,
+   const int desired_access, const int share_access,
+   const int omode, __u16 *netfid, int *oplock,
+   FILE_ALL_INFO *, struct cifs_sb_info *);
 extern int SMBLegacyOpen(const unsigned int xid, struct cifs_tcon *tcon,
const char *fileName, const int disposition,
const int access_flags, const int omode,
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index 8e2e799..c857b02 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -1289,10 +1289,10 @@ OldOpenRetry:
 
 int
 CIFSSMBOpen(const unsigned int xid, struct cifs_tcon *tcon,
-   const char *fileName, const int openDisposition,
-   const int access_flags, const int create_options, __u16 *netfid,
-   int *pOplock, FILE_ALL_INFO *pfile_info,
-   const struct nls_table *nls_codepage, int remap)
+   const char *file_name, const int disposition,
+   const int desired_access, const int share_access,
+   const int create_options, __u16 *netfid, int *oplock,
+   FILE_ALL_INFO *file_info, struct cifs_sb_info *cifs_sb)
 {
int rc = -EACCES;
OPEN_REQ *pSMB = NULL;
@@ -1300,6 +1300,8 @@ CIFSSMBOpen(const unsigned int xid, struct cifs_tcon 
*tcon,
int bytes_returned;
int name_len;
__u16 count;
+   struct nls_table *nls_codepage = cifs_sb->local_nls;
+   int remap = cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPE

[PATCH v6 2/7] VFS: Add O_DENYDELETE support for VFS

2013-04-26 Thread Pavel Shilovsky
Introduce new LOCK_DELETE flock flag that is suggested to be used
internally only to map O_DENYDELETE open flag:

!O_DENYDELETE -> LOCK_DELETE | LOCK_MAND.

Signed-off-by: Pavel Shilovsky 
---
 fs/locks.c   | 53 +---
 fs/namei.c   |  3 +++
 include/linux/fs.h   |  6 +
 include/uapi/asm-generic/fcntl.h |  1 +
 4 files changed, 54 insertions(+), 9 deletions(-)

diff --git a/fs/locks.c b/fs/locks.c
index dbc5557..1cc68a9 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -269,7 +269,7 @@ EXPORT_SYMBOL(locks_copy_lock);
 
 static inline int flock_translate_cmd(int cmd) {
if (cmd & LOCK_MAND)
-   return cmd & (LOCK_MAND | LOCK_RW);
+   return cmd & (LOCK_MAND | LOCK_RW | LOCK_DELETE);
switch (cmd) {
case LOCK_SH:
return F_RDLCK;
@@ -614,6 +614,8 @@ deny_flags_to_cmd(unsigned int flags)
cmd |= LOCK_READ;
if (!(flags & O_DENYWRITE))
cmd |= LOCK_WRITE;
+   if (!(flags & O_DENYDELETE))
+   cmd |= LOCK_DELETE;
 
return cmd;
 }
@@ -836,6 +838,31 @@ out:
return error;
 }
 
+int
+sharelock_may_delete(struct dentry *dentry)
+{
+   struct file_lock **before;
+   int rc = 0;
+
+   if (!IS_SHARELOCK(dentry->d_inode))
+   return rc;
+
+   lock_flocks();
+   for_each_lock(dentry->d_inode, before) {
+   struct file_lock *fl = *before;
+   if (IS_POSIX(fl))
+   break;
+   if (IS_LEASE(fl))
+   continue;
+   if (fl->fl_type & LOCK_DELETE)
+   continue;
+   rc = 1;
+   break;
+   }
+   unlock_flocks();
+   return rc;
+}
+
 /*
  * Determine if a file is allowed to be opened with specified access and share
  * modes. Lock the file and return 0 if checks passed, otherwise return
@@ -850,10 +877,6 @@ sharelock_lock_file(struct file *filp)
if (!IS_SHARELOCK(filp->f_path.dentry->d_inode))
return error;
 
-   /* Disable O_DENYDELETE support for now */
-   if (filp->f_flags & O_DENYDELETE)
-   return -EINVAL;
-
error = flock_make_lock(filp, &lock, deny_flags_to_cmd(filp->f_flags));
if (error)
return error;
@@ -1717,6 +1740,12 @@ SYSCALL_DEFINE2(flock, unsigned int, fd, unsigned int, 
cmd)
if (!f.file)
goto out;
 
+   /* LOCK_DELETE is defined to be translated from O_DENYDELETE only */
+   if (cmd & LOCK_DELETE) {
+   error = -EINVAL;
+   goto out;
+   }
+
can_sleep = !(cmd & LOCK_NB);
cmd &= ~LOCK_NB;
unlock = (cmd == LOCK_UN);
@@ -2261,10 +2290,16 @@ static void lock_get_status(struct seq_file *f, struct 
file_lock *fl,
seq_printf(f, "UNKNOWN UNKNOWN  ");
}
if (fl->fl_type & LOCK_MAND) {
-   seq_printf(f, "%s ",
-  (fl->fl_type & LOCK_READ)
-  ? (fl->fl_type & LOCK_WRITE) ? "RW   " : "READ "
-  : (fl->fl_type & LOCK_WRITE) ? "WRITE" : "NONE 
");
+   if (fl->fl_type & LOCK_DELETE)
+   seq_printf(f, "%s ",
+   (fl->fl_type & LOCK_READ) ?
+   (fl->fl_type & LOCK_WRITE) ? "RWDEL" : "RDDEL" :
+   (fl->fl_type & LOCK_WRITE) ? "WRDEL" : "DEL  ");
+   else
+   seq_printf(f, "%s ",
+   (fl->fl_type & LOCK_READ) ?
+   (fl->fl_type & LOCK_WRITE) ? "RW   " : "READ " :
+   (fl->fl_type & LOCK_WRITE) ? "WRITE" : "NONE ");
} else {
seq_printf(f, "%s ",
   (lease_breaking(fl))
diff --git a/fs/namei.c b/fs/namei.c
index dd236fe..a404f7d 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -2220,6 +2220,7 @@ static inline int check_sticky(struct inode *dir, struct 
inode *inode)
  *  9. We can't remove a root or mountpoint.
  * 10. We don't allow removal of NFS sillyrenamed files; it's handled by
  * nfs_async_unlink().
+ * 11. We can't do it if victim is locked by O_DENYDELETE sharelock.
  */
 static int may_delete(struct inode *dir,struct dentry *victim,int isdir)
 {
@@ -2250,6 +2251,8 @@ static int may_delete(struct inode *dir,struct dentry 
*victim,int isdir)
return -ENOENT;
if (victim->d_flags & DCACHE_NFSFS_RENAMED)
return -EBUSY;
+   if (sharelock_may_delete(victim))
+   return -ESHAREDENIED;
return 0;
 }
 
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 24066d2..afd56b1 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1006,6 +1006,7 @@ extern int lock_may_read(struct inode *, loff_t start, 
unsigned long count);
 e

[PATCH v6 1/7] VFS: Introduce new O_DENY* open flags

2013-04-26 Thread Pavel Shilovsky
This patch adds 3 flags:
1) O_DENYREAD that doesn't permit read access,
2) O_DENYWRITE that doesn't permit write access,
3) O_DENYDELETE that doesn't permit delete or rename.

Network filesystems CIFS, SMB2.0, SMB3.0 and NFSv4 have such flags -
this change can benefit cifs and nfs modules as well as Samba and
NFS file servers that export the same directory for Windows clients,
or Wine applications that access the same files simultaneously.

These flags are only take affect for opens on mounts with new sharelock
option. They are translated to flock's flags:

!O_DENYREAD  -> LOCK_READ | LOCK_MAND
!O_DENYWRITE -> LOCK_WRITE | LOCK_MAND

and set through flock_lock_file on a file. If the file can't be locked
due conflicts with another open with O_DENY* flags, a new -ESHAREDENIED
error code is returned.

Create codepath is slightly changed to prevent data races on
newely created files: when open with O_CREAT can return -ESHAREDENIED
error for successfully created files due to a sharelock set by
another task.

Temporary disable O_DENYDELETE support - will enable it in further patches.

Signed-off-by: Pavel Shilovsky 
---
 fs/fcntl.c   |  5 ++-
 fs/locks.c   | 97 +---
 fs/namei.c   | 45 +--
 fs/proc_namespace.c  |  1 +
 include/linux/fs.h   |  7 +++
 include/uapi/asm-generic/errno.h |  2 +
 include/uapi/asm-generic/fcntl.h | 11 +
 include/uapi/linux/fs.h  |  1 +
 8 files changed, 156 insertions(+), 13 deletions(-)

diff --git a/fs/fcntl.c b/fs/fcntl.c
index 6599222..a1eee47 100644
--- a/fs/fcntl.c
+++ b/fs/fcntl.c
@@ -730,14 +730,15 @@ static int __init fcntl_init(void)
 * Exceptions: O_NONBLOCK is a two bit define on parisc; O_NDELAY
 * is defined as O_NONBLOCK on some platforms and not on others.
 */
-   BUILD_BUG_ON(19 - 1 /* for O_RDONLY being 0 */ != HWEIGHT32(
+   BUILD_BUG_ON(22 - 1 /* for O_RDONLY being 0 */ != HWEIGHT32(
O_RDONLY| O_WRONLY  | O_RDWR|
O_CREAT | O_EXCL| O_NOCTTY  |
O_TRUNC | O_APPEND  | /* O_NONBLOCK | */
__O_SYNC| O_DSYNC   | FASYNC|
O_DIRECT| O_LARGEFILE   | O_DIRECTORY   |
O_NOFOLLOW  | O_NOATIME | O_CLOEXEC |
-   __FMODE_EXEC| O_PATH
+   __FMODE_EXEC| O_PATH| O_DENYREAD|
+   O_DENYWRITE | O_DENYDELETE
));
 
fasync_cache = kmem_cache_create("fasync_cache",
diff --git a/fs/locks.c b/fs/locks.c
index cb424a4..dbc5557 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -605,20 +605,73 @@ static int posix_locks_conflict(struct file_lock 
*caller_fl, struct file_lock *s
return (locks_conflict(caller_fl, sys_fl));
 }
 
-/* Determine if lock sys_fl blocks lock caller_fl. FLOCK specific
- * checking before calling the locks_conflict().
+static unsigned int
+deny_flags_to_cmd(unsigned int flags)
+{
+   unsigned int cmd = LOCK_MAND;
+
+   if (!(flags & O_DENYREAD))
+   cmd |= LOCK_READ;
+   if (!(flags & O_DENYWRITE))
+   cmd |= LOCK_WRITE;
+
+   return cmd;
+}
+
+/*
+ * locks_mand_conflict - Determine if there's a share reservation conflict
+ * @caller_fl: lock we're attempting to acquire
+ * @sys_fl: lock already present on system that we're checking against
+ *
+ * Check to see if there's a share_reservation conflict. LOCK_READ/LOCK_WRITE
+ * tell us whether the reservation allows other readers and writers.
+ */
+static int
+locks_mand_conflict(struct file_lock *caller_fl, struct file_lock *sys_fl)
+{
+   unsigned char caller_type = caller_fl->fl_type;
+   unsigned char sys_type = sys_fl->fl_type;
+   fmode_t caller_fmode = caller_fl->fl_file->f_mode;
+   fmode_t sys_fmode = sys_fl->fl_file->f_mode;
+
+   /* they can only conflict if FS is mounted with MS_SHARELOCK */
+   if (!IS_SHARELOCK(caller_fl->fl_file->f_path.dentry->d_inode))
+   return 0;
+
+   /* they can only conflict if they're both LOCK_MAND */
+   if (!(caller_type & LOCK_MAND) || !(sys_type & LOCK_MAND))
+   return 0;
+
+   if (!(caller_type & LOCK_READ) && (sys_fmode & FMODE_READ))
+   return 1;
+   if (!(caller_type & LOCK_WRITE) && (sys_fmode & FMODE_WRITE))
+   return 1;
+   if (!(sys_type & LOCK_READ) && (caller_fmode & FMODE_READ))
+   return 1;
+   if (!(sys_type & LOCK_WRITE) && (caller_fmode & FMODE_WRITE))
+   return 1;
+
+   return 0;
+}
+
+/*
+ * Determine if lock sys_fl blocks lock caller_fl. FLOCK specific checking
+ * before calling the locks_conflict().
  */
 static int flock_locks_conflict(struct file_lock *caller_fl, struct file_lock 
*sys_fl)
 {
-   /* FLOCK locks referring to the same filp do not confl

Re: [PATCH 1/2]vbscript: Implemented builtin function CInt(try 3)

2013-04-26 Thread Henri Verbeet
On 26 April 2013 12:41, Jacek Caban  wrote:
> On 04/26/13 12:02, Henri Verbeet wrote:
>> On 26 April 2013 10:27, Jacek Caban  wrote:
>>> - round is not portable. As I mentioned you before, Wine needs to be C89
>>> compatible. If we need some features that are not part of C89, we need
>>> to be careful about that and it often requires things like configure
>>> checks. In case of round, replacing it with floor(x+0.5) does the trick
>>> pretty well.
>>>
>> But that's going to do something different for negative values.
>
> That will be different only for numbers with fractional part equal to
> 0.5, which we have to handle separately using both round and floor anyway.
>
Yeah, it probably doesn't matter here, you just couldn't use it as a
general replacement in libwine_port.




Re: [PATCH 1/2]vbscript: Implemented builtin function CInt(try 3)

2013-04-26 Thread Jacek Caban
On 04/26/13 12:02, Henri Verbeet wrote:
> On 26 April 2013 10:27, Jacek Caban  wrote:
>> - round is not portable. As I mentioned you before, Wine needs to be C89
>> compatible. If we need some features that are not part of C89, we need
>> to be careful about that and it often requires things like configure
>> checks. In case of round, replacing it with floor(x+0.5) does the trick
>> pretty well.
>>
> But that's going to do something different for negative values.

That will be different only for numbers with fractional part equal to
0.5, which we have to handle separately using both round and floor anyway.

Jacek




Re: [PATCH 1/2]vbscript: Implemented builtin function CInt(try 3)

2013-04-26 Thread Henri Verbeet
On 26 April 2013 10:27, Jacek Caban  wrote:
> - round is not portable. As I mentioned you before, Wine needs to be C89
> compatible. If we need some features that are not part of C89, we need
> to be careful about that and it often requires things like configure
> checks. In case of round, replacing it with floor(x+0.5) does the trick
> pretty well.
>
But that's going to do something different for negative values.

What you actually want to use is probably lrint(), although that's C99
as well, and affected by the current rounding mode. The latter may be
what you want anyway, but would need tests.




Names with particles on South Africa and Namibia should be in the particle on the AUTHORS file.

2013-04-26 Thread Tae Wong
You have posted a message to show how surnames with particles of South
Africa and Namibia show in the credits, like van Schayck listed in S
and not under V: For example, van Schayck is under S and not in V.
Note that the name of the file is in all capitals. Here is a
correction of the va section, with van Schyack placed on the letter by
letter system. The file name is AUTHORS. It is a file in all capitals
and the file content contains just the heading and some names of the
developers. Note that the file is out of date.

Vainer, Moshe
Valoska, Hleb
Valtonen, Hannu
Vance, Carroll
Vanek, Tomas
van Schaik, Carl
Vaughn, Charles




Re: [PATCH 1/2]vbscript: Implemented builtin function CInt(try 3)

2013-04-26 Thread Jacek Caban
Hi Zhan,

It's better, thanks, but still needs more work.

On 04/25/13 23:37, Zhan Jianyu wrote:
>  }
>  
> +
> +

While we're at this, please put more attention into whitespace changes,
esp. useless ones.

>  static HRESULT to_double(VARIANT *v, double *ret)
>  {
>  switch(V_VT(v)) {
> @@ -217,6 +221,27 @@ static HRESULT to_string(VARIANT *v, BSTR *ret)
>  return S_OK;
>  }
>  
> +
> +static HRESULT banker_rounding(double dbval, int *result_val)
> +{
> + double frac_part;
> + double int_part; 
> +
> + *result_val = round(dbval);

This has two problems:
- you don't handle values that are out of int range by assigning double
value to int
- round is not portable. As I mentioned you before, Wine needs to be C89
compatible. If we need some features that are not part of C89, we need
to be careful about that and it often requires things like configure
checks. In case of round, replacing it with floor(x+0.5) does the trick
pretty well.

Cheers,
Jacek