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:
Axel Dörfler
2006-08-22 22:09:59 +00:00
parent 9e22843851
commit 1c494ffa65
2 changed files with 73 additions and 84 deletions
@@ -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;