#include "gnunet_os_lib.h"
#include "gnunet_scheduler_lib.h"
#include "gnunet_strings_lib.h"
+#include "gnunet_crypto_lib.h"
#include "disk.h"
#define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__)
*
* @param fn name of an existing named pipe
* @param flags open flags
- * @param perm access permissions
* @return pipe handle on success, NULL on error
*/
static struct GNUNET_DISK_FileHandle *
-npipe_open (const char *fn, enum GNUNET_DISK_OpenFlags flags,
- enum GNUNET_DISK_AccessPermissions perm)
+npipe_open (const char *fn, enum GNUNET_DISK_OpenFlags flags)
{
struct GNUNET_DISK_FileHandle *ret;
HANDLE h;
*
* @param fn name of the file
* @param flags flags to use
- * @param perm permissions to use
* @return NULL on error
*/
static struct GNUNET_DISK_FileHandle *
npipe_open (const char *fn,
- enum GNUNET_DISK_OpenFlags flags,
- enum GNUNET_DISK_AccessPermissions perm)
+ enum GNUNET_DISK_OpenFlags flags)
{
- flags = flags & (~GNUNET_DISK_OPEN_FAILIFEXISTS);
- return GNUNET_DISK_file_open (fn, flags, perm);
+ struct GNUNET_DISK_FileHandle *ret;
+ int fd;
+ struct timespec req;
+ int i;
+
+ /* 200 * 5ms = 1s at most */
+ for (i=0;i<200;i++)
+ {
+ fd = open (fn, O_NONBLOCK | ((flags == GNUNET_DISK_OPEN_READ) ? O_RDONLY : O_WRONLY));
+ if ( (-1 != fd) || (9 == i) || (flags == GNUNET_DISK_OPEN_READ))
+ break;
+ /* as this is for killing a child process via pipe and it is conceivable that
+ the child process simply didn't finish starting yet, we do some sleeping
+ (which is obviously usually not allowed). We can't select on the FD as
+ 'open' fails, and we probably shouldn't just "ignore" the error, so wait
+ and retry a few times is likely the best method; our process API doesn't
+ support continuations, so we need to sleep directly... */
+ req.tv_sec = 0;
+ req.tv_nsec = 5000000; /* 5ms */
+ (void) nanosleep (&req, NULL);
+ }
+ if (-1 == fd)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ (flags == GNUNET_DISK_OPEN_READ)
+ ? _("Failed to open named pipe `%s' for reading: %s\n")
+ : _("Failed to open named pipe `%s' for writing: %s\n"),
+ fn,
+ STRERROR (errno));
+ return NULL;
+ }
+ ret = GNUNET_malloc (sizeof (struct GNUNET_DISK_FileHandle));
+ ret->fd = fd;
+ return ret;
}
#endif
const struct GNUNET_SCHEDULER_TaskContext *tc)
{
struct GNUNET_DISK_FileHandle *control_pipe = cls;
- int sig;
-
+ char sig;
+ ssize_t ret;
+
LOG (GNUNET_ERROR_TYPE_DEBUG, "`%s' invoked because of %d\n", __FUNCTION__,
tc->reason);
if (tc->reason &
GNUNET_DISK_file_close (control_pipe);
return;
}
- if (GNUNET_DISK_file_read (control_pipe, &sig, sizeof (sig)) !=
- sizeof (sig))
+ ret = GNUNET_DISK_file_read (control_pipe, &sig, sizeof (sig));
+ if (sizeof (sig) != ret)
{
- LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "GNUNET_DISK_file_read");
+ if (-1 == ret)
+ LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "GNUNET_DISK_file_read");
GNUNET_DISK_file_close (control_pipe);
return;
}
GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
control_pipe, &parent_control_handler,
control_pipe);
- raise (sig);
+ raise ((int) sig);
}
return;
}
control_pipe =
- npipe_open (env_buf, GNUNET_DISK_OPEN_READ,
- GNUNET_DISK_PERM_USER_READ |
- GNUNET_DISK_PERM_USER_WRITE);
+ npipe_open (env_buf, GNUNET_DISK_OPEN_READ);
if (NULL == control_pipe)
{
LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "open", env_buf);
GNUNET_OS_process_kill (struct GNUNET_OS_Process *proc, int sig)
{
int ret;
+ char csig;
+ csig = (char) sig;
#if !WINDOWS
if ( (NULL == proc->control_pipe) &&
(NULL != proc->childpipename) )
proc->control_pipe = npipe_open (proc->childpipename,
- GNUNET_DISK_OPEN_WRITE,
- GNUNET_DISK_PERM_USER_READ |
- GNUNET_DISK_PERM_USER_WRITE);
+ GNUNET_DISK_OPEN_WRITE);
#endif
- if (NULL == proc->control_pipe)
+ if (NULL != proc->control_pipe)
{
-#if WINDOWS
- /* no pipe and windows? can't do this */
- errno = EINVAL;
- return -1;
-#else
- return kill (proc->pid, sig);
-#endif
+ ret = GNUNET_DISK_file_write (proc->control_pipe, &csig, sizeof (csig));
+ if (ret == sizeof (csig))
+ return 0;
}
- ret = GNUNET_DISK_file_write (proc->control_pipe, &sig, sizeof (sig));
- if (ret == sizeof (sig))
- return 0;
- /* pipe failed, try other methods */
+ /* pipe failed or non-existent, try other methods */
switch (sig)
{
+#if !WINDOWS
case SIGHUP:
+#endif
case SIGINT:
case SIGKILL:
case SIGTERM:
errno = EINVAL;
return -1;
#else
- return kill (proc->pid, sig);
+ return PLIBC_KILL (proc->pid, sig);
#endif
}
}
void
GNUNET_OS_process_close (struct GNUNET_OS_Process *proc)
{
-#if ENABLE_WINDOWS_WORKAROUNDS
- if (proc->control_pipe)
+ if (NULL != proc->control_pipe)
GNUNET_DISK_file_close (proc->control_pipe);
-#endif
// FIXME NILS
#ifdef WINDOWS
if (proc->handle != NULL)
#endif
if (NULL != proc->childpipename)
{
+#if !WINDOWS
cleanup_npipe (proc->childpipename);
+#endif
GNUNET_free (proc->childpipename);
}
GNUNET_free (proc);
return NULL;
if (pipe_stdout != NULL)
{
- GNUNET_DISK_internal_file_handle_ (GNUNET_DISK_pipe_handle
- (pipe_stdout,
- GNUNET_DISK_PIPE_END_WRITE),
- &fd_stdout_write, sizeof (int));
- GNUNET_DISK_internal_file_handle_ (GNUNET_DISK_pipe_handle
- (pipe_stdout, GNUNET_DISK_PIPE_END_READ),
- &fd_stdout_read, sizeof (int));
+ GNUNET_assert (GNUNET_OK ==
+ GNUNET_DISK_internal_file_handle_ (GNUNET_DISK_pipe_handle
+ (pipe_stdout,
+ GNUNET_DISK_PIPE_END_WRITE),
+ &fd_stdout_write, sizeof (int)));
+ GNUNET_assert (GNUNET_OK ==
+ GNUNET_DISK_internal_file_handle_ (GNUNET_DISK_pipe_handle
+ (pipe_stdout, GNUNET_DISK_PIPE_END_READ),
+ &fd_stdout_read, sizeof (int)));
}
if (pipe_stdin != NULL)
{
- GNUNET_DISK_internal_file_handle_ (GNUNET_DISK_pipe_handle
- (pipe_stdin, GNUNET_DISK_PIPE_END_READ),
- &fd_stdin_read, sizeof (int));
- GNUNET_DISK_internal_file_handle_ (GNUNET_DISK_pipe_handle
- (pipe_stdin, GNUNET_DISK_PIPE_END_WRITE),
- &fd_stdin_write, sizeof (int));
+ GNUNET_assert (GNUNET_OK ==
+ GNUNET_DISK_internal_file_handle_ (GNUNET_DISK_pipe_handle
+ (pipe_stdin, GNUNET_DISK_PIPE_END_READ),
+ &fd_stdin_read, sizeof (int)));
+ GNUNET_assert (GNUNET_OK ==
+ GNUNET_DISK_internal_file_handle_ (GNUNET_DISK_pipe_handle
+ (pipe_stdin, GNUNET_DISK_PIPE_END_WRITE),
+ &fd_stdin_write, sizeof (int)));
}
ret = fork ();
int argc, arg_count;
HANDLE stdin_handle;
HANDLE stdout_handle;
+ struct GNUNET_DISK_FileHandle *control_pipe;
char path[MAX_PATH + 1];
return NULL;
}
}
+ else
+ control_pipe = NULL;
if (NULL != childpipename)
{
LOG (GNUNET_ERROR_TYPE_DEBUG, "Opened the parent end of the pipe `%s'\n",
our_env[0] = NULL;
}
env_block = CreateCustomEnvTable (our_env);
- GNUNET_free (our_env[0]);
- GNUNET_free (our_env[1]);
+ GNUNET_free_non_null (our_env[0]);
+ GNUNET_free_non_null (our_env[1]);
if (ERROR_SUCCESS != plibc_conv_to_win_pathwconv(path, wpath)
|| ERROR_SUCCESS != plibc_conv_to_win_pathwconv(cmd, wcmd)
return NULL;
}
}
+ else
+ control_pipe = NULL;
if (lsocks != NULL && lsocks[0] != INVALID_SOCKET)
{
lsocks_pipe = GNUNET_DISK_pipe (GNUNET_YES, GNUNET_YES, GNUNET_YES, GNUNET_NO);