Raymond Toy pushed to branch issue-125-unix-stat-wrong at cmucl / cmucl

Commits:

2 changed files:

Changes:

  • src/code/unix.lisp
    ... ... @@ -74,8 +74,7 @@
    74 74
     
    
    75 75
     (def-alien-type dev-t
    
    76 76
         #-(or alpha svr4 bsd linux) short
    
    77
    -    #+(and linux (not amd64)) uquad-t
    
    78
    -    #+(and linux amd64) u-int64-t
    
    77
    +    #+linux u-int64-t
    
    79 78
         #+netbsd u-int64-t
    
    80 79
         #+alpha int
    
    81 80
         #+(and (not linux) (not netbsd) (or bsd svr4)) unsigned-long)
    
    ... ... @@ -1573,207 +1572,96 @@
    1573 1572
     ;;
    
    1574 1573
     ;; This should be updated so that all OSes do this.
    
    1575 1574
     #+linux
    
    1576
    -(progn
    
    1577
    -(defun unix-stat (name)
    
    1578
    -  _N"Unix-stat retrieves information about the specified
    
    1575
    +(macrolet
    
    1576
    +    ((call-stat (c-func-name first-arg-type first-arg)
    
    1577
    +       ;; Call the stat function named C-FUNC-NAME.  The type of the
    
    1578
    +       ;; first arg is FIRST-ARG_TYPE and FIRST-ARG is the first arg
    
    1579
    +       ;; to the stat function.  fstat is different from stat and
    
    1580
    +       ;; lstat since it takes an fd for the first arg instead of
    
    1581
    +       ;; string.
    
    1582
    +       `(with-alien ((dev dev-t)
    
    1583
    +		     (ino ino64-t)
    
    1584
    +		     (mode mode-t)
    
    1585
    +		     (nlink nlink-t)
    
    1586
    +		     (uid uid-t)
    
    1587
    +		     (gid gid-t)
    
    1588
    +		     (rdev dev-t)
    
    1589
    +		     (size off-t)
    
    1590
    +		     (atime time-t)
    
    1591
    +		     (mtime time-t)
    
    1592
    +		     (ctime time-t)
    
    1593
    +		     (blksize c-call:long)
    
    1594
    +		     (blocks off-t))
    
    1595
    +	  (let ((result
    
    1596
    +		  (alien-funcall
    
    1597
    +		   (extern-alien ,c-func-name
    
    1598
    +				 (function int
    
    1599
    +					   ,first-arg-type
    
    1600
    +					   (* dev-t)
    
    1601
    +					   (* ino64-t)
    
    1602
    +					   (* mode-t)
    
    1603
    +					   (* nlink-t)
    
    1604
    +					   (* uid-t)
    
    1605
    +					   (* gid-t)
    
    1606
    +					   (* dev-t)
    
    1607
    +					   (* off-t)
    
    1608
    +					   (* time-t)
    
    1609
    +					   (* time-t)
    
    1610
    +					   (* time-t)
    
    1611
    +					   (* c-call:long)
    
    1612
    +					   (* off-t)))
    
    1613
    +		   ,first-arg
    
    1614
    +		   (addr dev)
    
    1615
    +		   (addr ino)
    
    1616
    +		   (addr mode)
    
    1617
    +		   (addr nlink)
    
    1618
    +		   (addr uid)
    
    1619
    +		   (addr gid)
    
    1620
    +		   (addr rdev)
    
    1621
    +		   (addr size)
    
    1622
    +		   (addr atime)
    
    1623
    +		   (addr mtime)
    
    1624
    +		   (addr ctime)
    
    1625
    +		   (addr blksize)
    
    1626
    +		   (addr blocks))))
    
    1627
    +	    (if (eql -1 result)
    
    1628
    +		(values nil (unix-errno))
    
    1629
    +		(values t
    
    1630
    +			dev
    
    1631
    +			ino
    
    1632
    +			mode
    
    1633
    +			nlink
    
    1634
    +			uid
    
    1635
    +			gid
    
    1636
    +			rdev
    
    1637
    +			size
    
    1638
    +			atime
    
    1639
    +			mtime
    
    1640
    +			ctime
    
    1641
    +			blksize
    
    1642
    +			blocks))))))
    
    1643
    +  (defun unix-stat (name)
    
    1644
    +    _N"Unix-stat retrieves information about the specified
    
    1579 1645
        file returning them in the form of multiple values.
    
    1580 1646
        See the UNIX Programmer's Manual for a description
    
    1581 1647
        of the values returned.  If the call fails, then NIL
    
    1582 1648
        and an error number is returned instead."
    
    1583
    -  (declare (type unix-pathname name))
    
    1584
    -  (when (string= name "")
    
    1585
    -    (setf name "."))
    
    1586
    -  (with-alien ((dev dev-t)
    
    1587
    -	       (ino ino64-t)
    
    1588
    -	       (mode mode-t)
    
    1589
    -	       (nlink nlink-t)
    
    1590
    -	       (uid uid-t)
    
    1591
    -	       (gid gid-t)
    
    1592
    -	       (rdev dev-t)
    
    1593
    -	       (size off-t)
    
    1594
    -	       (atime (struct timespec-t))
    
    1595
    -	       (mtime (struct timespec-t))
    
    1596
    -	       (ctime (struct timespec-t))
    
    1597
    -	       (blksize off-t)
    
    1598
    -	       (blocks off-t))
    
    1599
    -    (let ((result
    
    1600
    -	    (alien-funcall
    
    1601
    -	     (extern-alien "unix_stat"
    
    1602
    -			   (function int
    
    1603
    -				     c-call::c-string
    
    1604
    -				     (* dev-t)
    
    1605
    -				     (* ino64-t)
    
    1606
    -				     (* mode-t)
    
    1607
    -				     (* nlink-t)
    
    1608
    -				     (* uid-t)
    
    1609
    -				     (* gid-t)
    
    1610
    -				     (* dev-t)
    
    1611
    -				     (* off-t)
    
    1612
    -				     (* (struct timespec-t))
    
    1613
    -				     (* (struct timespec-t))
    
    1614
    -				     (* (struct timespec-t))
    
    1615
    -				     (* off-t)
    
    1616
    -				     (* off-t)))
    
    1617
    -	     (%name->file name)
    
    1618
    -	     (addr dev)
    
    1619
    -	     (addr ino)
    
    1620
    -	     (addr mode)
    
    1621
    -	     (addr nlink)
    
    1622
    -	     (addr uid)
    
    1623
    -	     (addr gid)
    
    1624
    -	     (addr rdev)
    
    1625
    -	     (addr size)
    
    1626
    -	     (addr atime)
    
    1627
    -	     (addr mtime)
    
    1628
    -	     (addr ctime)
    
    1629
    -	     (addr blksize)
    
    1630
    -	     (addr blocks))))
    
    1631
    -      (if (eql -1 result)
    
    1632
    -	  (values nil (unix-errno))
    
    1633
    -	  (flet ((make-64bit (x)
    
    1634
    -		   (+ (alien:deref x 0)
    
    1635
    -		      (ash (alien:deref x 1) 32)))
    
    1636
    -		 (make-time (x)
    
    1637
    -		   (alien:slot x 'unix::ts-sec)))
    
    1638
    -	    (values t
    
    1639
    -		    (make-64bit dev) ino mode nlink uid gid
    
    1640
    -		    (make-64bit rdev)
    
    1641
    -		    size
    
    1642
    -		    (make-time atime)
    
    1643
    -		    (make-time mtime)
    
    1644
    -		    (make-time ctime)
    
    1645
    -		    blksize blocks))))))
    
    1649
    +    (declare (type unix-pathname name))
    
    1650
    +    (when (string= name "")
    
    1651
    +      (setf name "."))
    
    1652
    +    (call-stat "unix_stat" c-call:c-string (%name->file name)))
    
    1646 1653
     
    
    1647
    -(defun unix-lstat (name)
    
    1648
    -  "Unix-lstat is similar to unix-stat except the specified
    
    1654
    +  (defun unix-lstat (name)
    
    1655
    +    "Unix-lstat is similar to unix-stat except the specified
    
    1649 1656
        file must be a symbolic link."
    
    1650
    -  (declare (type unix-pathname name))
    
    1651
    -  (with-alien ((dev dev-t)
    
    1652
    -	       (ino ino64-t)
    
    1653
    -	       (mode mode-t)
    
    1654
    -	       (nlink nlink-t)
    
    1655
    -	       (uid uid-t)
    
    1656
    -	       (gid gid-t)
    
    1657
    -	       (rdev dev-t)
    
    1658
    -	       (size off-t)
    
    1659
    -	       (atime (struct timespec-t))
    
    1660
    -	       (mtime (struct timespec-t))
    
    1661
    -	       (ctime (struct timespec-t))
    
    1662
    -	       (blksize off-t)
    
    1663
    -	       (blocks off-t))
    
    1664
    -    (let ((result
    
    1665
    -	    (alien-funcall
    
    1666
    -	     (extern-alien "unix_lstat"
    
    1667
    -			   (function int
    
    1668
    -				     c-call::c-string
    
    1669
    -				     (* dev-t)
    
    1670
    -				     (* ino64-t)
    
    1671
    -				     (* mode-t)
    
    1672
    -				     (* nlink-t)
    
    1673
    -				     (* uid-t)
    
    1674
    -				     (* gid-t)
    
    1675
    -				     (* dev-t)
    
    1676
    -				     (* off-t)
    
    1677
    -				     (* (struct timespec-t))
    
    1678
    -				     (* (struct timespec-t))
    
    1679
    -				     (* (struct timespec-t))
    
    1680
    -				     (* off-t)
    
    1681
    -				     (* off-t)))
    
    1682
    -	     (%name->file name)
    
    1683
    -	     (addr dev)
    
    1684
    -	     (addr ino)
    
    1685
    -	     (addr mode)
    
    1686
    -	     (addr nlink)
    
    1687
    -	     (addr uid)
    
    1688
    -	     (addr gid)
    
    1689
    -	     (addr rdev)
    
    1690
    -	     (addr size)
    
    1691
    -	     (addr atime)
    
    1692
    -	     (addr mtime)
    
    1693
    -	     (addr ctime)
    
    1694
    -	     (addr blksize)
    
    1695
    -	     (addr blocks))))
    
    1696
    -      (if (eql -1 result)
    
    1697
    -	  (values nil (unix-errno))
    
    1698
    -	  (flet ((make-64bit (x)
    
    1699
    -		   (+ (alien:deref x 0)
    
    1700
    -		      (ash (alien:deref x 1) 32)))
    
    1701
    -		 (make-time (x)
    
    1702
    -		   (alien:slot x 'unix::ts-sec)))
    
    1703
    -	    (values t
    
    1704
    -		    (make-64bit dev) ino mode nlink uid gid
    
    1705
    -		    (make-64bit rdev)
    
    1706
    -		    size
    
    1707
    -		    (make-time atime)
    
    1708
    -		    (make-time mtime)
    
    1709
    -		    (make-time ctime)
    
    1710
    -		    blksize blocks))))))
    
    1657
    +    (declare (type unix-pathname name))
    
    1658
    +    (call-stat "unix_lstat" c-call:c-string (%name->file name)))
    
    1711 1659
     
    
    1712
    -(defun unix-fstat (fd)
    
    1713
    -  _N"Unix-fstat is similar to unix-stat except the file is specified
    
    1660
    +  (defun unix-fstat (fd)
    
    1661
    +    _N"Unix-fstat is similar to unix-stat except the file is specified
    
    1714 1662
        by the file descriptor fd."
    
    1715
    -  (declare (type unix-fd fd))
    
    1716
    -  (with-alien ((dev dev-t)
    
    1717
    -	       (ino ino64-t)
    
    1718
    -	       (mode mode-t)
    
    1719
    -	       (nlink nlink-t)
    
    1720
    -	       (uid uid-t)
    
    1721
    -	       (gid gid-t)
    
    1722
    -	       (rdev dev-t)
    
    1723
    -	       (size off-t)
    
    1724
    -	       (atime (struct timespec-t))
    
    1725
    -	       (mtime (struct timespec-t))
    
    1726
    -	       (ctime (struct timespec-t))
    
    1727
    -	       (blksize off-t)
    
    1728
    -	       (blocks off-t))
    
    1729
    -    (let ((result
    
    1730
    -	    (alien-funcall
    
    1731
    -	     (extern-alien "unix_fstat"
    
    1732
    -			   (function int
    
    1733
    -				     int
    
    1734
    -				     (* dev-t)
    
    1735
    -				     (* ino64-t)
    
    1736
    -				     (* mode-t)
    
    1737
    -				     (* nlink-t)
    
    1738
    -				     (* uid-t)
    
    1739
    -				     (* gid-t)
    
    1740
    -				     (* dev-t)
    
    1741
    -				     (* off-t)
    
    1742
    -				     (* (struct timespec-t))
    
    1743
    -				     (* (struct timespec-t))
    
    1744
    -				     (* (struct timespec-t))
    
    1745
    -				     (* off-t)
    
    1746
    -				     (* off-t)))
    
    1747
    -	     fd
    
    1748
    -	     (addr dev)
    
    1749
    -	     (addr ino)
    
    1750
    -	     (addr mode)
    
    1751
    -	     (addr nlink)
    
    1752
    -	     (addr uid)
    
    1753
    -	     (addr gid)
    
    1754
    -	     (addr rdev)
    
    1755
    -	     (addr size)
    
    1756
    -	     (addr atime)
    
    1757
    -	     (addr mtime)
    
    1758
    -	     (addr ctime)
    
    1759
    -	     (addr blksize)
    
    1760
    -	     (addr blocks))))
    
    1761
    -      (if (eql -1 result)
    
    1762
    -	  (values nil (unix-errno))
    
    1763
    -	  (flet ((make-64bit (x)
    
    1764
    -		   (+ (alien:deref x 0)
    
    1765
    -		      (ash (alien:deref x 1) 32)))
    
    1766
    -		 (make-time (x)
    
    1767
    -		   (alien:slot x 'unix::ts-sec)))
    
    1768
    -	    (values t
    
    1769
    -		    (make-64bit dev) ino mode nlink uid gid
    
    1770
    -		    (make-64bit rdev)
    
    1771
    -		    size
    
    1772
    -		    (make-time atime)
    
    1773
    -		    (make-time mtime)
    
    1774
    -		    (make-time ctime)
    
    1775
    -		    blksize blocks))))))
    
    1776
    -)
    
    1663
    +    (declare (type unix-fd fd))
    
    1664
    +    (call-stat "unix_fstat" int fd)))
    
    1777 1665
     
    
    1778 1666
     ;;; 64-bit versions of stat and friends
    
    1779 1667
     #+solaris
    

  • src/lisp/unix.c
    ... ... @@ -2,13 +2,18 @@
    2 2
      * C interfaces to unix syscalls
    
    3 3
      */
    
    4 4
     
    
    5
    +/* We want to support large files */
    
    6
    +
    
    7
    +#define _LARGEFILE_SOURCE
    
    8
    +#define _FILE_OFFSET_BITS 64
    
    9
    +
    
    5 10
     #include <stdio.h>
    
    6 11
     #include <sys/stat.h>
    
    7 12
     
    
    8 13
     int unix_stat(const char* path, dev_t *dev, ino_t *ino, mode_t *mode, nlink_t *nlink,
    
    9 14
                   uid_t *uid, gid_t *gid, dev_t *rdev, off_t *size,
    
    10
    -              struct timespec *atime, struct timespec *mtime, struct timespec *ctime,
    
    11
    -              long *blksize, long *blocks)
    
    15
    +              time_t *atime, time_t *mtime, time_t *ctime,
    
    16
    +              long *blksize, off_t *blocks)
    
    12 17
     {
    
    13 18
         int rc;
    
    14 19
         struct stat buf;
    
    ... ... @@ -38,9 +43,9 @@ int unix_stat(const char* path, dev_t *dev, ino_t *ino, mode_t *mode, nlink_t *n
    38 43
         *gid = buf.st_gid;
    
    39 44
         *rdev = buf.st_rdev;
    
    40 45
         *size = buf.st_size;
    
    41
    -    *atime = buf.st_atim;
    
    42
    -    *mtime = buf.st_mtim;
    
    43
    -    *ctime = buf.st_ctim;
    
    46
    +    *atime = buf.st_atime;
    
    47
    +    *mtime = buf.st_mtime;
    
    48
    +    *ctime = buf.st_ctime;
    
    44 49
         *blksize = buf.st_blksize;
    
    45 50
         *blocks = buf.st_blocks;
    
    46 51
     
    
    ... ... @@ -49,8 +54,8 @@ int unix_stat(const char* path, dev_t *dev, ino_t *ino, mode_t *mode, nlink_t *n
    49 54
     
    
    50 55
     int unix_fstat(int fd, dev_t *dev, ino_t *ino, mode_t *mode, nlink_t *nlink,
    
    51 56
                    uid_t *uid, gid_t *gid, dev_t *rdev, off_t *size,
    
    52
    -               struct timespec *atime, struct timespec *mtime, struct timespec *ctime,
    
    53
    -               long *blksize, long *blocks)
    
    57
    +               time_t *atime, time_t *mtime, time_t *ctime,
    
    58
    +               long *blksize, off_t *blocks)
    
    54 59
     {
    
    55 60
         int rc;
    
    56 61
         struct stat buf;
    
    ... ... @@ -65,9 +70,9 @@ int unix_fstat(int fd, dev_t *dev, ino_t *ino, mode_t *mode, nlink_t *nlink,
    65 70
         *gid = buf.st_gid;
    
    66 71
         *rdev = buf.st_rdev;
    
    67 72
         *size = buf.st_size;
    
    68
    -    *atime = buf.st_atim;
    
    69
    -    *mtime = buf.st_mtim;
    
    70
    -    *ctime = buf.st_ctim;
    
    73
    +    *atime = buf.st_atime;
    
    74
    +    *mtime = buf.st_mtime;
    
    75
    +    *ctime = buf.st_ctime;
    
    71 76
         *blksize = buf.st_blksize;
    
    72 77
         *blocks = buf.st_blocks;
    
    73 78
     
    
    ... ... @@ -76,8 +81,8 @@ int unix_fstat(int fd, dev_t *dev, ino_t *ino, mode_t *mode, nlink_t *nlink,
    76 81
     
    
    77 82
     int unix_lstat(const char* path, dev_t *dev, ino_t *ino, mode_t *mode, nlink_t *nlink,
    
    78 83
                    uid_t *uid, gid_t *gid, dev_t *rdev, off_t *size,
    
    79
    -               struct timespec *atime, struct timespec *mtime, struct timespec *ctime,
    
    80
    -               long *blksize, long *blocks)
    
    84
    +               time_t *atime, time_t *mtime, time_t *ctime,
    
    85
    +               long *blksize, off_t *blocks)
    
    81 86
     {
    
    82 87
         int rc;
    
    83 88
         struct stat buf;
    
    ... ... @@ -92,9 +97,9 @@ int unix_lstat(const char* path, dev_t *dev, ino_t *ino, mode_t *mode, nlink_t *
    92 97
         *gid = buf.st_gid;
    
    93 98
         *rdev = buf.st_rdev;
    
    94 99
         *size = buf.st_size;
    
    95
    -    *atime = buf.st_atim;
    
    96
    -    *mtime = buf.st_mtim;
    
    97
    -    *ctime = buf.st_ctim;
    
    100
    +    *atime = buf.st_atime;
    
    101
    +    *mtime = buf.st_mtime;
    
    102
    +    *ctime = buf.st_ctime;
    
    98 103
         *blksize = buf.st_blksize;
    
    99 104
         *blocks = buf.st_blocks;
    
    100 105