in src/main/c/Posix/PosixHelperFunctions.c [1856:1905]
int verifyAndSetUserPortGroup(const char *portFile)
{
// Check if the user can currently access the port file
int numGroups = getgroups(0, NULL);
int userCanAccess = (faccessat(0, portFile, R_OK | W_OK, AT_EACCESS) == 0);
// Attempt to acquire access if not available
if (!userCanAccess)
{
// Ensure that the port still exists
struct stat fileStats;
if (stat(portFile, &fileStats) == 0)
{
// Check if the user is part of the group that owns the port
int userPartOfPortGroup = 0;
gid_t *userGroups = (gid_t*)malloc(numGroups * sizeof(gid_t));
if (getgroups(numGroups, userGroups) >= 0)
for (int i = 0; i < numGroups; ++i)
if (userGroups[i] == fileStats.st_gid)
{
userPartOfPortGroup = 1;
break;
}
// Attempt to add the user to the group that owns the port
char *addUserToGroupCmd = (char*)malloc(256);
if (!userPartOfPortGroup)
{
struct group *portGroup;
struct passwd *userDetails;
if ((portGroup = getgrgid(fileStats.st_gid)) && (userDetails = getpwuid(geteuid())))
{
snprintf(addUserToGroupCmd, 256, "sudo usermod -a -G %s %s", portGroup->gr_name, userDetails->pw_name);
userCanAccess = (system(addUserToGroupCmd) == 0);
}
}
// Attempt to enable all read/write port permissions
snprintf(addUserToGroupCmd, 256, "sudo chmod 666 %s", portFile);
userCanAccess = (system(addUserToGroupCmd) == 0) || userCanAccess;
// Clean up memory
free(addUserToGroupCmd);
free(userGroups);
}
}
// Return whether the user can currently access the serial port
return userCanAccess;
}