-
Notifications
You must be signed in to change notification settings - Fork 36
Add a number of native calls to prepare for stat in PowerShell #32
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
ee1d059
123e32f
b7a4004
9270120
edeec7f
44277bb
b368d03
73f89d1
83ce14f
550b00b
8469cc5
b3c42d4
a9a4ff0
b0a44b4
887d580
a887305
773adca
9ac7b2a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
libdir=/usr/local/lib | ||
includedir=/usr/local/include | ||
|
||
Name: gmock | ||
Description: GoogleMock (without main() function) | ||
Version: 1.9.0 | ||
URL: https://github.com/google/googletest | ||
Libs: -L${libdir} -lgmock | ||
Cflags: -I${includedir} -DGTEST_HAS_PTHREAD=1 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
libdir=/usr/local/lib | ||
includedir=/usr/local/include | ||
|
||
Name: gmock_main | ||
Description: GoogleMock (with main() function) | ||
Version: 1.9.0 | ||
URL: https://github.com/google/googletest | ||
Libs: -L${libdir} -lgmock_main | ||
Cflags: -I${includedir} -DGTEST_HAS_PTHREAD=1 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
libdir=/usr/local/lib | ||
includedir=/usr/local/include | ||
|
||
Name: gtest | ||
Description: GoogleTest (without main() function) | ||
Version: 1.9.0 | ||
URL: https://github.com/google/googletest | ||
Libs: -L${libdir} -lgtest | ||
Cflags: -I${includedir} -DGTEST_HAS_PTHREAD=1 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
libdir=/usr/local/lib | ||
includedir=/usr/local/include | ||
|
||
Name: gtest_main | ||
Description: GoogleTest (with main() function) | ||
Version: 1.9.0 | ||
URL: https://github.com/google/googletest | ||
Requires: gtest | ||
Libs: -L${libdir} -lgtest_main | ||
Cflags: -I${includedir} -DGTEST_HAS_PTHREAD=1 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
// Copyright (c) Microsoft Corporation. All rights reserved. | ||
// Licensed under the MIT License. | ||
|
||
//! @brief returns the stat of a file | ||
|
||
#include <errno.h> | ||
#include <assert.h> | ||
#include <sys/types.h> | ||
#include <sys/stat.h> | ||
#include <pwd.h> | ||
#include <string.h> | ||
#include <unistd.h> | ||
|
||
#include <stdio.h> | ||
|
||
#include "getcommonlstat.h" | ||
|
||
// Provide a common structure for the various different stat structures. | ||
// This should be safe to call on all platforms | ||
int GetCommonLStat(const char* path, struct CommonStat* commonStat) | ||
{ | ||
struct stat st; | ||
assert(path); | ||
errno = 0; | ||
if (lstat(path, &st) == 0) | ||
{ | ||
commonStat->Inode = st.st_ino; | ||
commonStat->Mode = st.st_mode; | ||
commonStat->UserId = st.st_uid; | ||
commonStat->GroupId = st.st_gid; | ||
commonStat->HardlinkCount = st.st_nlink; | ||
commonStat->Size = st.st_size; | ||
#if defined (__APPLE__) | ||
commonStat->AccessTime = st.st_atimespec.tv_sec; | ||
commonStat->ModifiedTime = st.st_mtimespec.tv_sec; | ||
commonStat->ChangeTime = st.st_ctimespec.tv_sec; | ||
#else | ||
commonStat->AccessTime = st.st_atime; | ||
commonStat->ModifiedTime = st.st_mtime; | ||
commonStat->ChangeTime = st.st_ctime; | ||
#endif | ||
commonStat->BlockSize = st.st_blksize; | ||
commonStat->DeviceId = st.st_dev; | ||
commonStat->NumberOfBlocks = st.st_blocks; | ||
commonStat->IsBlockDevice = S_ISBLK(st.st_mode); | ||
commonStat->IsCharacterDevice = S_ISCHR(st.st_mode); | ||
commonStat->IsDirectory = S_ISDIR(st.st_mode); | ||
commonStat->IsFile = S_ISREG(st.st_mode); | ||
commonStat->IsNamedPipe = S_ISFIFO(st.st_mode); | ||
commonStat->IsSocket = S_ISSOCK(st.st_mode); | ||
commonStat->IsSymbolicLink = S_ISLNK(st.st_mode); | ||
commonStat->IsSetUid = (st.st_mode & 0xE00) == S_ISUID; | ||
commonStat->IsSetGid = (st.st_mode & 0xE00) == S_ISGID; | ||
commonStat->IsSticky = (st.st_mode & 0xE00) == S_ISVTX; | ||
return 0; | ||
} | ||
return -1; | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
// Copyright (c) Microsoft Corporation. All rights reserved. | ||
// Licensed under the MIT License. | ||
|
||
#pragma once | ||
|
||
#include "pal.h" | ||
|
||
#include <sys/stat.h> | ||
|
||
#include "getcommonstat.h" | ||
|
||
PAL_BEGIN_EXTERNC | ||
|
||
int32_t GetLStat(const char* path, struct stat* buf); | ||
int GetCommonLStat(const char* path, CommonStat* cs); | ||
|
||
PAL_END_EXTERNC | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
// Copyright (c) Microsoft Corporation. All rights reserved. | ||
// Licensed under the MIT License. | ||
|
||
//! @brief returns the stat of a file | ||
|
||
#include "getcommonstat.h" | ||
|
||
#include <errno.h> | ||
#include <assert.h> | ||
#include <sys/types.h> | ||
#include <sys/stat.h> | ||
#include <pwd.h> | ||
#include <string.h> | ||
#include <unistd.h> | ||
|
||
#include <stdio.h> | ||
|
||
// Provide a common structure for the various different stat structures. | ||
// This should be safe to call on all platforms | ||
int GetCommonStat(const char* path, struct CommonStat* commonStat) | ||
{ | ||
struct stat st; | ||
assert(path); | ||
errno = 0; | ||
if (stat(path, &st) == 0) | ||
{ | ||
commonStat->Inode = st.st_ino; | ||
commonStat->Mode = st.st_mode; | ||
commonStat->UserId = st.st_uid; | ||
commonStat->GroupId = st.st_gid; | ||
commonStat->HardlinkCount = st.st_nlink; | ||
commonStat->Size = st.st_size; | ||
#if defined (__APPLE__) | ||
commonStat->AccessTime = st.st_atimespec.tv_sec; | ||
commonStat->ModifiedTime = st.st_mtimespec.tv_sec; | ||
commonStat->ChangeTime = st.st_ctimespec.tv_sec; | ||
#else | ||
commonStat->AccessTime = st.st_atime; | ||
commonStat->ModifiedTime = st.st_mtime; | ||
commonStat->ChangeTime = st.st_ctime; | ||
#endif | ||
commonStat->BlockSize = st.st_blksize; | ||
commonStat->DeviceId = st.st_dev; | ||
commonStat->NumberOfBlocks = st.st_blocks; | ||
commonStat->IsBlockDevice = S_ISBLK(st.st_mode); | ||
commonStat->IsCharacterDevice = S_ISCHR(st.st_mode); | ||
commonStat->IsDirectory = S_ISDIR(st.st_mode); | ||
commonStat->IsFile = S_ISREG(st.st_mode); | ||
commonStat->IsNamedPipe = S_ISFIFO(st.st_mode); | ||
commonStat->IsSocket = S_ISSOCK(st.st_mode); | ||
commonStat->IsSymbolicLink = S_ISLNK(st.st_mode); | ||
commonStat->IsSetUid = (st.st_mode & 0xE00) == S_ISUID; | ||
commonStat->IsSetGid = (st.st_mode & 0xE00) == S_ISGID; | ||
commonStat->IsSticky = (st.st_mode & 0xE00) == S_ISVTX; | ||
return 0; | ||
} | ||
return -1; | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
// Copyright (c) Microsoft Corporation. All rights reserved. | ||
// Licensed under the MIT License. | ||
|
||
#pragma once | ||
|
||
#include "pal.h" | ||
|
||
#include <sys/stat.h> | ||
|
||
PAL_BEGIN_EXTERNC | ||
|
||
struct CommonStat | ||
{ | ||
long Inode; | ||
int Mode; | ||
int UserId; | ||
int GroupId; | ||
int HardlinkCount; | ||
long Size; | ||
long AccessTime; | ||
long ModifiedTime; | ||
long ChangeTime; | ||
long BlockSize; | ||
int DeviceId; | ||
int NumberOfBlocks; | ||
int IsDirectory; | ||
int IsFile; | ||
int IsSymbolicLink; | ||
int IsBlockDevice; | ||
int IsCharacterDevice; | ||
int IsNamedPipe; | ||
int IsSocket; | ||
int IsSetUid; | ||
int IsSetGid; | ||
int IsSticky; | ||
}; | ||
|
||
int32_t GetStat(const char* path, struct stat* buf); | ||
int GetCommonStat(const char* path, CommonStat* cs); | ||
|
||
PAL_END_EXTERNC | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
// Copyright (c) Microsoft Corporation. All rights reserved. | ||
// Licensed under the MIT License. | ||
|
||
//! @brief returns the groupname for a gid | ||
|
||
#include "getgrgid.h" | ||
|
||
#include <errno.h> | ||
#include <sys/types.h> | ||
#include <sys/stat.h> | ||
#include <grp.h> | ||
#include <string.h> | ||
#include <unistd.h> | ||
|
||
//! @brief GetGrGid returns the groupname for a gid | ||
//! | ||
//! GetGrGid | ||
//! | ||
//! @param[in] gid | ||
//! @parblock | ||
//! The group identifier to lookup. | ||
//! @endparblock | ||
//! | ||
//! @retval groupname as UTF-8 string, or NULL if unsuccessful | ||
//! | ||
char* GetGrGid(gid_t gid) | ||
{ | ||
int32_t ret = 0; | ||
struct group grp; | ||
struct group* result = NULL; | ||
char* buf; | ||
|
||
int buflen = sysconf(_SC_GETPW_R_SIZE_MAX); | ||
if (buflen < 1) | ||
{ | ||
buflen = 2048; | ||
} | ||
|
||
allocate: | ||
buf = (char*)calloc(buflen, sizeof(char)); | ||
|
||
errno = 0; | ||
ret = getgrgid_r(gid, &grp, buf, buflen, &result); | ||
|
||
if (ret != 0) | ||
{ | ||
if (errno == ERANGE) | ||
{ | ||
free(buf); | ||
buflen *= 2; | ||
goto allocate; | ||
} | ||
Comment on lines
+47
to
+52
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe add a check like There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. what are you attempting to do with this check? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Upper boundary. Or we can support the buffer without upper limit? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we should support whatever sysctl says it is. This can be set in the OS, while I don't believe there are any OSs which have larger than this, I don't know. |
||
return NULL; | ||
} | ||
|
||
// no group found | ||
if (result == NULL) | ||
{ | ||
return NULL; | ||
} | ||
|
||
// allocate copy on heap so CLR can free it | ||
size_t userlen = strnlen(grp.gr_name, buflen); | ||
char* groupname = strndup(grp.gr_name, userlen); | ||
free(buf); | ||
return groupname; | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
// Copyright (c) Microsoft Corporation. All rights reserved. | ||
// Licensed under the MIT License. | ||
|
||
#pragma once | ||
|
||
#include "pal.h" | ||
|
||
#include <sys/types.h> | ||
|
||
PAL_BEGIN_EXTERNC | ||
|
||
char* GetGrGid(gid_t gid); | ||
|
||
PAL_END_EXTERNC | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is difficult to see a difference GetCommonLStat vs GetCommonStat. Also name of returned struct
CommonStat
says all we want. I see short namesGetLStat
andGetStat
is used already. We could use name likeGetStatC
or even one common name with the third bool parameter UseSymbolicLink - in last case we will have only single P/Invoke entry in C#.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since in this project, all the APIs have a 1 to 1 mapping with the native APIs, we should have two APIs namely
GetCommonStat
->stat
andGetCommonLStat
->lstat