tags:

views:

91

answers:

1

Okay so I'm trying to make a file browser program, and I'm in the basics right now but this line here:

fprintf(stderr, "stat returned %i\n", stat(files[curser].c_str(), &st));

Says that stat is returning -1 (fail) and I am wondering why. Can anyone tell me? Here is the full source:

#include <SDL/sdl.h>
#include <SDL/sdl_image.h>

#include <SDL/SDL_audio.h>
#include <SDL/SDL_mixer.h>

#include <SDL/SDL_ttf.h>

#include <iostream>
#include <sstream> // String stream library
#include <string>
#include <stdio.h>
#include <vector>
#include <fstream>
#include <ios>

#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <errno.h>

#define TICK_INTERVAL    30

using namespace std;

extern "C" int SDL_main(int argc, char *argv[]);

const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;
const int SCREEN_BPP = 16;

SDL_Surface *screen = NULL;
SDL_Surface *message = NULL;

bool keys[322];

TTF_Font *font = NULL;
SDL_Color textColor = { 255, 255, 255};
SDL_Color highlightColor = { 255, 0, 0};

Uint32 TimeLeft(void)
{
    static Uint32 next_time = 0;
    Uint32 now;

    now = SDL_GetTicks();
    if ( next_time <= now ) {
        next_time = now+TICK_INTERVAL;
        return(0);
    }
    return(next_time-now);
}


void init(){

    // initialize SDL video. If there was an error SDL shows it on the screen
    if ( SDL_Init( SDL_INIT_EVERYTHING) < 0 )
    {
        fprintf(stderr, "Unable to init SDL: %s\n", SDL_GetError() );
        SDL_Delay( 5000 );
       // exit(EXIT_FAILURE);
    }

    // make sure SDL cleans up before exit
    atexit(SDL_Quit);
    SDL_ShowCursor(SDL_DISABLE);

    // create a new window
    screen = SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_DOUBLEBUF|SDL_HWSURFACE );
    if ( !screen )
    {
        fprintf(stderr, "Unable to set video: %s\n", SDL_GetError());
        SDL_Delay( 5000 );
     //   exit(EXIT_FAILURE);
    }

    SDL_WM_SetCaption("Dir Reader", "Dir Reader");


    TTF_Init();
    //SDL_JoystickEventState(SDL_ENABLE);
   // joystick = SDL_JoystickOpen(0);

}

void cleanup(){

     // we have to quit SDL
     SDL_Quit();
     exit(EXIT_SUCCESS);
}

void apply_surface ( int x, int y, SDL_Surface* source, SDL_Surface* destination ){

     // make a temporary rectangle to hold the offsets
     SDL_Rect offset;

     // give the offsets to the rectangle
     offset.x = x;
     offset.y = y;

     // blit the surface
     SDL_BlitSurface( source, NULL, destination, &offset );
}

void apply_surface ( int sourceX, int sourceY, int x, int y, SDL_Surface* source, SDL_Surface* destination ){

     // make a temporary rectangle to hold the offsets
     SDL_Rect offset;
     SDL_Rect sourceRect;

     // give the offsets to the rectangle
     offset.x = x;
     offset.y = y;
     sourceRect.x = sourceX;
     sourceRect.y = sourceY;
     sourceRect.h = source->h;
     sourceRect.w = source->w;

     // blit the surface
     SDL_BlitSurface( source, &sourceRect, destination, &offset );
}

void apply_surface ( int sourceX, int sourceY, int sourceW, int sourceH, int x, int y, SDL_Surface* source, SDL_Surface* destination ){

     // make a temporary rectangle to hold the offsets
     SDL_Rect offset;
     SDL_Rect sourceRect;

     // give the offsets to the rectangle
     offset.x = x;
     offset.y = y;
     sourceRect.x = sourceX;
     sourceRect.y = sourceY;
     sourceRect.h = sourceH;
     sourceRect.w = sourceW;

     // blit the surface
     SDL_BlitSurface( source, &sourceRect, destination, &offset );
}

int getdir (string dir, vector<string> &files)
{
    DIR *dp;

    struct dirent *dirp;
    if((dp  = opendir(dir.c_str())) == NULL) {
        cout << "Error(" << errno << ") opening " << dir << endl;
        return errno;
    }

    while ((dirp = readdir(dp)) != NULL) {
        files.push_back(string(dirp->d_name));
    }

    closedir(dp);
    return 1337;
}

int SDL_main( int argc, char* argv[] )
{
    printf("init.\n");
    init();

    font = TTF_OpenFont( "GOODTIME.ttf", 15 );

    bool done = false;

    string dir = "C:/";
   // dir = dir.substr(0, dir.size() - 1);

    int curser = 0;

    while(!done){

    vector<string> files = vector<string>();

    if(getdir(dir,files) == errno){
         printf("error number: %i.\n", errno);
    }

        SDL_Event event;
        while (SDL_PollEvent(&event))
        {
            // Close window : exit
            if( event.type == SDL_QUIT )
                    done = true ;

            else if (event.type == SDL_KEYDOWN )
            {
                keys[event.key.keysym.sym] = true;
            }

            else if (event.type == SDL_KEYUP )
            {
                keys[event.key.keysym.sym] = false;
            }
        }

        if (keys[SDLK_x]){
            struct stat st;

            fprintf(stderr, "stat returned %i\n", stat(files[curser].c_str(), &st));

            if(S_ISDIR(st.st_mode)){

                if(files[curser][0] == '.' && files[curser][1] == '.'){
                    dir = dir.substr(0, dir.size() - 1);
                    dir = dir.substr(0, dir.find_last_of('/'));
                }

                else{
                    string temp = string(files[curser]);

                    dir += "/";
                    dir += temp;
                }
            }

            curser = 1;

            keys[SDLK_x] = false;
        }

        if (keys[SDLK_UP]){
           curser--;

            if(curser <= 0){
                curser = (int) (files.size() - 1);
            }

            keys[SDLK_UP] = false;
        }


        if (keys[SDLK_DOWN]){
            curser++;

            if(curser >= (int) files.size()){
                curser = 1;
            }

            keys[SDLK_DOWN] = false;
        }

        SDL_Rect rect;
        rect.x = 0;
        rect.y = 0;
        rect.h = 480;
        rect.w = 640;

        SDL_FillRect(screen, &rect, 0x000000);

        message = TTF_RenderText_Solid( font, dir.c_str(), textColor );

        apply_surface(0, 0, message, screen);

        for(int i = 0; i < (int) files.size(); i++){

            if(curser == i){
                message = TTF_RenderText_Solid( font, files[i].c_str(), highlightColor );
            }

            else{
                message = TTF_RenderText_Solid( font, files[i].c_str(), textColor );
            }

            apply_surface(0,  25 + (i * 15), message, screen);
        }

        SDL_Delay(TimeLeft());
        SDL_Flip(screen);
    }

    cleanup();
    return 0;
}
+2  A: 

Yes, actually you can tell yourself. If stat fails, it will set the errno variable to indicate why. You just need to find out what that's set to. You may also want to ensure that files[curser].c_str() itself is valid even though you've stated it's set to "c:\".

Even if it is what you state, it may be that stat doesn't like working on the root directory in that form. This will depend a great deal on the implementation you're using (you should add that as a tag).

In other words, change your line to something like:

int x = stat(files[curser].c_str(), &st);
fprintf(stderr, "stat returned %d '%s' %d\n", x, files[curser].c_str(), errno);

For what it's worth (and that may not be much), the following program works fine under VS2008:

#include <stdio.h>
#include <errno.h>
#include <sys/stat.h>

int main(int argc, char* argv[]) {
    struct stat st;
    int x = stat("c:\\", &st);
    fprintf(stderr, "stat returned %d %d\n", x, errno);
    return 0;
}

outputting:

stat returned 0 0
paxdiablo
It just says "stat returned -1 0"...
William
@paxdiablo, or better yet use `perror` for a human-readable description.
Matthew Flaschen
That program isn't portable, as it might evaluate errno before the call to stat.
Yuliy
Way to miss the point, @Yuliy :-) That's why I used the phrase _"something like"_. Yes, snippets that I post here frequently _won't_ be bullet-proof. I don't want to give snippets which have a hundred lines of error checking code if the point I'm trying to get across can be shown in three lines, because (1) it's not necessary and (2) even _fewer_ people will read my answers :-)
paxdiablo
paxdiablo: my point is that it's probably why William got -1 as the return from stat, but 0 for errno (which means "no error") in his comment above
Yuliy
Okay, I see now (apology offered) - fixed to cover that case.
paxdiablo