Skip to content

Commit 367360a

Browse files
JamesWTruheradityapatwardhan
authored andcommitted
Add a number of native calls to prepare for stat in PowerShell (#32)
1 parent 8df34ae commit 367360a

22 files changed

+1050
-5
lines changed

build.psm1

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,19 @@ function Start-BuildNativeUnixBinaries {
439439

440440
git clean -qfdX $Native
441441

442+
# the stat tests rely on stat(1). On most platforms, this is /usr/bin/stat,
443+
# but on alpine it is in /bin. Be sure that /usr/bin/stat exists, or
444+
# create a link from /bin/stat. If /bin/stat is missing, we'll have to fail the build
445+
446+
if ( ! (Test-Path /usr/bin/stat) ) {
447+
if ( Test-Path /bin/stat ) {
448+
New-Item -Type SymbolicLink -Path /usr/bin/stat -Target /bin/stat
449+
}
450+
else {
451+
throw "Cannot create symlink to stat(1)"
452+
}
453+
}
454+
442455
try {
443456
Push-Location $Native
444457
if ($BuildLinuxArm) {
@@ -1927,7 +1940,7 @@ function Start-PSBootstrap {
19271940

19281941
# Install ours and .NET's dependencies
19291942
$Deps = @()
1930-
if ($Environment.IsUbuntu) {
1943+
if ($Environment.IsUbuntu -or $Environment.IsDebian) {
19311944
# Build tools
19321945
$Deps += "curl", "g++", "cmake", "make"
19331946

@@ -1985,7 +1998,8 @@ function Start-PSBootstrap {
19851998
}
19861999
} elseif ($Environment.IsSUSEFamily) {
19872000
# Build tools
1988-
$Deps += "gcc", "cmake", "make"
2001+
# we're using a flag which requires an up to date compiler
2002+
$Deps += "gcc7", "cmake", "make", "gcc7-c++"
19892003

19902004
# Packaging tools
19912005
if ($Package) { $Deps += "ruby-devel", "rpmbuild", "groff", 'libffi-devel' }
@@ -2003,6 +2017,21 @@ function Start-PSBootstrap {
20032017
Start-NativeExecution {
20042018
Invoke-Expression "$baseCommand $Deps"
20052019
}
2020+
2021+
# After installation, create the appropriate symbolic links
2022+
foreach ($compiler in "gcc-7","g++-7") {
2023+
$itemPath = "/usr/bin/${compiler}"
2024+
$name = $compiler -replace "-7"
2025+
$linkPath = "/usr/bin/${name}"
2026+
$link = Get-Item -Path $linkPath -ErrorAction SilentlyContinue
2027+
if ($link) {
2028+
if ($link.Target) { # Symbolic link - remove it
2029+
Remove-Item -Force -Path $linkPath
2030+
}
2031+
}
2032+
New-Item -Type SymbolicLink -Target $itemPath -Path $linkPath
2033+
}
2034+
20062035
} elseif ($Environment.IsMacOS) {
20072036
precheck 'brew' "Bootstrap dependency 'brew' not found, must install Homebrew! See http://brew.sh/"
20082037

src/libpsl-native/gmock.pc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
libdir=/usr/local/lib
2+
includedir=/usr/local/include
3+
4+
Name: gmock
5+
Description: GoogleMock (without main() function)
6+
Version: 1.9.0
7+
URL: https://github.com/google/googletest
8+
Libs: -L${libdir} -lgmock
9+
Cflags: -I${includedir} -DGTEST_HAS_PTHREAD=1

src/libpsl-native/gmock_main.pc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
libdir=/usr/local/lib
2+
includedir=/usr/local/include
3+
4+
Name: gmock_main
5+
Description: GoogleMock (with main() function)
6+
Version: 1.9.0
7+
URL: https://github.com/google/googletest
8+
Libs: -L${libdir} -lgmock_main
9+
Cflags: -I${includedir} -DGTEST_HAS_PTHREAD=1

src/libpsl-native/gtest.pc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
libdir=/usr/local/lib
2+
includedir=/usr/local/include
3+
4+
Name: gtest
5+
Description: GoogleTest (without main() function)
6+
Version: 1.9.0
7+
URL: https://github.com/google/googletest
8+
Libs: -L${libdir} -lgtest
9+
Cflags: -I${includedir} -DGTEST_HAS_PTHREAD=1

src/libpsl-native/gtest_main.pc

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
libdir=/usr/local/lib
2+
includedir=/usr/local/include
3+
4+
Name: gtest_main
5+
Description: GoogleTest (with main() function)
6+
Version: 1.9.0
7+
URL: https://github.com/google/googletest
8+
Requires: gtest
9+
Libs: -L${libdir} -lgtest_main
10+
Cflags: -I${includedir} -DGTEST_HAS_PTHREAD=1

src/libpsl-native/src/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,11 @@ include(CheckIncludeFiles)
22

33
add_library(psl-native SHARED
44
getstat.cpp
5+
getlstat.cpp
6+
getcommonstat.cpp
7+
getcommonlstat.cpp
58
getpwuid.cpp
9+
getgrgid.cpp
610
getppid.cpp
711
getuserfrompid.cpp
812
getfileowner.cpp
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
//! @brief returns the stat of a file
5+
6+
#include <errno.h>
7+
#include <assert.h>
8+
#include <sys/types.h>
9+
#include <sys/stat.h>
10+
#include <pwd.h>
11+
#include <string.h>
12+
#include <unistd.h>
13+
14+
#include <stdio.h>
15+
16+
#include "getcommonlstat.h"
17+
18+
// Provide a common structure for the various different stat structures.
19+
// This should be safe to call on all platforms
20+
int GetCommonLStat(const char* path, struct CommonStat* commonStat)
21+
{
22+
struct stat st;
23+
assert(path);
24+
errno = 0;
25+
if (lstat(path, &st) == 0)
26+
{
27+
commonStat->Inode = st.st_ino;
28+
commonStat->Mode = st.st_mode;
29+
commonStat->UserId = st.st_uid;
30+
commonStat->GroupId = st.st_gid;
31+
commonStat->HardlinkCount = st.st_nlink;
32+
commonStat->Size = st.st_size;
33+
#if defined (__APPLE__)
34+
commonStat->AccessTime = st.st_atimespec.tv_sec;
35+
commonStat->ModifiedTime = st.st_mtimespec.tv_sec;
36+
commonStat->ChangeTime = st.st_ctimespec.tv_sec;
37+
#else
38+
commonStat->AccessTime = st.st_atime;
39+
commonStat->ModifiedTime = st.st_mtime;
40+
commonStat->ChangeTime = st.st_ctime;
41+
#endif
42+
commonStat->BlockSize = st.st_blksize;
43+
commonStat->DeviceId = st.st_dev;
44+
commonStat->NumberOfBlocks = st.st_blocks;
45+
commonStat->IsBlockDevice = S_ISBLK(st.st_mode);
46+
commonStat->IsCharacterDevice = S_ISCHR(st.st_mode);
47+
commonStat->IsDirectory = S_ISDIR(st.st_mode);
48+
commonStat->IsFile = S_ISREG(st.st_mode);
49+
commonStat->IsNamedPipe = S_ISFIFO(st.st_mode);
50+
commonStat->IsSocket = S_ISSOCK(st.st_mode);
51+
commonStat->IsSymbolicLink = S_ISLNK(st.st_mode);
52+
commonStat->IsSetUid = (st.st_mode & 0xE00) == S_ISUID;
53+
commonStat->IsSetGid = (st.st_mode & 0xE00) == S_ISGID;
54+
commonStat->IsSticky = (st.st_mode & 0xE00) == S_ISVTX;
55+
return 0;
56+
}
57+
return -1;
58+
}
59+
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
#pragma once
5+
6+
#include "pal.h"
7+
8+
#include <sys/stat.h>
9+
10+
#include "getcommonstat.h"
11+
12+
PAL_BEGIN_EXTERNC
13+
14+
int32_t GetLStat(const char* path, struct stat* buf);
15+
int GetCommonLStat(const char* path, CommonStat* cs);
16+
17+
PAL_END_EXTERNC
18+
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
//! @brief returns the stat of a file
5+
6+
#include "getcommonstat.h"
7+
8+
#include <errno.h>
9+
#include <assert.h>
10+
#include <sys/types.h>
11+
#include <sys/stat.h>
12+
#include <pwd.h>
13+
#include <string.h>
14+
#include <unistd.h>
15+
16+
#include <stdio.h>
17+
18+
// Provide a common structure for the various different stat structures.
19+
// This should be safe to call on all platforms
20+
int GetCommonStat(const char* path, struct CommonStat* commonStat)
21+
{
22+
struct stat st;
23+
assert(path);
24+
errno = 0;
25+
if (stat(path, &st) == 0)
26+
{
27+
commonStat->Inode = st.st_ino;
28+
commonStat->Mode = st.st_mode;
29+
commonStat->UserId = st.st_uid;
30+
commonStat->GroupId = st.st_gid;
31+
commonStat->HardlinkCount = st.st_nlink;
32+
commonStat->Size = st.st_size;
33+
#if defined (__APPLE__)
34+
commonStat->AccessTime = st.st_atimespec.tv_sec;
35+
commonStat->ModifiedTime = st.st_mtimespec.tv_sec;
36+
commonStat->ChangeTime = st.st_ctimespec.tv_sec;
37+
#else
38+
commonStat->AccessTime = st.st_atime;
39+
commonStat->ModifiedTime = st.st_mtime;
40+
commonStat->ChangeTime = st.st_ctime;
41+
#endif
42+
commonStat->BlockSize = st.st_blksize;
43+
commonStat->DeviceId = st.st_dev;
44+
commonStat->NumberOfBlocks = st.st_blocks;
45+
commonStat->IsBlockDevice = S_ISBLK(st.st_mode);
46+
commonStat->IsCharacterDevice = S_ISCHR(st.st_mode);
47+
commonStat->IsDirectory = S_ISDIR(st.st_mode);
48+
commonStat->IsFile = S_ISREG(st.st_mode);
49+
commonStat->IsNamedPipe = S_ISFIFO(st.st_mode);
50+
commonStat->IsSocket = S_ISSOCK(st.st_mode);
51+
commonStat->IsSymbolicLink = S_ISLNK(st.st_mode);
52+
commonStat->IsSetUid = (st.st_mode & 0xE00) == S_ISUID;
53+
commonStat->IsSetGid = (st.st_mode & 0xE00) == S_ISGID;
54+
commonStat->IsSticky = (st.st_mode & 0xE00) == S_ISVTX;
55+
return 0;
56+
}
57+
return -1;
58+
}
59+

src/libpsl-native/src/getcommonstat.h

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
#pragma once
5+
6+
#include "pal.h"
7+
8+
#include <sys/stat.h>
9+
10+
PAL_BEGIN_EXTERNC
11+
12+
struct CommonStat
13+
{
14+
long Inode;
15+
int Mode;
16+
int UserId;
17+
int GroupId;
18+
int HardlinkCount;
19+
long Size;
20+
long AccessTime;
21+
long ModifiedTime;
22+
long ChangeTime;
23+
long BlockSize;
24+
int DeviceId;
25+
int NumberOfBlocks;
26+
int IsDirectory;
27+
int IsFile;
28+
int IsSymbolicLink;
29+
int IsBlockDevice;
30+
int IsCharacterDevice;
31+
int IsNamedPipe;
32+
int IsSocket;
33+
int IsSetUid;
34+
int IsSetGid;
35+
int IsSticky;
36+
};
37+
38+
int32_t GetStat(const char* path, struct stat* buf);
39+
int GetCommonStat(const char* path, CommonStat* cs);
40+
41+
PAL_END_EXTERNC
42+

src/libpsl-native/src/getgrgid.cpp

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
//! @brief returns the groupname for a gid
5+
6+
#include "getgrgid.h"
7+
8+
#include <errno.h>
9+
#include <sys/types.h>
10+
#include <sys/stat.h>
11+
#include <grp.h>
12+
#include <string.h>
13+
#include <unistd.h>
14+
15+
//! @brief GetGrGid returns the groupname for a gid
16+
//!
17+
//! GetGrGid
18+
//!
19+
//! @param[in] gid
20+
//! @parblock
21+
//! The group identifier to lookup.
22+
//! @endparblock
23+
//!
24+
//! @retval groupname as UTF-8 string, or NULL if unsuccessful
25+
//!
26+
char* GetGrGid(gid_t gid)
27+
{
28+
int32_t ret = 0;
29+
struct group grp;
30+
struct group* result = NULL;
31+
char* buf;
32+
33+
int buflen = sysconf(_SC_GETPW_R_SIZE_MAX);
34+
if (buflen < 1)
35+
{
36+
buflen = 2048;
37+
}
38+
39+
allocate:
40+
buf = (char*)calloc(buflen, sizeof(char));
41+
42+
errno = 0;
43+
ret = getgrgid_r(gid, &grp, buf, buflen, &result);
44+
45+
if (ret != 0)
46+
{
47+
if (errno == ERANGE)
48+
{
49+
free(buf);
50+
buflen *= 2;
51+
goto allocate;
52+
}
53+
return NULL;
54+
}
55+
56+
// no group found
57+
if (result == NULL)
58+
{
59+
return NULL;
60+
}
61+
62+
// allocate copy on heap so CLR can free it
63+
size_t userlen = strnlen(grp.gr_name, buflen);
64+
char* groupname = strndup(grp.gr_name, userlen);
65+
free(buf);
66+
return groupname;
67+
}
68+

src/libpsl-native/src/getgrgid.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
#pragma once
5+
6+
#include "pal.h"
7+
8+
#include <sys/types.h>
9+
10+
PAL_BEGIN_EXTERNC
11+
12+
char* GetGrGid(gid_t gid);
13+
14+
PAL_END_EXTERNC
15+

0 commit comments

Comments
 (0)