Merge branch '1897_libc_respect_return_values'
* 1897_libc_respect_return_values: Final Indentation of all touched files Changes into src/consaver directory: Changes into src/editor directory: Changes into src directory: Ticket #1897: Build breaks on ignored return values
Этот коммит содержится в:
Коммит
3b375cc2d3
14
lib/util.c
14
lib/util.c
@ -1241,6 +1241,7 @@ mc_util_write_backup_content (const char *from_file_name, const char *to_file_na
|
||||
FILE *backup_fd;
|
||||
char *contents;
|
||||
gsize length;
|
||||
gboolean ret1 = TRUE;
|
||||
|
||||
if (!g_file_get_contents (from_file_name, &contents, &length, NULL))
|
||||
return FALSE;
|
||||
@ -1252,12 +1253,15 @@ mc_util_write_backup_content (const char *from_file_name, const char *to_file_na
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
fwrite ((const void *) contents, length, 1, backup_fd);
|
||||
|
||||
fflush (backup_fd);
|
||||
fclose (backup_fd);
|
||||
if (fwrite ((const void *) contents, length, 1, backup_fd) != length)
|
||||
ret1 = FALSE;
|
||||
{
|
||||
int ret2;
|
||||
ret2 = fflush (backup_fd);
|
||||
ret2 = fclose (backup_fd);
|
||||
}
|
||||
g_free (contents);
|
||||
return TRUE;
|
||||
return ret1;
|
||||
}
|
||||
|
||||
/* Finds out a relative path from first to second, i.e. goes as many ..
|
||||
|
904
lib/utilunix.c
904
lib/utilunix.c
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
@ -1261,8 +1261,10 @@ vfs_s_get_line (struct vfs_class *me, int sock, char *buf, int buf_len, char ter
|
||||
return 0;
|
||||
if (logfile)
|
||||
{
|
||||
fwrite (buf, 1, 1, logfile);
|
||||
fflush (logfile);
|
||||
size_t ret1;
|
||||
int ret2;
|
||||
ret1 = fwrite (buf, 1, 1, logfile);
|
||||
ret2 = fflush (logfile);
|
||||
}
|
||||
if (*buf == term)
|
||||
{
|
||||
@ -1277,8 +1279,10 @@ vfs_s_get_line (struct vfs_class *me, int sock, char *buf, int buf_len, char ter
|
||||
{
|
||||
if (logfile)
|
||||
{
|
||||
fwrite (&c, 1, 1, logfile);
|
||||
fflush (logfile);
|
||||
size_t ret1;
|
||||
int ret2;
|
||||
ret1 = fwrite (&c, 1, 1, logfile);
|
||||
ret2 = fflush (logfile);
|
||||
}
|
||||
if (c == '\n')
|
||||
return 1;
|
||||
|
@ -597,8 +597,7 @@ extfs_which (struct vfs_class *me, const char *path)
|
||||
info = &g_array_index (extfs_plugins, extfs_plugin_info_t, i);
|
||||
|
||||
if ((strncmp (path, info->prefix, path_len) == 0)
|
||||
&& ((info->prefix[path_len] == '\0')
|
||||
|| (info->prefix[path_len] == '+')))
|
||||
&& ((info->prefix[path_len] == '\0') || (info->prefix[path_len] == '+')))
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
@ -706,7 +705,7 @@ extfs_resolve_symlinks_int (struct entry *entry, GSList * list)
|
||||
|
||||
looping = g_slist_prepend (list, entry);
|
||||
pent = extfs_find_entry_int (entry->dir, entry->inode->linkname, looping, FALSE, FALSE);
|
||||
g_slist_delete_link (looping, looping);
|
||||
looping = g_slist_delete_link (looping, looping);
|
||||
|
||||
if (pent == NULL)
|
||||
my_errno = ENOENT;
|
||||
|
@ -159,8 +159,9 @@ fish_command (struct vfs_class *me, struct vfs_s_super *super, int wait_reply, c
|
||||
|
||||
if (logfile)
|
||||
{
|
||||
fwrite (str, strlen (str), 1, logfile);
|
||||
fflush (logfile);
|
||||
size_t ret;
|
||||
ret = fwrite (str, strlen (str), 1, logfile);
|
||||
ret = fflush (logfile);
|
||||
}
|
||||
|
||||
tty_enable_interrupt_key ();
|
||||
@ -217,15 +218,13 @@ fish_pipeopen (struct vfs_s_super *super, const char *path, const char *argv[])
|
||||
}
|
||||
else
|
||||
{
|
||||
close (0);
|
||||
dup (fileset1[0]);
|
||||
res = dup2 (fileset1[0], 0);
|
||||
close (fileset1[0]);
|
||||
close (fileset1[1]);
|
||||
close (1);
|
||||
res = dup2 (fileset2[1], 1);
|
||||
close (2);
|
||||
dup (fileset2[1]);
|
||||
/* stderr to /dev/null */
|
||||
open ("/dev/null", O_WRONLY);
|
||||
res = open ("/dev/null", O_WRONLY);
|
||||
close (fileset2[0]);
|
||||
close (fileset2[1]);
|
||||
execvp (path, const_cast (char **, argv));
|
||||
@ -294,7 +293,6 @@ fish_open_archive_int (struct vfs_class *me, struct vfs_s_super *super)
|
||||
print_vfs_message ("%s", answer);
|
||||
if (strstr (answer, "assword"))
|
||||
{
|
||||
|
||||
/* Currently, this does not work. ssh reads passwords from
|
||||
/dev/tty, not from stdin :-(. */
|
||||
|
||||
@ -312,8 +310,16 @@ fish_open_archive_int (struct vfs_class *me, struct vfs_s_super *super)
|
||||
SUP.password = op;
|
||||
}
|
||||
print_vfs_message (_("fish: Sending password..."));
|
||||
write (SUP.sockw, SUP.password, strlen (SUP.password));
|
||||
write (SUP.sockw, "\n", 1);
|
||||
|
||||
{
|
||||
size_t str_len;
|
||||
str_len = strlen (SUP.password);
|
||||
if ((write (SUP.sockw, SUP.password, str_len) != (ssize_t) str_len)
|
||||
|| (write (SUP.sockw, "\n", 1) != 1))
|
||||
{
|
||||
ERRNOR (EIO, -1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -757,6 +763,7 @@ fish_file_store (struct vfs_class *me, struct vfs_s_fh *fh, char *name, char *lo
|
||||
|
||||
/* FIXME: File size is limited to ULONG_MAX */
|
||||
if (!fh->u.fish.append)
|
||||
{
|
||||
/* *INDENT-OFF* */
|
||||
n = fish_command (me, super, WAIT_REPLY,
|
||||
"#STOR %lu /%s\n"
|
||||
@ -781,7 +788,9 @@ fish_file_store (struct vfs_class *me, struct vfs_s_fh *fh, char *name, char *lo
|
||||
(unsigned long) s.st_size, quoted_name,
|
||||
quoted_name, (unsigned long) s.st_size, (unsigned long) s.st_size);
|
||||
/* *INDENT-ON* */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* *INDENT-OFF* */
|
||||
n = fish_command (me, super, WAIT_REPLY,
|
||||
"#STOR %lu /%s\n"
|
||||
@ -799,7 +808,7 @@ fish_file_store (struct vfs_class *me, struct vfs_s_fh *fh, char *name, char *lo
|
||||
(unsigned long) s.st_size, quoted_name,
|
||||
quoted_name, (unsigned long) s.st_size);
|
||||
/* *INDENT-ON* */
|
||||
|
||||
}
|
||||
if (n != PRELIM)
|
||||
{
|
||||
close (h);
|
||||
@ -1024,8 +1033,8 @@ fish_send_command (struct vfs_class *me, struct vfs_s_super *super, const char *
|
||||
static int
|
||||
fish_chmod (struct vfs_class *me, const char *path, int mode)
|
||||
{
|
||||
PREFIX
|
||||
/* *INDENT-OFF* */
|
||||
PREFIX
|
||||
g_snprintf (buf, sizeof (buf),
|
||||
"#CHMOD %4.4o /%s\n"
|
||||
"if chmod %4.4o /%s 2>/dev/null; then\n"
|
||||
@ -1034,10 +1043,11 @@ fish_chmod (struct vfs_class *me, const char *path, int mode)
|
||||
"echo '### 500'\n"
|
||||
"fi\n",
|
||||
mode & 07777, rpath, mode & 07777, rpath);
|
||||
/* *INDENT-ON* */
|
||||
POSTFIX (OPT_FLUSH);
|
||||
/* *INDENT-ON* */
|
||||
}
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
#define FISH_OP(name, string) \
|
||||
static int fish_##name (struct vfs_class *me, const char *path1, const char *path2) \
|
||||
{ \
|
||||
@ -1066,7 +1076,6 @@ static int fish_##name (struct vfs_class *me, const char *path1, const char *pat
|
||||
return fish_send_command(me, super2, buf, OPT_FLUSH); \
|
||||
}
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
FISH_OP (rename,
|
||||
"#RENAME /%s /%s\n"
|
||||
"if mv /%s /%s 2>/dev/null; then\n"
|
||||
@ -1119,8 +1128,8 @@ fish_chown (struct vfs_class *me, const char *path, int owner, int group)
|
||||
sowner = pw->pw_name;
|
||||
sgroup = gr->gr_name;
|
||||
{
|
||||
PREFIX
|
||||
/* *INDENT-OFF* */
|
||||
PREFIX
|
||||
g_snprintf (buf, sizeof (buf),
|
||||
"#CHOWN %s:%s /%s\n"
|
||||
"if chown %s:%s /%s 2>/dev/null; then\n"
|
||||
@ -1139,9 +1148,9 @@ fish_chown (struct vfs_class *me, const char *path, int owner, int group)
|
||||
static int
|
||||
fish_unlink (struct vfs_class *me, const char *path)
|
||||
{
|
||||
/* *INDENT-OFF* */
|
||||
PREFIX
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
g_snprintf (buf, sizeof (buf),
|
||||
"#DELE /%s\n"
|
||||
"if rm -f /%s 2>/dev/null; then\n"
|
||||
@ -1158,9 +1167,9 @@ fish_unlink (struct vfs_class *me, const char *path)
|
||||
static int
|
||||
fish_exists (struct vfs_class *me, const char *path)
|
||||
{
|
||||
/* *INDENT-OFF* */
|
||||
PREFIX
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
g_snprintf (buf, sizeof (buf),
|
||||
"#ISEXISTS /%s\n"
|
||||
"ls -l /%s >/dev/null 2>/dev/null\n"
|
||||
@ -1182,9 +1191,9 @@ fish_mkdir (struct vfs_class *me, const char *path, mode_t mode)
|
||||
{
|
||||
int ret_code;
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
PREFIX (void) mode;
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
g_snprintf (buf, sizeof (buf),
|
||||
"#MKD /%s\n"
|
||||
"if mkdir /%s 2>/dev/null; then\n"
|
||||
@ -1211,8 +1220,8 @@ fish_mkdir (struct vfs_class *me, const char *path, mode_t mode)
|
||||
static int
|
||||
fish_rmdir (struct vfs_class *me, const char *path)
|
||||
{
|
||||
PREFIX
|
||||
/* *INDENT-OFF* */
|
||||
PREFIX
|
||||
g_snprintf (buf, sizeof (buf),
|
||||
"#RMD /%s\n"
|
||||
"if rmdir /%s 2>/dev/null; then\n"
|
||||
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
@ -1,12 +1,12 @@
|
||||
/* Low-level protocol for MCFS.
|
||||
|
||||
|
||||
Copyright (C) 1995, 1996 Miguel de Icaza
|
||||
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library 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
|
||||
@ -51,12 +51,12 @@
|
||||
#include <errno.h>
|
||||
|
||||
#include "lib/global.h"
|
||||
#include "src/wtools.h" /* message() */
|
||||
#include "src/main.h" /* print_vfs_message */
|
||||
#include "src/wtools.h" /* message() */
|
||||
#include "src/main.h" /* print_vfs_message */
|
||||
#include "utilvfs.h"
|
||||
#include "mcfsutil.h"
|
||||
#include "netutil.h"
|
||||
#include "mcfs.h" /* tcp_invalidate_socket() */
|
||||
#include "mcfs.h" /* tcp_invalidate_socket() */
|
||||
|
||||
#define CHECK_SIG_PIPE(sock) if (got_sigpipe) \
|
||||
{ tcp_invalidate_socket (sock); return got_sigpipe = 0; }
|
||||
@ -68,13 +68,15 @@ socket_read_block (int sock, char *dest, int len)
|
||||
{
|
||||
int nread, n;
|
||||
|
||||
for (nread = 0; nread < len;) {
|
||||
n = read (sock, dest + nread, len - nread);
|
||||
if (n <= 0) {
|
||||
tcp_invalidate_socket (sock);
|
||||
return 0;
|
||||
}
|
||||
nread += n;
|
||||
for (nread = 0; nread < len;)
|
||||
{
|
||||
n = read (sock, dest + nread, len - nread);
|
||||
if (n <= 0)
|
||||
{
|
||||
tcp_invalidate_socket (sock);
|
||||
return 0;
|
||||
}
|
||||
nread += n;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@ -84,13 +86,14 @@ socket_write_block (int sock, const char *buffer, int len)
|
||||
{
|
||||
int left, status;
|
||||
|
||||
for (left = len; left > 0;) {
|
||||
status = write (sock, buffer, left);
|
||||
CHECK_SIG_PIPE (sock);
|
||||
if (status < 0)
|
||||
return 0;
|
||||
left -= status;
|
||||
buffer += status;
|
||||
for (left = len; left > 0;)
|
||||
{
|
||||
status = write (sock, buffer, left);
|
||||
CHECK_SIG_PIPE (sock);
|
||||
if (status < 0)
|
||||
return 0;
|
||||
left -= status;
|
||||
buffer += status;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@ -104,40 +107,58 @@ rpc_send (int sock, ...)
|
||||
|
||||
va_start (ap, sock);
|
||||
|
||||
for (;;) {
|
||||
cmd = va_arg (ap, int);
|
||||
switch (cmd) {
|
||||
case RPC_END:
|
||||
va_end (ap);
|
||||
return 1;
|
||||
for (;;)
|
||||
{
|
||||
cmd = va_arg (ap, int);
|
||||
switch (cmd)
|
||||
{
|
||||
case RPC_END:
|
||||
va_end (ap);
|
||||
return 1;
|
||||
|
||||
case RPC_INT:
|
||||
tmp = htonl (va_arg (ap, int));
|
||||
write (sock, &tmp, sizeof (tmp));
|
||||
CHECK_SIG_PIPE (sock);
|
||||
break;
|
||||
case RPC_INT:
|
||||
tmp = htonl (va_arg (ap, int));
|
||||
if (write (sock, &tmp, sizeof (tmp)) != sizeof (tmp))
|
||||
{
|
||||
vfs_die ("RPC: write failed (RPC_INT)");
|
||||
break;
|
||||
}
|
||||
CHECK_SIG_PIPE (sock);
|
||||
break;
|
||||
|
||||
case RPC_STRING:
|
||||
text = va_arg (ap, char *);
|
||||
len = strlen (text);
|
||||
tmp = htonl (len);
|
||||
write (sock, &tmp, sizeof (tmp));
|
||||
CHECK_SIG_PIPE (sock);
|
||||
write (sock, text, len);
|
||||
CHECK_SIG_PIPE (sock);
|
||||
break;
|
||||
case RPC_STRING:
|
||||
text = va_arg (ap, char *);
|
||||
len = strlen (text);
|
||||
tmp = htonl (len);
|
||||
if (write (sock, &tmp, sizeof (tmp)) != sizeof (tmp))
|
||||
{
|
||||
vfs_die ("RPC: write failed (RPC_STRING)");
|
||||
break;
|
||||
}
|
||||
CHECK_SIG_PIPE (sock);
|
||||
if (write (sock, text, len) != len)
|
||||
{
|
||||
vfs_die ("RPC: write failed (RPC_STRING)");
|
||||
break;
|
||||
}
|
||||
CHECK_SIG_PIPE (sock);
|
||||
break;
|
||||
|
||||
case RPC_BLOCK:
|
||||
len = va_arg (ap, int);
|
||||
text = va_arg (ap, char *);
|
||||
tmp = htonl (len);
|
||||
write (sock, text, len);
|
||||
CHECK_SIG_PIPE (sock);
|
||||
break;
|
||||
case RPC_BLOCK:
|
||||
len = va_arg (ap, int);
|
||||
text = va_arg (ap, char *);
|
||||
tmp = htonl (len);
|
||||
if (write (sock, text, len) != len)
|
||||
{
|
||||
vfs_die ("RPC: write failed (RPC_BLOCK)");
|
||||
break;
|
||||
}
|
||||
CHECK_SIG_PIPE (sock);
|
||||
break;
|
||||
|
||||
default:
|
||||
vfs_die ("Unknown rpc message\n");
|
||||
}
|
||||
default:
|
||||
vfs_die ("Unknown rpc message\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -151,63 +172,70 @@ rpc_get (int sock, ...)
|
||||
|
||||
va_start (ap, sock);
|
||||
|
||||
for (;;) {
|
||||
cmd = va_arg (ap, int);
|
||||
switch (cmd) {
|
||||
case RPC_END:
|
||||
va_end (ap);
|
||||
return 1;
|
||||
for (;;)
|
||||
{
|
||||
cmd = va_arg (ap, int);
|
||||
switch (cmd)
|
||||
{
|
||||
case RPC_END:
|
||||
va_end (ap);
|
||||
return 1;
|
||||
|
||||
case RPC_INT:
|
||||
if (socket_read_block (sock, (char *) &tmp, sizeof (tmp)) == 0) {
|
||||
va_end (ap);
|
||||
return 0;
|
||||
}
|
||||
dest = va_arg (ap, int *);
|
||||
*dest = ntohl (tmp);
|
||||
break;
|
||||
case RPC_INT:
|
||||
if (socket_read_block (sock, (char *) &tmp, sizeof (tmp)) == 0)
|
||||
{
|
||||
va_end (ap);
|
||||
return 0;
|
||||
}
|
||||
dest = va_arg (ap, int *);
|
||||
*dest = ntohl (tmp);
|
||||
break;
|
||||
|
||||
/* returns an allocated string */
|
||||
case RPC_LIMITED_STRING:
|
||||
case RPC_STRING:
|
||||
if (socket_read_block (sock, (char *) &tmp, sizeof (tmp)) == 0) {
|
||||
va_end (ap);
|
||||
return 0;
|
||||
}
|
||||
len = ntohl (tmp);
|
||||
if (cmd == RPC_LIMITED_STRING)
|
||||
if (len > 16 * 1024) {
|
||||
/* silently die */
|
||||
abort ();
|
||||
}
|
||||
if (len > 128 * 1024)
|
||||
abort ();
|
||||
/* returns an allocated string */
|
||||
case RPC_LIMITED_STRING:
|
||||
case RPC_STRING:
|
||||
if (socket_read_block (sock, (char *) &tmp, sizeof (tmp)) == 0)
|
||||
{
|
||||
va_end (ap);
|
||||
return 0;
|
||||
}
|
||||
len = ntohl (tmp);
|
||||
if (cmd == RPC_LIMITED_STRING)
|
||||
if (len > 16 * 1024)
|
||||
{
|
||||
/* silently die */
|
||||
abort ();
|
||||
}
|
||||
if (len > 128 * 1024)
|
||||
abort ();
|
||||
|
||||
/* Don't use glib functions here - this code is used by mcserv */
|
||||
text = malloc (len + 1);
|
||||
if (socket_read_block (sock, text, len) == 0) {
|
||||
free (text);
|
||||
va_end (ap);
|
||||
return 0;
|
||||
}
|
||||
text[len] = '\0';
|
||||
/* Don't use glib functions here - this code is used by mcserv */
|
||||
text = malloc (len + 1);
|
||||
if (socket_read_block (sock, text, len) == 0)
|
||||
{
|
||||
free (text);
|
||||
va_end (ap);
|
||||
return 0;
|
||||
}
|
||||
text[len] = '\0';
|
||||
|
||||
str_dest = va_arg (ap, char **);
|
||||
*str_dest = text;
|
||||
break;
|
||||
str_dest = va_arg (ap, char **);
|
||||
*str_dest = text;
|
||||
break;
|
||||
|
||||
case RPC_BLOCK:
|
||||
len = va_arg (ap, int);
|
||||
text = va_arg (ap, char *);
|
||||
if (socket_read_block (sock, text, len) == 0) {
|
||||
va_end (ap);
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case RPC_BLOCK:
|
||||
len = va_arg (ap, int);
|
||||
text = va_arg (ap, char *);
|
||||
if (socket_read_block (sock, text, len) == 0)
|
||||
{
|
||||
va_end (ap);
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
vfs_die ("Unknown rpc message\n");
|
||||
}
|
||||
default:
|
||||
vfs_die ("Unknown rpc message\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* ENABLE_VFS_MCFS || ENABLE_MCSERVER */
|
||||
#endif /* ENABLE_VFS_MCFS || ENABLE_MCSERVER */
|
||||
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
514
src/background.c
514
src/background.c
@ -3,14 +3,14 @@
|
||||
/* Background support.
|
||||
Copyright (C) 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
|
||||
Written by: 1996 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
|
||||
@ -39,18 +39,19 @@
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h> /* waitpid() */
|
||||
#include <sys/wait.h> /* waitpid() */
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "lib/global.h"
|
||||
#include "background.h"
|
||||
#include "wtools.h"
|
||||
#include "layout.h" /* repaint_screen() */
|
||||
#include "fileopctx.h" /* FileOpContext */
|
||||
#include "lib/tty/key.h" /* add_select_channel(), delete_select_channel() */
|
||||
#include "layout.h" /* repaint_screen() */
|
||||
#include "fileopctx.h" /* FileOpContext */
|
||||
#include "lib/tty/key.h" /* add_select_channel(), delete_select_channel() */
|
||||
|
||||
enum ReturnType {
|
||||
enum ReturnType
|
||||
{
|
||||
Return_String,
|
||||
Return_Integer
|
||||
};
|
||||
@ -64,26 +65,25 @@ static int parent_fd;
|
||||
/* File descriptor for messages from our parent */
|
||||
static int from_parent_fd;
|
||||
|
||||
#define MAXCALLARGS 4 /* Number of arguments supported */
|
||||
#define MAXCALLARGS 4 /* Number of arguments supported */
|
||||
|
||||
struct TaskList *task_list = NULL;
|
||||
|
||||
static int background_attention (int fd, void *closure);
|
||||
|
||||
|
||||
static void
|
||||
register_task_running (FileOpContext *ctx, pid_t pid, int fd, int to_child,
|
||||
char *info)
|
||||
register_task_running (FileOpContext * ctx, pid_t pid, int fd, int to_child, char *info)
|
||||
{
|
||||
TaskList *new;
|
||||
|
||||
new = g_new (TaskList, 1);
|
||||
new->pid = pid;
|
||||
new->info = info;
|
||||
new->pid = pid;
|
||||
new->info = info;
|
||||
new->state = Task_Running;
|
||||
new->next = task_list;
|
||||
new->fd = fd;
|
||||
new->next = task_list;
|
||||
new->fd = fd;
|
||||
new->to_child_fd = to_child;
|
||||
task_list = new;
|
||||
task_list = new;
|
||||
|
||||
add_select_channel (fd, background_attention, ctx);
|
||||
}
|
||||
@ -94,18 +94,20 @@ destroy_task_and_return_fd (pid_t pid)
|
||||
TaskList *p = task_list;
|
||||
TaskList *prev = 0;
|
||||
|
||||
while (p){
|
||||
if (p->pid == pid){
|
||||
if (prev)
|
||||
prev->next = p->next;
|
||||
else
|
||||
task_list = p->next;
|
||||
g_free (p->info);
|
||||
g_free (p);
|
||||
return p->fd;
|
||||
}
|
||||
prev = p;
|
||||
p = p->next;
|
||||
while (p)
|
||||
{
|
||||
if (p->pid == pid)
|
||||
{
|
||||
if (prev)
|
||||
prev->next = p->next;
|
||||
else
|
||||
task_list = p->next;
|
||||
g_free (p->info);
|
||||
g_free (p);
|
||||
return p->fd;
|
||||
}
|
||||
prev = p;
|
||||
p = p->next;
|
||||
}
|
||||
|
||||
/* pid not found */
|
||||
@ -115,16 +117,16 @@ destroy_task_and_return_fd (pid_t pid)
|
||||
void
|
||||
unregister_task_running (pid_t pid, int fd)
|
||||
{
|
||||
destroy_task_and_return_fd(pid);
|
||||
destroy_task_and_return_fd (pid);
|
||||
delete_select_channel (fd);
|
||||
}
|
||||
|
||||
void
|
||||
unregister_task_with_pid (pid_t pid)
|
||||
{
|
||||
int fd = destroy_task_and_return_fd(pid);
|
||||
int fd = destroy_task_and_return_fd (pid);
|
||||
if (fd != -1)
|
||||
delete_select_channel (fd);
|
||||
delete_select_channel (fd);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -138,51 +140,56 @@ unregister_task_with_pid (pid_t pid)
|
||||
int
|
||||
do_background (struct FileOpContext *ctx, char *info)
|
||||
{
|
||||
int comm[2]; /* control connection stream */
|
||||
int back_comm[2]; /* back connection */
|
||||
int comm[2]; /* control connection stream */
|
||||
int back_comm[2]; /* back connection */
|
||||
pid_t pid;
|
||||
|
||||
if (pipe (comm) == -1)
|
||||
return -1;
|
||||
return -1;
|
||||
|
||||
if (pipe (back_comm) == -1)
|
||||
return -1;
|
||||
return -1;
|
||||
|
||||
if ((pid = fork ()) == -1) {
|
||||
int saved_errno = errno;
|
||||
(void) close (comm[0]);
|
||||
(void) close (comm[1]);
|
||||
(void) close (back_comm[0]);
|
||||
(void) close (back_comm[1]);
|
||||
errno = saved_errno;
|
||||
return -1;
|
||||
if ((pid = fork ()) == -1)
|
||||
{
|
||||
int saved_errno = errno;
|
||||
(void) close (comm[0]);
|
||||
(void) close (comm[1]);
|
||||
(void) close (back_comm[0]);
|
||||
(void) close (back_comm[1]);
|
||||
errno = saved_errno;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (pid == 0) {
|
||||
int nullfd;
|
||||
if (pid == 0)
|
||||
{
|
||||
int nullfd;
|
||||
|
||||
parent_fd = comm[1];
|
||||
from_parent_fd = back_comm[0];
|
||||
parent_fd = comm[1];
|
||||
from_parent_fd = back_comm[0];
|
||||
|
||||
we_are_background = 1;
|
||||
current_dlg = NULL;
|
||||
we_are_background = 1;
|
||||
current_dlg = NULL;
|
||||
|
||||
/* Make stdin/stdout/stderr point somewhere */
|
||||
close (0);
|
||||
close (1);
|
||||
close (2);
|
||||
/* Make stdin/stdout/stderr point somewhere */
|
||||
close (0);
|
||||
close (1);
|
||||
close (2);
|
||||
|
||||
if ((nullfd = open ("/dev/null", O_RDWR)) != -1) {
|
||||
while (dup2 (nullfd, 0) == -1 && errno == EINTR);
|
||||
while (dup2 (nullfd, 1) == -1 && errno == EINTR);
|
||||
while (dup2 (nullfd, 2) == -1 && errno == EINTR);
|
||||
}
|
||||
if ((nullfd = open ("/dev/null", O_RDWR)) != -1)
|
||||
{
|
||||
while (dup2 (nullfd, 0) == -1 && errno == EINTR);
|
||||
while (dup2 (nullfd, 1) == -1 && errno == EINTR);
|
||||
while (dup2 (nullfd, 2) == -1 && errno == EINTR);
|
||||
}
|
||||
|
||||
return 0;
|
||||
} else {
|
||||
ctx->pid = pid;
|
||||
register_task_running (ctx, pid, comm[0], back_comm[1], info);
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
ctx->pid = pid;
|
||||
register_task_running (ctx, pid, comm[0], back_comm[1], info);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
@ -231,174 +238,211 @@ background_attention (int fd, void *closure)
|
||||
{
|
||||
FileOpContext *ctx;
|
||||
int have_ctx;
|
||||
union
|
||||
union
|
||||
{
|
||||
int (*have_ctx0)(int);
|
||||
int (*have_ctx1)(int, char *);
|
||||
int (*have_ctx2)(int, char *, char *);
|
||||
int (*have_ctx3)(int, char *, char *, char *);
|
||||
int (*have_ctx4)(int, char *, char *, char *, char *);
|
||||
int (*have_ctx0) (int);
|
||||
int (*have_ctx1) (int, char *);
|
||||
int (*have_ctx2) (int, char *, char *);
|
||||
int (*have_ctx3) (int, char *, char *, char *);
|
||||
int (*have_ctx4) (int, char *, char *, char *, char *);
|
||||
|
||||
int (*non_have_ctx0)(FileOpContext *, int);
|
||||
int (*non_have_ctx1)(FileOpContext *, int, char *);
|
||||
int (*non_have_ctx2)(FileOpContext *, int, char *, char *);
|
||||
int (*non_have_ctx3)(FileOpContext *, int, char *, char *, char *);
|
||||
int (*non_have_ctx4)(FileOpContext *, int, char *, char *, char *, char *);
|
||||
int (*non_have_ctx0) (FileOpContext *, int);
|
||||
int (*non_have_ctx1) (FileOpContext *, int, char *);
|
||||
int (*non_have_ctx2) (FileOpContext *, int, char *, char *);
|
||||
int (*non_have_ctx3) (FileOpContext *, int, char *, char *, char *);
|
||||
int (*non_have_ctx4) (FileOpContext *, int, char *, char *, char *, char *);
|
||||
|
||||
char * (*ret_str0)();
|
||||
char * (*ret_str1)(char *);
|
||||
char * (*ret_str2)(char *, char *);
|
||||
char * (*ret_str3)(char *, char *, char *);
|
||||
char * (*ret_str4)(char *, char *, char *, char *);
|
||||
char *(*ret_str0) ();
|
||||
char *(*ret_str1) (char *);
|
||||
char *(*ret_str2) (char *, char *);
|
||||
char *(*ret_str3) (char *, char *, char *);
|
||||
char *(*ret_str4) (char *, char *, char *, char *);
|
||||
|
||||
void *pointer;
|
||||
void *pointer;
|
||||
} routine;
|
||||
/* void *routine;*/
|
||||
int argc, i, result, status;
|
||||
char *data [MAXCALLARGS];
|
||||
ssize_t bytes;
|
||||
struct TaskList *p;
|
||||
int to_child_fd = -1;
|
||||
/* void *routine; */
|
||||
int argc, i, result, status;
|
||||
char *data[MAXCALLARGS];
|
||||
ssize_t bytes, ret;
|
||||
struct TaskList *p;
|
||||
int to_child_fd = -1;
|
||||
enum ReturnType type;
|
||||
|
||||
ctx = closure;
|
||||
|
||||
bytes = read (fd, &routine.pointer, sizeof (routine));
|
||||
if (bytes == -1 || (size_t) bytes < (sizeof (routine))) {
|
||||
const char *background_process_error = _(" Background process error ");
|
||||
if (bytes == -1 || (size_t) bytes < (sizeof (routine)))
|
||||
{
|
||||
const char *background_process_error = _(" Background process error ");
|
||||
|
||||
unregister_task_running (ctx->pid, fd);
|
||||
if (!waitpid (ctx->pid, &status, WNOHANG)) {
|
||||
/* the process is still running, but it misbehaves - kill it */
|
||||
kill (ctx->pid, SIGTERM);
|
||||
message (D_ERROR, background_process_error, _(" Unknown error in child "));
|
||||
return 0;
|
||||
}
|
||||
unregister_task_running (ctx->pid, fd);
|
||||
if (!waitpid (ctx->pid, &status, WNOHANG))
|
||||
{
|
||||
/* the process is still running, but it misbehaves - kill it */
|
||||
kill (ctx->pid, SIGTERM);
|
||||
message (D_ERROR, background_process_error, _(" Unknown error in child "));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* 0 means happy end */
|
||||
if (WIFEXITED (status) && (WEXITSTATUS (status) == 0))
|
||||
return 0;
|
||||
/* 0 means happy end */
|
||||
if (WIFEXITED (status) && (WEXITSTATUS (status) == 0))
|
||||
return 0;
|
||||
|
||||
message (D_ERROR, background_process_error, _(" Child died unexpectedly "));
|
||||
message (D_ERROR, background_process_error, _(" Child died unexpectedly "));
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
read (fd, &argc, sizeof (argc));
|
||||
if (argc > MAXCALLARGS){
|
||||
message (D_ERROR, _(" Background protocol error "),
|
||||
_(" Background process sent us a request for more arguments \n"
|
||||
" than we can handle. \n"));
|
||||
if ((read (fd, &argc, sizeof (argc)) != sizeof (argc)) ||
|
||||
(read (fd, &type, sizeof (type)) != sizeof (type)) ||
|
||||
(read (fd, &have_ctx, sizeof (have_ctx)) != sizeof (have_ctx)))
|
||||
{
|
||||
message (D_ERROR, _(" Background protocol error "), _("Reading failed"));
|
||||
return 0;
|
||||
}
|
||||
read (fd, &type, sizeof (type));
|
||||
read (fd, &have_ctx, sizeof (have_ctx));
|
||||
|
||||
if (argc > MAXCALLARGS)
|
||||
{
|
||||
message (D_ERROR, _(" Background protocol error "),
|
||||
_(" Background process sent us a request for more arguments \n"
|
||||
" than we can handle. \n"));
|
||||
}
|
||||
|
||||
if (have_ctx)
|
||||
read (fd, ctx, sizeof (FileOpContext));
|
||||
|
||||
for (i = 0; i < argc; i++){
|
||||
int size;
|
||||
|
||||
read (fd, &size, sizeof (size));
|
||||
data [i] = g_malloc (size+1);
|
||||
read (fd, data [i], size);
|
||||
|
||||
data [i][size] = 0; /* NULL terminate the blocks (they could be strings) */
|
||||
{
|
||||
if (read (fd, ctx, sizeof (FileOpContext)) != sizeof (FileOpContext))
|
||||
{
|
||||
message (D_ERROR, _(" Background protocol error "), _("Reading failed"));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Find child task info by descriptor */
|
||||
/* Find before call, because process can destroy self after */
|
||||
for (p = task_list; p; p = p->next) {
|
||||
if (p->fd == fd)
|
||||
break;
|
||||
}
|
||||
for (i = 0; i < argc; i++)
|
||||
{
|
||||
int size;
|
||||
|
||||
if (p) to_child_fd = p->to_child_fd;
|
||||
if (read (fd, &size, sizeof (size)) != sizeof (size))
|
||||
{
|
||||
message (D_ERROR, _(" Background protocol error "), _("Reading failed"));
|
||||
return 0;
|
||||
}
|
||||
data[i] = g_malloc (size + 1);
|
||||
if (read (fd, data[i], size) != size)
|
||||
{
|
||||
message (D_ERROR, _(" Background protocol error "), _("Reading failed"));
|
||||
return 0;
|
||||
}
|
||||
data[i][size] = 0; /* NULL terminate the blocks (they could be strings) */
|
||||
}
|
||||
|
||||
/* Find child task info by descriptor */
|
||||
/* Find before call, because process can destroy self after */
|
||||
for (p = task_list; p; p = p->next)
|
||||
{
|
||||
if (p->fd == fd)
|
||||
break;
|
||||
}
|
||||
|
||||
if (p)
|
||||
to_child_fd = p->to_child_fd;
|
||||
|
||||
if (to_child_fd == -1)
|
||||
message (D_ERROR, _(" Background process error "), _(" Unknown error in child "));
|
||||
message (D_ERROR, _(" Background process error "), _(" Unknown error in child "));
|
||||
|
||||
/* Handle the call */
|
||||
if (type == Return_Integer){
|
||||
if (!have_ctx)
|
||||
switch (argc){
|
||||
case 0:
|
||||
result = routine.have_ctx0 (Background);
|
||||
break;
|
||||
case 1:
|
||||
result = routine.have_ctx1 (Background, data [0]);
|
||||
break;
|
||||
case 2:
|
||||
result = routine.have_ctx2 (Background, data [0], data [1]);
|
||||
break;
|
||||
case 3:
|
||||
result = routine.have_ctx3 (Background, data [0], data [1], data [2]);
|
||||
break;
|
||||
case 4:
|
||||
result = routine.have_ctx4 (Background, data [0], data [1], data [2], data [3]);
|
||||
break;
|
||||
}
|
||||
else
|
||||
switch (argc){
|
||||
case 0:
|
||||
result = routine.non_have_ctx0 (ctx, Background);
|
||||
break;
|
||||
case 1:
|
||||
result = routine.non_have_ctx1 (ctx, Background, data [0]);
|
||||
break;
|
||||
case 2:
|
||||
result = routine.non_have_ctx2 (ctx, Background, data [0], data [1]);
|
||||
break;
|
||||
case 3:
|
||||
result = routine.non_have_ctx3 (ctx, Background, data [0], data [1], data [2]);
|
||||
break;
|
||||
case 4:
|
||||
result = routine.non_have_ctx4 (ctx, Background, data [0], data [1], data [2], data [3]);
|
||||
break;
|
||||
}
|
||||
if (type == Return_Integer)
|
||||
{
|
||||
if (!have_ctx)
|
||||
switch (argc)
|
||||
{
|
||||
case 0:
|
||||
result = routine.have_ctx0 (Background);
|
||||
break;
|
||||
case 1:
|
||||
result = routine.have_ctx1 (Background, data[0]);
|
||||
break;
|
||||
case 2:
|
||||
result = routine.have_ctx2 (Background, data[0], data[1]);
|
||||
break;
|
||||
case 3:
|
||||
result = routine.have_ctx3 (Background, data[0], data[1], data[2]);
|
||||
break;
|
||||
case 4:
|
||||
result = routine.have_ctx4 (Background, data[0], data[1], data[2], data[3]);
|
||||
break;
|
||||
}
|
||||
else
|
||||
switch (argc)
|
||||
{
|
||||
case 0:
|
||||
result = routine.non_have_ctx0 (ctx, Background);
|
||||
break;
|
||||
case 1:
|
||||
result = routine.non_have_ctx1 (ctx, Background, data[0]);
|
||||
break;
|
||||
case 2:
|
||||
result = routine.non_have_ctx2 (ctx, Background, data[0], data[1]);
|
||||
break;
|
||||
case 3:
|
||||
result = routine.non_have_ctx3 (ctx, Background, data[0], data[1], data[2]);
|
||||
break;
|
||||
case 4:
|
||||
result =
|
||||
routine.non_have_ctx4 (ctx, Background, data[0], data[1], data[2], data[3]);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Send the result code and the value for shared variables */
|
||||
write (to_child_fd, &result, sizeof (int));
|
||||
if (have_ctx && to_child_fd != -1)
|
||||
write (to_child_fd, ctx, sizeof (FileOpContext));
|
||||
} else if (type == Return_String) {
|
||||
int len;
|
||||
char *resstr = NULL;
|
||||
/* Send the result code and the value for shared variables */
|
||||
ret = write (to_child_fd, &result, sizeof (int));
|
||||
if (have_ctx && to_child_fd != -1)
|
||||
ret = write (to_child_fd, ctx, sizeof (FileOpContext));
|
||||
}
|
||||
else if (type == Return_String)
|
||||
{
|
||||
int len;
|
||||
char *resstr = NULL;
|
||||
|
||||
/* FIXME: string routines should also use the Foreground/Background
|
||||
* parameter. Currently, this is not used here
|
||||
*/
|
||||
switch (argc){
|
||||
case 0:
|
||||
resstr = routine.ret_str0 ();
|
||||
break;
|
||||
case 1:
|
||||
resstr = routine.ret_str1 (data [0]);
|
||||
break;
|
||||
case 2:
|
||||
resstr = routine.ret_str2 (data [0], data [1]);
|
||||
break;
|
||||
case 3:
|
||||
resstr = routine.ret_str3 (data [0], data [1], data [2]);
|
||||
break;
|
||||
case 4:
|
||||
resstr = routine.ret_str4 (data [0], data [1], data [2], data [3]);
|
||||
break;
|
||||
default: g_assert_not_reached();
|
||||
}
|
||||
if (resstr){
|
||||
len = strlen (resstr);
|
||||
write (to_child_fd, &len, sizeof (len));
|
||||
if (len){
|
||||
write (to_child_fd, resstr, len);
|
||||
g_free (resstr);
|
||||
}
|
||||
} else {
|
||||
len = 0;
|
||||
write (to_child_fd, &len, sizeof (len));
|
||||
}
|
||||
/* FIXME: string routines should also use the Foreground/Background
|
||||
* parameter. Currently, this is not used here
|
||||
*/
|
||||
switch (argc)
|
||||
{
|
||||
case 0:
|
||||
resstr = routine.ret_str0 ();
|
||||
break;
|
||||
case 1:
|
||||
resstr = routine.ret_str1 (data[0]);
|
||||
break;
|
||||
case 2:
|
||||
resstr = routine.ret_str2 (data[0], data[1]);
|
||||
break;
|
||||
case 3:
|
||||
resstr = routine.ret_str3 (data[0], data[1], data[2]);
|
||||
break;
|
||||
case 4:
|
||||
resstr = routine.ret_str4 (data[0], data[1], data[2], data[3]);
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
if (resstr)
|
||||
{
|
||||
len = strlen (resstr);
|
||||
ret = write (to_child_fd, &len, sizeof (len));
|
||||
if (len)
|
||||
{
|
||||
write (to_child_fd, resstr, len);
|
||||
}
|
||||
g_free (resstr);
|
||||
}
|
||||
else
|
||||
{
|
||||
len = 0;
|
||||
ret = write (to_child_fd, &len, sizeof (len));
|
||||
}
|
||||
}
|
||||
for (i = 0; i < argc; i++)
|
||||
g_free (data [i]);
|
||||
g_free (data[i]);
|
||||
|
||||
repaint_screen ();
|
||||
return 0;
|
||||
@ -414,19 +458,20 @@ background_attention (int fd, void *closure)
|
||||
* the call be a file operation context.
|
||||
*/
|
||||
static void
|
||||
parent_call_header (void *routine, int argc, enum ReturnType type, FileOpContext *ctx)
|
||||
parent_call_header (void *routine, int argc, enum ReturnType type, FileOpContext * ctx)
|
||||
{
|
||||
int have_ctx;
|
||||
ssize_t ret;
|
||||
|
||||
have_ctx = (ctx != NULL);
|
||||
|
||||
write (parent_fd, &routine, sizeof (routine));
|
||||
write (parent_fd, &argc, sizeof (int));
|
||||
write (parent_fd, &type, sizeof (type));
|
||||
write (parent_fd, &have_ctx, sizeof (have_ctx));
|
||||
ret = write (parent_fd, &routine, sizeof (routine));
|
||||
ret = write (parent_fd, &argc, sizeof (int));
|
||||
ret = write (parent_fd, &type, sizeof (type));
|
||||
ret = write (parent_fd, &have_ctx, sizeof (have_ctx));
|
||||
|
||||
if (have_ctx)
|
||||
write (parent_fd, ctx, sizeof (FileOpContext));
|
||||
ret = write (parent_fd, ctx, sizeof (FileOpContext));
|
||||
}
|
||||
|
||||
int
|
||||
@ -434,22 +479,24 @@ parent_call (void *routine, struct FileOpContext *ctx, int argc, ...)
|
||||
{
|
||||
va_list ap;
|
||||
int i;
|
||||
ssize_t ret;
|
||||
|
||||
va_start (ap, argc);
|
||||
parent_call_header (routine, argc, Return_Integer, ctx);
|
||||
for (i = 0; i < argc; i++) {
|
||||
int len;
|
||||
void *value;
|
||||
for (i = 0; i < argc; i++)
|
||||
{
|
||||
int len;
|
||||
void *value;
|
||||
|
||||
len = va_arg (ap, int);
|
||||
value = va_arg (ap, void *);
|
||||
write (parent_fd, &len, sizeof (int));
|
||||
write (parent_fd, value, len);
|
||||
len = va_arg (ap, int);
|
||||
value = va_arg (ap, void *);
|
||||
ret = write (parent_fd, &len, sizeof (int));
|
||||
ret = write (parent_fd, value, len);
|
||||
}
|
||||
|
||||
read (from_parent_fd, &i, sizeof (int));
|
||||
ret = read (from_parent_fd, &i, sizeof (int));
|
||||
if (ctx)
|
||||
read (from_parent_fd, ctx, sizeof (FileOpContext));
|
||||
ret = read (from_parent_fd, ctx, sizeof (FileOpContext));
|
||||
|
||||
return i;
|
||||
}
|
||||
@ -460,25 +507,32 @@ parent_call_string (void *routine, int argc, ...)
|
||||
va_list ap;
|
||||
char *str;
|
||||
int i;
|
||||
|
||||
|
||||
va_start (ap, argc);
|
||||
parent_call_header (routine, argc, Return_String, NULL);
|
||||
for (i = 0; i < argc; i++){
|
||||
int len;
|
||||
void *value;
|
||||
for (i = 0; i < argc; i++)
|
||||
{
|
||||
int len;
|
||||
void *value;
|
||||
|
||||
len = va_arg (ap, int);
|
||||
value = va_arg (ap, void *);
|
||||
write (parent_fd, &len, sizeof (int));
|
||||
write (parent_fd, value, len);
|
||||
len = va_arg (ap, int);
|
||||
value = va_arg (ap, void *);
|
||||
if ((write (parent_fd, &len, sizeof (int)) != sizeof (int)) ||
|
||||
(write (parent_fd, value, len) != len))
|
||||
return NULL;
|
||||
}
|
||||
read (from_parent_fd, &i, sizeof (int));
|
||||
if (read (from_parent_fd, &i, sizeof (int)) != sizeof (int))
|
||||
return NULL;
|
||||
if (!i)
|
||||
return NULL;
|
||||
return NULL;
|
||||
str = g_malloc (i + 1);
|
||||
read (from_parent_fd, str, i);
|
||||
str [i] = 0;
|
||||
if (read (from_parent_fd, str, i) != i)
|
||||
{
|
||||
g_free (str);
|
||||
return NULL;
|
||||
}
|
||||
str[i] = 0;
|
||||
return str;
|
||||
}
|
||||
|
||||
#endif /* WITH_BACKGROUND */
|
||||
#endif /* WITH_BACKGROUND */
|
||||
|
@ -1,12 +1,12 @@
|
||||
/* Client interface for General purpose Linux console save/restore server
|
||||
Copyright (C) 1994, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
|
||||
2006, 2007 Free Software Foundation, Inc.
|
||||
|
||||
|
||||
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
|
||||
@ -37,7 +37,7 @@
|
||||
#include "lib/global.h"
|
||||
|
||||
#include "lib/tty/tty.h"
|
||||
#include "lib/skin.h" /* tty_set_normal_attrs */
|
||||
#include "lib/skin.h" /* tty_set_normal_attrs */
|
||||
#include "lib/tty/win.h"
|
||||
|
||||
#include "consaver/cons.saver.h"
|
||||
@ -54,47 +54,49 @@ static int pipefd1[2] = { -1, -1 };
|
||||
static int pipefd2[2] = { -1, -1 };
|
||||
|
||||
static void
|
||||
show_console_contents_linux (int starty, unsigned char begin_line,
|
||||
unsigned char end_line)
|
||||
show_console_contents_linux (int starty, unsigned char begin_line, unsigned char end_line)
|
||||
{
|
||||
unsigned char message = 0;
|
||||
unsigned short bytes = 0;
|
||||
int i;
|
||||
ssize_t ret;
|
||||
|
||||
/* Is tty console? */
|
||||
if (!console_flag)
|
||||
return;
|
||||
return;
|
||||
/* Paranoid: Is the cons.saver still running? */
|
||||
if (cons_saver_pid < 1 || kill (cons_saver_pid, SIGCONT)) {
|
||||
cons_saver_pid = 0;
|
||||
console_flag = 0;
|
||||
return;
|
||||
if (cons_saver_pid < 1 || kill (cons_saver_pid, SIGCONT))
|
||||
{
|
||||
cons_saver_pid = 0;
|
||||
console_flag = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Send command to the console handler */
|
||||
message = CONSOLE_CONTENTS;
|
||||
write (pipefd1[1], &message, 1);
|
||||
ret = write (pipefd1[1], &message, 1);
|
||||
/* Check for outdated cons.saver */
|
||||
read (pipefd2[0], &message, 1);
|
||||
ret = read (pipefd2[0], &message, 1);
|
||||
if (message != CONSOLE_CONTENTS)
|
||||
return;
|
||||
return;
|
||||
|
||||
/* Send the range of lines that we want */
|
||||
write (pipefd1[1], &begin_line, 1);
|
||||
write (pipefd1[1], &end_line, 1);
|
||||
ret = write (pipefd1[1], &begin_line, 1);
|
||||
ret = write (pipefd1[1], &end_line, 1);
|
||||
/* Read the corresponding number of bytes */
|
||||
read (pipefd2[0], &bytes, 2);
|
||||
ret = read (pipefd2[0], &bytes, 2);
|
||||
|
||||
/* Read the bytes and output them */
|
||||
for (i = 0; i < bytes; i++) {
|
||||
if ((i % COLS) == 0)
|
||||
tty_gotoyx (starty + (i / COLS), 0);
|
||||
read (pipefd2[0], &message, 1);
|
||||
tty_print_char (message);
|
||||
for (i = 0; i < bytes; i++)
|
||||
{
|
||||
if ((i % COLS) == 0)
|
||||
tty_gotoyx (starty + (i / COLS), 0);
|
||||
ret = read (pipefd2[0], &message, 1);
|
||||
tty_print_char (message);
|
||||
}
|
||||
|
||||
/* Read the value of the console_flag */
|
||||
read (pipefd2[0], &message, 1);
|
||||
ret = read (pipefd2[0], &message, 1);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -104,91 +106,114 @@ handle_console_linux (unsigned char action)
|
||||
char *mc_conssaver;
|
||||
int status;
|
||||
|
||||
switch (action) {
|
||||
switch (action)
|
||||
{
|
||||
case CONSOLE_INIT:
|
||||
/* Close old pipe ends in case it is the 2nd time we run cons.saver */
|
||||
close (pipefd1[1]);
|
||||
close (pipefd2[0]);
|
||||
/* Create two pipes for communication */
|
||||
pipe (pipefd1);
|
||||
pipe (pipefd2);
|
||||
/* Get the console saver running */
|
||||
cons_saver_pid = fork ();
|
||||
if (cons_saver_pid < 0) {
|
||||
/* Cannot fork */
|
||||
/* Delete pipes */
|
||||
close (pipefd1[1]);
|
||||
close (pipefd1[0]);
|
||||
close (pipefd2[1]);
|
||||
close (pipefd2[0]);
|
||||
console_flag = 0;
|
||||
} else if (cons_saver_pid > 0) {
|
||||
/* Parent */
|
||||
/* Close the extra pipe ends */
|
||||
close (pipefd1[0]);
|
||||
close (pipefd2[1]);
|
||||
/* Was the child successful? */
|
||||
read (pipefd2[0], &console_flag, 1);
|
||||
if (!console_flag) {
|
||||
close (pipefd1[1]);
|
||||
close (pipefd2[0]);
|
||||
waitpid (cons_saver_pid, &status, 0);
|
||||
}
|
||||
} else {
|
||||
/* Child */
|
||||
/* Close the extra pipe ends */
|
||||
close (pipefd1[1]);
|
||||
close (pipefd2[0]);
|
||||
tty_name = ttyname (0);
|
||||
/* Bind the pipe 0 to the standard input */
|
||||
close (0);
|
||||
dup (pipefd1[0]);
|
||||
close (pipefd1[0]);
|
||||
/* Bind the pipe 1 to the standard output */
|
||||
close (1);
|
||||
dup (pipefd2[1]);
|
||||
close (pipefd2[1]);
|
||||
/* Bind standard error to /dev/null */
|
||||
close (2);
|
||||
open ("/dev/null", O_WRONLY);
|
||||
if (tty_name) {
|
||||
/* Exec the console save/restore handler */
|
||||
mc_conssaver = concat_dir_and_file (SAVERDIR, "cons.saver");
|
||||
execl (mc_conssaver, "cons.saver", tty_name, (char *) NULL);
|
||||
}
|
||||
/* Console is not a tty or execl() failed */
|
||||
console_flag = 0;
|
||||
write (1, &console_flag, 1);
|
||||
_exit (3);
|
||||
} /* if (cons_saver_pid ...) */
|
||||
break;
|
||||
/* Close old pipe ends in case it is the 2nd time we run cons.saver */
|
||||
status = close (pipefd1[1]);
|
||||
status = close (pipefd2[0]);
|
||||
/* Create two pipes for communication */
|
||||
if (!((pipe (pipefd1) == 0) && ((pipe (pipefd2)) == 0)))
|
||||
{
|
||||
console_flag = 0;
|
||||
break;
|
||||
}
|
||||
/* Get the console saver running */
|
||||
cons_saver_pid = fork ();
|
||||
if (cons_saver_pid < 0)
|
||||
{
|
||||
/* Cannot fork */
|
||||
/* Delete pipes */
|
||||
status = close (pipefd1[1]);
|
||||
status = close (pipefd1[0]);
|
||||
status = close (pipefd2[1]);
|
||||
status = close (pipefd2[0]);
|
||||
console_flag = 0;
|
||||
}
|
||||
else if (cons_saver_pid > 0)
|
||||
{
|
||||
/* Parent */
|
||||
/* Close the extra pipe ends */
|
||||
status = close (pipefd1[0]);
|
||||
status = close (pipefd2[1]);
|
||||
/* Was the child successful? */
|
||||
status = read (pipefd2[0], &console_flag, 1);
|
||||
if (!console_flag)
|
||||
{
|
||||
pid_t ret;
|
||||
status = close (pipefd1[1]);
|
||||
status = close (pipefd2[0]);
|
||||
ret = waitpid (cons_saver_pid, &status, 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Child */
|
||||
/* Close the extra pipe ends */
|
||||
status = close (pipefd1[1]);
|
||||
status = close (pipefd2[0]);
|
||||
tty_name = ttyname (0);
|
||||
/* Bind the pipe 0 to the standard input */
|
||||
do
|
||||
{
|
||||
if (dup2 (pipefd1[0], 0) == -1)
|
||||
break;
|
||||
status = close (pipefd1[0]);
|
||||
/* Bind the pipe 1 to the standard output */
|
||||
if (dup2 (pipefd2[1], 1) == -1)
|
||||
break;
|
||||
|
||||
status = close (pipefd2[1]);
|
||||
/* Bind standard error to /dev/null */
|
||||
status = open ("/dev/null", O_WRONLY);
|
||||
if (dup2 (status, 2) == -1)
|
||||
break;
|
||||
status = close (status);
|
||||
if (tty_name)
|
||||
{
|
||||
/* Exec the console save/restore handler */
|
||||
mc_conssaver = concat_dir_and_file (SAVERDIR, "cons.saver");
|
||||
execl (mc_conssaver, "cons.saver", tty_name, (char *) NULL);
|
||||
}
|
||||
/* Console is not a tty or execl() failed */
|
||||
}
|
||||
while (0);
|
||||
console_flag = 0;
|
||||
status = write (1, &console_flag, 1);
|
||||
_exit (3);
|
||||
} /* if (cons_saver_pid ...) */
|
||||
break;
|
||||
|
||||
case CONSOLE_DONE:
|
||||
case CONSOLE_SAVE:
|
||||
case CONSOLE_RESTORE:
|
||||
/* Is tty console? */
|
||||
if (!console_flag)
|
||||
return;
|
||||
/* Paranoid: Is the cons.saver still running? */
|
||||
if (cons_saver_pid < 1 || kill (cons_saver_pid, SIGCONT)) {
|
||||
cons_saver_pid = 0;
|
||||
console_flag = 0;
|
||||
return;
|
||||
}
|
||||
/* Send command to the console handler */
|
||||
write (pipefd1[1], &action, 1);
|
||||
if (action != CONSOLE_DONE) {
|
||||
/* Wait the console handler to do its job */
|
||||
read (pipefd2[0], &console_flag, 1);
|
||||
}
|
||||
if (action == CONSOLE_DONE || !console_flag) {
|
||||
/* We are done -> Let's clean up */
|
||||
close (pipefd1[1]);
|
||||
close (pipefd2[0]);
|
||||
waitpid (cons_saver_pid, &status, 0);
|
||||
console_flag = 0;
|
||||
}
|
||||
break;
|
||||
/* Is tty console? */
|
||||
if (!console_flag)
|
||||
return;
|
||||
/* Paranoid: Is the cons.saver still running? */
|
||||
if (cons_saver_pid < 1 || kill (cons_saver_pid, SIGCONT))
|
||||
{
|
||||
cons_saver_pid = 0;
|
||||
console_flag = 0;
|
||||
return;
|
||||
}
|
||||
/* Send command to the console handler */
|
||||
status = write (pipefd1[1], &action, 1);
|
||||
if (action != CONSOLE_DONE)
|
||||
{
|
||||
/* Wait the console handler to do its job */
|
||||
status = read (pipefd2[0], &console_flag, 1);
|
||||
}
|
||||
if (action == CONSOLE_DONE || !console_flag)
|
||||
{
|
||||
/* We are done -> Let's clean up */
|
||||
pid_t ret;
|
||||
close (pipefd1[1]);
|
||||
close (pipefd2[0]);
|
||||
ret = waitpid (cons_saver_pid, &status, 0);
|
||||
console_flag = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -208,18 +233,18 @@ static void
|
||||
console_init (void)
|
||||
{
|
||||
if (console_flag)
|
||||
return;
|
||||
return;
|
||||
|
||||
screen_info.size = sizeof (screen_info);
|
||||
if (ioctl (FD_OUT, CONS_GETINFO, &screen_info) == -1)
|
||||
return;
|
||||
return;
|
||||
|
||||
memset (&screen_shot, 0, sizeof (screen_shot));
|
||||
screen_shot.xsize = screen_info.mv_csz;
|
||||
screen_shot.ysize = screen_info.mv_rsz;
|
||||
screen_shot.buf = g_try_malloc (screen_info.mv_csz * screen_info.mv_rsz * 2);
|
||||
if (screen_shot.buf != NULL)
|
||||
console_flag = 1;
|
||||
console_flag = 1;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -236,7 +261,7 @@ set_attr (unsigned attr)
|
||||
bc = (attr >> 4) & 0xF;
|
||||
|
||||
printf ("\x1B[%d;%d;3%d;4%dm", (bc & 8) ? 5 : 25, (tc & 8) ? 1 : 22,
|
||||
color_map[tc & 7], color_map[bc & 7]);
|
||||
color_map[tc & 7], color_map[bc & 7]);
|
||||
}
|
||||
|
||||
#define cursor_to(x, y) do { \
|
||||
@ -250,15 +275,16 @@ console_restore (void)
|
||||
int i, last;
|
||||
|
||||
if (!console_flag)
|
||||
return;
|
||||
return;
|
||||
|
||||
cursor_to (0, 0);
|
||||
|
||||
/* restoring all content up to cursor position */
|
||||
last = screen_info.mv_row * screen_info.mv_csz + screen_info.mv_col;
|
||||
for (i = 0; i < last; ++i) {
|
||||
set_attr ((screen_shot.buf[i] >> 8) & 0xFF);
|
||||
putc (screen_shot.buf[i] & 0xFF, stdout);
|
||||
for (i = 0; i < last; ++i)
|
||||
{
|
||||
set_attr ((screen_shot.buf[i] >> 8) & 0xFF);
|
||||
putc (screen_shot.buf[i] & 0xFF, stdout);
|
||||
}
|
||||
|
||||
/* restoring cursor color */
|
||||
@ -271,7 +297,7 @@ static void
|
||||
console_shutdown (void)
|
||||
{
|
||||
if (!console_flag)
|
||||
return;
|
||||
return;
|
||||
|
||||
g_free (screen_shot.buf);
|
||||
|
||||
@ -286,94 +312,101 @@ console_save (void)
|
||||
scrmap_t revmap;
|
||||
|
||||
if (!console_flag)
|
||||
return;
|
||||
return;
|
||||
|
||||
/* screen_info.size is already set in console_init() */
|
||||
if (ioctl (FD_OUT, CONS_GETINFO, &screen_info) == -1) {
|
||||
console_shutdown ();
|
||||
return;
|
||||
if (ioctl (FD_OUT, CONS_GETINFO, &screen_info) == -1)
|
||||
{
|
||||
console_shutdown ();
|
||||
return;
|
||||
}
|
||||
|
||||
/* handle console resize */
|
||||
if (screen_info.mv_csz != screen_shot.xsize
|
||||
|| screen_info.mv_rsz != screen_shot.ysize) {
|
||||
console_shutdown ();
|
||||
console_init ();
|
||||
if (screen_info.mv_csz != screen_shot.xsize || screen_info.mv_rsz != screen_shot.ysize)
|
||||
{
|
||||
console_shutdown ();
|
||||
console_init ();
|
||||
}
|
||||
|
||||
if (ioctl (FD_OUT, CONS_SCRSHOT, &screen_shot) == -1) {
|
||||
console_shutdown ();
|
||||
return;
|
||||
if (ioctl (FD_OUT, CONS_SCRSHOT, &screen_shot) == -1)
|
||||
{
|
||||
console_shutdown ();
|
||||
return;
|
||||
}
|
||||
|
||||
if (ioctl (FD_OUT, GIO_SCRNMAP, &map) == -1) {
|
||||
console_shutdown ();
|
||||
return;
|
||||
if (ioctl (FD_OUT, GIO_SCRNMAP, &map) == -1)
|
||||
{
|
||||
console_shutdown ();
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < 256; i++) {
|
||||
char *p = memchr (map.scrmap, i, 256);
|
||||
revmap.scrmap[i] = p ? p - map.scrmap : i;
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
char *p = memchr (map.scrmap, i, 256);
|
||||
revmap.scrmap[i] = p ? p - map.scrmap : i;
|
||||
}
|
||||
|
||||
for (i = 0; i < screen_shot.xsize * screen_shot.ysize; i++) {
|
||||
screen_shot.buf[i] =
|
||||
(screen_shot.buf[i] & 0xff00) | (unsigned char) revmap.
|
||||
scrmap[screen_shot.buf[i] & 0xff];
|
||||
for (i = 0; i < screen_shot.xsize * screen_shot.ysize; i++)
|
||||
{
|
||||
screen_shot.buf[i] =
|
||||
(screen_shot.buf[i] & 0xff00) | (unsigned char) revmap.
|
||||
scrmap[screen_shot.buf[i] & 0xff];
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
show_console_contents_freebsd (int starty, unsigned char begin_line,
|
||||
unsigned char end_line)
|
||||
show_console_contents_freebsd (int starty, unsigned char begin_line, unsigned char end_line)
|
||||
{
|
||||
int col, line;
|
||||
char c;
|
||||
|
||||
if (!console_flag)
|
||||
return;
|
||||
return;
|
||||
|
||||
for (line = begin_line; line <= end_line; line++) {
|
||||
tty_gotoyx (starty + line - begin_line, 0);
|
||||
for (col = 0; col < min (COLS, screen_info.mv_csz); col++) {
|
||||
c = screen_shot.buf[line * screen_info.mv_csz + col] & 0xFF;
|
||||
tty_print_char (c);
|
||||
}
|
||||
for (line = begin_line; line <= end_line; line++)
|
||||
{
|
||||
tty_gotoyx (starty + line - begin_line, 0);
|
||||
for (col = 0; col < min (COLS, screen_info.mv_csz); col++)
|
||||
{
|
||||
c = screen_shot.buf[line * screen_info.mv_csz + col] & 0xFF;
|
||||
tty_print_char (c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
handle_console_freebsd (unsigned char action)
|
||||
{
|
||||
switch (action) {
|
||||
switch (action)
|
||||
{
|
||||
case CONSOLE_INIT:
|
||||
console_init ();
|
||||
break;
|
||||
console_init ();
|
||||
break;
|
||||
|
||||
case CONSOLE_DONE:
|
||||
console_shutdown ();
|
||||
break;
|
||||
console_shutdown ();
|
||||
break;
|
||||
|
||||
case CONSOLE_SAVE:
|
||||
console_save ();
|
||||
break;
|
||||
console_save ();
|
||||
break;
|
||||
|
||||
case CONSOLE_RESTORE:
|
||||
console_restore ();
|
||||
break;
|
||||
console_restore ();
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif /* __FreeBSD__ */
|
||||
#endif /* __FreeBSD__ */
|
||||
|
||||
void
|
||||
show_console_contents (int starty, unsigned char begin_line,
|
||||
unsigned char end_line)
|
||||
show_console_contents (int starty, unsigned char begin_line, unsigned char end_line)
|
||||
{
|
||||
tty_set_normal_attrs ();
|
||||
|
||||
if (look_for_rxvt_extensions ()) {
|
||||
show_rxvt_contents (starty, begin_line, end_line);
|
||||
return;
|
||||
if (look_for_rxvt_extensions ())
|
||||
{
|
||||
show_rxvt_contents (starty, begin_line, end_line);
|
||||
return;
|
||||
}
|
||||
#ifdef __linux__
|
||||
show_console_contents_linux (starty, begin_line, end_line);
|
||||
@ -390,7 +423,7 @@ handle_console (unsigned char action)
|
||||
(void) action;
|
||||
|
||||
if (look_for_rxvt_extensions ())
|
||||
return;
|
||||
return;
|
||||
|
||||
#ifdef __linux__
|
||||
handle_console_linux (action);
|
||||
|
@ -9,12 +9,12 @@
|
||||
This code requires root privileges.
|
||||
You may want to make the cons.saver setuid root.
|
||||
The code should be safe even if it is setuid but who knows?
|
||||
|
||||
|
||||
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
|
||||
@ -67,175 +67,184 @@
|
||||
static void
|
||||
send_contents (char *buffer, unsigned int columns, unsigned int rows)
|
||||
{
|
||||
unsigned char begin_line = 0, end_line = 0;
|
||||
unsigned int lastline, lc_index, x;
|
||||
unsigned char message, outbuf[1024], *p;
|
||||
unsigned short bytes;
|
||||
unsigned char begin_line = 0, end_line = 0;
|
||||
unsigned int lastline, lc_index, x;
|
||||
unsigned char message, outbuf[1024], *p;
|
||||
unsigned short bytes;
|
||||
|
||||
lc_index = 2 * rows * columns;
|
||||
for (lastline = rows; lastline > 0; lastline--)
|
||||
for (x = 0; x < columns; x++)
|
||||
{
|
||||
lc_index -= 2;
|
||||
if (buffer [lc_index] != ' ')
|
||||
goto out;
|
||||
}
|
||||
out:
|
||||
lc_index = 2 * rows * columns;
|
||||
for (lastline = rows; lastline > 0; lastline--)
|
||||
for (x = 0; x < columns; x++)
|
||||
{
|
||||
lc_index -= 2;
|
||||
if (buffer[lc_index] != ' ')
|
||||
goto out;
|
||||
}
|
||||
out:
|
||||
|
||||
message = CONSOLE_CONTENTS;
|
||||
write (1, &message, 1);
|
||||
message = CONSOLE_CONTENTS;
|
||||
if (write (1, &message, 1) != 1)
|
||||
return;
|
||||
if (read (0, &begin_line, 1) != 1)
|
||||
return;
|
||||
if (read (0, &end_line, 1) != 1)
|
||||
return;
|
||||
if (begin_line > lastline)
|
||||
begin_line = lastline;
|
||||
if (end_line > lastline)
|
||||
end_line = lastline;
|
||||
|
||||
read (0, &begin_line, 1);
|
||||
read (0, &end_line, 1);
|
||||
if (begin_line > lastline)
|
||||
begin_line = lastline;
|
||||
if (end_line > lastline)
|
||||
end_line = lastline;
|
||||
lc_index = (end_line - begin_line) * columns;
|
||||
|
||||
lc_index = (end_line - begin_line) * columns;
|
||||
bytes = lc_index;
|
||||
if (lc_index != bytes)
|
||||
bytes = 0;
|
||||
write (1, &bytes, 2);
|
||||
if (! bytes)
|
||||
return;
|
||||
if (write (1, &bytes, 2) != 2)
|
||||
return;
|
||||
if (!bytes)
|
||||
return;
|
||||
|
||||
p = outbuf;
|
||||
for (lc_index = 2 * begin_line * columns;
|
||||
lc_index < 2 * end_line * columns;
|
||||
lc_index += 2)
|
||||
p = outbuf;
|
||||
for (lc_index = 2 * begin_line * columns; lc_index < 2 * end_line * columns; lc_index += 2)
|
||||
{
|
||||
*p++ = buffer [lc_index];
|
||||
if (p == outbuf + sizeof (outbuf))
|
||||
{
|
||||
write (1, outbuf, sizeof (outbuf));
|
||||
p = outbuf;
|
||||
}
|
||||
*p++ = buffer[lc_index];
|
||||
if (p == outbuf + sizeof (outbuf))
|
||||
{
|
||||
if (write (1, outbuf, sizeof (outbuf)) != sizeof (outbuf))
|
||||
return;
|
||||
p = outbuf;
|
||||
}
|
||||
}
|
||||
|
||||
if (p != outbuf)
|
||||
write (1, outbuf, p - outbuf);
|
||||
if (p != outbuf)
|
||||
if (write (1, outbuf, p - outbuf) < (p - outbuf))
|
||||
return;
|
||||
}
|
||||
|
||||
static void __attribute__ ((noreturn))
|
||||
die (void)
|
||||
static void __attribute__ ((noreturn)) die (void)
|
||||
{
|
||||
unsigned char zero = 0;
|
||||
write (1, &zero, 1);
|
||||
exit (3);
|
||||
unsigned char zero = 0;
|
||||
ssize_t ret;
|
||||
ret = write (1, &zero, 1);
|
||||
exit (3);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
unsigned char action = 0, console_flag = 3;
|
||||
int console_fd, vcsa_fd, console_minor, buffer_size;
|
||||
struct stat st;
|
||||
uid_t uid, euid;
|
||||
char *buffer, *tty_name, console_name [16], vcsa_name [16];
|
||||
const char *p, *q;
|
||||
struct winsize winsz;
|
||||
unsigned char action = 0, console_flag = 3;
|
||||
int console_fd, vcsa_fd, console_minor, buffer_size;
|
||||
struct stat st;
|
||||
uid_t uid, euid;
|
||||
char *buffer, *tty_name, console_name[16], vcsa_name[16];
|
||||
const char *p, *q;
|
||||
struct winsize winsz;
|
||||
|
||||
close (2);
|
||||
close (2);
|
||||
|
||||
if (argc != 2)
|
||||
die ();
|
||||
if (argc != 2)
|
||||
die ();
|
||||
|
||||
tty_name = argv [1];
|
||||
if (strnlen (tty_name, 15) == 15
|
||||
|| strncmp (tty_name, "/dev/", 5))
|
||||
die ();
|
||||
tty_name = argv[1];
|
||||
if (strnlen (tty_name, 15) == 15 || strncmp (tty_name, "/dev/", 5))
|
||||
die ();
|
||||
|
||||
setsid ();
|
||||
uid = getuid ();
|
||||
euid = geteuid ();
|
||||
setsid ();
|
||||
uid = getuid ();
|
||||
euid = geteuid ();
|
||||
|
||||
if (seteuid (uid) < 0)
|
||||
die ();
|
||||
console_fd = open (tty_name, O_RDONLY);
|
||||
if (console_fd < 0)
|
||||
die ();
|
||||
if (fstat (console_fd, &st) < 0 || ! S_ISCHR (st.st_mode))
|
||||
die ();
|
||||
if ((st.st_rdev & 0xff00) != 0x0400)
|
||||
die ();
|
||||
console_minor = (int) (st.st_rdev & 0x00ff);
|
||||
if (console_minor < 1 || console_minor > 63)
|
||||
die ();
|
||||
if (st.st_uid != uid)
|
||||
die ();
|
||||
if (seteuid (uid) < 0)
|
||||
die ();
|
||||
console_fd = open (tty_name, O_RDONLY);
|
||||
if (console_fd < 0)
|
||||
die ();
|
||||
if (fstat (console_fd, &st) < 0 || !S_ISCHR (st.st_mode))
|
||||
die ();
|
||||
if ((st.st_rdev & 0xff00) != 0x0400)
|
||||
die ();
|
||||
console_minor = (int) (st.st_rdev & 0x00ff);
|
||||
if (console_minor < 1 || console_minor > 63)
|
||||
die ();
|
||||
if (st.st_uid != uid)
|
||||
die ();
|
||||
|
||||
switch (tty_name [5])
|
||||
switch (tty_name[5])
|
||||
{
|
||||
/* devfs */
|
||||
case 'v': p = "/dev/vc/%d"; q = "/dev/vcc/a%d"; break;
|
||||
/* /dev/ttyN */
|
||||
case 't': p = "/dev/tty%d"; q = "/dev/vcsa%d"; break;
|
||||
default: die (); break;
|
||||
/* devfs */
|
||||
case 'v':
|
||||
p = "/dev/vc/%d";
|
||||
q = "/dev/vcc/a%d";
|
||||
break;
|
||||
/* /dev/ttyN */
|
||||
case 't':
|
||||
p = "/dev/tty%d";
|
||||
q = "/dev/vcsa%d";
|
||||
break;
|
||||
default:
|
||||
die ();
|
||||
break;
|
||||
}
|
||||
|
||||
snprintf (console_name, sizeof (console_name), p, console_minor);
|
||||
if (strncmp (console_name, tty_name, sizeof (console_name)) != 0)
|
||||
die ();
|
||||
snprintf (console_name, sizeof (console_name), p, console_minor);
|
||||
if (strncmp (console_name, tty_name, sizeof (console_name)) != 0)
|
||||
die ();
|
||||
|
||||
if (seteuid (euid) < 0)
|
||||
die ();
|
||||
if (seteuid (euid) < 0)
|
||||
die ();
|
||||
|
||||
snprintf (vcsa_name, sizeof (vcsa_name), q, console_minor);
|
||||
vcsa_fd = open (vcsa_name, O_RDWR);
|
||||
if (vcsa_fd < 0)
|
||||
die ();
|
||||
if (fstat (vcsa_fd, &st) < 0 || ! S_ISCHR (st.st_mode))
|
||||
die ();
|
||||
snprintf (vcsa_name, sizeof (vcsa_name), q, console_minor);
|
||||
vcsa_fd = open (vcsa_name, O_RDWR);
|
||||
if (vcsa_fd < 0)
|
||||
die ();
|
||||
if (fstat (vcsa_fd, &st) < 0 || !S_ISCHR (st.st_mode))
|
||||
die ();
|
||||
|
||||
if (seteuid (uid) < 0)
|
||||
die ();
|
||||
if (seteuid (uid) < 0)
|
||||
die ();
|
||||
|
||||
winsz.ws_col = winsz.ws_row = 0;
|
||||
if (ioctl (console_fd, TIOCGWINSZ, &winsz) < 0
|
||||
|| winsz.ws_col <= 0 || winsz.ws_row <= 0
|
||||
|| winsz.ws_col >= 256 || winsz.ws_row >= 256)
|
||||
die ();
|
||||
winsz.ws_col = winsz.ws_row = 0;
|
||||
if (ioctl (console_fd, TIOCGWINSZ, &winsz) < 0
|
||||
|| winsz.ws_col <= 0 || winsz.ws_row <= 0 || winsz.ws_col >= 256 || winsz.ws_row >= 256)
|
||||
die ();
|
||||
|
||||
buffer_size = 4 + 2 * winsz.ws_col * winsz.ws_row;
|
||||
buffer = calloc (buffer_size, 1);
|
||||
if (buffer == NULL)
|
||||
die ();
|
||||
buffer_size = 4 + 2 * winsz.ws_col * winsz.ws_row;
|
||||
buffer = calloc (buffer_size, 1);
|
||||
if (buffer == NULL)
|
||||
die ();
|
||||
|
||||
write (1, &console_flag, 1);
|
||||
if (write (1, &console_flag, 1) != 1)
|
||||
die ();
|
||||
|
||||
while (console_flag && read (0, &action, 1) == 1)
|
||||
while (console_flag && read (0, &action, 1) == 1)
|
||||
{
|
||||
switch (action)
|
||||
{
|
||||
case CONSOLE_DONE:
|
||||
console_flag = 0;
|
||||
continue;
|
||||
case CONSOLE_SAVE:
|
||||
if (seteuid (euid) < 0
|
||||
|| lseek (vcsa_fd, 0, 0) != 0
|
||||
|| fstat (console_fd, &st) < 0 || st.st_uid != uid
|
||||
|| read (vcsa_fd, buffer, buffer_size) != buffer_size
|
||||
|| fstat (console_fd, &st) < 0 || st.st_uid != uid)
|
||||
memset (buffer, 0, buffer_size);
|
||||
if (seteuid (uid) < 0)
|
||||
die ();
|
||||
break;
|
||||
case CONSOLE_RESTORE:
|
||||
if (seteuid (euid) >= 0
|
||||
&& lseek (vcsa_fd, 0, 0) == 0
|
||||
&& fstat (console_fd, &st) >= 0 && st.st_uid == uid)
|
||||
write (vcsa_fd, buffer, buffer_size);
|
||||
if (seteuid (uid) < 0)
|
||||
die ();
|
||||
break;
|
||||
case CONSOLE_CONTENTS:
|
||||
send_contents (buffer + 4, winsz.ws_col, winsz.ws_row);
|
||||
break;
|
||||
}
|
||||
switch (action)
|
||||
{
|
||||
case CONSOLE_DONE:
|
||||
console_flag = 0;
|
||||
continue;
|
||||
case CONSOLE_SAVE:
|
||||
if (seteuid (euid) < 0
|
||||
|| lseek (vcsa_fd, 0, 0) != 0
|
||||
|| fstat (console_fd, &st) < 0 || st.st_uid != uid
|
||||
|| read (vcsa_fd, buffer, buffer_size) != buffer_size
|
||||
|| fstat (console_fd, &st) < 0 || st.st_uid != uid)
|
||||
memset (buffer, 0, buffer_size);
|
||||
if (seteuid (uid) < 0)
|
||||
die ();
|
||||
break;
|
||||
case CONSOLE_RESTORE:
|
||||
if (seteuid (euid) >= 0
|
||||
&& lseek (vcsa_fd, 0, 0) == 0 && fstat (console_fd, &st) >= 0 && st.st_uid == uid)
|
||||
if (write (vcsa_fd, buffer, buffer_size) != buffer_size)
|
||||
die ();
|
||||
if (seteuid (uid) < 0)
|
||||
die ();
|
||||
break;
|
||||
case CONSOLE_CONTENTS:
|
||||
send_contents (buffer + 4, winsz.ws_col, winsz.ws_row);
|
||||
break;
|
||||
}
|
||||
|
||||
write (1, &console_flag, 1);
|
||||
if (write (1, &console_flag, 1) != 1)
|
||||
die ();
|
||||
}
|
||||
|
||||
exit (0);
|
||||
exit (0);
|
||||
}
|
||||
|
@ -328,6 +328,7 @@ edit_load_file_fast (WEdit * edit, const char *filename)
|
||||
{
|
||||
long buf, buf2;
|
||||
int file = -1;
|
||||
int ret = 1;
|
||||
edit->curs2 = edit->last_byte;
|
||||
buf2 = edit->curs2 >> S_EDIT_BUF_SIZE;
|
||||
edit->utf8 = 0;
|
||||
@ -343,20 +344,32 @@ edit_load_file_fast (WEdit * edit, const char *filename)
|
||||
if (!edit->buffers2[buf2])
|
||||
edit->buffers2[buf2] = g_malloc0 (EDIT_BUF_SIZE);
|
||||
|
||||
mc_read (file,
|
||||
(char *) edit->buffers2[buf2] + EDIT_BUF_SIZE -
|
||||
(edit->curs2 & M_EDIT_BUF_SIZE), edit->curs2 & M_EDIT_BUF_SIZE);
|
||||
|
||||
for (buf = buf2 - 1; buf >= 0; buf--)
|
||||
do
|
||||
{
|
||||
/* edit->buffers2[0] is already allocated */
|
||||
if (!edit->buffers2[buf])
|
||||
edit->buffers2[buf] = g_malloc0 (EDIT_BUF_SIZE);
|
||||
mc_read (file, (char *) edit->buffers2[buf], EDIT_BUF_SIZE);
|
||||
}
|
||||
if (mc_read (file,
|
||||
(char *) edit->buffers2[buf2] + EDIT_BUF_SIZE -
|
||||
(edit->curs2 & M_EDIT_BUF_SIZE), edit->curs2 & M_EDIT_BUF_SIZE) < 0)
|
||||
break;
|
||||
|
||||
for (buf = buf2 - 1; buf >= 0; buf--)
|
||||
{
|
||||
/* edit->buffers2[0] is already allocated */
|
||||
if (!edit->buffers2[buf])
|
||||
edit->buffers2[buf] = g_malloc0 (EDIT_BUF_SIZE);
|
||||
if (mc_read (file, (char *) edit->buffers2[buf], EDIT_BUF_SIZE) < 0)
|
||||
break;
|
||||
}
|
||||
ret = 0;
|
||||
}
|
||||
while (0);
|
||||
if (ret)
|
||||
{
|
||||
char *err_str = g_strdup_printf (_(" Error reading %s "), filename);
|
||||
edit_error_dialog (_("Error"), err_str);
|
||||
g_free (err_str);
|
||||
}
|
||||
mc_close (file);
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* detecting an error on save is easy: just check if every byte has been written. */
|
||||
|
@ -273,9 +273,11 @@ edit_save_file (WEdit * edit, const char *filename)
|
||||
}
|
||||
else
|
||||
savename = g_strdup (real_filename);
|
||||
|
||||
mc_chown (savename, edit->stat1.st_uid, edit->stat1.st_gid);
|
||||
mc_chmod (savename, edit->stat1.st_mode);
|
||||
{
|
||||
int ret;
|
||||
ret = mc_chown (savename, edit->stat1.st_uid, edit->stat1.st_gid);
|
||||
ret = mc_chmod (savename, edit->stat1.st_mode);
|
||||
}
|
||||
|
||||
if ((fd =
|
||||
mc_open (savename, O_CREAT | O_WRONLY | O_TRUNC | O_BINARY, edit->stat1.st_mode)) == -1)
|
||||
@ -757,7 +759,10 @@ edit_delete_macro (WEdit * edit, int k)
|
||||
n = 0;
|
||||
while (fscanf (f, "%lu %d, ", ¯o[n].command, ¯o[n].ch))
|
||||
n++;
|
||||
fscanf (f, ";\n");
|
||||
{
|
||||
int ret;
|
||||
ret = fscanf (f, ";\n");
|
||||
}
|
||||
if (s != k)
|
||||
{
|
||||
fprintf (g, ("key '%d 0': "), s);
|
||||
@ -866,7 +871,10 @@ edit_load_macro_cmd (WEdit * edit, struct macro macro[], int *n, int k)
|
||||
{
|
||||
while (2 == fscanf (f, "%lu %d, ", &dummy.command, &dummy.ch));
|
||||
}
|
||||
fscanf (f, ";\n");
|
||||
{
|
||||
int ret;
|
||||
ret = fscanf (f, ";\n");
|
||||
}
|
||||
if (s == k)
|
||||
found = 1;
|
||||
}
|
||||
@ -2503,8 +2511,6 @@ edit_block_process_cmd (WEdit * edit, const char *shell_cmd, int block)
|
||||
*/
|
||||
tmp = g_strconcat (" ", home_dir, PATH_SEP_STR EDIT_DIR, shell_cmd, " ", quoted_name,
|
||||
" ", home_dir, PATH_SEP_STR EDIT_BLOCK_FILE " /dev/null", (char *) NULL);
|
||||
system (tmp);
|
||||
g_free (tmp);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -2515,23 +2521,31 @@ edit_block_process_cmd (WEdit * edit, const char *shell_cmd, int block)
|
||||
*/
|
||||
tmp = g_strconcat (" ", home_dir, PATH_SEP_STR EDIT_DIR, shell_cmd, " ",
|
||||
quoted_name, (char *) NULL);
|
||||
system (tmp);
|
||||
g_free (tmp);
|
||||
}
|
||||
g_free (quoted_name);
|
||||
close_error_pipe (D_NORMAL, NULL);
|
||||
|
||||
edit_refresh_cmd (edit);
|
||||
edit->force |= REDRAW_COMPLETELY;
|
||||
|
||||
/* insert result block */
|
||||
if (block && !edit_block_delete_cmd (edit))
|
||||
if (system (tmp) == -1)
|
||||
{
|
||||
edit_insert_file (edit, b);
|
||||
block_file = fopen (b, "w");
|
||||
if (block_file != NULL)
|
||||
fclose (block_file);
|
||||
edit_error_dialog (_("Process block"), _("Error calling program"));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
g_free (quoted_name);
|
||||
close_error_pipe (D_NORMAL, NULL);
|
||||
|
||||
edit_refresh_cmd (edit);
|
||||
edit->force |= REDRAW_COMPLETELY;
|
||||
|
||||
/* insert result block */
|
||||
if (block && !edit_block_delete_cmd (edit))
|
||||
{
|
||||
edit_insert_file (edit, b);
|
||||
block_file = fopen (b, "w");
|
||||
if (block_file != NULL)
|
||||
fclose (block_file);
|
||||
}
|
||||
}
|
||||
g_free (tmp);
|
||||
|
||||
edit_block_process_cmd__EXIT:
|
||||
g_free (b);
|
||||
|
23
src/file.c
23
src/file.c
@ -416,8 +416,8 @@ warn_same_file (const char *fmt, const char *a, const char *b)
|
||||
union
|
||||
{
|
||||
void *p;
|
||||
FileProgressStatus (*f) (enum OperationMode, const char *fmt,
|
||||
const char *a, const char *b);
|
||||
FileProgressStatus (*f) (enum OperationMode, const char *fmt,
|
||||
const char *a, const char *b);
|
||||
} pntr;
|
||||
pntr.f = real_warn_same_file;
|
||||
|
||||
@ -1991,7 +1991,7 @@ panel_operate (void *source_panel, FileOperation operation, gboolean force_singl
|
||||
{
|
||||
WPanel *panel = (WPanel *) source_panel;
|
||||
const gboolean single_entry = force_single || (panel->marked <= 1)
|
||||
|| (get_current_type () == view_tree);
|
||||
|| (get_current_type () == view_tree);
|
||||
|
||||
char *source = NULL;
|
||||
#ifdef WITH_FULL_PATHS
|
||||
@ -2003,6 +2003,7 @@ panel_operate (void *source_panel, FileOperation operation, gboolean force_singl
|
||||
char *temp = NULL;
|
||||
char *save_cwd = NULL, *save_dest = NULL;
|
||||
struct stat src_stat;
|
||||
gboolean ret_val = TRUE;
|
||||
int i;
|
||||
FileProgressStatus value;
|
||||
FileOpContext *ctx;
|
||||
@ -2197,8 +2198,12 @@ panel_operate (void *source_panel, FileOperation operation, gboolean force_singl
|
||||
/* We now have ETA in all cases */
|
||||
|
||||
/* One file: FIXME mc_chdir will take user out of any vfs */
|
||||
if (operation != OP_COPY && get_current_type () == view_tree)
|
||||
mc_chdir (PATH_SEP_STR);
|
||||
if ((operation != OP_COPY) && (get_current_type () == view_tree) &&
|
||||
(mc_chdir (PATH_SEP_STR) < 0))
|
||||
{
|
||||
ret_val = FALSE;
|
||||
goto clean_up;
|
||||
}
|
||||
|
||||
/* The source and src_stat variables have been initialized before */
|
||||
#ifdef WITH_FULL_PATHS
|
||||
@ -2417,7 +2422,9 @@ panel_operate (void *source_panel, FileOperation operation, gboolean force_singl
|
||||
#endif /* WITH_BACKGROUND */
|
||||
|
||||
file_op_context_destroy (ctx);
|
||||
return TRUE;
|
||||
file_op_total_context_destroy (tctx);
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
@ -2557,8 +2564,8 @@ query_replace (FileOpContext * ctx, const char *destname, struct stat *_s_stat,
|
||||
union
|
||||
{
|
||||
void *p;
|
||||
FileProgressStatus (*f) (FileOpContext *, enum OperationMode, const char *,
|
||||
struct stat *, struct stat *);
|
||||
FileProgressStatus (*f) (FileOpContext *, enum OperationMode, const char *,
|
||||
struct stat *, struct stat *);
|
||||
} pntr;
|
||||
pntr.f = file_progress_real_query_replace;
|
||||
|
||||
|
1201
src/find.c
1201
src/find.c
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
1491
src/main.c
1491
src/main.c
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
@ -480,8 +480,9 @@ do_external_panelize (char *command)
|
||||
current_panel->count = next_free;
|
||||
if (list->list[0].fname[0] == PATH_SEP)
|
||||
{
|
||||
int ret;
|
||||
strcpy (current_panel->cwd, PATH_SEP_STR);
|
||||
chdir (PATH_SEP_STR);
|
||||
ret = chdir (PATH_SEP_STR);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
23
src/screen.c
23
src/screen.c
@ -1404,7 +1404,10 @@ panel_new_with_dir (const char *panel_name, const char *wpath)
|
||||
|
||||
/* Because do_load_dir lists files in current directory */
|
||||
if (wpath)
|
||||
mc_chdir (wpath);
|
||||
{
|
||||
int ret;
|
||||
ret = mc_chdir (wpath);
|
||||
}
|
||||
|
||||
/* Load the default format */
|
||||
panel->count =
|
||||
@ -1413,7 +1416,10 @@ panel_new_with_dir (const char *panel_name, const char *wpath)
|
||||
|
||||
/* Restore old right path */
|
||||
if (wpath)
|
||||
mc_chdir (curdir);
|
||||
{
|
||||
int ret;
|
||||
ret = mc_chdir (curdir);
|
||||
}
|
||||
|
||||
return panel;
|
||||
}
|
||||
@ -3467,7 +3473,10 @@ reload_panelized (WPanel * panel)
|
||||
dir_list *list = &panel->dir;
|
||||
|
||||
if (panel != current_panel)
|
||||
mc_chdir (panel->cwd);
|
||||
{
|
||||
int ret;
|
||||
ret = mc_chdir (panel->cwd);
|
||||
}
|
||||
|
||||
for (i = 0, j = 0; i < panel->count; i++)
|
||||
{
|
||||
@ -3498,7 +3507,10 @@ reload_panelized (WPanel * panel)
|
||||
panel->count = j;
|
||||
|
||||
if (panel != current_panel)
|
||||
mc_chdir (current_panel->cwd);
|
||||
{
|
||||
int ret;
|
||||
ret = mc_chdir (current_panel->cwd);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@ -3560,6 +3572,7 @@ update_panels (int force_update, const char *current_file)
|
||||
{
|
||||
int reload_other = !(force_update & UP_ONLY_CURRENT);
|
||||
WPanel *panel;
|
||||
int ret;
|
||||
|
||||
update_one_panel (get_current_index (), force_update, current_file);
|
||||
if (reload_other)
|
||||
@ -3570,7 +3583,7 @@ update_panels (int force_update, const char *current_file)
|
||||
else
|
||||
panel = (WPanel *) get_panel_widget (get_other_index ());
|
||||
|
||||
mc_chdir (panel->cwd);
|
||||
ret = mc_chdir (panel->cwd);
|
||||
}
|
||||
|
||||
gsize
|
||||
|
1142
src/subshell.c
1142
src/subshell.c
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
@ -663,13 +663,14 @@ tree_rescan (void *data)
|
||||
{
|
||||
char old_dir[MC_MAXPATHLEN];
|
||||
WTree *tree = data;
|
||||
int ret;
|
||||
|
||||
if (!tree->selected_ptr || !mc_get_current_wd (old_dir, MC_MAXPATHLEN) ||
|
||||
mc_chdir (tree->selected_ptr->name))
|
||||
return;
|
||||
|
||||
tree_store_rescan (tree->selected_ptr->name);
|
||||
mc_chdir (old_dir);
|
||||
ret = mc_chdir (old_dir);
|
||||
}
|
||||
|
||||
static void
|
||||
|
833
src/treestore.c
833
src/treestore.c
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
22
src/widget.c
22
src/widget.c
@ -4,11 +4,11 @@
|
||||
2004, 2005, 2006, 2007, 2009 Free Software Foundation, Inc.
|
||||
|
||||
Authors: 1994, 1995 Radek Doulik
|
||||
1994, 1995 Miguel de Icaza
|
||||
1995 Jakub Jelinek
|
||||
1996 Andrej Borsenkow
|
||||
1997 Norbert Warmuth
|
||||
2009, 2010 Andrew Borodin
|
||||
1994, 1995 Miguel de Icaza
|
||||
1995 Jakub Jelinek
|
||||
1996 Andrej Borsenkow
|
||||
1997 Norbert Warmuth
|
||||
2009, 2010 Andrew Borodin
|
||||
|
||||
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
|
||||
@ -71,10 +71,7 @@ widget_selectcolor (Widget * w, gboolean focused, gboolean hotkey)
|
||||
tty_setcolor (hotkey
|
||||
? (focused
|
||||
? DLG_HOT_FOCUSC (h)
|
||||
: DLG_HOT_NORMALC (h))
|
||||
: (focused
|
||||
? DLG_FOCUSC (h)
|
||||
: DLG_NORMALC (h)));
|
||||
: DLG_HOT_NORMALC (h)) : (focused ? DLG_FOCUSC (h) : DLG_NORMALC (h)));
|
||||
}
|
||||
|
||||
struct hotkey_t
|
||||
@ -615,6 +612,8 @@ save_text_to_clip_file (const char *text)
|
||||
{
|
||||
int file;
|
||||
char *fname = NULL;
|
||||
ssize_t ret;
|
||||
size_t str_len;
|
||||
|
||||
fname = g_build_filename (home_dir, EDIT_CLIP_FILE, NULL);
|
||||
file = mc_open (fname, O_CREAT | O_WRONLY | O_TRUNC,
|
||||
@ -624,9 +623,10 @@ save_text_to_clip_file (const char *text)
|
||||
if (file == -1)
|
||||
return FALSE;
|
||||
|
||||
mc_write (file, (char *) text, strlen (text));
|
||||
str_len = strlen (text);
|
||||
ret = mc_write (file, (char *) text, str_len);
|
||||
mc_close (file);
|
||||
return TRUE;
|
||||
return ret == (ssize_t) str_len;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
Загрузка…
x
Ссылка в новой задаче
Block a user