Ejemplo n.º 1
0
void LibClose (void)
/* Write remaining data, close both files and copy the temp file to the old
 * filename
 */
{
    /* Do we have a temporary library? */
    if (NewLib) {

        unsigned I;
        unsigned char Buf [4096];
        size_t Count;

        /* Walk through the object file list, inserting exports into the
         * export list checking for duplicates. Copy any data that is still
         * in the old library into the new one.
         */
        for (I = 0; I < CollCount (&ObjPool); ++I) {

            /* Get a pointer to the object */
            ObjData* O = CollAtUnchecked (&ObjPool, I);

            /* Check exports, make global export table */
            LibCheckExports (O);

            /* Copy data if needed */
            if ((O->Flags & OBJ_HAVEDATA) == 0) {
                /* Data is still in the old library */
                fseek (Lib, O->Start, SEEK_SET);
                O->Start = ftell (NewLib);
                LibCopyTo (Lib, O->Size);
                O->Flags |= OBJ_HAVEDATA;
            }
        }

        /* Write the index */
        WriteIndex ();

        /* Write the updated header */
        WriteHeader ();

        /* Close the file */
        if (Lib && fclose (Lib) != 0) {
            Error ("Error closing library: %s", strerror (errno));
        }

        /* Reopen the library and truncate it */
        Lib = fopen (LibName, "wb");
        if (Lib == 0) {
            Error ("Cannot open library `%s' for writing: %s",
                   LibName, strerror (errno));
        }

        /* Copy the new library to the new one */
        fseek (NewLib, 0, SEEK_SET);
        while ((Count = fread (Buf, 1, sizeof (Buf), NewLib)) != 0) {
            if (fwrite (Buf, 1, Count, Lib) != Count) {
                Error ("Cannot write to `%s': %s", LibName, strerror (errno));
            }
        }
    }

    /* Close both files */
    if (Lib && fclose (Lib) != 0) {
        Error ("Problem closing `%s': %s", LibName, strerror (errno));
    }
    if (NewLib && fclose (NewLib) != 0) {
        Error ("Problem closing temporary library file: %s", strerror (errno));
    }
}
Ejemplo n.º 2
0
void ObjAdd (const char* Name)
/* Add an object file to the library */
{
    struct stat StatBuf;
    const char* Module;
    ObjHeader H;
    ObjData* O;

    /* Open the object file */
    FILE* Obj = fopen (Name, "rb");
    if (Obj == 0) {
        Error ("Could not open `%s': %s", Name, strerror (errno));
    }

    /* Get the modification time of the object file. There a race condition
     * here, since we cannot use fileno() (non standard identifier in standard
     * header file), and therefore not fstat. When using stat with the
     * file name, there's a risk that the file was deleted and recreated
     * while it was open. Since mtime and size are only used to check
     * if a file has changed in the debugger, we will ignore this problem
     * here.
     */
    if (FileStat (Name, &StatBuf) != 0) {
        Error ("Cannot stat object file `%s': %s", Name, strerror (errno));
    }

    /* Read and check the header */
    ObjReadHeader (Obj, &H, Name);

    /* Make a module name from the file name */
    Module = GetModule (Name);

    /* Check if we already have a module with this name */
    O = FindObjData (Module);
    if (O == 0) {
        /* Not found, create a new entry */
        O = NewObjData ();
    } else {
        /* Found - check the file modification times of the internal copy
         * and the external one.
         */
        if (difftime ((time_t)O->MTime, StatBuf.st_mtime) > 0.0) {
            Warning ("Replacing module `%s' by older version in library `%s'",
                     O->Name, LibName);
        }

        /* Free data */
        ClearObjData (O);
    }

    /* Initialize the object module data structure */
    O->Name     = xstrdup (Module);
    O->Flags  	= OBJ_HAVEDATA;
    O->MTime  	= StatBuf.st_mtime;
    O->Start    = 0;

    /* Determine the file size. Note: Race condition here */
    fseek (Obj, 0, SEEK_END);
    O->Size     = ftell (Obj);

    /* Read the basic data from the object file */
    ObjReadData (Obj, O);

    /* Copy the complete object data to the library file and update the
     * starting offset
     */
    fseek (Obj, 0, SEEK_SET);
    O->Start    = LibCopyTo (Obj, O->Size);

    /* Done, close the file (we read it only, so no error check) */
    fclose (Obj);
}