3

I have an issue when using libzip. I am on linux and have installed the library using sudo apt-get install libzip2 libzip-dev (so it is not the latest version).

Here is my code :

#include <iostream>
#include <zip.h>
#include <unistd.h>
#include <sys/stat.h>

#define ZIP_ERROR 2

using namespace std;

bool isFilePresent(string const& path)
{
    struct stat *buf;
    return(stat(path.c_str(), buf)==0);
}

int main(void)
{
    struct zip *zip;
    struct zip_source *zip_source;
    int err(0);
    string zipFile("filesZip/zipTest");
    string fileToZip("filesToZip/test1");
    string fileToZip2("filesToZip/test2");
    char tmp[] = "filesZip/zipTest\0";

    // Test if the file is present
    if(isFilePresent(zipFile))
    {
        // if(remove(tmp) != 0)
        if(remove(zipFile.c_str()) != 0)
        {
            return ZIP_ERROR;
        }
    }
    // Open a zip archive
    zip = zip_open(zipFile.c_str(), ZIP_CREATE, &err);

    // if there is an error on the opening
    if(err != ZIP_ER_OK)
    {
        cout << "error when opening" << endl;
        return ZIP_ERROR;
    }

    // If the zip file is not open
    if(zip == NULL)
    {
        zip_close(zip);
        cout << "error when zip opens" << endl;
        return ZIP_ERROR;
    }

    // zip_source_file zip a file so that it can be added to the zip
    if((zip_source = zip_source_file(zip, fileToZip.c_str(), (off_t)0, (off_t)0))== NULL)
    {
        zip_close(zip);
        zip_source_free(zip_source);
        cout << "pb when zipping file1" << endl;
        return ZIP_ERROR;
    }

    // Add the zipped file to the zip  
    if(zip_add(zip, fileToZip.c_str(), zip_source)==-1)
    {
        zip_close(zip);
        zip_source_free(zip_source);
        cout << "pb when adding file1" << endl;
        return ZIP_ERROR;
    }

    // zip_source_file zip a file so that it can be added to the zip
    if((zip_source = zip_source_file(zip, fileToZip2.c_str(), (off_t)0, (off_t)0))== NULL)
    {
        zip_close(zip);
        zip_source_free(zip_source);
        cout << "pb when zipping file2" << endl;
        return ZIP_ERROR;
    }

    if(zip_add(zip, fileToZip2.c_str(), zip_source)==-1)
    {
        zip_close(zip);
        zip_source_free(zip_source);
        cout << "pb when adding file2" << endl;
        return ZIP_ERROR;
    }

    // sleep(180);

    // Closing the archive
    zip_close(zip);

    return 0;
}

This code is supposed to take the two files in the filesToZip folder and compress them in a zipTest file in the filesZip folder.

To do so, first it checks if the zipTest file already exists. If so, then it deletes it. And then it opens a zip archive, zip the files to add and add them to the archive before closing the archive.

So my problem is :

when the zip archive filesZip/zipTest doesnt exist then it works just fine. when the zip archive filesZip/zipTest do exist, then i got a core dumped.

What i have tried so far :

  • I thought it was because i was using strings for the names of the files. I tried with char and it did not change anything
  • then i thought it was because the remove task was not finished and then a confict might be encountered. So i put sleep(180) (in seconds) after each function call. It did not change anything
  • I also tried to put only one file in the archive. Did not change anything
  • I ran gdb to see what was happening. I tried both when the zip archive already existed and did not.
    • if the archive didn't already existed : everything went smoothly till the return 0 and then i saw that the program redefined fileToZip and fileToZip2, then did another return 0 then would stop.
    • if the archive already exists : it does the same thing but then says cannot find bounds of current function. (i have read here that it means gdb doesnt have debugging information and is unhappy with that..)

Does anyone have any idea what could be my problem ?

Community
  • 1
  • 1
M0rkHaV
  • 432
  • 1
  • 4
  • 16

1 Answers1

4

This is dangerous:

bool isFilePresent(string const& path)
{
    struct stat *buf;
    return(stat(path.c_str(), buf)==0);
}

You don't allocate any memory for your struct stat* so random memory gets written to when the function is called - likely causing a crash.

Try this:

bool isFilePresent(string const& path)
{
    struct stat buf; // memory is allocated on the stack for this object
    return(stat(path.c_str(), &buf)==0); // pass its address to the function
}

It creates a local struct stat object and passes its address to the function.

Galik
  • 47,303
  • 4
  • 80
  • 117
  • It seems to work ! Thank you ! However i still have the 3 weird lines at the end of the program.. Any idea what could cause that ? – M0rkHaV Oct 13 '14 at 08:43
  • @M0rkHaV I don't see any weird lines when I run it, can you give more info? – Galik Oct 13 '14 at 09:16
  • I can see those when running the program with gdb. After the `return 0` i have `string fileToZip2("filesToZip/test2"); string fileToZip("filesToZip/test1");return 0;` – M0rkHaV Oct 13 '14 at 10:04
  • 1
    @M0rkHaV Do you mean in the debugger variable after `return 0` is called? If so I wouldn't worry about what the contents of the variables look like after their destructors have been called, their contents is now undefined. I can get the same thing by deleting the whole program except the `strings`. After their destructor is called the debugger seems to lose track of their lengths and display beyond their bounds. – Galik Oct 13 '14 at 10:20