I'm using C++ and XCode to create a cmd line app to save file permissions, however I can't get the sperm() method to be identified, the error is
'Use of undeclared identifier 'sperm'
My includes and the piece of code in question are below ...
// My includes ...
#include <iostream>
#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>
#include <string.h>
#include <vector>
#include <sys/stat.h>
#include <dirent.h>
#include <pwd.h>
#include <grp.h>
#include <time.h>
#include <locale.h>
#include <langinfo.h>
#include <stdint.h>
// Code fragment ...
dp = opendir ("/var/someplace");
if (dp != NULL)
{
while ((ep = readdir (dp)))
{
oFile = new FileObject;
oFile->setName( ep->d_name );
oFile->setIsDirectory( ep->d_type == isFolder );
oFiles.push_back (*oFile);
// If it's a folder then we can get it's innards
if (stat(ep->d_name, &statbuf) == -1)
continue;
cout << "%10.10s", sperm(statbuf.st_mode);
iFile++;
}
closedir (dp);
}
else
perror ("Couldn't open the directory");
This might make me look like a pervert, but I searched google for 'sperm' (ofcourse only for .h and .cpp files). The bad news is I can't find any references to it (except on the stat function page itself).
The good news is I found this piece of code which defines it's own 'sperm' function:
char const * sperm(__mode_t mode) {
static char local_buff[16] = {0};
int i = 0;
// user permissions
if ((mode & S_IRUSR) == S_IRUSR) local_buff[i] = 'r';
else local_buff[i] = '-';
i++;
if ((mode & S_IWUSR) == S_IWUSR) local_buff[i] = 'w';
else local_buff[i] = '-';
i++;
if ((mode & S_IXUSR) == S_IXUSR) local_buff[i] = 'x';
else local_buff[i] = '-';
i++;
// group permissions
if ((mode & S_IRGRP) == S_IRGRP) local_buff[i] = 'r';
else local_buff[i] = '-';
i++;
if ((mode & S_IWGRP) == S_IWGRP) local_buff[i] = 'w';
else local_buff[i] = '-';
i++;
if ((mode & S_IXGRP) == S_IXGRP) local_buff[i] = 'x';
else local_buff[i] = '-';
i++;
// other permissions
if ((mode & S_IROTH) == S_IROTH) local_buff[i] = 'r';
else local_buff[i] = '-';
i++;
if ((mode & S_IWOTH) == S_IWOTH) local_buff[i] = 'w';
else local_buff[i] = '-';
i++;
if ((mode & S_IXOTH) == S_IXOTH) local_buff[i] = 'x';
else local_buff[i] = '-';
return local_buff;
}
usage is simple:
#include <sys/types.h>
#include <sys/stat.h>
#include <iostream>
int main(int argc, char ** argv)
{
std::cout<<sperm(S_IRUSR | S_IXUSR | S_IWGRP | S_IROTH)<<std::endl;
std::cout<<sperm(S_IRUSR)<<std::endl;
std::cout<<sperm(S_IRUSR | S_IRGRP | S_IWOTH | S_IROTH)<<std::endl;
return 0;
}
output on ideone:
r-x-w-r--
r--------
r--r--rw-
I ran into this a couple years ago. I don't feel like tiptoeing my way through Google with that particular search term at the moment, but if I remember correctly, the answer is that sperm()
is a non-standard system function available on Solaris. But since it's not part of the unix standard, you won't find it on OS X.
Assuming the function is defined (and I'm not going to google that name from work), you have a problem with the way you're printing it:
cout << "%10.10s", sperm(statbuf.st_mode);
That's not going to print a formatted string, since C++ iostreams don't work like C's printf
. You could either not format it:
cout << sperm(statbuf.st_mode);
or use printf
:
printf("%10.10s", sperm(statbuf.st_mode));
or do some jiggery-pokery with iostream manipulators.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With