Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

XCode C++ missing sperm()

Tags:

c++

xcode

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");
like image 733
creativetechnologist Avatar asked Mar 09 '12 17:03

creativetechnologist


3 Answers

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-
like image 145
Tom Knapen Avatar answered Oct 25 '22 09:10

Tom Knapen


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.

like image 44
BJ Homer Avatar answered Oct 25 '22 11:10

BJ Homer


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.

like image 2
Mike Seymour Avatar answered Oct 25 '22 10:10

Mike Seymour