delorie.com/archives/browse.cgi   search  
Mail Archives: cygwin/2011/03/21/19:06:10

X-Recipient: archive-cygwin AT delorie DOT com
X-SWARE-Spam-Status: No, hits=-0.9 required=5.0 tests=BAYES_00,RCVD_IN_DNSWL_NONE,SARE_OBFUFCK2
X-Spam-Check-By: sourceware.org
Message-ID: <4D87D9A9.8080202@chezcox.net>
Date: Mon, 21 Mar 2011 17:05:13 -0600
From: Chuck Cox <chuck AT chezcox DOT net>
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.15) Gecko/20110303 Thunderbird/3.1.9
MIME-Version: 1.0
To: cygwin AT cygwin DOT com
Subject: ioctl problem with pconsole
Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm
List-Id: <cygwin.cygwin.com>
List-Subscribe: <mailto:cygwin-subscribe AT cygwin DOT com>
List-Archive: <http://sourceware.org/ml/cygwin/>
List-Post: <mailto:cygwin AT cygwin DOT com>
List-Help: <mailto:cygwin-help AT cygwin DOT com>, <http://sourceware.org/ml/#faqs>
Sender: cygwin-owner AT cygwin DOT com
Mail-Followup-To: cygwin AT cygwin DOT com
Delivered-To: mailing list cygwin AT cygwin DOT com

--------------000604020703090706020800
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit

I'm trying to compile pconsole (from http://www.heiho.net/pconsole/) on 
Cygwin 1.7.8 with the standard gcc 4.3.4 compiler. I have compiled many 
things before on Solaris and Linux, but this is my first adventure with 
Cygwin.  :-)

First off, you have to add "#define TIOCSTI 0x5412" to pconsole.c as 
mentioned on the author's webpage above. I also commented out lines 
186-189 of pconsole.c because it's checking to see if your euid is zero, 
which doesn't really exist in Cygwin. It wants to be installed setuid 
root on most UNIX flavors...

With the euid check commented out, the pconsole.exe binary runs and will 
attach to a tty, but as soon as you try to type something it detaches 
and says "ioctl() : Invalid argument".

There's only one call to ioctl() on line 162 of pconsole.c:
	if (ioctl(c->fd, TIOCSTI, &kar) == -1) {

I'm guessing that it's failing due to the way Cygwin implements ttys as 
pipes and/or maybe the value of TIOCSTI given above just doesn't work on 
Cygwin.

Anyone have a suggestion here?


Thanks,
Chuck

--------------000604020703090706020800
Content-Type: text/plain;
 name="pconsole.c"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
 filename="pconsole.c"

/*
    pconsole WJ101
    Copyright (C) 2001  Walter de Jong <walter AT heiho DOT net>

    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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/
/*
	pconsole.c	WJ101
*/

#include "config.h"
#include "pconsole.h"
#include "commands.h"
#include "cstring.h"
#include "terminal.h"
#include "Conn.h"

#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <signal.h>
#include <sys/stat.h>
#include <sys/types.h>

#ifdef HAVE_SYS_IOCTL_H
#include <sys/ioctl.h>
#endif

#define KEY_CTRL(x)		((x) - 'A' + 1)

int flags = FLAGS_ECHO;

void command_mode(void) {
char buf[256], *p;

	terminal_mode(TERMINAL_COOKED);
	printf("\n"
		"pconsole command mode\n"
		">>> ");
	fflush(stdout);

	flags |= FLAGS_CMD_MODE;

	while((p = fgets(buf, 256, stdin)) != NULL) {
		cstrip_line(buf);
		if (*buf)
			pcommand(buf);

		if (flags & FLAGS_CMD_MODE) {
			if (*buf)
				printf("\n");
			printf(">>> ");
			fflush(stdout);
		} else
			break;
	}
	if (p == NULL) {
		if (AllConns == NULL) {
			printf("\n\n");
			terminal_mode(TERMINAL_COOKED);
			exit(0);
		} else
			printf("<Ctrl-D>\n");
	}
	flags &= ~FLAGS_CMD_MODE;

	printf("\n"
		"Press <Ctlr-A> for command mode\n"
		"> ");
	fflush(stdout);
	terminal_mode(TERMINAL_RAW);
}

void pconsole(void) {
int key, typed = 0;
char kar;
Conn *c, *c_next;

	if (AllConns == NULL)
		command_mode();										/* start in command mode */
	else {
		printf("\n"
			"Press <Ctlr-A> for command mode\n"
			"> ");
		fflush(stdout);
		terminal_mode(TERMINAL_RAW);
	}
	while(read(fileno(stdin), &kar, 1) > 0) {
		key = kar & 0xff;
		if (key == 1) {										/* Ctrl-A => command mode */
			printf("<Ctrl-A>\n");
			command_mode();
			continue;
		}
		if (key == KEY_CTRL('S')) {							/* Ctrl-S => toggle echo */
			printf("<Ctrl-S> ");
			cmd_echo(NULL);

			printf("> ");
			fflush(stdout);
			typed = 0;
			continue;
		}
		if (key == '\r' || key == '\n') {					/* return */
			printf("\n> ");
			fflush(stdout);
			typed = 0;
		} else {
			if (flags & FLAGS_ECHO) {
				if (key == 0x7f || key == '\b') {			/* backspace */
					if (typed) {
						printf("\b \b");
						fflush(stdout);
						typed--;
					}
				} else {
					if (key >= ' ' && key <= '~') {
						fputc(key, stdout);
						typed++;
					} else {
						switch(key) {
							case 0x1b:
								printf("<Esc>");
								break;

							case '\t':
								printf("<Tab>");
								break;

							default:
								printf("<Ctrl-%c>", key - 1 + 'A');
						}
						printf("\n> ");
						typed = 0;
					}
					fflush(stdout);
				}
			}
		}
/*
	put character in everyones input buffer
*/
		for(c = AllConns; c != NULL; c = c_next) {
			c_next = c->next;

			if (c->fd > 0) {
				seteuid(0);											/* regain root privs */
				if (ioctl(c->fd, TIOCSTI, &kar) == -1) {			/* simulate terminal input */
					seteuid(getuid());								/* drop root privs again */
					printf("\nioctl() : %s\n", strerror(errno));
					if (c->hostname != NULL)
						printf("detaching from %s#%s\n", c->hostname, c->dev);
					else
						printf("detaching from %s\n", c->dev);
					remove_Conn(c);
					destroy_Conn(c);
				} else
					seteuid(getuid());								/* drop the root privs */
			}
		}
		if (AllConns == NULL)
			command_mode();
	}
}

RETSIGTYPE sig_exit(int sig) {
	cmd_exit(NULL);
	exit(127 + sig);				/* never reached... but hey */
}

int main(int argc, char **argv) {
	if (geteuid()) {
		fprintf(stderr, "You must be root to run this program or this program should be setuid root.\n");
		return -1;
	}
	if (seteuid(getuid())) {				/* drop root privs */
		fprintf(stderr, "failed to drop root privileges\n");
		exit(-1);
	}
	if (!isatty(fileno(stdin))) {
		fprintf(stderr, "pconsole: not a tty\n");
		return -1;
	}
	printf("pconsole WJ101\n");

	signal(SIGTERM, sig_exit);
	signal(SIGINT, sig_exit);

	if (argc > 1)
		cmd_attach(&argv[1]);

	pconsole();
	cmd_exit(NULL);
	return 0;
}

/* EOB */


--------------000604020703090706020800
Content-Type: text/plain; charset=us-ascii

--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
--------------000604020703090706020800--

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019