It no longer crashes, but now runs forever! At least this fixes bug #760.
Looks like our fdopen() does not work correctly, though. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@18572 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -17,10 +17,6 @@
|
|||||||
#include <Path.h>
|
#include <Path.h>
|
||||||
#include <Volume.h>
|
#include <Volume.h>
|
||||||
|
|
||||||
#include <String.h>
|
|
||||||
#include <Window.h>
|
|
||||||
#include <OS.h>
|
|
||||||
|
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
@@ -32,7 +28,7 @@ const char* kZipperThreadName = "ZipperThread";
|
|||||||
ZipperThread::ZipperThread (BMessage* refsMessage, BWindow* window)
|
ZipperThread::ZipperThread (BMessage* refsMessage, BWindow* window)
|
||||||
: GenericThread(kZipperThreadName, B_NORMAL_PRIORITY, refsMessage),
|
: GenericThread(kZipperThreadName, B_NORMAL_PRIORITY, refsMessage),
|
||||||
fWindowMessenger(window),
|
fWindowMessenger(window),
|
||||||
m_zip_process_thread_id(-1),
|
fZipProcess(-1),
|
||||||
m_std_in(-1),
|
m_std_in(-1),
|
||||||
m_std_out(-1),
|
m_std_out(-1),
|
||||||
m_std_err(-1),
|
m_std_err(-1),
|
||||||
@@ -57,46 +53,43 @@ ZipperThread::ThreadStartup()
|
|||||||
{
|
{
|
||||||
PRINT(("ZipperThread::ThreadStartup()\n"));
|
PRINT(("ZipperThread::ThreadStartup()\n"));
|
||||||
|
|
||||||
// init
|
BString archiveName = "Archive.zip";
|
||||||
status_t status = B_OK;
|
|
||||||
entry_ref ref;
|
|
||||||
entry_ref last_ref;
|
|
||||||
bool same_folder = true;
|
|
||||||
|
|
||||||
BString zip_archive_filename = "Archive.zip";
|
|
||||||
|
|
||||||
// do all refs have the same parent dir?
|
// do all refs have the same parent dir?
|
||||||
type_code ref_type = B_REF_TYPE;
|
type_code type = B_REF_TYPE;
|
||||||
int32 ref_count = 0;
|
int32 refCount = 0;
|
||||||
|
entry_ref ref;
|
||||||
|
entry_ref lastRef;
|
||||||
|
bool sameFolder = true;
|
||||||
|
|
||||||
status = m_thread_data_store->GetInfo("refs", &ref_type, &ref_count);
|
status_t status = m_thread_data_store->GetInfo("refs", &type, &refCount);
|
||||||
if (status != B_OK)
|
if (status != B_OK)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
for (int index = 0; index < ref_count ; index++) {
|
for (int index = 0; index < refCount; index++) {
|
||||||
m_thread_data_store->FindRef("refs", index, & ref);
|
m_thread_data_store->FindRef("refs", index, &ref);
|
||||||
|
|
||||||
if (index > 0) {
|
if (index > 0) {
|
||||||
BEntry entry(&ref);
|
BEntry entry(&ref);
|
||||||
if (entry.IsSymLink()) {
|
if (entry.IsSymLink()) {
|
||||||
entry.SetTo(& ref, true);
|
entry.SetTo(&ref, true);
|
||||||
entry_ref target;
|
entry_ref target;
|
||||||
entry.GetRef(& target);
|
entry.GetRef(&target);
|
||||||
if (last_ref.directory != target.directory) {
|
if (lastRef.directory != target.directory) {
|
||||||
same_folder = false;
|
sameFolder = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else if (last_ref.directory != ref.directory) {
|
} else if (lastRef.directory != ref.directory) {
|
||||||
same_folder = false;
|
sameFolder = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
last_ref = ref;
|
lastRef = ref;
|
||||||
}
|
}
|
||||||
|
|
||||||
// change active dir
|
// change active dir
|
||||||
if (same_folder) {
|
if (sameFolder) {
|
||||||
BEntry entry(&last_ref);
|
BEntry entry(&lastRef);
|
||||||
BPath path;
|
BPath path;
|
||||||
entry.GetParent(&entry);
|
entry.GetParent(&entry);
|
||||||
entry.GetPath(&path);
|
entry.GetPath(&path);
|
||||||
@@ -108,48 +101,52 @@ ZipperThread::ThreadStartup()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// archive filename
|
// archive filename
|
||||||
if (ref_count == 1) {
|
if (refCount == 1) {
|
||||||
zip_archive_filename = last_ref.name;
|
archiveName = lastRef.name;
|
||||||
zip_archive_filename += ".zip";
|
archiveName += ".zip";
|
||||||
}
|
}
|
||||||
|
|
||||||
int32 argc = ref_count + 3;
|
int32 argc = refCount + 3;
|
||||||
const char** argv = new const char* [argc + 1];
|
const char** argv = new const char* [argc + 1];
|
||||||
|
|
||||||
argv[0] = strdup("/bin/zip");
|
argv[0] = strdup("/bin/zip");
|
||||||
argv[1] = strdup("-ry");
|
argv[1] = strdup("-ry");
|
||||||
argv[2] = strdup(zip_archive_filename.String());
|
argv[2] = strdup(archiveName.String());
|
||||||
|
|
||||||
// files to zip
|
// files to zip
|
||||||
for (int ref_index = 0; ref_index < ref_count ; ref_index++) {
|
for (int index = 0; index < refCount ; index++) {
|
||||||
m_thread_data_store->FindRef("refs", ref_index, &ref);
|
m_thread_data_store->FindRef("refs", index, &ref);
|
||||||
|
|
||||||
if (same_folder) {
|
if (sameFolder) {
|
||||||
argv[3 + ref_index] = strdup(ref.name); // just the file name
|
// just the file name
|
||||||
|
argv[3 + index] = strdup(ref.name);
|
||||||
} else {
|
} else {
|
||||||
|
// full path
|
||||||
BPath path(&ref);
|
BPath path(&ref);
|
||||||
BString file = path.Path();
|
BString file = path.Path();
|
||||||
argv[3 + ref_index] = strdup(path.Path()); // full path
|
argv[3 + index] = strdup(path.Path());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
argv[argc] = NULL;
|
argv[argc] = NULL;
|
||||||
|
|
||||||
m_zip_process_thread_id = PipeCommand(argc, argv, m_std_in, m_std_out, m_std_err);
|
fZipProcess = _PipeCommand(argc, argv, m_std_in, m_std_out, m_std_err);
|
||||||
|
|
||||||
delete [] argv;
|
delete [] argv;
|
||||||
|
|
||||||
if (m_zip_process_thread_id < 0)
|
if (fZipProcess < 0)
|
||||||
return m_zip_process_thread_id;
|
return fZipProcess;
|
||||||
|
|
||||||
resume_thread(m_zip_process_thread_id);
|
resume_thread(fZipProcess);
|
||||||
|
|
||||||
fOutputFile = fdopen(m_std_out, "r");
|
fOutputFile = fdopen(m_std_out, "r");
|
||||||
|
if (fOutputFile == NULL)
|
||||||
|
return errno;
|
||||||
|
|
||||||
zip_archive_filename.Prepend("Creating archive: ");
|
archiveName.Prepend("Creating archive: ");
|
||||||
|
|
||||||
SendMessageToWindow ('strt', "archive_filename", zip_archive_filename.String());
|
_SendMessageToWindow('strt', "archive_filename", archiveName.String());
|
||||||
SendMessageToWindow ('outp', "zip_output", "Preparing to archive");
|
_SendMessageToWindow('outp', "zip_output", "Preparing to archive");
|
||||||
|
|
||||||
PRINT(("\n"));
|
PRINT(("\n"));
|
||||||
|
|
||||||
@@ -176,12 +173,12 @@ ZipperThread::ExecuteUnit()
|
|||||||
|
|
||||||
if (!strncmp(" a", output, 3)) {
|
if (!strncmp(" a", output, 3)) {
|
||||||
output[2] = 'A';
|
output[2] = 'A';
|
||||||
SendMessageToWindow('outp', "zip_output", output + 2);
|
_SendMessageToWindow('outp', "zip_output", output + 2);
|
||||||
} else if (!strncmp("up", output, 2)) {
|
} else if (!strncmp("up", output, 2)) {
|
||||||
output[0] = 'U';
|
output[0] = 'U';
|
||||||
SendMessageToWindow('outp', "zip_output", output);
|
_SendMessageToWindow('outp', "zip_output", output);
|
||||||
} else {
|
} else {
|
||||||
SendMessageToWindow('outp', "zip_output", output);
|
_SendMessageToWindow('outp', "zip_output", output);
|
||||||
}
|
}
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
@@ -216,10 +213,10 @@ ZipperThread::ExecuteUnitFailed(status_t status)
|
|||||||
|
|
||||||
if (status == EOF) {
|
if (status == EOF) {
|
||||||
// thread has finished, been quit or killed, we don't know
|
// thread has finished, been quit or killed, we don't know
|
||||||
SendMessageToWindow('exit');
|
_SendMessageToWindow('exit');
|
||||||
} else {
|
} else {
|
||||||
// explicit error - communicate error to Window
|
// explicit error - communicate error to Window
|
||||||
SendMessageToWindow('exrr');
|
_SendMessageToWindow('exrr');
|
||||||
}
|
}
|
||||||
|
|
||||||
Quit();
|
Quit();
|
||||||
@@ -234,7 +231,7 @@ ZipperThread::ThreadShutdownFailed(status_t status)
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ZipperThread::MakeShellSafe(BString* string)
|
ZipperThread::_MakeShellSafe(BString* string)
|
||||||
{
|
{
|
||||||
string->CharacterEscape("\"$`", '\\');
|
string->CharacterEscape("\"$`", '\\');
|
||||||
string->Prepend("\"");
|
string->Prepend("\"");
|
||||||
@@ -250,7 +247,7 @@ ZipperThread::ProcessRefs(BMessage* msg)
|
|||||||
|
|
||||||
|
|
||||||
thread_id
|
thread_id
|
||||||
ZipperThread::PipeCommand(int argc, const char** argv, int& in, int& out,
|
ZipperThread::_PipeCommand(int argc, const char** argv, int& in, int& out,
|
||||||
int& err, const char** envp)
|
int& err, const char** envp)
|
||||||
{
|
{
|
||||||
// This function written by Peter Folk <[email protected]>
|
// This function written by Peter Folk <[email protected]>
|
||||||
@@ -301,7 +298,7 @@ ZipperThread::PipeCommand(int argc, const char** argv, int& in, int& out,
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ZipperThread::SendMessageToWindow(uint32 what, const char* name, const char* value)
|
ZipperThread::_SendMessageToWindow(uint32 what, const char* name, const char* value)
|
||||||
{
|
{
|
||||||
BMessage msg(what);
|
BMessage msg(what);
|
||||||
if (name != NULL && value != NULL)
|
if (name != NULL && value != NULL)
|
||||||
@@ -316,13 +313,11 @@ ZipperThread::SuspendExternalZip()
|
|||||||
{
|
{
|
||||||
PRINT(("ZipperThread::SuspendExternalZip()\n"));
|
PRINT(("ZipperThread::SuspendExternalZip()\n"));
|
||||||
|
|
||||||
status_t status = B_OK;
|
thread_info info;
|
||||||
thread_info zip_thread_info;
|
status_t status = get_thread_info(fZipProcess, &info);
|
||||||
status = get_thread_info(m_zip_process_thread_id, &zip_thread_info);
|
|
||||||
BString thread_name = zip_thread_info.name;
|
|
||||||
|
|
||||||
if (status == B_OK && thread_name == "zip")
|
if (status == B_OK && !strcmp(info.name, "zip"))
|
||||||
return suspend_thread (m_zip_process_thread_id);
|
return suspend_thread(fZipProcess);
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
@@ -333,13 +328,11 @@ ZipperThread::ResumeExternalZip()
|
|||||||
{
|
{
|
||||||
PRINT(("ZipperThread::ResumeExternalZip()\n"));
|
PRINT(("ZipperThread::ResumeExternalZip()\n"));
|
||||||
|
|
||||||
status_t status = B_OK;
|
thread_info info;
|
||||||
thread_info zip_thread_info;
|
status_t status = get_thread_info(fZipProcess, &info);
|
||||||
status = get_thread_info(m_zip_process_thread_id, &zip_thread_info);
|
|
||||||
BString thread_name = zip_thread_info.name;
|
|
||||||
|
|
||||||
if (status == B_OK && thread_name == "zip")
|
if (status == B_OK && !strcmp(info.name, "zip"))
|
||||||
return resume_thread(m_zip_process_thread_id);
|
return resume_thread(fZipProcess);
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
@@ -350,14 +343,12 @@ ZipperThread::InterruptExternalZip()
|
|||||||
{
|
{
|
||||||
PRINT(("ZipperThread::InterruptExternalZip()\n"));
|
PRINT(("ZipperThread::InterruptExternalZip()\n"));
|
||||||
|
|
||||||
status_t status = B_OK;
|
thread_info info;
|
||||||
thread_info zip_thread_info;
|
status_t status = get_thread_info(fZipProcess, &info);
|
||||||
status = get_thread_info(m_zip_process_thread_id, &zip_thread_info);
|
|
||||||
BString thread_name = zip_thread_info.name;
|
|
||||||
|
|
||||||
if (status == B_OK && thread_name == "zip") {
|
if (status == B_OK && !strcmp(info.name, "zip")) {
|
||||||
status = B_OK;
|
status = B_OK;
|
||||||
status = send_signal(m_zip_process_thread_id, SIGINT);
|
status = send_signal(fZipProcess, SIGINT);
|
||||||
WaitOnExternalZip();
|
WaitOnExternalZip();
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
@@ -371,13 +362,11 @@ ZipperThread::WaitOnExternalZip()
|
|||||||
{
|
{
|
||||||
PRINT(("ZipperThread::WaitOnExternalZip()\n"));
|
PRINT(("ZipperThread::WaitOnExternalZip()\n"));
|
||||||
|
|
||||||
status_t status = B_OK;
|
thread_info info;
|
||||||
thread_info zip_thread_info;
|
status_t status = get_thread_info(fZipProcess, &info);
|
||||||
status = get_thread_info(m_zip_process_thread_id, &zip_thread_info);
|
|
||||||
BString thread_name = zip_thread_info.name;
|
|
||||||
|
|
||||||
if (status == B_OK && thread_name == "zip")
|
if (status == B_OK && !strcmp(info.name, "zip"))
|
||||||
return wait_for_thread(m_zip_process_thread_id, &status);
|
return wait_for_thread(fZipProcess, &status);
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,17 +39,17 @@ class ZipperThread : public GenericThread {
|
|||||||
virtual void ThreadShutdownFailed(status_t a_status);
|
virtual void ThreadShutdownFailed(status_t a_status);
|
||||||
|
|
||||||
status_t ProcessRefs(BMessage* msg);
|
status_t ProcessRefs(BMessage* msg);
|
||||||
void MakeShellSafe(BString* string);
|
void _MakeShellSafe(BString* string);
|
||||||
|
|
||||||
thread_id PipeCommand(int argc, const char **argv,
|
thread_id _PipeCommand(int argc, const char** argv,
|
||||||
int & in, int & out, int & err,
|
int& in, int& out, int& err,
|
||||||
const char **envp = (const char **)environ);
|
const char** envp = (const char**)environ);
|
||||||
|
|
||||||
void SendMessageToWindow(uint32 what,
|
void _SendMessageToWindow(uint32 what,
|
||||||
const char* name = NULL, const char* value = NULL);
|
const char* name = NULL, const char* value = NULL);
|
||||||
|
|
||||||
BMessenger fWindowMessenger;
|
BMessenger fWindowMessenger;
|
||||||
int32 m_zip_process_thread_id;
|
thread_id fZipProcess;
|
||||||
int m_std_in;
|
int m_std_in;
|
||||||
int m_std_out;
|
int m_std_out;
|
||||||
int m_std_err;
|
int m_std_err;
|
||||||
|
|||||||
Reference in New Issue
Block a user