Re: [gtk-list] Re: Need help in GTK-project



On Thu, 09 Dec 1999 21:46:45 +0100, Bart Vandewoestyne wrote:
> Erik Mouw wrote:
>> On Sun, 05 Dec 1999 02:47:26 +0100, Bart Vandewoestyne wrote:

[snip]

>> GTK is _not_ considered safe enough to be useful for root or suid root
>> programs. Make a small helper application that can safely be suid'ed, it
>> only has to do the ioperm() and outb() plus it needs some way to
>> communicate with the main program (which does the user interface).
> 
> What do you mean by 'helper application'?  I don't have much experience
> in this... can you be a little bit more specific ?

The small helper application should do the dirty work controlling the
motor. The helper should only contain the most neccessary bits to deal
with the motor: get required ioperms, inb/outb and communication with the
GUI. The GUI application sets up the communication with the helper
application, fork()s and exec()s the helper application. At first, this is
not an easy task, but with some example code you will succeed (take my
fork() example from the GTK FAQ and combine it with the unix2dos() I/O
redirection from DOSemu in src/base/misc).

>> I'd suggest using more header files, so
>> showmessage.c gets a header file showmessage.h.
> 
> Why do I need a headerfile for this?  Sorry to ask such stupid
> questions, but this is my first BIG program... at school al always
> learned to program in just one .c file and that was quite stupid I

Are you serious? It's really bad programming practice.

> think... I never actually learned to work well with headerfiles.  Can
> you give me some tips on using more headerfiles for my program?  When
> should I decide to make a headerfile and what kind of stuff should
> belong in that headerfile ?

This is modular programming. Each module has a .c and a .h file: the .h
file contains the interface, the .c the implementation.

>> Oh, and please do use the
>> anti-double-include-header-file trick (this example is for motor.h):
>> 
>> #ifndef MOTOR_MOTOR_H
>> #define MOTOR_MOTOR_H
>> 
>> /* asm/io.h is not needed here, but in motor.c, so include it there
>>  * same for unistd.h and stdio.h. gtk.h needs to be included here
>>  */
>> 
>> #include <gtk/gtk.h>
>> 
>>   ... rest of motor.h ...
>> 
>> #endif
> 
> OK, I think I've changed everything like you told me to... still, i get
> these two errors when I compile my program:
> 
> main.c: In function `main':
> main.c:19: warning: implicit declaration of function `ioperm'
> main.c:19: warning: implicit declaration of function `perror'

To use ioperm, you should include unistd.h (although that fails on some
systems). perror needs stdio.h and on some Unices also errno.h. See "man
ioperm" and "man perror".

>> Oh, "int portstatus" doesn't belong in a header file, but in one of the C
>> files.
> 
> I have put portstatus as a global variabele in main.c, is this ok? 
> Could you also please explain me why it is better to put it in a .c file
> instead of in a .h file ?

If you put it in a header file, the compiler reserves a symbol for it in
each object file. The linker will detect this and complain about a
multiple defined symbol. What you actually want is:

main.c:
  /* implement portstatus variable. it is actually good programming practice
   * to initialize each variable
   */
  int portstatus = 0;


headerfile:
  /* declaration of the portstatus variable. the extern keyword is to notify
   * the compiler that the variable is not in this object file, but that it
   * is implemented in some other object file and the linker will solve this
   */
  extern int portstatus;

>> Another thing: avoid namespace pollution. Your project is small enough to
>> be bitten by it, but you actually should prefix all your functions and
>> variables (so mot_CreateMenuItem() and MOT_LEFT). Been there and learned
>> it the hard way.
> 
> Huh?  Need more explanation on this...

Okay, take your portstatus variable:

int portstatus;

It is defined in main.c and contains the status of the hardware port. Now
suppose that you want to link with a library that does some TCP/IP
connection. This library also needs to keep track of the status of a
certain TCP/IP port, so it uses a variable ... portstatus. Your program
won't link, because the library and main.c pollute each others namespace
by using the same variable name. If you prefixed your variable with
"mot_", it wouldn't have happened.

>> About your Makefile, try my version which uses implicit rules etc. It's
>> not as sophisticated as a version that fully supports GNU make, but it
>> will work with most sane make utilities.
> 
> First of all: can you explain what 'implicit rules' are ?
> 
>> # The main things: compiler, linker, flags
>> CC=gcc
>> CFLAGS=-Wall -O2 -g `gtk-config --cflags`
>> LDFLAGS=-g
>> LIBS=`gtk-config --libs`
>> 
>> # Sources, object files and target
>> SRCS=main.c motor.c menu.c misc.c about.c showmessage.c
>> OBJS=main.o motor.o menu.o misc.o about.o showmessage.o
>> TARGET=motor
>> 
>> # Implicit rules
>> .c.o:
>>         $(CC) $(CFLAGS) -c $< -o $@
> 
> I don't quite understand the last 3 lines... Somebody who wants to
> explain them to me ?

An implicit rule is a general rule. This specific rule tells make: if you
want to get an .o file from a .c file, use the following command. $< is
the input file, $@ is the output file. See the GNU make info pages.

>> # Some phony targets (i.e. targets without files)
>> .PHONY: all clean realclean install
> 
> 'phony targets' ???

A phony target is a target without file output. If there is a file "clean"
in your current directory, you can't do "make clean" because make thinks
that the target "clean" is up to date. Marking the target "clean" as phony
instructs make to ignore the file "clean".

>> all: $(TARGET)
>> 
>> $(TARGET): $(OBJS)
>>         $(CC) $(LDFLAGS) -o $@ $(OBJS) $(LIBS)
> 
> What is this $@ thing doing in between ???

$@ is the name of the target. There are more specific variables in make,
but $@ and $< are the most important. Using the $^ variable (meaning all
dependencies), the rule can be rewritten as:

$(TARGET): $(OBJS)
        $(CC) $(LDFLAGS) -o $@ $^ $(LIBS)

>> clean:
>>         rm -f $(OBJS) $(TARGET)
>> 
>> realclean: clean
>>         rm -f *~
>> 
>> install: $(TARGET)
>>         chown root.mc303 $(TARGET)
>>         chmod ug+s $(TARGET)
> 
> Tnx!  The Makefile did very well!
> 
>> HTH
> 
> It sure did help!  Programming practice is the best way to learn :-)
> People who want to give me more feedback, tips, bug reports etc... on my
> program should take a look at http://hello.to/MC303 and follow the link
> 'stepper motor' on the left and download the buggy version.  I updated
> it today.  The program has already been expanded and I have changed the
> things you adviced me to change.  Want to check it out and send me
> feedback ?

Again: make it more modular. misc.c should get a header file misc.h with
the following content:

  #ifndef MOTOR_MISC_H
  #define MOTOR_MISC_H

  #include <gtk/gtk.h>

  GtkWidget *CreateMenuItem (GtkWidget *menu,
                             char *szName,
                             char *szAccel,
                             char *szTip,
                             GtkSignalFunc func,
                             gpointer data);

  GtkWidget *CreateBarSubMenu (GtkWidget *menu, char *szName);

  #endif


Erik

-- 
J.A.K. (Erik) Mouw, Information and Communication Theory Group, Department
of Electrical Engineering, Faculty of Information Technology and Systems,
Delft University of Technology, PO BOX 5031,  2600 GA Delft, The Netherlands
Phone: +31-15-2785859  Fax: +31-15-2781843  Email J.A.K.Mouw@its.tudelft.nl
WWW: http://www-ict.its.tudelft.nl/~erik/





[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]