Patchwork [03,of,11,c-hglib:level0,V2] hg_open: open a connection with hg cmd-server

login
register
mail settings
Submitter Iulian Stana
Date Sept. 13, 2013, 8:31 p.m.
Message ID <a214d1affc17a4c03257.1379104313@doppler>
Download mbox | patch
Permalink /patch/2439/
State Deferred, archived
Headers show

Comments

Iulian Stana - Sept. 13, 2013, 8:31 p.m.
# HG changeset patch
# User Iulian Stana <julian.stana@gmail.com>
# Date 1379102887 -10800
#      Fri Sep 13 23:08:07 2013 +0300
# Node ID a214d1affc17a4c03257f6f5d9a30dd520453df2
# Parent  1c3f11950b3e4a267c6973e6682beaf90a94bb2b
hg_open: open a connection with hg cmd-server

Patch

diff --git a/client.c b/client.c
new file mode 100644
--- /dev/null
+++ b/client.c
@@ -0,0 +1,74 @@ 
+#include <errno.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+
+#include "client.h"
+#include "utils.h"
+
+#define HGPATH "hg"
+
+
+/*
+ * Open the connection with the mercurial command server.
+ * */
+hg_handle *hg_open(const char *path, char *encoding)
+{
+	hg_handle *handle = malloc(sizeof(hg_handle));
+	handle->header = malloc(sizeof(hg_header));
+	char command[100];
+	int wpipe[2];
+	int rpipe[2];
+	int c_write;
+	int c_read;
+
+	sprintf(command,
+		"%s serve --cmdserver pipe --config ui.interactive=True",
+		HGPATH);
+
+	if (path)
+		sprintf(command, "%s -R %s", command, path);
+
+	if (pipe(wpipe) < 0 || pipe(rpipe) < 0) {
+		return NULL;
+	}
+	handle->p_read = rpipe[0];
+	c_write = rpipe[1];
+	c_read = wpipe[0];
+	handle->p_write = wpipe[1];
+	handle->protect = 0;
+	handle->bytes_on_pipe = 0;
+
+	if ((handle->childpid = fork()) < 0) {
+		return NULL;
+
+	} else if (handle->childpid == 0) {	/* child */
+		close(handle->p_write);
+		close(handle->p_read);
+		if(dup2(c_read, STDIN_FILENO) < 0){
+			return NULL;
+		}
+		close(c_read);
+		if(dup2(c_write, STDOUT_FILENO) < 0){
+			return NULL;
+		}
+		close(c_write);
+		if(execl("/bin/sh", "sh", "-c", command, NULL) < 0){
+			return NULL;
+		}
+
+	} else {	/* parent */
+		close(c_read);
+		close(c_write);
+	}
+
+	if(read_hello(handle) < 0)
+		return NULL;
+
+	handle->out_data = NULL;
+	handle->out_data_size = 0;
+	return handle;
+}
diff --git a/client.h b/client.h
--- a/client.h
+++ b/client.h
@@ -88,4 +88,25 @@ 
 	char *out_data;
 } hg_handle;
 
+/**
+ * \brief Open the connection with the mercurial command server.
+ *
+ * The handle structure will be allocated.
+ * \param path The path to the repository wherewith I want to create a connection
+ *        NULL argument means the repository in which I am.
+ * \param encoding Will set HGENCODING to the given encoding
+ *        NULL argument means the default encoding. (UTF-8)
+ * \retval handle - A handle for this connection. 
+ * \retval NULL Indicate an error, with errno set appropriately.
+ * 
+ * errno can be :
+ *      - execl(2) command errors
+ *      - dup2(2)  command errors
+ *      - fork(2)  command errors
+ *      - pipe(2)  command errors
+ *      - EFAULT - for a bad path address
+ *      - EINVAL - for a bad encoding
+ * */
+hg_handle *hg_open(const char *path, char *encoding);
+
 #endif