Patchwork [06,of,14,RFC,c-hglib:level0] hg_rawcommand: send a command to the mercurial command server

login
register
mail settings
Submitter Iulian Stana
Date Sept. 3, 2013, 8:30 p.m.
Message ID <bc8721af130cb444e6a0.1378240245@doppler>
Download mbox | patch
Permalink /patch/2311/
State Deferred, archived
Headers show

Comments

Iulian Stana - Sept. 3, 2013, 8:30 p.m.
# HG changeset patch
# User Iulian Stana <julian.stana@gmail.com>
# Date 1378235031 -10800
#      Tue Sep 03 22:03:51 2013 +0300
# Node ID bc8721af130cb444e6a0c5351c6ea56f44f283ab
# Parent  1d20e8ae28ff6b4b39eb527888c3869ab5e98b86
hg_rawcommand: send a command to the mercurial command server
Giovanni Gherdovich - Sept. 12, 2013, 4:49 a.m.
:::: # HG changeset patch
:::: # User Iulian Stana <julian.stana at gmail.com>
:::: # Date 1378235031 -10800
:::: #      Tue Sep 03 22:03:51 2013 +0300
:::: # Node ID bc8721af130cb444e6a0c5351c6ea56f44f283ab
:::: # Parent  1d20e8ae28ff6b4b39eb527888c3869ab5e98b86
:::: hg_rawcommand: send a command to the mercurial command server
::::
:::: diff --git a/client.c b/client.c
:::: --- a/client.c
:::: +++ b/client.c
:::: @@ -10,6 +10,9 @@
::::  #include <signal.h>
::::
::::
:::: +#include "client.h"
:::: +#include "utils.h"
:::: +
::::  /**
::::   * \brief Reading the header from cmdsrv.
::::   *
:::: @@ -172,5 +175,48 @@
::::   return 0;
::::  }
::::
:::: -#include "client.h"
:::: -#include "utils.h"
:::: +/*
:::: + * Sending a command to the mercurial command server, through
the given handle.
:::: + * */
:::: +int hg_rawcommand(hg_handle *handle, char *const command[])
:::: +{
:::: + if(!handle) {
:::: + errno = EINVAL;
:::: + return -1;
:::: + }
:::: +
:::: + if(handle->protect){
:::: + errno = EPERM;
:::: + return -1;
:::: + }
:::: +
:::: + char runcommand[] = "runcommand\n";
:::: + int cmd_size = 0;
:::: + char *cmd_send = cmd_prepare(command, &cmd_size);
:::: + uint32_t big_endian_size = swap_uint32(cmd_size);
:::: +
:::: + if(write(handle->p_write, runcommand, strlen(runcommand)) < 0){
:::: + free(cmd_send);
:::: + return -1;
:::: + }
:::: + if(write(handle->p_write, &big_endian_size, sizeof(uint32_t)) < 0){
:::: + free(cmd_send);
:::: + return -1;
:::: + }
:::: + if(write(handle->p_write, cmd_send, cmd_size) < 0){
:::: + free(cmd_send);
:::: + return -1;
:::: + }
:::: +
:::: + if(read_header(handle) < 0){


I don't think it's a good idea to read the incoming header
in the function that sends command. See comments on read_header().


:::: + free(cmd_send);
:::: + return -1;
:::: + }
:::: +
:::: + free_data(handle);
:::: + handle->protect = 1;
:::: + free(cmd_send);
:::: + return 0;
:::: +}
:::: +
:::: +
:::: diff --git a/client.h b/client.h
:::: --- a/client.h
:::: +++ b/client.h
:::: @@ -85,5 +85,20 @@
::::   * */
::::  int hg_close(hg_handle **handle);
::::
:::: +/**
:::: + * \brief Sending a command to the mercurial command server,
through the given
:::: + *        handle.
:::: + * \param handle The handle of the connection, wherewith I want
to communicate
:::: + * \param command An array of pointers to null-terminated
strings that represent
:::: + *                the argument list available to the new
command. The list of
:::: + *                arguments must be terminated by a NULL pointer.
:::: + * \retval   0 if successful
:::: + * \retval  -1 to indicate an error, with errno set appropriately.
:::: + *
:::: + * errno can be:
:::: + *      - EINVAL   - Invalid argument ( handle it's set to a null pointer)
:::: + *      - write(2) command errors
:::: + * */
:::: +int hg_rawcommand(hg_handle *handle, char *const command[]);
::::
::::  #endif

Patch

diff --git a/client.c b/client.c
--- a/client.c
+++ b/client.c
@@ -10,6 +10,9 @@ 
 #include <signal.h>
 
 
+#include "client.h"
+#include "utils.h"
+
 /**
  * \brief Reading the header from cmdsrv.
  *
@@ -172,5 +175,48 @@ 
 	return 0;
 }
 
-#include "client.h"
-#include "utils.h"
+/*
+ * Sending a command to the mercurial command server, through the given handle.
+ * */
+int hg_rawcommand(hg_handle *handle, char *const command[])
+{
+	if(!handle) {
+		errno = EINVAL;
+		return -1;
+	}
+
+	if(handle->protect){
+		errno = EPERM;
+		return -1;
+	}
+
+	char runcommand[] = "runcommand\n";
+	int cmd_size = 0;
+	char *cmd_send = cmd_prepare(command, &cmd_size);
+	uint32_t big_endian_size = swap_uint32(cmd_size);
+
+	if(write(handle->p_write, runcommand, strlen(runcommand)) < 0){
+		free(cmd_send);
+		return -1;
+	}
+	if(write(handle->p_write, &big_endian_size, sizeof(uint32_t)) < 0){
+		free(cmd_send);
+		return -1;
+	}
+	if(write(handle->p_write, cmd_send, cmd_size) < 0){
+		free(cmd_send);
+		return -1;
+	}
+
+	if(read_header(handle) < 0){
+		free(cmd_send);
+		return -1;
+	}
+
+	free_data(handle);
+	handle->protect = 1;
+	free(cmd_send);
+	return 0;
+}
+
+
diff --git a/client.h b/client.h
--- a/client.h
+++ b/client.h
@@ -85,5 +85,20 @@ 
  * */
 int hg_close(hg_handle **handle);
 
+/**
+ * \brief Sending a command to the mercurial command server, through the given 
+ *        handle.
+ * \param handle The handle of the connection, wherewith I want to communicate
+ * \param command An array of pointers to null-terminated strings that represent
+ *                the argument list available to the new command. The list of
+ *                arguments must be terminated by a NULL pointer.
+ * \retval   0 if successful
+ * \retval  -1 to indicate an error, with errno set appropriately.
+ *
+ * errno can be:
+ *      - EINVAL   - Invalid argument ( handle it's set to a null pointer)
+ *      - write(2) command errors
+ * */
+int hg_rawcommand(hg_handle *handle, char *const command[]);
 
 #endif