1
1

Piles of bug fixes; piles of new toys; running to a dinner, comment later -mig

Этот коммит содержится в:
Miguel de Icaza 1998-03-05 04:53:47 +00:00
родитель 93ffc92a80
Коммит 89821ca886
12 изменённых файлов: 488 добавлений и 131 удалений

Просмотреть файл

@ -14,10 +14,25 @@ INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
GNOMESRCS = gkey.c gmain.c gscreen.c gwidget.c \
gmenu.c ginfo.c ghelp.c glayout.c gtools.c gdesktop.c
GNOMESRCS = \
gkey.c \
gmain.c \
gscreen.c \
gwidget.c \
gmenu.c \
ginfo.c \
ghelp.c \
glayout.c \
gtools.c \
gdesktop.c \
gutil.c \
gtrans.c
GNOMEHDRS = gmain.h gscreen.h gwidget.h gconf.h
GNOMEHDRS = \
gmain.h \
gscreen.h \
gwidget.h \
gconf.h
#
# These objects from ../src do not depend on HAVE_X / HAVE_GNOME??
@ -37,7 +52,7 @@ OOBJS = main.o dlg.o screen.o widget.o wtools.o info.o boxes.o \
OBJS = $(LOBJS) $(OOBJS) \
gkey.o gmain.o gscreen.o gwidget.o gmenu.o ghelp.o ginfo.o \
glayout.o gtools.o gdesktop.o
glayout.o gtools.o gdesktop.o gtrans.o gutil.o
#
# Distribution variables

Просмотреть файл

@ -3,7 +3,7 @@
#define PORT_HAS_FRONTEND_RUN_DLG 1
#define PORT_HAS_FILE_HANDLERS 1
#define PORT_HAS_GETCH 1
#define PORT_HAS_MY_SYSTEM 1
#define PORT_HAS_DIALOG_TITLE 1
#define PORT_WANTS_CLEAN_BUTTON 1
#define PORT_HAS_CREATE_PANELS 1

Просмотреть файл

@ -55,47 +55,6 @@ enum {
/* The list of icons on the desktop */
static GList *desktop_icons;
/*
* Creates a shaped window, toplevel, non-wm managed window from a given file
* uses the all-mighty Imlib to do all the difficult work for us
*/
GtkWidget *
shaped_icon_new_from_file (char *file, int extra_events)
{
GtkWidget *window;
GdkImlibImage *im;
GdkWindowPrivate *private;
if (!g_file_exists (file))
return;
im = gdk_imlib_load_image (file);
if (!im)
return NULL;
gtk_widget_push_visual (gdk_imlib_get_visual ());
gtk_widget_push_colormap (gdk_imlib_get_colormap ());
window = gtk_window_new (GTK_WINDOW_POPUP);
gtk_widget_set_events (window, gtk_widget_get_events (window) | extra_events);
gtk_widget_pop_colormap ();
gtk_widget_pop_visual ();
gtk_widget_set_usize (window, im->rgb_width, im->rgb_height);
gtk_widget_realize (window);
gdk_window_resize (window->window, im->rgb_width, im->rgb_height);
private = (GdkWindowPrivate *) window->window;
private->width = im->rgb_width;
private->height = im->rgb_height;
gdk_imlib_apply_image (im, window->window);
gdk_imlib_destroy_image (im);
return window;
}
/*
* If the dentry is zero, then no information from the on-disk .desktop file is used
* In this case, we probably will have to store the geometry for a file somewhere
@ -125,15 +84,16 @@ desktop_icon_set_position (desktop_icon_t *di, GtkWidget *widget)
x = current_x;
y = current_y;
current_y += 64;
gtk_widget_size_request (widget, &widget->requisition);
current_y += widget->requisition.height + 8;
if (current_y > gdk_screen_height ()){
current_x += 64;
current_x += 0;
current_y = 0;
}
}
di->x = x;
di->y = y;
gtk_widget_set_uposition (widget, x, y);
gtk_widget_set_uposition (widget, 6 + x, y);
}
static int operation_value;
@ -210,8 +170,7 @@ check_window_id_in_one_panel (gpointer data, gpointer user_data)
PanelContainer *pc = (PanelContainer *) data;
int id = (int) user_data;
WPanel *panel = pc->panel;
g_panel_contents *gpc = (g_panel_contents *) panel->widget.wdata;
GtkCList *clist = GTK_CLIST (gpc->list);
GtkCList *clist = GTK_CLIST (panel->list);
GdkWindowPrivate *gdk_wp;
gdk_wp = (GdkWindowPrivate *) clist->clist_window;
@ -385,14 +344,16 @@ desktop_load_dentry (char *filename)
GnomeDesktopEntry *dentry;
desktop_icon_t *di;
GtkWidget *window;
char *icon_label;
dentry = gnome_desktop_entry_load (filename);
if (!dentry)
return;
icon_label = dentry->name ? dentry->name : x_basename (dentry->exec);
if (dentry->icon)
window = shaped_icon_new_from_file (dentry->icon, GDK_BUTTON_PRESS_MASK);
window = create_transparent_text_window (dentry->icon, icon_label, GDK_BUTTON_PRESS_MASK);
else {
static char *default_icon_path;
static char exists;
@ -404,7 +365,7 @@ desktop_load_dentry (char *filename)
}
if (exists)
window = shaped_icon_new_from_file (default_icon_path, GDK_BUTTON_PRESS_MASK);
window = create_transparent_text_window (default_icon_path, icon_label, GDK_BUTTON_PRESS_MASK);
else {
window = gtk_window_new (GTK_WINDOW_POPUP);
gtk_widget_set_usize (window, 20, 20);
@ -500,7 +461,7 @@ desktop_create_launch_entry (char *pathname, char *short_name)
char *icon;
icon = get_desktop_icon (pathname);
window = shaped_icon_new_from_file (icon, GDK_BUTTON_PRESS_MASK);
window = create_transparent_text_window (icon, x_basename (pathname), GDK_BUTTON_PRESS_MASK);
g_free (icon);
di = xmalloc (sizeof (desktop_icon_t), "dcle");
di->dentry = NULL;

Просмотреть файл

@ -1 +1,2 @@
#define MC_LIB_DESKTOP "mc.desktop"
GtkWidget *create_transparent_text_window (char *file, char *text, int extra_events);

Просмотреть файл

@ -88,10 +88,7 @@ set_new_current_panel (WPanel *panel)
void
set_hintbar (char *str)
{
g_panel_contents *gp;
gp = (g_panel_contents *) current_panel_ptr->panel->widget.wdata;
gtk_label_set (GTK_LABEL (gp->status), str);
gtk_label_set (GTK_LABEL (current_panel_ptr->panel->status), str);
}
void

Просмотреть файл

@ -178,15 +178,7 @@ x_panel_container_show (widget_data wdata)
void
x_focus_widget (Widget_Item *p)
{
/* Ok, ultra hack again: the top-level containers dont have regular
* widgets in p->widget->wdata, but a g_panel_contents in there
*/
if (((void *)p->widget->callback) == ((void *)panel_callback)){
g_panel_contents *g = (g_panel_contents *) p->widget->wdata;
gtk_widget_grab_focus (GTK_WIDGET (g->list));
} else
gtk_widget_grab_focus (GTK_WIDGET (p->widget->wdata));
gtk_widget_grab_focus (GTK_WIDGET (p->widget->wdata));
}
void
@ -224,8 +216,8 @@ x_init_dlg (Dlg_head *h)
void
x_destroy_dlg (Dlg_head *h)
{
printf ("me llaman!\n");
gtk_grab_remove (GTK_WIDGET (GTK_BIN (h->wdata)->child));
if (!(h->grided & DLG_NO_TED))
gtk_grab_remove (GTK_WIDGET (GTK_BIN (h->wdata)->child));
gtk_widget_destroy (GTK_WIDGET(h->wdata));
}
@ -280,3 +272,4 @@ create_panels (void)
set_current_panel (0);
run_dlg (h);
}

Просмотреть файл

@ -7,3 +7,7 @@
- Menu organization
- Intenrationalization
- All of the dialogs.
Possibly make a way to bind a toplevel widget to the Dlg_head part of the
system so that grab_add/ungrab and the widget destruction reuse all of that
code for NON_TED dialogs.

Просмотреть файл

@ -82,10 +82,9 @@ panel_file_list_set_row_colors (GtkCList *cl, int row, int color_pair)
void
x_fill_panel (WPanel *panel)
{
g_panel_contents *g = (g_panel_contents *) panel->widget.wdata;
const int top = panel->count;
const int items = panel->format->items;
GtkCList *cl = GTK_CLIST (g->list);
GtkCList *cl = GTK_CLIST (panel->list);
int i, col, type_col, color;
char **texts;
@ -169,8 +168,7 @@ static int will_select;
void
x_select_item (WPanel *panel)
{
g_panel_contents *g = (g_panel_contents *) panel->widget.wdata;
GtkCList *clist = GTK_CLIST (g->list);
GtkCList *clist = GTK_CLIST (panel->list);
if (will_select)
return;
@ -184,31 +182,26 @@ x_select_item (WPanel *panel)
void
x_unselect_item (WPanel *panel)
{
g_panel_contents *g = (g_panel_contents *) panel->widget.wdata;
gtk_clist_unselect_row (GTK_CLIST (g->list), panel->selected, 0);
gtk_clist_unselect_row (GTK_CLIST (panel->list), panel->selected, 0);
}
void
x_filter_changed (WPanel *panel)
{
g_panel_contents *g = (g_panel_contents *) panel->widget.wdata;
if (panel->filter){
char *string;
string = g_copy_strings ("Filter: ", panel->filter, NULL);
gtk_label_set (GTK_LABEL (g->filter), string);
gtk_label_set (GTK_LABEL (panel->filter), string);
g_free (string);
} else
gtk_label_set (GTK_LABEL (g->filter), "No filter");
gtk_label_set (GTK_LABEL (panel->filter), "No filter");
}
void
x_adjust_top_file (WPanel *panel)
{
g_panel_contents *g = (g_panel_contents *) panel->widget.wdata;
gtk_clist_moveto (GTK_CLIST (g->list), panel->top_file, 0, 0.0, 0.0);
gtk_clist_moveto (GTK_CLIST (panel->list), panel->top_file, 0, 0.0, 0.0);
}
#define COLUMN_INSET 3
@ -788,56 +781,55 @@ panel_create_filter (WPanel *panel, GtkWidget **label)
void
x_create_panel (Dlg_head *h, widget_data parent, WPanel *panel)
{
g_panel_contents *g = g_new (g_panel_contents, 1);
GtkWidget *status_line, *filter_w, *statusbar, *vbox;
g->table = gtk_table_new (2, 1, 0);
gtk_widget_show (g->table);
panel->table = gtk_table_new (2, 1, 0);
gtk_widget_show (panel->table);
g->list = panel_create_file_list (panel);
gtk_widget_show (g->list);
panel->list = panel_create_file_list (panel);
gtk_widget_show (panel->list);
g->current_dir = panel_create_cwd (panel);
gtk_widget_show (g->current_dir);
panel->current_dir = panel_create_cwd (panel);
gtk_widget_show (panel->current_dir);
filter_w = panel_create_filter (panel, &g->filter);
filter_w = panel_create_filter (panel, &panel->filter_w);
gtk_widget_show (filter_w);
status_line = gtk_hbox_new (0, 0);
gtk_widget_show (status_line);
gtk_box_pack_start (GTK_BOX (status_line), g->current_dir, 0, 0, 0);
gtk_box_pack_start (GTK_BOX (status_line), panel->current_dir, 0, 0, 0);
gtk_box_pack_end (GTK_BOX (status_line), filter_w, 0, 0, 0);
g->status = statusbar = gtk_label_new ("");
panel->status = statusbar = gtk_label_new ("");
gtk_widget_show (statusbar);
gtk_table_attach (GTK_TABLE (g->table), g->list, 0, 1, 1, 2,
gtk_table_attach (GTK_TABLE (panel->table), panel->list, 0, 1, 1, 2,
GTK_EXPAND | GTK_FILL | GTK_SHRINK,
GTK_EXPAND | GTK_FILL | GTK_SHRINK,
0, 0);
gtk_table_attach (GTK_TABLE (g->table), status_line, 0, 1, 0, 1,
gtk_table_attach (GTK_TABLE (panel->table), status_line, 0, 1, 0, 1,
GTK_EXPAND | GTK_FILL, GTK_SHRINK, 0, 0);
gtk_table_attach (GTK_TABLE (g->table), statusbar, 0, 1, 2, 3,
gtk_table_attach (GTK_TABLE (panel->table), statusbar, 0, 1, 2, 3,
GTK_EXPAND | GTK_FILL | GTK_SHRINK,
0, 0, 0);
gtk_widget_show (g->table);
gtk_widget_show (panel->table);
/* Ultra nasty hack: pull the vbox from wdata */
vbox = GTK_WIDGET (panel->widget.wdata);
panel->widget.wdata = (widget_data) g;
panel->widget.wdata = (widget_data) panel->table;
/* Now, insert our table in our parent */
gtk_container_add (GTK_CONTAINER (vbox), g->table);
gtk_container_add (GTK_CONTAINER (vbox), panel->table);
if (!pixmaps_ready){
if (!GTK_WIDGET_REALIZED (g->list))
gtk_widget_realize (g->list);
panel_create_pixmaps (g->list);
if (!GTK_WIDGET_REALIZED (panel->list))
gtk_widget_realize (panel->list);
panel_create_pixmaps (panel->list);
}
}

Просмотреть файл

@ -9,14 +9,6 @@ void x_add_sort_label (WPanel *panel, int index, char *text, char *tag, void *sr
void x_sort_label_start (WPanel *panel);
void x_reset_sort_labels (WPanel *panel);
typedef struct {
GtkWidget *table;
GtkWidget *list;
GtkWidget *current_dir;
GtkWidget *filter;
GtkWidget *status;
} g_panel_contents;
WPanel *create_container (Dlg_head *h, char *str);
typedef struct {

Просмотреть файл

@ -1,6 +1,12 @@
/*
* (C) 1998 the Free Software Foundation
*
* Written by Miguel de Icaza
*/
#include "util.h"
#include <gnome.h>
#include <gdk/gdkkeysyms.h>
#include "gconf.h"
#include "myslang.h"
#include "dlg.h"
#undef HAVE_LIBGPM
@ -9,6 +15,7 @@
#include "widget.h"
#include "wtools.h"
#include "dialog.h"
#include "color.h"
static int sel_pos;
@ -17,47 +24,79 @@ void query_set_sel (int new_sel)
sel_pos = new_sel;
}
static void
pack_button (WButton *button, GtkBox *box)
{
if (!button)
return;
gtk_box_pack_start_defaults (GTK_BOX (box), GTK_WIDGET (button->widget.wdata));
}
int query_dialog (char *header, char *text, int flags, int count, ...)
{
va_list ap;
Dlg_head *h;
WLabel *label;
GtkDialog *dialog;
GtkWidget *label, *focus_widget;
int i;
GList *list;
int i, result = -1;
va_start (ap, count);
h = create_dlg (0, 0, 0, 0, dialog_colors, default_dlg_callback, "[QueryBox]", "query",
DLG_NO_TED);
dialog = GTK_DIALOG (gtk_dialog_new ());
label = gtk_label_new (text);
gtk_widget_show (label);
x_set_dialog_title (h, header);
label = label_new (0, 0, text, NULL);
add_widget (h, label);
if (flags & D_ERROR)
fprintf (stderr, "Messagebox: this should be displayed like an error\n");
gtk_container_add (GTK_CONTAINER (dialog->vbox), label);
gtk_container_border_width (GTK_CONTAINER (dialog->vbox), 5);
va_start (ap, count);
list = g_list_alloc ();
for (i = 0; i < count; i++){
GtkWidget *button;
WButton *button;
char *cur_name = va_arg (ap, char *);
button = gtk_button_new_with_label (cur_name);
gtk_widget_show (button);
button = button_new (0, 0, B_USER+i, NORMAL_BUTTON, cur_name, 0, 0, NULL);
gtk_box_pack_start_defaults (GTK_BOX (GTK_DIALOG (dialog)->action_area), button);
add_widget (h, button);
list = g_list_append (list, button);
if (i == sel_pos){
focus_widget = button;
}
if (i == sel_pos)
h->initfocus = h->current;
}
if (focus_widget)
gtk_widget_grab_focus (focus_widget);
va_end (ap);
/* Init the widgets */
init_dlg (h);
gtk_grab_add (dialog);
/* Now do the GTK stuff */
gtk_container_add (GTK_CONTAINER (dialog->vbox), GTK_WIDGET (label->widget.wdata));
gtk_container_border_width (GTK_CONTAINER (dialog->vbox), 5);
g_list_foreach (list, (GFunc) pack_button, dialog->action_area);
g_list_free (list);
gtk_widget_show (GTK_WIDGET (dialog));
gtk_grab_add (GTK_WIDGET (dialog));
gtk_main ();
gtk_grab_remove (GTK_WIDGET (dialog));
frontend_run_dlg (h);
dlg_run_done (h);
gtk_grab_remove (dialog);
gtk_widget_destroy (dialog);
switch (h->ret_value){
case B_CANCEL:
break;
default:
result = h->ret_value - B_USER;
}
destroy_dlg (h);
sel_pos = 0;
return result;
}
/* To show nice messages to the users */

276
gnome/gtrans.c Обычный файл
Просмотреть файл

@ -0,0 +1,276 @@
/* Module for creating a shaped window with text (for desktop icons)
*
* Copyright (C) 1998 the Free Software Foundation
*
* Author: Federico Mena <federico@nuclecu.unam.mx>
*/
#include <gnome.h>
#include <string.h>
#include "gdesktop.h"
/* The spacing between the cute little icon and the text */
#define SPACING 2
/*
* Most of this code was yanked from the gtktooltips module in Gtk+.
* I have tweaked it a bit for MC's purposes - Federico
*/
struct text_info {
GList *rows;
GdkFont *font;
int width;
int height;
int baseline_skip;
};
static void
free_string (gpointer data, gpointer user_data)
{
if (data)
g_free (data);
}
static void
text_info_free (struct text_info *ti)
{
g_list_foreach (ti->rows, free_string, NULL);
g_list_free (ti->rows);
g_free (ti);
}
static struct text_info *
layout_text (GtkWidget *widget, char *text)
{
struct text_info *ti;
char *row_end, *row_text, *break_pos;
int i, row_width, window_width;
size_t len;
ti = g_new (struct text_info, 1);
ti->rows = NULL;
ti->font = widget->style->font;
ti->width = 0;
ti->height = 0;
ti->baseline_skip = ti->font->ascent + ti->font->descent;
window_width = 0;
while (*text) {
row_end = strchr (text, '\n');
if (!row_end)
row_end = strchr (text, '\0');
len = row_end - text + 1;
row_text = g_new (char, len);
memcpy (row_text, text, len - 1);
row_text[len - 1] = '\0';
/* Adjust the window's width or shorten the row until
* it fits in the window.
*/
while (1) {
row_width = gdk_string_width (ti->font, row_text);
if (!window_width) {
/* make an initial guess at window's width */
if (row_width > (gdk_screen_width () / 12))
window_width = gdk_screen_width () / 12;
else
window_width = row_width;
}
if (row_width <= window_width)
break;
if (strchr (row_text, ' ')) {
/* the row is currently too wide, but we have
* blanks in the row so we can break it into
* smaller pieces
*/
int avg_width = row_width / strlen (row_text);
i = window_width;
if (avg_width != 0)
i /= avg_width;
if ((size_t) i >= len)
i = len - 1;
break_pos = strchr (row_text + i, ' ');
if (!break_pos) {
break_pos = row_text+ i;
while (*--break_pos != ' ');
}
*break_pos = '\0';
} else {
/* We can't break this row into any smaller
* pieces, so we have no choice but to widen
* the window
*
* For MC, we may want to modify the code above
* so that it can also split the string on the
* slahes of filenames.
*/
window_width = row_width;
break;
}
}
if (row_width > ti->width)
ti->width = row_width;
ti->rows = g_list_append (ti->rows, row_text);
ti->height += ti->baseline_skip;
text += strlen (row_text);
if (!*text)
break;
if (text[0] == '\n' && text[1]) {
/* end of paragraph and there is more text to come */
ti->rows = g_list_append (ti->rows, NULL);
ti->height += ti->baseline_skip / 2;
}
text++; /* skip blank or newline */
}
return ti;
}
static void
paint_text (struct text_info *ti, GdkDrawable *drawable, GdkGC *gc, int x_ofs, int y_ofs)
{
int y, w;
GList *item;
y = y_ofs + ti->font->ascent;
for (item = ti->rows; item; item = item->next) {
if (item->data) {
w = gdk_string_width (ti->font, item->data);
gdk_draw_string (drawable, ti->font, gc, x_ofs + (ti->width - w) / 2, y, item->data);
y += ti->baseline_skip;
} else
y += ti->baseline_skip / 2;
}
}
static void
set_window_text (GtkWidget *window, GdkImlibImage *im, char *text)
{
GdkPixmap *pixmap;
GdkPixmap *im_pixmap;
GdkBitmap *mask;
GdkBitmap *im_mask;
struct text_info *ti;
GdkColor color;
GdkGC *gc;
int width, height;
ti = layout_text (window, text);
width = MAX (ti->width, im->rgb_width);
height = im->rgb_height + SPACING + ti->height;
/* pixmap */
pixmap = gdk_pixmap_new (window->window, width, height, gdk_imlib_get_visual ()->depth);
gc = gdk_gc_new (pixmap);
gdk_color_white (gdk_imlib_get_colormap (), &color);
gdk_gc_set_foreground (gc, &color);
gdk_draw_rectangle (pixmap, gc, TRUE, 0, 0, width, height);
im_pixmap = gdk_imlib_move_image (im);
gdk_window_copy_area (pixmap, gc,
(width - im->rgb_width) / 2,
0,
im_pixmap,
0, 0,
im->rgb_width, im->rgb_height);
gdk_imlib_free_pixmap (im_pixmap);
/* mask */
mask = gdk_pixmap_new (window->window, width, height, 1);
gc = gdk_gc_new (mask);
color.pixel = 0;
gdk_gc_set_foreground (gc, &color);
gdk_draw_rectangle (mask, gc, TRUE, 0, 0, width, height);
im_mask = gdk_imlib_move_mask (im);
if (im_mask) {
gdk_window_copy_area (mask, gc,
(width - im->rgb_width) / 2,
0,
im_mask,
0, 0,
im->rgb_width, im->rgb_height);
gdk_imlib_free_bitmap (im_mask);
}
color.pixel = 1;
gdk_gc_set_foreground (gc, &color);
paint_text (ti, mask, gc,
(width - ti->width) / 2,
im->rgb_height + SPACING);
gdk_gc_destroy (gc);
/* set contents */
gtk_widget_set_usize (window, width, height);
gdk_window_set_back_pixmap (window->window, pixmap, FALSE);
gdk_window_shape_combine_mask (window->window, mask, 0, 0);
gdk_pixmap_unref (pixmap);
gdk_pixmap_unref (mask);
text_info_free (ti);
}
GtkWidget *
create_transparent_text_window (char *file, char *text, int extra_events)
{
GtkWidget *window;
GdkImlibImage *im;
if (!g_file_exists (file))
return NULL;
im = gdk_imlib_load_image (file);
if (!im)
return NULL;
gtk_widget_push_visual (gdk_imlib_get_visual ());
gtk_widget_push_colormap (gdk_imlib_get_colormap ());
window = gtk_window_new (GTK_WINDOW_POPUP);
gtk_widget_set_events (window, gtk_widget_get_events (window) | extra_events);
gtk_widget_pop_colormap ();
gtk_widget_pop_visual ();
gtk_widget_realize (window);
gdk_imlib_render (im, im->rgb_width, im->rgb_height);
set_window_text (window, im, text);
gdk_imlib_destroy_image (im);
return window;
}

87
gnome/gutil.c Обычный файл
Просмотреть файл

@ -0,0 +1,87 @@
/* Various utilities - Unix variants
Copyright (C) 1998 the Free Software Foundation.
Written 1998 by:
Miguel de Icaza
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <fcntl.h>
#include <signal.h> /* my_system */
#include <limits.h> /* INT_MAX */
#include <sys/time.h> /* select: timeout */
#include <sys/param.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdarg.h>
#ifdef HAVE_SYS_WAIT_H
# include <sys/wait.h> /* my_system */
#endif
#include <errno.h> /* my_system */
#include <pwd.h>
#include <grp.h>
#include <string.h>
#include <ctype.h>
#ifdef HAVE_SYS_SELECT_H
# include <sys/select.h>
#endif
int my_system (int as_shell_command, const char *shell, const char *command)
{
struct sigaction ignore, save_intr, save_quit, save_stop;
pid_t pid;
int status = 0;
ignore.sa_handler = SIG_IGN;
sigemptyset (&ignore.sa_mask);
ignore.sa_flags = 0;
sigaction (SIGINT, &ignore, &save_intr);
sigaction (SIGQUIT, &ignore, &save_quit);
if ((pid = fork ()) < 0){
fprintf (stderr, "\n\nfork () = -1\n");
return -1;
}
if (pid == 0){
sigaction (SIGINT, &save_intr, NULL);
sigaction (SIGQUIT, &save_quit, NULL);
if (as_shell_command)
execl (shell, shell, "-c", command, (char *) 0);
else
execlp (shell, shell, command, (char *) 0);
_exit (127); /* Exec error */
}
sigaction (SIGINT, &save_intr, NULL);
sigaction (SIGQUIT, &save_quit, NULL);
sigaction (SIGTSTP, &save_stop, NULL);
#ifdef SCO_FLAVOR
waitpid(-1, NULL, WNOHANG);
#endif /* SCO_FLAVOR */
return WEXITSTATUS(status);
}