BeDevTalk FAQ


Version   1.1.0
Last-modified  25. June 1998
URL   <http://www.begeek.com/ArticleDisplay.servlet?ArticleID=157>
Author   Ingmar Krusch <clueless@begeek.com> (feel free to mail any comments, suggestions, corrections, Q&As etc. to this address).
Copyright  The entire BeDevTalk FAQ document is Copyright © 1997 and 1998 Ingmar Krusch <clueless@begeek.com>. All rights reserved. All wrongs also. Copying is permitted only under designated situations [1.3]. For details, see section [1].
No warranty  This work is provided on an as is basis. The author provides no warranty whatsoever, either express or implied, regarding the work, including warranties with respect to its merchantability or fitness for any particular purpose.

Content Hierarchy:
1 Copying permissions
1.1 Author
1.2 Copyright notice
1.3 Copying permissions
1.4 No warranty
2 On-line sites that distribute this document and related issues
2.1 Where's the closest site to access this document on-line?
2.2 Where can I get a copy of all the HTML files of the BeDevTalk FAQ so I can read them off-line?
2.3 Where can I find archives of BeDevTalk?
3 List Charter and Netiquette when posting to BeDevTalk
3.1 What is the List Charter?
3.2 Appropriate Netiquette when posting to BeDevTalk
3.3 What to do with off-topic posts?
3.4 What do I do if someone else posts a question that's already in the FAQ?
3.5 What makes a good "Subject:" line?
4 Development
4.1 When, why and how do I submit bug reports?
AKA: My bug is labled as unreproducible. How do I change that?
4.2 Can I make commercial quality apps with the BeOS provided limited BeIDE?
AKA: Why should I get the full CodeWarrior?
AKA: What's the limit of the limited IDE?
4.3 What is a good tool for editing a resource file?
AKA: What resource information can I edit with FileTypes?
4.4 Is there a Java VM for BeOs or will any Java development be based on the BeIDE?
4.5 How do I save my application's preferences as resources inside the application?
4.6 How do I search for something in the headers?
AKA: In which header is a function defined?
4.7 Resources for C++ beginner questions
AKA: How do I learn C++?
AKA: What are good programming related books?
4.8 How do I add a version attribute to shared libraries?
5 Coding issues
5.1 How do I get a valid connection to the app_server?
AKA: Why do I need a BApplication instance?
5.2 What's the right way to set my app's mimetype?
5.3 Why is my app slower with two threads than with one?
AKA: What's the MEI cache protocol?
5.4 Why does my app behave differently if run from the shell/Tracker/debugger?
AKA: How do I set the current working directory (cwd)?
5.5 What ANSI C functions are not thread safe
AKA: Is strtok() not thread safe?
5.6 Are BMessages reference counted?
AKA: Who owns posted/received BMessages?
6 Compiling
6.1 How do I compile an application under a later release that will still run under a previous one?
6.2 How do I cross-compile from my Mac with CodeWarrior Pro 1?
6.3 The compiler complains about possible unwanted assignment. How do I get rid of this warning?
6.4 My application, using <iostream.h>, won't build. Why?
AKA: I've included the header file--why won't the IDE build my program?
AKA: What library implements a certain Be Kit?
6.5 Why doesn't HelloWorld link?
AKA: My app exceeds the 64K limit. What do I do?
AKA: My app, using <iostream>s, won't compile. Why?
AKA: Can I use GCC so build my Be application?
6.6 I always get a Ignoring dup resource warning when I build my program?!
7 Why doesn't BeOS ...?
7.1 Where is mmap()?
7.2 Why doesn't Be specify a standard OS-wide scripting language?
AKA: AREXX rules!
AKA: How do I upset the Be List Guy?
7.3 Why doesn't Be port BeOS to {Alpha, MIPS, Sparc, StrongARM, etc}?
7.4 Where is focus-follows-mouse?
AKA: Why are the active windows forced to the front?
7.5 Why isn't BeOS multi-user?
7.6 Can I expect BeOS to be a general replacement for a UNIX box?
AKA: Is BeOS POSIX 1003.1 compilant?
AKA: Does fork()/exec() inheriting open file descriptors?
7.7 Can I use the BeOS as a graphics workstation for custom apps (for example, replacing a Sun workstation)?
7.8 Can I use the BeOS as a hobbyist OS (like Linux)?
7.9 Can I use the BeOS as a media workstation OS (for example, replacing MacOS for MIDI or SGI for video work)?
7.10 Can I use the BeOS as a UNIX server replacement (for example, a high-end web or database server)?
8 Porting software
8.1 Why don't I just port this?
9 Add-ons
9.1 How to debug add-ons?
9.2 How do I do plug-ins on BeOS?
9.3 How do I export functions or data from my application for use in my add-ons?
AKA: Why should I name my app _APP_ when linking add-ons against it?
9.4 How do I access application global variables from my add-ons?
10 Getting the BeOS to do something for me
10.1 How do I get the output back from a command line tool I invoke from my own program?
AKA: Where's the code for popen()?
10.2 Why doesn't my HookFunction get called?
AKA: Why should I enable the warning for Hidden Virtual Functions?
10.3 MouseUp() isn't ever called. Why?
10.4 Why is my application not getting any mouse/keyboard events?
AKA: What compiler switches should I leave alone?
10.5 How do I create a Background Application (without an icon in the DeskBar)?
10.6 Why is there no FindWindow()?
10.7 How do I get a list of all running applications?
10.8 How can I send a BMessage to a particular BWindow rather than to the BApplication it belongs to?
10.9 How do I get a BMessenger for every open BWindow in the Tracker?
10.10 How do I get Tracker icons from a file?
10.11 How and when do I set the mouse cursor?
11 Using standard BeOS classes
11.1 How do I get a BFilePanel to select directories?
11.2 How do I implement Read-Writer-Locks using semaphores?
AKA: Is is possible to acquire a semaphore only partially?
AKA: How do I check whether the acquisition of a semaphore succeeded?
12 How is it done using C/C++?
12.1 How do I print an int64 (long long) using printf()?
12.2 How do I wake up a thread that is blocked on a semaphore?
12.3 How do I create random numbers?
13 Miscellaneous
13.1 What to do if you can't boot off the HD?
13.2 Help! I can't delete my Replicants from the Desktop!
13.3 Brother in Arms
13.4 Acknowledgements
13.5 Good citizens
13.6 History


1 Copying permissions
1.1 Author

Ingmar Krusch <clueless@begeek.com>

The BeDevTalk FAQ is always improving. Your input is most welcome. Send your comments, suggestions, corrections, Q&As etc. to <clueless@begeek.com>.

1.2 Copyright notice

The entire BeDevTalk FAQ document is Copyright © 1997 and 1998 Ingmar Krusch <clueless@begeek.com>. All rights reserved. All wrongs also. Copying is permitted only under designated situations [1.3].

Portions of the Be Book and Be Developer Guide quoted herein are Copyright © 1998 by Be, Incorporated, and are used by permission.

1.3 Copying permissions

If all you want to do is quote a small portion of the BeDevTalk FAQ (such as one or two FAQs) in a larger document or an email, simply attribute the quoted portion with something vaguely similar to, "From the BeDevTalk FAQ, <http://www.begeek.com/ArticleDisplay.servlet?ArticleID=157>:".

If you want to make a copy of large portions and/or the entire BeDevTalk FAQ document for your own personal use, you may do so without restriction (provided, of course, that you do not redistribute the document to others, or allow others to copy the document).

If you want to redistribute large portions and/or the entire BeDevTalk FAQ document to others, whether or not for commercial use, you must get permission from the author first (and that permission is normally granted; note however that it is often easier for you to simply tell your recipients about the download option [2.2]). Nevertheless, this FAQ was produced for free redistribution, so you must not charge any kind of fee if you are allowed to redistribute this FAQ. In any event, you must retain and conspicuously display all copyright notices on all copies of the documents you copy, and you must include the Author [1.1], Copyright Notice [1.2], No Warranty [1.4], and Copying Permissions [1.3] items, and display these items conspicuously.

If you want more and/or different privileges than are outlined here, please contact me, <clueless@begeek.com>. I'm a very reasonable guy...

1.4 No warranty

This work is provided on an as is basis. The author provides no warranty whatsoever, either express or implied, regarding the work, including warranties with respect to its merchantability or fitness for any particular purpose.

2 On-line sites that distribute this document and related issues
 
2.1 Where's the closest site to access this document on-line?

USA <http://www.begeek.com/ArticleDisplay.servlet?ArticleID=157>
Germany <http://www.fho-emden.de/~www42/BeDevTalk_FAQ/BeDevTalk_FAQ.html>
Canada <http://www.qnx.com/~chrish/Be/FAQ/BeDevTalk_FAQ.html>
Austria <http://winf.oeh.univie.ac.at/be/bedevtalk_faq.html>
USA (Illinois) <http://www.abisoft.com/faq/BeDevTalk_FAQ.html>
USA (Nevada) <http://www.artillion.com/research/faq/BeDevTalk_FAQ.html>

2.2 Where can I get a copy of all the HTML files of the BeDevTalk FAQ so I can read them off-line?

USA <http://www.begeek.com/archives/General_FAQ/BeDevTalk_FAQ.zip>
Germany <http://www.fho-emden.de/~www42/BeDevTalk_FAQ/BeDevTalk_FAQ.zip>
Canada <http://www.qnx.com/~chrish/Be/FAQ/BeDevTalk_FAQ.zip>
Austria <http://winf.oeh.univie.ac.at/be/bedevtalk_faq.zip>
USA (Illinois) <http://www.abisoft.com/faq/BeDevTalk_FAQ.zip>
USA (Nevada) <http://www.artillion.com/research/faq/BeDevTalk_FAQ.zip>

Restriction 1: You must still abide by the Copyright Notice [1.2] and Copying Permissions [1.3]. In particular, you must not redistribute the BeDevTalk FAQ to others without permission from the author [1.1]. If you want to redistribute the BeDevTalk FAQ to someone else, the easiest way is to tell them about this download feature [2.2], and let them get their own copy.

Restriction 2: The BeDevTalk FAQ uses long filenames. If your machine can't handle long filenames (e.g., if it is DOS and/or Windows 3.x), you may run into trouble browsing the unpacked files. BeOS, MacOS, UNIX, Windows NT/95, Amiga etc. all handle long filenames correctly.

2.3 Where can I find archives of BeDevTalk?
There are curretly two archives, all searchable: Similarly, archives for BeCodeTalk can be found at

3 List Charter and Netiquette when posting to BeDevTalk
 
3.1 What is the List Charter?

  1. Welcome! The BeDevTalk discussion list is an open discussion list covering developing software on and for the BeOS. The list was created by Be, Inc. as a forum for discussing issues important to BeOS developers, including programming, tools, techniques, business issues, and the like. It is administered by Michael A. Alderete <listmaster@be.com>. The official List Charter from Be, Inc. can be found at <http://www.be.com/aboutbe/lists/bedevtalk.html>.

  2. To subscribe to the list, send mail to <listserv@be.com> with the following command in the Subject: field (the body is ignored) of your message:

    subscribe BeDevTalk

    You can also use the form on the Be web site to send the correct subscribe message:

    <http://www.be.com/aboutbe/mailinglists.html>

    You can only send messages to the list if you are a subscriber. You must send your messages from the account with which you subscribed to the list.

  3. To unsubscribe from the list, send mail to <listserv@be.com> with the following command in the Subject: field (the body is ignored) of your message:

    unsubscribe BeDevTalk

    You can also use the form on the Be web site to send the correct unsubscribe message:

    <http://www.be.com/aboutbe/mailinglists.html>

    You can only unsubscribe from the list using the account with which you subscribed to the list. The list server is very picky about From: addresses, and if your apparent address changes, due to changes on your network or mail server, you may be unable to unsubscribe. If this happens, send mail to <listmaster@be.com> and request a manual unsubscription.

  4. BeDevTalk is open to anyone who wants to subscribe, and will be a good citizen of the list. Period. This is not a registered developers only list. Some non-developers get use out of the list, as do a number of non-registered developers. All are welcome.

  5. The list's purpose is the discussion of developing for the BeOS. This is (hopefully mainly) programming questions, but also includes other topics of interest to development under the BeOS (see item 1).

  6. Attachments and Enclosures are prohibited for the list and will be rejected. You may try and convince the list Admin (Michael A. Alderete <listmaster@be.com>) to grant you the right to attach to your posts. If you feel the need to attach something, make it available via http or ftp and post the URL to the list instead.

3.2 Appropriate Netiquette when posting to BeDevTalk

  1. Do not say: Please respond by e-mail because I don't normally read this list. If you do not have enough time for the list, do not expect the list to have enough time for you.

  2. Do not post questions that are answered in the list's FAQ. That's like saying your time (to read the FAQ) is more valuable than the time of hundreds and hundreds of others (to answer your question). Très uncool. Read the FAQ first! [3.3]

    development-related topics would be things like:

    • This doesn't work like the BeBook says!
    • Bugs in the BeOS or Be Kits that affect development [4.1]
    • This code gives me trouble!
    • API discussions and discussion of design considerations
    • Application design
    • How should I implement something?

    Off-topic and/or inappropriate posts would be things like:

    • How do I set up this program?
    • How do I set up this Hardware Device?
    • HELP - My Computer won't boot!
    • You/this suck(s)/rule(s)
    • Lisp is better than C++ is better than AREXX is better than ...
    • Is the listserver down? Am I still subscibed?

    If you suspect that the listserver is down or you got unsubscribed from the list somehow, do not post test messages to the list. Instead, try subscribing again, this will yield exactly the same information to you as a test message without annoying other list memebers.

  3. General questions for help with the BeOS are not appropriate for this list [3.3]. The list Admin generally will not shut down off-topic threads unless forced to.

  4. Flaming of any kind is not appropriate for this list. Flaming sucks. Go somewhere else if you absolutely have to do it. This is supposed to be a friendly discussion list. Please keep the tone of all postings to the list respectful, and refrain from correcting people's grammar, spelling, typing, etc. on the list (remember, not everyone is from an English speaking country).

  5. Avoid excessive quoting. Only quote the part of the original post that is relevant to your reply along with the original author's name.

  6. Some sites with netiquette files (just find out yourself by searching the net):

3.3 What to do with off-topic posts?

Every member of the list will benefit from keeping the signal-to-noise ratio high. Please do not answer a question that does not conform to the List Charter [3.1] or Netiquette [3.2]. Instead politely but firmly point the questioner to an appropriate place for these issues (please send mail directly to the person and CC <listmaster@be.com>; do not post such comments to the list). These may include:

3.4 What do I do if someone else posts a question that's already in the FAQ?

Please do not answer a question that is already in the FAQ. Instead politely but firmly point the questioner to the URL of an appropriate FAQ (please send mail directly to the person, do not post such comments to the list). These may include:

3.5 What makes a good "Subject:" line?

  1. Be descriptive:

    • Bad Subject: "HELP"
    • Bad Subject: "Problem"
    • Bad Subject: "(none)"
    • Bad Subject: "Re: BeDevTalk Digest for 11/6/97"
    • Good Subject: "Clearing Messages from the message queue"
    • Good Subject: "BLooper loses Messages"
    • Good Subject: "Should this be a shared library or a server?"

  2. If the topic of a thread changes, change the Subject line accordingly:

    "Subject: Who owns BMessages (was Re: Clearing Messages from the message queue)"

4 Development
 
4.1 When, why and how do I submit bug reports?
AKA: My bug is labled as unreproducible. How do I change that?

While talking about bugs that affect development and possible workarounds on BeDevTalk is fine, this will most likely not result in a bugfix for the OS, no matter who is involed in the discussion:

  • Don't reley on someone saying that he will submit the bug talked about. If you're involved, always check that it really happend and if not, submit it yourself.

  • Don't reley on Be emplyees who took part in a discussion to actually fix the bug. If you're involved, always submit the bug. This is the only way to ensure that a bug gets a priority and eventually gets fixed.

  • Keep an eye on the bugs you submit. If they get classified as unreproducible or not a bug, send mail to <devsupport@be.com> and tell them to double check the bug in question because it is really reproducible or really is a bug and explain why. Provide the bug number in your mail.
Also, you can always send any development related problems or questions to <devsupport@be.com>. The Be staff does their best to answer them as quickly as possible. If you want to know what's up with a bug report (e.g. like mentioned above), please refer to the bug number.

Submiting each and every Bug you find in the BeOS and the BeBook at Be's Webpage via their Bug Report Form at <http://www.be.com/developers/bugform.html> earns good Karma!

4.2 Can I make commercial quality apps with the BeOS provided limited BeIDE?
AKA: Why should I get the full CodeWarrior?
AKA: What's the limit of the limited IDE?

Yes.

You can write a substantial app with the limited linker.

The CodeWarrior that comes with BeOS has a limited linker--it can only link projects smaller than 64k of code [6.5], the amount of data in not limited. The quality of the compiler you buy is the same as the one that comes with the OS. If your commercial-quality app is bigger than that, you will need to get the full version from Be (yes, the CodeWarrior package for BeOS is distributed by Be, check their website).

Another benefit to owning the full version is, of course, that you can use any updates that come along (the updates they post on their Web site are generally only for the commercial version of their software, and not the limited one on the BeOS CDs).

If you for some reasons cannot afford the full CW, you are out of luck for now. Be's official answer can be found at <http://www.be.com/support/qandas/faqs/faq-0020.html>.

4.3 What is a good tool for editing a resource file?
AKA: What resource information can I edit with FileTypes?

If the only thing in your resource file is what shows up in FileTypes--the version info, app sig, and icon, then FileTypes works fine. For more elaborate resource files, you may find Interface Elements or AppSketcher meets your needs, look for those two applications on your BeOS CD, but there are probably newer versions available. Check BeWare. Although setting the signature is best done in the FileTypes application or the FileType Tracker add-on.

4.4 Is there a Java VM for BeOs or will any Java development be based on the BeIDE?

There is a Java compiler, AWT implementation, VM with JIT, and development tools available from Metrowerks. Development tools come with a license for you to freely bundle the VM and JIT with the application you develop in Java. Check your CodeWarrior license for details. Thus, you can develop as much Java as you want and ship it to your customers.

4.5 How do I save my application's preferences as resources inside the application?

You don't.

Saving preferences as resources in the application has several drawbacks.

The Mac does not (despite common believe) save settings as resources in the application in any application that was written the last 10 years. The reason for this is that applications may sit on a CD-ROM, or they may be on a read-only file server, or they may be on a file server where more than one person can start it at the same time, or the user may have anti-virus software that prevents application file modification, or any imaginable other situation that breaks trying to write to your own application file.

Most of these reasons also hold true for the argument that the settings file should be in the same folder as the application: There simply is no guarantee that it is writable.

There are system-defined settings folders (check out /boot/develop/headers/be/storage/FindDirectory.h); use them. You may also want to check out the preference library libprefs.so on BeWare.

Be resources can't be stored together with actual data. You can store either resources or your own data in a data file--the only exception being an application/shared library/add-on, which is a special-case of the resource file format that allows both code and resources in the same file.

The Be Way(tm) is to store window positions and other such document-dependent things as attributes for the file (which follow the file around wherever it gets moved, copied or duplicated). This already works great for e.g. the Tracker and BeIDE. It should be mentioned that if you move files with attributes across a foreign file system that does not support attributes (HFS, NFS, FAT, ...), this information is lost. All attributes unknown to an application should be copied unmodified. Similarly, every application has to be prepared to deal with inconsistent attributes vs. the file content.

4.6 How do I search for something in the headers?
AKA: In which header is a function defined?

Put this in your /boot/home/.profile file:


   function hgrep
   {
      find /boot/develop/headers -name \
         *.h | xargs egrep -n "$@" /dev/null
   }
   

Now looking for any function definition is easy:

$ hgrep spawn_thread
/boot/develop/headers/be/kernel/OS.h:230: extern thread_id spawn_thread (
$

This hgrep function searches the headers directly, not the current working directory. You use it much like egrep and this function lets you pass egrep arguments directly to hgrep.

4.7 Resources for C++ beginner questions
AKA: How do I learn C++?
AKA: What are good programming related books?

The BeOS API is currently expressed in C++, so questions in this area are per definition BeOS related and as such a logical topic for BeDevTalk. However, before subscribers rely on the list to answer basic questions about C++, please consider that there are good C++ resources on the net as well as in printed form where people should find answers to most basic language questions.

List subscribers can't possibly teach each other C++, the list can only serve the purpose of a discussion forum. As such, a basic understanding on how to program/develop is required before posting C++ related questions to the list. Nevertheless it should be stressed that there is no such thing as a dumb question, only too basic and therefore not appropriate questions (for this list).

As for net-based resources, there are the newsgroups

and many more, refer to your local news server. It is not uncommon for Stroustrup, Koenig, and other people involved with the design and evolution of C++ to answer questions on those newsgroups.

In addition, there are several C++ FAQs available on the net, try out:

Worthwhile for the BeOS programmer are also the following multithreading related FAQs:

There are also several introductions to the STL and the ANSI C++ Standard Library:

Please keep in mind that it used to be called the STL, and it used to be developed by Stepanov. It is now made part of the ANSI C++ Standard Library, and there were some subtle changes made in that process. Any book using the old STL, or making references to the STL, not to the ANSI Standard C++ Library, could (possibly) lead you astray in several places. Getting the most up-to-date book on the ANSI C++ Standard Library is recommended.

Also note that the Metrowerks implementation (the one you have available with the BeOS) is not based on the HP code.

Furthermore, several books have been recommended on BeDevTalk in regard to C++ and development in general (in no particular order):

NameAuthorPressComments
Effective C++ and More Effective C++ Scott Meyers Addison-Wesley Considered as a must have, both are very easy for the beginning C++ programmer to dip into, while still being useful for the more experienced developer.
The C++ Programming Language, 3rd Edition Bjarne Stroustrup ??? The third edition is possibly the best single book to get as it is both comprehensive and current. It is one of the very few books to deal with the ANSI C++ Standard Library, rather than the old STL. Do not expect a reference, this is more of a learning guide. It does try to be complete, so don't expect a quick read!
Industrial Strength C++ Mats Henricson, et al Prentice-HallThis book expands the public domain Ellemtel C++ coding standard. The presented guidelines define a C++ coding standard that should be valid and usable for almost all programmers.
Taligent's Guide to Designing Programs: Well-Mannered Object-Oriented Design in C++Inc. Taligent Inc. TaligentA quick overview of Object-oriented program design, with special regard for operating-system development. A provocative summary of good OOP techniques.
C++ Primer, 3rd Edition Stanley B. Lippman Addison-Wesley Introductory book on C++ as a learning tool and as a reference.
Writing Solid Code Steve Maguire Microsoft Press For professional intermediates to advanced C programmers who develop software, here is a focused and practical book based on writing bug-free programs in C. Includes practical solutions to detect mistakes before they become a costly problem.
Advanced C++ Programming Styles and Idioms James O. Coplien Addison-WesleyCoplien shows how to become an expert C++ programmer by learning the idioms of the language. His approach is organized around the abstractions that C++ supports. He shows how these abstractions can be combined to use the language effectively.
Code Complete Steve McConnell Microsoft PressPresents an expert look at the process of commercial software development. Lots of example code, insights on managing technical yet creative people, and examines each milestone in software development in detail.
Large-Scale C++ Software Design John S. Lakos Addison-WesleyShows how to decompose a large program into a number of smaller, more easily manageable components. A single 12,000-line code example runs throughout the book which shows the reader how to build a complex project which the professional can use later in actual work.
    
STL Tutorial and Reference Guide Musser and Saini Addison-Wesley This is a must-have reference to the STL portion of the C++ Standard Library. Atul Saini, one of the authors, is the principal behind Modena, who wrote the CodeWarrior STL.
    
Design Patterns Gamma, Helm, Johnson, and Vlissides Addison-WesleyA review of recurring constructs in software development, but put it into a larger, connected framework. Very good.
Operating System Concepts, 4th Edition A. Silberschatz, Peter Baer Galvin Addison-WesleyClear coverage of the fundamental concepts which are the foundation of operating systems. The book has been revised to decrease coverage of older ideas, and expand discussion of new, common operating systems.
Modern Operating Systems, 2nd Edition A. S. Tanenbaum Hanser/Prentice-HallProvides a balanced coverage between centralized and distributed operating systems. Part I covers processes, memory management, file systems, I/O systems, and deadlocks in single operating system environments. Part II covers communication, synchronization process execution, and file systems in a distributed operating system environment. Includes case studies on UNIX, MACH, AMOEBA, and DOS operating systems.
    
UNIX Network Programming W. Richard Stevens Prentice-HallA classic, all-around book covering a wide range of network programming issues and parts are still very applicable to the BeOS BSD sockets interface.
TCP/IP Illustrated, vols. 1-3 W. Richard Stevens Prentice-HallA series on networking which covers TCP/IP in a much more in-depth fashion than Unix Network Programming. For the advanced networking programmer.
POSIX Programmer's Guide: Writing Portable Unix Programs With the Posix.1 Standard Donald Lewine O'Reilly & Associates Intended as an explanation of the POSIX standard and as a reference for the POSIX.1 programming library, this book helps writing more portable programs. This guide is especially helpful when writing programs that must run on multiple UNIX platforms.
UNIX Systems Programming for SVR4 David A. Curry O'Reilly & Associates Presenting the nitty gritty details on how UNIX interacts with applications, this book offers a thorough explanation of all UNIX system calls and library routines related to systems programming, working with I/O, files and directories, processing multiple input streams, file and record locking, and memory-mapped files.
    
OpenGL Programming Guide OpenGL ARB, Woo, Neider & Davis Addison-WesleyThis book explains how to create graphics programs using OpenGL, Release 1. It presents the overall architecture of OpenGL and discusses in detail every function included in the specification. Numerous programming examples in C show how to use OpenGL functions.
OpenGL Reference Guide, 2nd Edition OpenGL ARB Addison-Wesley Explaining how graphics programs using Release 1.1, this book presents the overall structure of OpenGL and discusses in detail every OpenGL feature including the new features introduced in Release 1.1. Numerous programming examples in C show how to use OpenGL functions. Also includes 16 pages of full-color examples.
    
About Face: The Essentials of User Interface Design Alan Cooper IDG Books WorldwidePresents a methodology of user-interfaces. Helps designing user-interfaces with the user's goals in mind, arguably the whole point of UI design. This book does not focus on code; instead it discusses highly technical topics in clear English (or French or German, whatever your copy is written in :-).

4.8 How do I add a version attribute to shared libraries?

The BeOS provides a defined format and classes to deal with versioning, which is the same format as for BApplications. The version info is stored in an APPV resource of the library or application (so it does not get lost in FTP, and gets pulled into an attribute). See the BAppMimeInfo class and the serversion command-line tool for additional information.

5 Coding issues
 
5.1 How do I get a valid connection to the app_server?
AKA: Why do I need a BApplication instance?

You have a complete connection to the app_server from the time of construction of your BApplication until the object is destructed. This includes before, during and after a BApplication::Run() execution:


   int main()
   {
      BApplication app("application/x-what-ever");
      
      /*
         your code goes here
      */
      
      return B_OK;
   }

You will need this connection in order to use most parts of the Be Kits, e.g. BBitmap, BView, BWindow, ... That's right, you won't be able to use those classes unless you have this connection.

5.2 What's the right way to set my app's mimetype?

You should set it in a resource file included in your project, and as the constructor to BApplication. Those both have to match and you have to set it in both places. The FileTypes program can generate a resource file that tells the Tracker what your mimetype is (and the Tracker then caches it into an attribute). The run-time BApplication constructor argument informs the run-time system of the applications mimetype. This way the information can be rebuild if the Tracker generated attribute gets lost, for instance.

Some related URLs:

5.3 Why is my app slower with two threads than with one?
AKA: What's the MEI cache protocol?

You probably have shared data (even read-only) that your threads are working with and a 603 PPC based computer.

The problem is that the 603 PPC chip only implements an MEI cache protocol. This means that data in the 603 PPC's cache is in one of three states: (M)odified, (E)xclusive, or (I)nvalid. Notice that there is no state which says that cache data could be (S)hared between this processor and another. This is the nature of the cache thrashing which occurs and is also one of the reasons that the 603 PPC is not recommended for use in MP systems but the 604 PPC is (the 604 PPC implements a MESI cache protocol).

To illustrate the point, consider two threads, each running on a different processor, which are merely reading the same shared data. Processor one (P1) reads the data, storing the result in its cache and marking that cache line as Exclusive, data is in P1's cache only. Processor two (P2) then reads the data, storing the result in its cache, with the same effect on P2's cache. However, this second read is detected by P1, causing P1 to change the state of the cache line in its cache. Thus, P1's cache line becomes Invalid (in a 604 PPC, it would become Shared). Therefore, when P1 again reads the global data, it must refetch it from main memory. This invalidates P2's cache line and the whole cycle begins again.

Another problem may be if many threads are doing memory allocations simultaneously via new(), then every new() needs to "lock the heap" because the heap is a global structure; so all the new()'s need to be serialized. This of course drops performance if one would call new() in a tight loop from several threads, say to multithread a computation. This is more noticeable on slower machines than on fast ones. The current workaround: Don't do that. Move the new() and delete() calls to a less frequently called spot (see Bug report 970722-075741).

5.4 Why does my app behave differently if run from the shell/Tracker/debugger?
AKA: How do I set the current working directory (cwd)?

Because the current working directory (cwd) is set to where the application is when running in the debugger, set to who-knows-what when run from the Tracker and to where you are when run from the shell.

If you always want the cwd to be the same location, e.g. where the application lives, invoke this function on startup:


   #include <app/Roster.h>
   #include <storage/Path.h>
   #include <storage/Entry.h>
   #include <posix/unistd.h>
   
   void SetCurrentDirectory()
   {
      app_info info;
      BPath path;
      be_app->GetAppInfo(&info);
      BEntry entry(&info.ref);
      entry.GetPath(&path);
      path.GetParent(&path);
      chdir(path.Path());
   }

Error checking is left as an Exercise For Reader(tm).

5.5 What ANSI C functions are not thread safe
AKA: Is strtok() not thread safe?

As a rule of thumb, most ANSI C or POSIX 1003.1 functions must be thread safe (for POSIX 1003.1 compliance), although there are some exceptions:

  • asctime()
  • ctime()
  • getgrgid()
  • getgrnam()
  • getlogin()
  • getpwnam()
  • getpwuid()
  • gmtime()
  • localtime()
  • rand()
  • readdir()
  • strtok()
  • ttyname()

All of these functions have _r versions (e.g. asctime_r()) that are guaranteed to be thread-safe. Note that these may not all be available under BeOS, requiring a manual wrapper of semaphores around these function calls in order to make them thread-safe.

This should not be a problem when porting single-threaded code to the BeOS, but may be an issue when writing new, multi-threaded code.

5.6 Are BMessages reference counted?
AKA: Who owns posted/received BMessages?

There is no reference counting in BMessages. BMessages are copied on SendMessage()/PostMessage(). In order to save overhead for passing large data there are several options:

  • Within the same address space just pass a pointer to data.
  • Across address spaces set up a shared area and pass references to that shared area.
In either case, in order to know when to release the memory/area, it is nescessary to implement a custom reference counting scheme. There are other options like writing data to a port/pipe following some self designed protocol.

Related info:

  • Calling PostMessage() on any message does not transfer ownership of the BMessage object to the system. So if you own the message that you posted you are responsible for its proper destruction.
  • The BMessage you get in MessageReceived() is owned by the system, therefore it is forbidden to delete it (you did not construct it so do not destruct).
  • If you repost/resend a BMessage that you received, any replies to that resend will still go back to the orginal sender:
    A sends to B, B resends to C, C sends a reply (it will go to A)

6 Compiling
 
6.1 How do I compile an application under a later release that will still run under a previous one?

First, this has nothing to do with the BeOS being backwards-compatible. A later release (LR) will run all existing software for all previous releases (PR).

The PR might not run LR software, however, because the LR adds new features that are not in the PR. A PR isn't expected to run LR software.

A problem arises if new features are implemented in a LR through new virtual member functions of existing classes (using the virtual void reservedXXX() methods, or whatever they're called; Be engineers tend to be very creative, read the headers for a laugh or two), thus an application compiled under a LR will not run on a PR, even if you do not use them! This only happens if you use (or derive from) the class(es) that get new virtual members. Instantiating a class with virtual members means you are using all of those members, even if you, yourself, are not calling them directly. So, in a sense, you are using the new functions, just not realizing it. After all, the internals of the object may call those virtual functions behind your back.

If you really do not use them you can simply compile with the older headers and libraries from the appropriate BeOS CD, and thus link your application without pulling in those new symbols:

  1. Copy headers and libraries from some former version of the BeOS into a folder on your hard disk.
  2. Set the Access Paths:
    1. If you are using a CodeWarrior project, set the Access Paths in BeIDE to point to these older headers/libraries, rather than the current versions that would normally be used for the release you are executing on.
    2. If you use makefiles and the command-line tools, set the BEINCLUDES and BELIBRARIES environment variables to point to these older headers/libraries, rather than the current version.
  3. Build your application.

One important thing you have to keep in mind are RP bugs whichwere fixed in a LR, but your app's work arounds do not take this into consideration. The only way to deal with this is to develop under the PR and test it there a lot. If that is too much effort, then develop under the LR and test under the PR, a whole lot. Remember that (hopefully) many bugs were fixed since the PR. You can write code under a LR that works fine and as explained in the BeBook but which will not work correctly under a PR.

Be no longer supports using PreviewRelease 1 or earlier releases of the BeOS, so developing for PreviewRelease 2 or later, and suggesting your customers use PreviewRelease 2 or later, is reasonable. PreviewRelease 2 is freely available as an internet download, so there is no reason for customers to be using an earlier release.

6.2 How do I cross-compile from my Mac with CodeWarrior Pro 1?

Generating Be executables on the Mac with the Metrowerks tools is just a matter of copying over the appropriate headers and libraries and getting your access paths correct. The Metrowerks PPC tools on the Mac generate the same executable format as the Be tools. BTW, with CodeWarrior for Windows NT you can do the same thing.

Be aware that these are unsupported uses of the tools, but should work.

6.3 The compiler complains about possible unwanted assignment. How do I get rid of this warning?

Either recode the if-statement like this:


      if (someVariable = SomeFunction()) {
         /* Do Stuff, because result was not false */
      }
   

to something like:


      if ((someVariable = SomeFunction()) != false) {
         /* Do Stuff, because result was not false */
      }
   

or you use a pragma:


      #pragma warn_possunwant off
         if (someVariable = SomeFunction()) {
            /* Do Stuff, because result was not false */
         }
      #pragma warn_possunwant reset
   

For chronic command-line people who never want the warning, this will work, too:

$ mwcc -pragma "warn_possunwant off" -warn all [your_regular_command-line_arguments_go_here]

Putting the equivalent in a prefix file will work for IDE users as well.

6.4 My application, using <iostream.h>, won't build. Why?
AKA: I've included the header file--why won't the IDE build my program?
AKA: What library implements a certain Be Kit?

You are using <iostream.h> and are seeing these errors:


      ### /boot/apps/Metrowerks/tools/mwld Linker Error:
      # undefined 'ios_base::Init::Init()' (code)
      # Referenced from '__sinit_hello_cp' in hello.cp
      ### /boot/apps/Metrowerks/tools/mwld Linker Error:
      # undefined 'cout' (data)
      # Referenced from 'main' in hello.cp
      # errors caused tool to abort
   

You are probably failing to specify -lmslcpp on your link line, or do not have libmslcpp.a in your IDE project.

Using BFilePanel may produce errors of similar nature:


      ### /boot/apps/Metrowerks/tools/mwld Linker Error:
      # undefined 'run_open_panel()' (code)
      # Referenced from 'Application::MessageReceived(BMessage*)' in main.cpp
   

You are probably failing to specify -llibtracker.so on your link line (for PPC, on Intel this would be -llibtracker.so.LIB), or do not have libtracker.so in your IDE project (BFilePanel is the only Storage Kit class not implemented in libbe.so). Note that for BeOS Intel, libraries end with an .LIB!

The problem here is that the Be API (the Kits) is implemented in several libraries, and depending on what parts you use, you have to link against several libraries.

To quote from the Be Developer's Guide (page 7):

Library Contents
libroot.so Provides access to the kernel; all applications must link with this library.
libbe.so Contains the Application, Interface, and Support Kits, as well as most of the Storage Kit. All applications should link with this one, too.
libGL.so The OpenGL Kit.
libdevice.so The Device Kit.
libgame.so The Game Kit.
libmedia.so The Media Kit.
libmidi.so The Midi Kit.
libmail.so The library for applications that want to use the mail portions of the Network Kit.
libnet.so The rest of the Network Kit.
libnetdev.so The library for developing a Network Server add-on.
libtracker.so Contains parts of the Tracker application that can be used by other applications. Currently, the library contains the code for the BFilePanel class (the API is defined by the Storage Kit).

The warnings you will likely see, if you use the STL part of the ANSI C++ Standard Library, are benign and may be removed with an option to the linker to ignore duplicate-definition warnings. Note however that warnings are your friend and to ignore them means you know exactly what you are doing.

6.5 Why doesn't HelloWorld link?
AKA: My app exceeds the 64K limit. What do I do?
AKA: My app, using <iostream>s, won't compile. Why?
AKA: Can I use GCC so build my Be application?

You will probably see this error in the Message Window:


   Error   : output code size exceeds 64K limit;
   # please contact sales@metrowerks.com for info on unlimited linker
   

You cannot use <iostream>s with the limited linker that comes with the BeOS. The ANSI C++ Standard Library is currently a static library rather than a shared one, since the standard was moving until recently. Thus, if using <iostream> you have to link with this huge lib, and since BeOS ships with CodeWarrior Light, you hit the 64K code limit of the linker [4.2]. This should improve RSN, since the standard is now approved. For serious development under BeOS, you should consider buying the full CodeWarrior anyway.

In the meantime, well, couldn't MW exclude libmslcpp.a from the linker's limit? Hey, it's free. You do not have to use it if you don't want to :-) Metrowerks also does not give away Java. It's light for a reason, and making it not so light would also make it cost money. That's the sad truth.

On the bright side, there is a lightweight version of <iostream> on BeWare at <http://www.be.com/beware/Development.html#iostream.h>. It's a stub that will let you use basic cin << and cout >> functionality.

For staright C development, you can always use GCC, available at <ftp://ftp.ninemoons.com/pub/be/geekgadgets/>. Realize that GCC and C++ is currently a no go on both PCC and x86.

For PPC BeOS, you do have to have the Metrowerks linker since the GNU tools do not handle PEF and may never handle PEF unless Apples license politics change.

For x86 BeOS, the object and executable format is currently PE. The GNU linker and other tools can read object files produced by the Metrowerks linker and the Metrowerks linker also accepts PE object files produced by a GNU toolchain. However, since x86 BeOS uses the same shared library conventions as Windows, and that requires changes to the compiler and other tools to implement, it is not currently possible to use the GNU tools to generate either working objects or executables. The good news is that this problem is simply one of software, not politics or legalities, so it will eventually get fixed.

To summarise, it is unlikely that GCC will be usable for C++ programs that require use the C++ system interfaces for quite some time. Programs written in C++ that only interface to the system using C conventions should work just fine with GCCs own internal C++ runtime layout.

6.6 I always get a Ignoring dup resource warning when I build my program?!

Note that this only applies to BeIDE versions prior to 1.5!

Warning : "Ignoring dup resource in libbe.so MIMS/2/"BEOS:TYPE"

Be has added filetype and version resources to all of the system libraries. During a build associated resources are copied to the executable and now the resources in libbe.so and other libraries are copied, too. Since these are duplicates this warning is generated. To fix this:

  • Open the Target prefs panel.
  • Select application/x-be-executable.
  • Choose the flags popup and uncheck the Has Resources item.
  • Hit the change button.
  • Also remove the Has Resources flag for the target item for .so files.
  • Save changes.

The only remaining stock item that has the Has Resources flag turned on should be files with the extension .rsrc.

After making the above changes BeIDE won't try to copy resources from .so files in the project. It will only copy resources from .rsrc files in the project.

7 Why doesn't BeOS ...?
 
7.1 Where is mmap()?

Hiding and not coming out any time soon. There are no plans to do it for R3. To quote

Dominic Giampaolo:

While I'd love to do it but adding features like that will just push out release dates and that's something we'd prefer not to do.

7.2 Why doesn't Be specify a standard OS-wide scripting language?
AKA: AREXX rules!
AKA: How do I upset the Be List Guy?

With the Preview Release, Be has specified a standard messaging interface for scriptable applications. This can be implemented in any language that can support sending and receiving BMessage objects.

Despite this, there are two recurring observations:

1 -
This is great. We (and the users) can use whatever language they (the users) prefer. The market will decide what the standard is.

2 -
This is bad. New users need to be able to depend on having a simple language available. {Insert your favorite language here} on the {Insert your favorite OS here} rules the world, and should be the standard on BeOS, too.

Be's Line -
The default language shipping with BeOS is sh, so you can always count on that being there. Do not post solicitations or dissertations in an attempt to influence a BeOS scripting standard. The Be List Guy hates those so-called Scripting Wars posts, and will terminate those threads. The Be List Guy, and all of Be, loves working code. Post your code, or better yet, a URL to it, if you want to influence a standard.

If you believe that one true language should be agreed upon (since sh cannot send or receive BMessages on it's own, but instead has to rely on utilities such as hey or tell), write/port it! Post the URL to your ready-to-test/use scripting language, examples, etc. on BeDevTalk. Solicit comments about your implementation from the community on the list when necessary, i.e., when it is of general use to the BeOS programming community.

7.3 Why doesn't Be port BeOS to {Alpha, MIPS, Sparc, StrongARM, etc}?

We all know BeOS is portable. It has already been ported from a strange Hobbit/DSP mixture system to the PowerPC and Intel ... again, there are two re-occurring observations:

1 -
Porting to { my favorite CPU } would expand Be's market and show people that they mean business. On the other hand, if Be doesn't port to { my favorite CPU }, they'll go down in flames.

2 -
Be is a small company and can't afford the resources it'd take to port to { whatever } right now. BTW, { whatever } is a nasty legacy architecture that should've died ages ago, Be is about new beginnings.

3 -
With the next release of the BeOS, Be will be covering both Intel and PowerPC architectures, which covers 99% of the desktop computer systems in the world. Making a compelling business case for porting the BeOS to any processor with less than 1% of the market is very difficult.

Be's Line -
<http://www.be.com/support/qandas/beos.html#FAQ-0252>

If you would like to see a particular processor or architecture running the BeOS, contact the processor company and ask them to approach Be about porting to their architecture.

7.4 Where is focus-follows-mouse?
AKA: Why are the active windows forced to the front?

Active == Front is the default behaviour of BeOS. Run /bin/ffm from a Terminal if you want this to change (PR2). To turn it off, run /bin/ffm off (any argument will turn it off).

In R3, you can turn focus-follows-mouse on and off from the Mouse preferences app.

Note: If you run a fullscreen application (BWindowScreen) such as Dominos with ffm turned on, mouse and keyboard input will get ignored, so you cannot Quit(Cmd-Q) the application. Switch to another workspace instead (e.g. Cmd-F2), then close all Domino windows via the Deskbar.

Despite this, BeDevTalk traditionally has two standpoints:

1 -
Focus should be separate from window depth; the default behaviour should be as it is now, but you should have the option of deciding if the focus window is brought to the front or not, and whether the focus follows the mouse pointer or not. Several other options have been suggested.

2 -
The current behaviour should stay the same, end of story. This will prevent new users from being hopelessly confused.

7.5 Why isn't BeOS multi-user?

The BeOS file system has support for user/group permissions, and something like the ACLs in Windows NT could easily be implemented using the file attributes.

No other parts of the OS do any security checks or anything but the foundation is there. Be patient and watch BeOS gain multi-user capability before your very eyes.

7.6 Can I expect BeOS to be a general replacement for a UNIX box?
AKA: Is BeOS POSIX 1003.1 compilant?
AKA: Does fork()/exec() inheriting open file descriptors?

No.

Despite this, you can in fact use the BeOS much like you would other UNIX boxes.

The system ships with the GNU Bash shell and a full complement of UNIX utilities (awk, sed, grep, rcs tools, diff, make, etc.).

The BeOS is not UNIX (not by a long-shot) nor is it Be's goal to make BeOS be just like UNIX but from an end user standpoint the BeOS shell environment is quite like UNIX.

BeOS, like most UNIXes, is not yet fully POSIX 1003.1 compilant. From a programming standpoint there are a few differences but even there the BeOS C library has not only the strict POSIX functions but also supports some common UNIX functions (such as gettimeofday(), the Berkeley random() function, etc.). A good deal of UNIX code simply recompiles for the BeOS with no modifications, even though most UNIXes are not POSIX 1003.1 compliant either. Things like web servers require a bit more work because of the heavy reliance on UNIX idioms like fork()/exec() inheriting open file descriptors and because sockets are not file descriptors.

If you are using a UNIX box as a single user, the BeOS can pretty much replace it, check BeWare.

If you are using a UNIX box to serve NFS volumes, anonymous FTP, and as a telnet-in MUD server, there currently is no software available that does as good a job of it on BeOS as there is for UNIX. But solutions might become available on BeWare anytime.

7.7 Can I use the BeOS as a graphics workstation for custom apps (for example, replacing a Sun workstation)?

Yes.

Because of BeOS's high degree of POSIX compatibility, OpenGL support and standard UNIX commands, BeOS on commodity PowerPC (and soon Intel) hardware can make an excellent replacement for expensive RISC workstations.

In addition, BeOS features an easy-to-program GUI, a basic collection of office apps from third parties (for example BeatWare Basics), and the ability to dual-boot into MacOS or Windows to take advantage of even more software without the performance hit of emulation (unlike a Sun, which can only run Windows applications in emulation, or with an expensive add-on card).

7.8 Can I use the BeOS as a hobbyist OS (like Linux)?

Of course!

With a bundled C++ compiler and IDE environment, BeOS makes a solid platform for learning C/C++ and UNIX/POSIX APIs. Unlike Linux, you do not have to learn X to write powerful GUI apps--the Be Kits make it much simpler. If you feel like hardware hacking, you can write your own device drivers (there are even sample drivers with full source on the Be web site to get you started).

BeOS is also easier to install (no need to edit text files to set up your hard drives, graphics or networking, no need to recompile your kernel) and use (the Tracker lets you manipulate your files with a GUI, even if you are still learning the command-line environment).

7.9 Can I use the BeOS as a media workstation OS (for example, replacing MacOS for MIDI or SGI for video work)?

You will.

BeOS was designed from the ground up as a high-performance media-oriented OS, with a high-performance 64-bit filesystem, full memory protection, and native support for multiple processors. While there are few AV apps currently available, there are some interesting ones under development. Because BeOS is the natural choice for the next generation of media applications, as more developers realize this, applications will follow.

7.10 Can I use the BeOS as a UNIX server replacement (for example, a high-end web or database server)?

Not yet.

Because BeOS has some of the attributes of a powerful server OS already (multiprocessor support, multithreading, memory protection, built-in networking, high-performance filesystem, etc.), it is already capable of many useful server tasks (Web and FTP serving, for example).

In fact, basic HTTP, FTP, and telnet servers are bundled with BeOS. However, because there are currently no tools for RAID, multiple users, DNS or email serving, or an SQL database, it is not yet recommended for use as a general purpose UNIX server.

8 Porting software
 
8.1 Why don't I just port this?

Because it might be easier to rewrite from scratch than to force a square peg through a round hole.

Hail to the new era of multi-threaded everything:

The good part about the BeOS is that it is multi-threaded to the core. One window does its thing; another window does its thing, and they both do these things at the same time.

The bad part about most old APIs (say, the Mac Toolbox, Windows SDK, or X Window system) is that they are single-threaded. You ask for an event; you check what window this event was intended for; you handle the event; then you ask for the next event.

Before BeOS, there was nothing iffy about assuming that nobody else would change your global variables, or the variables pertaining to a specific window, while you were using them--unless you were doing interrupt-level stuff.

However, when porting to BeOS, all that changes. Suddenly, all those globals, and all that state, is subject to arbitrary change from anywhere. Just wrapping big locks around everything is not a solution--it's a recipe for disaster.

Take drawing for example: In most APIs, you just focus your destination and draw; the system takes care of displaying what you do. On the Mac, there is even a global that tells you what window you are currently drawing into. On BeOS, you may be drawing into more than one window simultaneously, or you may be wanting to draw into the same window from more than one place, so you have to lock the window you are drawing into. You also have to Flush() the window you are drawing into to make sure what you are drawing shows up on the screen.

The BeOS heralds a whole new era of truly multi-threaded everything, including the UI. There is practically no legacy code in BeOS and you will find that even highly portable code is prepared to deal with this fully multithreaded OS because you can do it right if you start from the ground up. However, for the developer it means that in most cases, existing code will not port cleanly but take heart in the fact that the real joy is in making it work in a multi-threaded environment.

This becomes obvious if you try porting a program that assumes (even forces) a single-threaded event loop API; something like GLUT. It may take three porting attempts to figure out that the correct approach is not to try to port over this code, but to bite the bullet and rewrite those portions from scratch, as C++.

There's a fine line between knowing when to port and when to rewrite. In the case of POSIX code, it is much easier to port. In the case of GUI code, it all depends on the application. Something with a high percentage of portable code with a well-written GUI abstraction layer (like Ghostscript) that only opens a single window can be very straightforward to port. GLUT was better to rewrite from scratch.

9 Add-ons
 
9.1 How to debug add-ons?

If you want to do printf() debugging, you can open a Terminal, start the application that will load your add-on, then any output from that application and the output from your add-on will go to that Terminal.

This will also work with the Tracker and Tracker-add-ons, i.e. you can open a Terminal, shut down the Tracker with Cmd-Alt-Z and restart it from the command line with /boot/beos/system/Tracker&. Then any output from the Tracker will come to your Terminal.

A more complete answer can be found at <http://www.begeek.com/ArticleDisplay.servlet?ArticleID=12>

9.2 How do I do plug-ins on BeOS?

There is a Be Newsletter article with the recipe for loading and using add-ons <http://www.be.com/aboutbe/benewsletter/Issue82.html#Insight>.

There really are only three basic ways to do plug-ins on BeOS:

  1. Define an API for each plug-in that uses C function calls; typically one call per function you require of the plug-in. Note that even though the function calls are C, they can take pointers to object as arguments if you feel like it.

  2. Say that each plug-in should implement a subclass of some class that is known to both your app and the plug-in. It may be a pure virtual class you implement in your app and ship the header for, or it may be a Be system class. Then the plug-in exports one function, whose job it is to take the arguments passed to it and manufacture an object of the defined class and return it to you; further interaction happens through the known virtual member functions of the object.

  3. Use the Be-defined Replicant functionality. The plug-in has to derive from BArchivable, and have some way of getting your application a BMessage representing an instance of the class implemented by the plug-in. This works best for BViews right now, since there is some system level support for un-archiving BView archive BMessages that are dropped on BShelf instances.

You may want to get a copy of Datatypes.lib from BeWare and study how it is put together; it uses mostly method one with some influences of method two.

9.3 How do I export functions or data from my application for use in my add-ons?
AKA: Why should I name my app _APP_ when linking add-ons against it?

When linking in a shared (i.e. not static) object under the BeOS, a reference to the shared object is included in the resulting file (executable, add-on, or shared library) so that the run-time loader knows where to look for resolving function and data symbols. The BeOS loader treats a shared object container named _APP_ as a magic reference to the application that is loading an add-on even if the loading application is not the one the add-on was linked against. This feature allows a programmer to replace an older version of an application with a newer one and continue to have all the old add-ons work, as long as the new application exports a super-set of the symbols exported by the old application.

With this in mind there are two ways to link an add-on so that it can use functions or data exported from the loading application:

  1. Make a copy of the application in question and rename it to _APP_ (exactly these 5 letters). When linking the add-on, include _APP_ in the list of object to link with.

  2. Create a stub shared library called _APP_ with just the functions and data to be exported and include it in the link command. The stubs do not have to do anything except be a place-holder for the function and data symbols to be exported from the application.

Option 2 is a good choice in a makefile environment because once the stub library is built it will not change (unless one explicitly needs to change or extend which functions or data are exported). In addition, it will not trigger a re-link step for the add-ons.

9.4 How do I access application global variables from my add-ons?

One of three ways:

1. Preferred
Use the scripting BMessages to query the BApplication for properties that are the globals. If those globals are your BWindows and BHandlers, it is already built into BApplication; if they are just arbitrary data members, you have to implement those properties yourself (by overriding ResolveSpecifier()).

2. Pretty good
Define the API to your add-on such that the application tells the add-on about what the globals are. You may pass in an object of a certain class with only virtual members, and the add-on can call those members to find out. Or you may call an initialization function that passes in data to the add-on.

3. Hoakey but useful
Export the symbols needed from your BApplication [9.3].

10 Getting the BeOS to do something for me
 
10.1 How do I get the output back from a command line tool I invoke from my own program?
AKA: Where's the code for popen()?

There are two and a half solutions, with varying drawbacks.

  1. pipe()s and load_image()
  2. Advantages:
    Fast, efficient, flexible, safe, and not (much of) a hack.
    You can control stdin, stdout, and stderr.
    Disadvantages:
    load_image() and thread_ids are BeOS-specific (though you can easily replace them with more standard fork and exec).

    Reading from or writing to stdin, stdout, or stderr while this function is executing can be hazardous, which means you may have to lock large parts of your app before calling it. A workaround is possible, but pretty ugly. Email Peter Folk at <pfolk@uni.uiuc.edu> if you really want to know about it.

    Code:
    
        #include <unistd.h>
        #include <be/KernelKit.h>
        extern char **environ;  /* Your environment (Gift from The
                                   Powers That Be) */
        
        thread_id pipe_command(int argc, char **argv,
            int &in, int &out, int &err,
            char **envp=environ)
        {
            // Save current FDs
            int old_in=dup(0);
            int old_out=dup(1);
            int old_err=dup(2);
            
            int filedes[2];
            
            /* Create new pipe FDs as stdin, stdout, stderr */
            pipe(filedes);  dup2(filedes[0],0); close(filedes[0]);
            in=filedes[1];  // Write to in, appears on cmd's stdin
            pipe(filedes);  dup2(filedes[1],1); close(filedes[1]);
            out=filedes[0]; // Read from out, taken from cmd's stdout
            pipe(filedes);  dup2(filedes[1],2); close(filedes[1]);
            err=filedes[0]; // Read from err, taken from cmd's stderr
            
            
            // "load" command.
            thread_id ret=load_image(argc,argv,envp);
            // thread ret is now suspended.
            
        
            // Restore old FDs
            close(0); dup(old_in); close(old_in);
            close(1); dup(old_out); close(old_out);
            close(2); dup(old_err); close(old_err);
            
            /* Theoretically I should do loads of error checking, but
               the calls aren't very likely to fail, and that would
               muddy up the example quite a bit.  YMMV. */
        
            return ret;
        }
        
        // In your code...
        int in,out,err;
        char **argv={"foo","args",NULL};
        thread_id tid=pipe_command(2,argv,in,out,err);
        if (tid<B_NO_ERROR) explode(tid);
        resume_thread(tid);
        write(in,"hey\n",strlen("hey\n"));
        close(in);
        close(out);
        close(err);
        
    Explanation:
    You use pipe_command() by passing the command, arguments, and environment in the normal way:
    • argv is a NULL-terminated array whose first element is the command path,
    • argc is the number of strings in argv, and
    • envp is a pointer to a NULL-terminated array of "name=value" pairs which will become the environment for the command.
    • The three int references are assigned the values of pipes to the command's std{in,out,err} file descriptors.
    To send data to the command, write() to in.
    To get the command's output read() from out.
    To get any errors the program generated, read() from err.
    If you don't like using file descriptors, you can always fdopen() them into FILE *'s, or use close() to get rid of them altogether.


    The tricky part of the above is the string of pipe(), dup2(), and close() calls.

    1. In those lines, you first create a "pipe" (a pair of file descriptors that have the funny property that data write()n to the second can then be read() from the first) from filedes[1] to filedes[0] using pipe().

    2. Then, you "dup" (duplicate--create a new file descriptor that acts exactly the same as the original) filedes[0] to stdin (file descriptor (int)0)--so now the pipe is from filedes[1] to stdin and filedes[0]. But you only need one of the two recieving ends of that pipe, so you close(filedes[0]) and save filedes[1] as the pipe that leads to the new stdin.

    3. Then you create another pair of pipe FDs, once again storing them in filedes[0] and filedes[1], make the writing end of that pipe out and the other end stdout (file descriptor (int)1), and close the extra.

    4. Repeat for err and stderr, and you have your file descriptors all set up.

      Note that now, reading from stdin, or writing to stdout or stderr, from some other thread in this team would be a bad thing.

    5. When you spawn the command by calling load_image(), it inherits the file descriptors, after which you can restore your originals and continue using printf() and fprintf().


    When this function returns, the command's main thread (whose ID is the return value) is suspended. You have to call resume_thread() or wait_for_thread() with this ID to start the command.


  3. popen()
  4. Advantages:
    Portable, short, standard, reasonably efficient.
    Disadvantages:
    Dangerous (uses shell to run command), possible deadlocks.
    Only one of stdin or stdout easily available.
    Code:
    
        #include <stdio.h>
        FILE *command=popen("foo args </dev/null 2>/dev/null","r");
                                      /* close unwanted descriptors,
                                         so they don't get in your way */
        if (!command) explode();
        else {
            char buf[512];
            fgets(s,512,command);
            // ...
            int retval=pclose(command);
        }
        
    Explanation:
    popen() uses the shell to run the command (so beware of executing commands from untrusted sources), redirecting its stdin or stdout (depending on whether the second argument to popen() is "w" or "r", respectively) to the returned FILE *. Don't forget to redirect the unused descriptors (you can alias the command's n'th file descriptor to its m'th using the shell's "n>&m" syntax) or it will use yours, and watch out for race conditions.

    If you want more control, you can always combine this with the above pipe() techniques. This allows one to control all three descriptors.

    If locking the app to prevent accidental use of std{in,out,err} is absolutely unacceptable but you want to control all three of them, consider the following:

    
        void pipe_command(char *command,FILE *&in,FILE *&out,FILE *&err)
        {
            int filedes[2], out_fd,err_fd;
            pipe(filedes);  out_fd=filedes[1];  out=fdopen(filedes[0],"r");
            pipe(filedes);  err_fd=filedes[1];  err=fdopen(filedes[0],"r");
            
            char *buf=(char *)malloc(strlen(command)+24); // should be ample space
            sprintf(buf,"%s 1>&%i 2>&%i",command,out_fd,err_fd);
            in=popen(buf,"w");
            free(buf);
        }
        // ...
        int retval=pclose(in);
        fclose(out);
        fclose(err);
        
    In fact, the only reason I recommend *not* using that, is that it's unsafe and inefficient because it uses the shell, and deadlocks are harder to avoid because buffering can be erratic.

2  1/2.   There is no special magic to popen().

In fact, here is what it does:

     FILE *
     popen(const char *cmd, const char *type) {
         int p[2];

         pipe(p);  // NOTE: check for failure

         if((child_pid = fork()) > 0) {  // parent
        if (*type == 'r') {
            close(p[1]);
            fp = fdopen(p[0], type);
        } else {
            close(p[0]);
            fp = fdopen(p[1], type);
        }
        return fp;
         } else if (child_pid == 0) {  // child
        if (*type == 'r') {
            fflush(stdout);
            close(1);
            dup(p[1]);  // NOTE check for error
        } else {
            close(0);
            dup(p[0]);
        }
        close(p[0]);  close(p[1]);
        args[0] = "/bin/sh";
        args[1] = "-c";
        args[2] = (char*)cmd;
        args[3] = NULL;
        execvp(args[0], args);
         }
     }

You can easily write your own version to redirect stderr to the pipe in addition to stdout, simply by calling close(2); dup(p[1]); in addition to close(1); dup(p[1]);

One tip: You could eliminate the overhead of an extra copy of bash by changing the args[] array to reflect your actual program command and arguments, instead of running your command through /bin/sh.

10.2 Why doesn't my HookFunction get called?
AKA: Why should I enable the warning for Hidden Virtual Functions?

Consider


   void BView::MouseMoved(BPoint point, uint32 tr, const BMessage* message);

Now you try to override the above with:


   void MView::MouseMoved(BPoint point, uint32 tr,BMessage* message);

This method will never get called in reaction to a MouseDown event. Actually you are not overriding the MouseMoved method--you're defining a new method. In this particular case, you need to make the BMessage argument const. In general, the signature of the overriding method must match the overridden one, thus it must take the exact same arguments. No exceptions. This is the same with every virtual method you try to overload!

In this particular case, the warning for Hidden Virtual Functions is the one that, if enabled, will tell you when this happens. It is highly recommended to enable all warnings and check the output after each compile. As already mentioned [6.4], some warnings you will likely see (e.g. if you use the STL part of the ANSI C++ Standard Library) are benign and may be ignored. Nevertheless, the second best thing one can do for some piece of code is to make it compile without warnings (as noted earlier, this is not always possible with the current libraries and compiler). The best thing you can do for your code is to force prototypes for each and every function you will be calling.

10.3 MouseUp() isn't ever called. Why?

B_MOUSE_UP events are not dispatched to MouseUp() in BWindow::DispatchMessage(). You have to do this yourself until this is fixed. See <ftp://ftp.be.com/pub/contrib/develop/MessageDemo-0.1.zip>.

10.4 Why is my application not getting any mouse/keyboard events?
AKA: What compiler switches should I leave alone?

Always compile with RTTI and C++ exceptions turned on! Without them on, you will loose Pulse(), MouseDown() and KeyDown().

Apparently libbe.so uses RTTI when dispatching messages. If client code is compiled without RTTI then the dispatching does not work. Exceptions are not related, but all C++ code that uses the Be libraries should be compiled with both of these options turned on. Do not even think of turning them off unless you're sure you know what you're doing.

Also, you will run into problems with the class libraries if you do not have Treat enums as ints checked, as all the Be libraries assume this to be the case.

10.5 How do I create a Background Application (without an icon in the DeskBar)?

It is possible for the programmer to do that. Use B_BACKGROUND_APP when setting your application flags.

It is also possible for users to set this with the FileTypes add-on, though the program might override it next time it runs (and thus it is much better if it is done by the author).

10.6 Why is there no FindWindow()?

So it can become a FAQ:

Here's a nice (but untested, sorry) FindWindow:


   BWindow  *FindWindow(const char *title)
   {
       BWindow *win = NULL;
       int32 i = 0;
       char *tmptitle;
       
       while ((win = be_app->WindowAt(i)) == NULL) { 
           win->Lock();
           if((tmptitle = win->Title()) != NULL 
           && strcmp(tmptitle,title) == 0) {
               win->Unlock();
               break;
           }
           win->Unlock();
           ++i;
       } 
       return win;
   }

10.7 How do I get a list of all running applications?

   #include <AppKit.h>
   #include <support/List.h>

   int main()
   {
       BApplication("application/x-what-ever");

       BList teams;
       be_roster->GetAppList(&teams);

       app_info ai;
       team_id team;
       for (int32 i = 0; i < teams.CountItems(); i++) {
           team = (team_id)teams.ItemAt(i);
           if (be_roster->GetRunningAppInfo(team, &ai) == B_OK) {
               printf("team %d: %s\n", ai.team, ai.signature);
           }
       }
       
       return B_OK;
   }

You might want to check out the app_info structure in <app/AppDefs.h> in order to get more information--for example, you can find ai.flags to make sure it is not a background application.

10.8 How can I send a BMessage to a particular BWindow rather than to the BApplication it belongs to?

Once you have an application's BMessenger through the be_roster, you can use the scripting interface to find another BMessenger, even without the other program being specifically designed to do this.


   BMessenger app;  // this is the application messenger

   BMessage msg(B_GET_PROPERTY);
   /* notice specifiers are in reverse order */
   msg.AddSpecifier("Messenger");
   msg.AddSpecifier("Window", 3);  /* window number 4 */
   BMessage reply;                 /* (starting from 0) */
   app.SendMessage(&msg, &reply);

   BMessenger win;
   if(reply.FindMessenger("result", &win) == B_OK && win.IsValid()) {
      // ...
   }

   BMessage msg2(B_GET_PROPERTY);
   /* this is a "relative path", you could use the app messenger and
      add the window specifier */
   msg2.AddSpecifier("Messenger");
   msg2.AddSpecifier("View", 1); /* view number 2 (starting from 0) */
   Message reply2;
   win.SendMessage(&msg2, &reply2);

   BMessenger view;
   if(reply2.FindMessenger("result", &view) == B_OK && view.IsValid()) {
      // ...
   }
   

10.9 How do I get a BMessenger for every open BWindow in the Tracker?

Using the scripting interface, you can ask for various properties by index or name. The following program, when compiled and run from the command line, retrieves a BMessenger for each open window in the Tracker. You can modify it to work on other applications, or retrieve other things.


   /*  this program lists the windows of the tracker as messengers */

   #include <Message.h>
   #include <Application.h>
   #include <Looper.h>
   #include <Messenger.h>
   #include <Roster.h>

   int main()
   {
     BApplication app("application/x-lister");
     entry_ref ref;
   
     if (get_ref_for_path("/system/Tracker", &ref)) {
       puts("can't get ref");
       return B_ERROR;
     }
     
     team_id tracker_team = be_roster->TeamFor(&ref);
     if (tracker_team < 0) {
       puts("can't get team");
       return B_ERROR;
     }
 
     status_t err = B_OK;
     BMessenger tracker((const char *)NULL, tracker_team, &err);
     if (err < 0) {
       puts("can't make messenger");
       return B_ERROR;
     }
     
     int ix = 0;
     BMessage query(B_GET_PROPERTY);
     BMessage reply;

     do {
       query.MakeEmpty();
       reply.MakeEmpty();
       query.AddSpecifier("Window", ix);
       err = tracker.SendMessage(&query, &reply);
       if (err) {
         printf("Query %d error %08x\n", ix, err);
         break;
       }
       printf("Query %d\n", ix);
       reply.PrintToStream();
       ++ix;
     } while (reply.what != B_MESSAGE_NOT_UNDERSTOOD);

     app.PostMessage(B_QUIT_REQUESTED);
     app.Run();
     
     return B_OK;
   }

10.10 How do I get Tracker icons from a file?

Suppose you have a BFile yourFile and a BView yourView (preferably the size of a mini icon):


      BBitmap *iconMap = new BBitmap(BRect(0, 0, B_MINI_ICON - 1,
                                     B_MINI_ICON - 1), B_COLOR_8_BIT);
      BNodeInfo mime(yourFile);
      mime.GetTrackerIcon(iconMap, B_MINI_ICON);

      yourView->SetDrawingMode(B_OP_OVER);
      yourView->SetLowColor(B_TRANSPARENT_32_BIT);
      yourView->DrawBitmap(iconMap);

      delete iconMap;
   

Error checking is left as an Exercise For The Reader(tm). Check out the header /boot/develop/headers/be/storage/NodeInfo.h on your BeOS machine.

Note that the draw uses a mode where parts of the icon that are transparent (masked out) are not drawn. If you do not care about that, you can skip the SetDrawingMode() and SetLowColor() calls.

Also note that GetTrackerIcon() does not currently return icons for volumes (use get_device_icon() from /boot/develop/headers/be/storage/Mime.h for this) or default application, document, folder and symlink icons.

10.11 How and when do I set the mouse cursor?

The BeDevTalk FAQ Tutorial 1 demonstrates cursor handling under BeOS. It shows how to specify a cursor, and how/when to make the system show it.

How

While making the system display a custom cursor is relatively easy, the actual routine to do so is not in the most intuitable place, though. While cursors mostly react to the BView the mouse is over, the cursor-setting routine is actually in BApplication. The method BApplication::SetCursor(void* data) takes a pointer to anything and attempts to use it as a cursor. The format of data is documented in the tutorial sourcefile VuCursor.cpp and below. Cursor definitions should be stored in a resource.

When

Likewise, when to set the cursor is pretty easy. Basically whenever a different cursor is needed. Unless fine control over the cursor shape within a single BView is needed, a good place to set the cursor is in an override of BView::MouseMoved(). MouseMoved() provides the information of when the cursor enters a BView, moves within it, or leaves a BView. Set a custom cursor when the mouse enters, reset the cursor to the default hand cursor when it leaves. If there are multiple cursors for a given BView, watch the movement within that BView. The only caveat is that notifications of internal movement are only generated when the mouse has moved a few pixels. For a finer control handle the cursor in Pulse() or spawn a separate thread to watch the mouse cursor manually.

Cursor Specification

The data is just plain memory. The first four bytes of a cursor are a header block that define the cursor geometry and imply the size of the remaining data. At this writing, cursors must be 16x16 pixels and one bit deep; all cursors are therefore 68 bytes in current BeOS applications.

11 Using standard BeOS classes
 
11.1 How do I get a BFilePanel to select directories?

Make the filepanel a B_OPEN_PANEL (this is required), and set the node_flavors argument to B_DIRECTORY_NODE.

11.2 How do I implement Read-Writer-Locks using semaphores?
AKA: Is is possible to acquire a semaphore only partially?
AKA: How do I check whether the acquisition of a semaphore succeeded?

   // --- rw_lock.h ---
   #pragma once

   const uint32 MAX_READERS = 10000000;

   status_t create_rwlock(const char * name);
   status_t delete_rwlock(sem_id rwlock);

   status_t acquire_read(sem_id rwlock);
   status_t acquire_read_etc(sem_id rwlock, bigtime_t timeout);
   status_t release_read(sem_id rwlock);

   status_t acquire_write(sem_id rwlock);
   status_t acquire_write_etc(sem_id rwlock, bigtime_t timeout);
   status_t release_write(sem_id rwlock);


   // --- rw_lock.cpp ---
   #include "rw_lock.h"

   status_t create_rwlock(const char * name) {
       return create_sem(MAX_READERS, name);
   }

   status_t delete_rwlock(sem_id rwlock) {
       return delete_sem(rwlock);
   }



   status_t acquire_read(sem_id rwlock) {
       return acquire_sem(rwlock);
   }

   status_t acquire_read_etc(sem_id rwlock,  bigtime_t timeout) {
       return acquire_sem_etc(rwlock, 1, B_TIMEOUT, timeout);
   }

   status_t release_read(sem_id rwlock) {
       return release_sem(rwlock);
   }



   status_t acquire_write(sem_id rwlock) {
       return acquire_sem_etc(rwlock, MAX_READERS, 0, 0);
   }

   status_t acquire_write_etc(sem_id rwlock,  bigtime_t timeout) {
       return acquire_sem_etc(rwlock, MAX_READERS, B_TIMEOUT, timeout);
   }

   status_t release_write(sem_id rwlock) {
       retu rn release_sem_etc(rwlock, MAX_READERS, 0);
   }

 

Some related information about the above code

When acquiring a semaphore the acquiring thread will block until the semaphore is available (or until the timeout expires--see the documentation for acquire_sem_etc()) . This means that there is no need to check when the acquisition of the semaphore succeeded, but do check the return code.

There is no such thing as a partial acquisition of a semaphore. You either succeede to acquire the semaphore (as many times as specified with uint32 count) or fail. Failure means that there was no acquisition at all (in total) and thus there is no need to realease anything. You don't try to acquire it six times, but once, and alter the semaphores value by six.

Since the Be counting semaphore implementation enforces FIFO fairness, semaphore acquisition is first come first serve and not serve who is serviceable, so the above implementation will not let writers starve.

In addition to the code above, there is a pretty comprehensive syncronisation library available for BeOS--Betelgeuse, to be found on BeWare.

For additional and more indepth information read the Kernel Kit of the BeBook and get a copy of Operating System Concepts, 4th Edition by A. Silberschatz, Peter Baer Galvin [4.7] and Modern Operating Systems, 2nd Edition by A. S. Tanenbaum [4.7].

It is not possible to implement a Read-Writer-Lock using only one benaphore without introducing a race condition in the code. In case someone does have a solution to this problem, be sure to contact <devsupport@be.com> for a job opportunity.

Related tidbit: The BLocker class is a benaphore.

12 How is it done using C/C++?
 
12.1 How do I print an int64 (long long) using printf()?

   int64 some_int64 = 4711;
   printf("%Ld", some_int64);

Note the capital L!

Or, using <iostream.h>:


   cout << some_int64;

12.2 How do I wake up a thread that is blocked on a semaphore?

You can send a POSIX signal to a thread through the send_signal() function. The SIGCONT signal tries to unblock a blocked or sleeping thread without killing it; all other signals kill the thread. To override this behavior, you can install your own signal handlers.

If you do this to quit the thread, it can test for its quit boolean (or something else) after each system call, to avoid blocking again right after being dislodged.

When you send_signal() to a thread that is blocked on something, such as a pipe or semaphore, it cancels the blocking operation. That is, the blocking call returns, and the thread resumes running. The call returns an error code indicating that the call was interrupted. POSIX calls set errno to EINTR, BeOS calls return B_INTERRUPTED. Those two are equal error codes.

Note that each thread has a separate errno, so no other thread will change the result unless you do (by calling another blocking operation).

12.3 How do I create random numbers?

   long Random(ulong min, ulong max)
   {
      long r;
   
      /* Sanity check */
      ASSERT(min <= max);
      if (min > max) { return(0); }

      /* Find range of values. */
      max -= min;

      /* This ensures that it's (x <= max) as opposed
       * to (x < max) */
      ++max;

      /* This is the /recommended/ method for getting a
       * number between min and max-1. The high bits are
       * more random than the low bits.*/
      r = (long) ((double)max*random()/(RAND_MAX+1.0));

      return(r+min);
   }

   ulong Random(ulong max)
   {
      /* This is the /recommended/ method for getting a
       * number between 0 and max-1. The high bits are more
       * random than the low bits.*/
      return((ulong) ((double)max*random()/(RAND_MAX+1.0)));
   }

   void Randomize(void)
   {
      time_t t;
      srandom((unsigned) time(&t));
   }

Note: random() and the ANSI C rand() are not thread safe [5.5]. Proper synchronization is left as an Exercise To The Reader(tm).

These routines do not use modulo. This is because the periodicity of random() is the bit length of the returned data. Therefore, using modulo would only result in a periodicity of max for this case, whereas using division uses the entire random() value and thus has a higher periodicity.

If you need better random numbers, try finding a lrand48() function which usually comes with any {Net,Free}BSD or Linux libc library.

There is also a /dev/random on BeWare if you need really good random numbers. This will be slightly slower and to save some overhead, you could read a few hundred numbers into a buffer in one operation.

13 Miscellaneous
 
13.1 What to do if you can't boot off the HD?

Insert your BeOS CD, wait untill you see the Installer, hit Cmd-Alt-Shift-T, this will open up a Terminal and you should be able to mount any drive via /boot/beos/preferences/DriveSetup&. You should be able to take it from there.

13.2 Help! I can't delete my Replicants from the Desktop!

For some reason, the Replicant has grown so much that the little Dragger-Hand is no longer visible, and thus it can't be right-clicked to delete the gone wild Replicant. Find (Tracker Cmd-F) the file named tracker_shelf, shut down the Tracker with Cmd-Alt-Z and restart it from the command line with /boot/beos/system/Tracker& [9.1] or reboot.

13.3 Brother in Arms

Thanks for making this FAQ possible (in the order of the first contact):

  • Craig Longman
  • Ed Musgrove

13.4 Acknowledgements

Thanks for contributing to this FAQ (in no particular order):

  • Andy Philpotts
  • Peter Folk
  • Michael A. Alderete
  • Chris Herborth
  • Jon Wätte
  • Jake Hamby
  • John R. Ashmun
  • Trey Boudreau
  • Seth R. Flaxman
  • Gregory Weston
  • Andreas Huber

13.5 Good citizens

Thanks for suggestions, corrections, submissions and the like (in no particular order):

  • Raymund Ramos
  • Jon Ragnarsson
  • Kenneth N. Flaxman
  • Timothy A. James
  • Joerg Stegemann
  • Peter Greis
  • Peter Urbanec
  • Duncan Wilcox
  • Dirk Olbertz
  • Albert Köllner
  • Howard Berkey
  • Stephen van Egmond
  • Fred Fish
  • Dirk Hill
  • William E. Bull

13.6 History

Version 1.1.0 (09.03.1998):
  • extensive AKA's added
  • moved [5.4] -> [10.10], [11.2] -> [5.4]
  • added FAQ [4.7], [4.8], [5.5], [5.6], [9.3], [9.4], [10.11], [11.2], [N.2], [N.5] (and rearranged existing Q&As in Section N accordingly)
  • changes to FAQ [0.0], [1.2], [2.1], [2.2], [2.3], [3.2], [4.1], [4.2], [4.5], [5.1], [5.2], [5.4],[5.5], [6.1], [6.4], [6.5], [7.4], [7.6], [8.1], [10.3], [10.6], [10.7], [10.9], [12.3], [N.3], [N.4]
  • released 25.06.1998
Version 1.0.0 (26.01.1998):
  • converted into HTML
  • some last-minute-corrections und URL-checking
  • released 05.02.1998
beta Version 0.9.5 (21.01.1998):
  • folded back Ed Musgrove's suggestions for beta Version 0.9.4
  • fundamental punctuation correction
  • cleared up the question's capitalisation
  • changes to FAQ [7.3]
beta Version 0.9.4 (18.01.1998):
  • folded back Michael A. Alderete's suggestions for beta Version 0.9.3
  • overall cosmetic changes and rewording
  • changes to FAQ [6.1], [7.2], [7.3]
beta Version 0.9.3 (07.01.1998):
  • folded back Ed Musgrove's suggestions for beta Version 0.9.2
  • cosmetic changes to SECTION [1], [2] and [3]
  • overall rewording
  • changes to FAQ [5.3]
  • added FAQ [6.6], [12.3], [4.5], [4.6], [9.2]
  • removed [7.6]
  • changed History format
  • changed versioning scheme retroactive
beta Version 0.9.2 (03.01.1998):
  • added this History
  • added Sections [4] Development ([4.1] - [4.4]) and [5] Coding issues ([5.1] - [5.4]) and rearranged existing Sections accordingly, old [8.4] moved to new [5.1]
  • cosmetic changes to the header and removed Subject Index:
  • folded back Andy Philpotts' suggestions for beta Version 0.9.1
  • [3.1] and [3.3] brought in line with the Be posted List Charter
  • changes to FAQ [6.3], [6.5], [7.2], [7.4], [8.1], [9.1], [10.1], [10.2], [12.1], [N.1], [N.2], [N.3]
  • added FAQ [4.1], [4.2], [4.3], [4.4], [5.1], [5.2], [5.3], [5.4], [7.5], [7.6], [7.7], [7.8], [7.9], [7.10], [7.11], [10.3], [10.4], [10.6], [10.7], [10.8], [10.9], [N.4]