mirror of
https://github.com/git/git.git
synced 2024-11-18 15:04:49 +01:00
Merge branch 'master' into next
* master: Const tightening. Documentation/Makefile: Some `git-*.txt' files aren't manpages. cvsserver: updated documentation
This commit is contained in:
commit
ee5c78434a
12 changed files with 108 additions and 64 deletions
|
@ -1,4 +1,7 @@
|
||||||
MAN1_TXT=$(wildcard git-*.txt) gitk.txt
|
MAN1_TXT= \
|
||||||
|
$(filter-out $(addsuffix .txt, $(ARTICLES) $(SP_ARTICLES)), \
|
||||||
|
$(wildcard git-*.txt)) \
|
||||||
|
gitk.txt
|
||||||
MAN7_TXT=git.txt
|
MAN7_TXT=git.txt
|
||||||
|
|
||||||
DOC_HTML=$(patsubst %.txt,%.html,$(MAN1_TXT) $(MAN7_TXT))
|
DOC_HTML=$(patsubst %.txt,%.html,$(MAN1_TXT) $(MAN7_TXT))
|
||||||
|
@ -11,6 +14,7 @@ ARTICLES += howto-index
|
||||||
ARTICLES += repository-layout
|
ARTICLES += repository-layout
|
||||||
ARTICLES += hooks
|
ARTICLES += hooks
|
||||||
ARTICLES += everyday
|
ARTICLES += everyday
|
||||||
|
ARTICLES += git-tools
|
||||||
# with their own formatting rules.
|
# with their own formatting rules.
|
||||||
SP_ARTICLES = glossary howto/revert-branch-rebase
|
SP_ARTICLES = glossary howto/revert-branch-rebase
|
||||||
|
|
||||||
|
|
|
@ -5,14 +5,12 @@ NAME
|
||||||
----
|
----
|
||||||
git-cvsserver - A CVS server emulator for git
|
git-cvsserver - A CVS server emulator for git
|
||||||
|
|
||||||
|
|
||||||
SYNOPSIS
|
SYNOPSIS
|
||||||
--------
|
--------
|
||||||
[verse]
|
[verse]
|
||||||
export CVS_SERVER=git-cvsserver
|
export CVS_SERVER=git-cvsserver
|
||||||
'cvs' -d :ext:user@server/path/repo.git co <HEAD_name>
|
'cvs' -d :ext:user@server/path/repo.git co <HEAD_name>
|
||||||
|
|
||||||
|
|
||||||
DESCRIPTION
|
DESCRIPTION
|
||||||
-----------
|
-----------
|
||||||
|
|
||||||
|
@ -27,48 +25,85 @@ plugin. Most functionality works fine with both of these clients.
|
||||||
|
|
||||||
LIMITATIONS
|
LIMITATIONS
|
||||||
-----------
|
-----------
|
||||||
Currently gitcvs only works over ssh connections.
|
|
||||||
|
|
||||||
|
Currently cvsserver works over SSH connections for read/write clients, and
|
||||||
|
over pserver for anonymous CVS access.
|
||||||
|
|
||||||
|
CVS clients cannot tag, branch or perform GIT merges.
|
||||||
|
|
||||||
INSTALLATION
|
INSTALLATION
|
||||||
------------
|
------------
|
||||||
1. Put server.pl somewhere useful on the same machine that is hosting your git repos
|
|
||||||
|
1. If you are going to offer anonymous CVS access via pserver, add a line in
|
||||||
|
/etc/inetd.conf like
|
||||||
|
|
||||||
|
cvspserver stream tcp nowait nobody git-cvsserver pserver
|
||||||
|
|
||||||
|
Note: In some cases, you need to pass the 'pserver' argument twice for
|
||||||
|
git-cvsserver to see it. So the line would look like
|
||||||
|
|
||||||
|
cvspserver stream tcp nowait nobody git-cvsserver pserver pserver
|
||||||
|
|
||||||
|
No special setup is needed for SSH access, other than having GIT tools
|
||||||
|
in the PATH. If you have clients that do not accept the CVS_SERVER
|
||||||
|
env variable, you can rename git-cvsserver to cvs.
|
||||||
|
|
||||||
2. For each repo that you want accessible from CVS you need to edit config in
|
2. For each repo that you want accessible from CVS you need to edit config in
|
||||||
the repo and add the following section.
|
the repo and add the following section.
|
||||||
|
|
||||||
[gitcvs]
|
[gitcvs]
|
||||||
enabled=1
|
enabled=1
|
||||||
|
# optional for debugging
|
||||||
logfile=/path/to/logfile
|
logfile=/path/to/logfile
|
||||||
|
|
||||||
n.b. you need to ensure each user that is going to invoke server.pl has
|
Note: you need to ensure each user that is going to invoke git-cvsserver has
|
||||||
write access to the log file.
|
write access to the log file and to the git repository. When offering anon
|
||||||
|
access via pserver, this means that the nobody user should have write access
|
||||||
|
to at least the sqlite database at the root of the repository.
|
||||||
|
|
||||||
5. On each client machine you need to set the following variables.
|
3. On the client machine you need to set the following variables.
|
||||||
CVSROOT should be set as per normal, but the directory should point at the
|
CVSROOT should be set as per normal, but the directory should point at the
|
||||||
appropriate git repo.
|
appropriate git repo. For example:
|
||||||
CVS_SERVER should be set to the server.pl script that has been put on the
|
|
||||||
remote machine.
|
|
||||||
|
|
||||||
6. Clients should now be able to check out modules (where modules are the names
|
For SSH access, CVS_SERVER should be set to git-cvsserver
|
||||||
of branches in git).
|
|
||||||
$ cvs co -d mylocaldir master
|
Example:
|
||||||
|
|
||||||
|
export CVSROOT=:ext:user@server:/var/git/project.git
|
||||||
|
export CVS_SERVER=git-cvsserver
|
||||||
|
|
||||||
|
4. For SSH clients that will make commits, make sure their .bashrc file
|
||||||
|
sets the GIT_AUTHOR and GIT_COMMITTER variables.
|
||||||
|
|
||||||
|
5. Clients should now be able to check out the project. Use the CVS 'module'
|
||||||
|
name to indicate what GIT 'head' you want to check out. Example:
|
||||||
|
|
||||||
|
cvs co -d project-master master
|
||||||
|
|
||||||
Eclipse CVS Client Notes
|
Eclipse CVS Client Notes
|
||||||
------------------------
|
------------------------
|
||||||
|
|
||||||
To get a checkout with the Eclipse CVS client:
|
To get a checkout with the Eclipse CVS client:
|
||||||
|
|
||||||
1. Create a new project from CVS checkout, giving it repository and module
|
1. Select "Create a new project -> From CVS checkout"
|
||||||
2. Context Menu->Team->Share Project...
|
2. Create a new location. See the notes below for details on how to choose the
|
||||||
3. Enter the repository and module information again and click Finish
|
right protocol.
|
||||||
4. The Synchronize view appears. Untick "launch commit wizard" to avoid
|
3. Browse the 'modules' available. It will give you a list of the heads in
|
||||||
committing the .project file, and select HEAD as the tag to synchronize to.
|
the repository. You will not be able to browse the tree from there. Only
|
||||||
Update all incoming changes.
|
the heads.
|
||||||
|
4. Pick 'HEAD' when it asks what branch/tag to check out. Untick the
|
||||||
|
"launch commit wizard" to avoid committing the .project file.
|
||||||
|
|
||||||
Note that most versions of Eclipse ignore CVS_SERVER (which you can set in
|
Protocol notes: If you are using anonymous acces via pserver, just select that.
|
||||||
the Preferences->Team->CVS->ExtConnection pane), so you may have to
|
Those using SSH access should choose the 'ext' protocol, and configure 'ext'
|
||||||
rename, alias or symlink git-cvsserver to 'cvs' on the server.
|
access on the Preferences->Team->CVS->ExtConnection pane. Set CVS_SERVER to
|
||||||
|
'git-cvsserver'. Not that password support is not good when using 'ext',
|
||||||
|
you will definitely want to have SSH keys setup.
|
||||||
|
|
||||||
|
Alternatively, you can just use the non-standard extssh protocol that Eclipse
|
||||||
|
offer. In that case CVS_SERVER is ignored, and you will have to replace
|
||||||
|
the cvs utility on the server with git-cvsserver or manipulate your .bashrc
|
||||||
|
so that calling 'cvs' effectively calls git-cvsserver.
|
||||||
|
|
||||||
Clients known to work
|
Clients known to work
|
||||||
---------------------
|
---------------------
|
||||||
|
|
2
blame.c
2
blame.c
|
@ -226,6 +226,7 @@ static void print_patch(struct patch *p)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
/* For debugging only */
|
/* For debugging only */
|
||||||
static void print_map(struct commit *cmit, struct commit *other)
|
static void print_map(struct commit *cmit, struct commit *other)
|
||||||
{
|
{
|
||||||
|
@ -259,6 +260,7 @@ static void print_map(struct commit *cmit, struct commit *other)
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// p is a patch from commit to other.
|
// p is a patch from commit to other.
|
||||||
static void fill_line_map(struct commit *commit, struct commit *other,
|
static void fill_line_map(struct commit *commit, struct commit *other,
|
||||||
|
|
13
exec_cmd.c
13
exec_cmd.c
|
@ -29,10 +29,9 @@ const char *git_exec_path(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int execv_git_cmd(char **argv)
|
int execv_git_cmd(const char **argv)
|
||||||
{
|
{
|
||||||
char git_command[PATH_MAX + 1];
|
char git_command[PATH_MAX + 1];
|
||||||
char *tmp;
|
|
||||||
int len, err, i;
|
int len, err, i;
|
||||||
const char *paths[] = { current_exec_path,
|
const char *paths[] = { current_exec_path,
|
||||||
getenv("GIT_EXEC_PATH"),
|
getenv("GIT_EXEC_PATH"),
|
||||||
|
@ -40,6 +39,8 @@ int execv_git_cmd(char **argv)
|
||||||
|
|
||||||
for (i = 0; i < sizeof(paths)/sizeof(paths[0]); ++i) {
|
for (i = 0; i < sizeof(paths)/sizeof(paths[0]); ++i) {
|
||||||
const char *exec_dir = paths[i];
|
const char *exec_dir = paths[i];
|
||||||
|
const char *tmp;
|
||||||
|
|
||||||
if (!exec_dir) continue;
|
if (!exec_dir) continue;
|
||||||
|
|
||||||
if (*exec_dir != '/') {
|
if (*exec_dir != '/') {
|
||||||
|
@ -82,7 +83,7 @@ int execv_git_cmd(char **argv)
|
||||||
argv[0] = git_command;
|
argv[0] = git_command;
|
||||||
|
|
||||||
/* execve() can only ever return if it fails */
|
/* execve() can only ever return if it fails */
|
||||||
execve(git_command, argv, environ);
|
execve(git_command, (char **)argv, environ);
|
||||||
|
|
||||||
err = errno;
|
err = errno;
|
||||||
|
|
||||||
|
@ -93,11 +94,11 @@ int execv_git_cmd(char **argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int execl_git_cmd(char *cmd,...)
|
int execl_git_cmd(const char *cmd,...)
|
||||||
{
|
{
|
||||||
int argc;
|
int argc;
|
||||||
char *argv[MAX_ARGS + 1];
|
const char *argv[MAX_ARGS + 1];
|
||||||
char *arg;
|
const char *arg;
|
||||||
va_list param;
|
va_list param;
|
||||||
|
|
||||||
va_start(param, cmd);
|
va_start(param, cmd);
|
||||||
|
|
|
@ -3,8 +3,8 @@
|
||||||
|
|
||||||
extern void git_set_exec_path(const char *exec_path);
|
extern void git_set_exec_path(const char *exec_path);
|
||||||
extern const char* git_exec_path(void);
|
extern const char* git_exec_path(void);
|
||||||
extern int execv_git_cmd(char **argv); /* NULL terminated */
|
extern int execv_git_cmd(const char **argv); /* NULL terminated */
|
||||||
extern int execl_git_cmd(char *cmd, ...);
|
extern int execl_git_cmd(const char *cmd, ...);
|
||||||
|
|
||||||
|
|
||||||
#endif /* __GIT_EXEC_CMD_H_ */
|
#endif /* __GIT_EXEC_CMD_H_ */
|
||||||
|
|
32
git.c
32
git.c
|
@ -216,33 +216,33 @@ static void prepend_to_path(const char *dir, int len)
|
||||||
setenv("PATH", path, 1);
|
setenv("PATH", path, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void show_man_page(char *git_cmd)
|
static void show_man_page(const char *git_cmd)
|
||||||
{
|
{
|
||||||
char *page;
|
const char *page;
|
||||||
|
|
||||||
if (!strncmp(git_cmd, "git", 3))
|
if (!strncmp(git_cmd, "git", 3))
|
||||||
page = git_cmd;
|
page = git_cmd;
|
||||||
else {
|
else {
|
||||||
int page_len = strlen(git_cmd) + 4;
|
int page_len = strlen(git_cmd) + 4;
|
||||||
|
char *p = malloc(page_len + 1);
|
||||||
page = malloc(page_len + 1);
|
strcpy(p, "git-");
|
||||||
strcpy(page, "git-");
|
strcpy(p + 4, git_cmd);
|
||||||
strcpy(page + 4, git_cmd);
|
p[page_len] = 0;
|
||||||
page[page_len] = 0;
|
page = p;
|
||||||
}
|
}
|
||||||
|
|
||||||
execlp("man", "man", page, NULL);
|
execlp("man", "man", page, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cmd_version(int argc, char **argv, char **envp)
|
static int cmd_version(int argc, const char **argv, char **envp)
|
||||||
{
|
{
|
||||||
printf("git version %s\n", GIT_VERSION);
|
printf("git version %s\n", GIT_VERSION);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cmd_help(int argc, char **argv, char **envp)
|
static int cmd_help(int argc, const char **argv, char **envp)
|
||||||
{
|
{
|
||||||
char *help_cmd = argv[1];
|
const char *help_cmd = argv[1];
|
||||||
if (!help_cmd)
|
if (!help_cmd)
|
||||||
cmd_usage(git_exec_path(), NULL);
|
cmd_usage(git_exec_path(), NULL);
|
||||||
show_man_page(help_cmd);
|
show_man_page(help_cmd);
|
||||||
|
@ -251,7 +251,7 @@ static int cmd_help(int argc, char **argv, char **envp)
|
||||||
|
|
||||||
#define LOGSIZE (65536)
|
#define LOGSIZE (65536)
|
||||||
|
|
||||||
static int cmd_log(int argc, char **argv, char **envp)
|
static int cmd_log(int argc, const char **argv, char **envp)
|
||||||
{
|
{
|
||||||
struct rev_info rev;
|
struct rev_info rev;
|
||||||
struct commit *commit;
|
struct commit *commit;
|
||||||
|
@ -263,7 +263,7 @@ static int cmd_log(int argc, char **argv, char **envp)
|
||||||
|
|
||||||
argc = setup_revisions(argc, argv, &rev, "HEAD");
|
argc = setup_revisions(argc, argv, &rev, "HEAD");
|
||||||
while (1 < argc) {
|
while (1 < argc) {
|
||||||
char *arg = argv[1];
|
const char *arg = argv[1];
|
||||||
if (!strncmp(arg, "--pretty", 8)) {
|
if (!strncmp(arg, "--pretty", 8)) {
|
||||||
commit_format = get_commit_format(arg + 8);
|
commit_format = get_commit_format(arg + 8);
|
||||||
if (commit_format == CMIT_FMT_ONELINE)
|
if (commit_format == CMIT_FMT_ONELINE)
|
||||||
|
@ -325,12 +325,12 @@ static int cmd_log(int argc, char **argv, char **envp)
|
||||||
|
|
||||||
#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
|
#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
|
||||||
|
|
||||||
static void handle_internal_command(int argc, char **argv, char **envp)
|
static void handle_internal_command(int argc, const char **argv, char **envp)
|
||||||
{
|
{
|
||||||
const char *cmd = argv[0];
|
const char *cmd = argv[0];
|
||||||
static struct cmd_struct {
|
static struct cmd_struct {
|
||||||
const char *cmd;
|
const char *cmd;
|
||||||
int (*fn)(int, char **, char **);
|
int (*fn)(int, const char **, char **);
|
||||||
} commands[] = {
|
} commands[] = {
|
||||||
{ "version", cmd_version },
|
{ "version", cmd_version },
|
||||||
{ "help", cmd_help },
|
{ "help", cmd_help },
|
||||||
|
@ -346,9 +346,9 @@ static void handle_internal_command(int argc, char **argv, char **envp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv, char **envp)
|
int main(int argc, const char **argv, char **envp)
|
||||||
{
|
{
|
||||||
char *cmd = argv[0];
|
const char *cmd = argv[0];
|
||||||
char *slash = strrchr(cmd, '/');
|
char *slash = strrchr(cmd, '/');
|
||||||
char git_command[PATH_MAX + 1];
|
char git_command[PATH_MAX + 1];
|
||||||
const char *exec_path = NULL;
|
const char *exec_path = NULL;
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
static const char receive_pack_usage[] = "git-receive-pack <git-dir>";
|
static const char receive_pack_usage[] = "git-receive-pack <git-dir>";
|
||||||
|
|
||||||
static char *unpacker[] = { "unpack-objects", NULL };
|
static const char *unpacker[] = { "unpack-objects", NULL };
|
||||||
|
|
||||||
static int report_status = 0;
|
static int report_status = 0;
|
||||||
|
|
||||||
|
@ -177,7 +177,7 @@ static void run_update_post_hook(struct command *cmd)
|
||||||
{
|
{
|
||||||
struct command *cmd_p;
|
struct command *cmd_p;
|
||||||
int argc;
|
int argc;
|
||||||
char **argv;
|
const char **argv;
|
||||||
|
|
||||||
if (access(update_post_hook, X_OK) < 0)
|
if (access(update_post_hook, X_OK) < 0)
|
||||||
return;
|
return;
|
||||||
|
@ -190,10 +190,12 @@ static void run_update_post_hook(struct command *cmd)
|
||||||
argv[0] = update_post_hook;
|
argv[0] = update_post_hook;
|
||||||
|
|
||||||
for (argc = 1, cmd_p = cmd; cmd_p; cmd_p = cmd_p->next) {
|
for (argc = 1, cmd_p = cmd; cmd_p; cmd_p = cmd_p->next) {
|
||||||
|
char *p;
|
||||||
if (cmd_p->error_string)
|
if (cmd_p->error_string)
|
||||||
continue;
|
continue;
|
||||||
argv[argc] = xmalloc(strlen(cmd_p->ref_name) + 1);
|
p = xmalloc(strlen(cmd_p->ref_name) + 1);
|
||||||
strcpy(argv[argc], cmd_p->ref_name);
|
strcpy(p, cmd_p->ref_name);
|
||||||
|
argv[argc] = p;
|
||||||
argc++;
|
argc++;
|
||||||
}
|
}
|
||||||
argv[argc] = NULL;
|
argv[argc] = NULL;
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include "exec_cmd.h"
|
#include "exec_cmd.h"
|
||||||
|
|
||||||
int run_command_v_opt(int argc, char **argv, int flags)
|
int run_command_v_opt(int argc, const char **argv, int flags)
|
||||||
{
|
{
|
||||||
pid_t pid = fork();
|
pid_t pid = fork();
|
||||||
|
|
||||||
|
@ -47,7 +47,7 @@ int run_command_v_opt(int argc, char **argv, int flags)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int run_command_v(int argc, char **argv)
|
int run_command_v(int argc, const char **argv)
|
||||||
{
|
{
|
||||||
return run_command_v_opt(argc, argv, 0);
|
return run_command_v_opt(argc, argv, 0);
|
||||||
}
|
}
|
||||||
|
@ -55,7 +55,7 @@ int run_command_v(int argc, char **argv)
|
||||||
int run_command(const char *cmd, ...)
|
int run_command(const char *cmd, ...)
|
||||||
{
|
{
|
||||||
int argc;
|
int argc;
|
||||||
char *argv[MAX_RUN_COMMAND_ARGS];
|
const char *argv[MAX_RUN_COMMAND_ARGS];
|
||||||
const char *arg;
|
const char *arg;
|
||||||
va_list param;
|
va_list param;
|
||||||
|
|
||||||
|
|
|
@ -13,8 +13,8 @@ enum {
|
||||||
|
|
||||||
#define RUN_COMMAND_NO_STDIO 1
|
#define RUN_COMMAND_NO_STDIO 1
|
||||||
#define RUN_GIT_CMD 2 /*If this is to be git sub-command */
|
#define RUN_GIT_CMD 2 /*If this is to be git sub-command */
|
||||||
int run_command_v_opt(int argc, char **argv, int opt);
|
int run_command_v_opt(int argc, const char **argv, int opt);
|
||||||
int run_command_v(int argc, char **argv);
|
int run_command_v(int argc, const char **argv);
|
||||||
int run_command(const char *cmd, ...);
|
int run_command(const char *cmd, ...);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -27,7 +27,7 @@ static int is_zero_sha1(const unsigned char *sha1)
|
||||||
|
|
||||||
static void exec_pack_objects(void)
|
static void exec_pack_objects(void)
|
||||||
{
|
{
|
||||||
static char *args[] = {
|
static const char *args[] = {
|
||||||
"pack-objects",
|
"pack-objects",
|
||||||
"--stdout",
|
"--stdout",
|
||||||
NULL
|
NULL
|
||||||
|
@ -39,7 +39,7 @@ static void exec_pack_objects(void)
|
||||||
static void exec_rev_list(struct ref *refs)
|
static void exec_rev_list(struct ref *refs)
|
||||||
{
|
{
|
||||||
struct ref *ref;
|
struct ref *ref;
|
||||||
static char *args[1000];
|
static const char *args[1000];
|
||||||
int i = 0, j;
|
int i = 0, j;
|
||||||
|
|
||||||
args[i++] = "rev-list"; /* 0 */
|
args[i++] = "rev-list"; /* 0 */
|
||||||
|
|
2
shell.c
2
shell.c
|
@ -15,7 +15,7 @@ static int do_generic_cmd(const char *me, char *arg)
|
||||||
my_argv[1] = arg;
|
my_argv[1] = arg;
|
||||||
my_argv[2] = NULL;
|
my_argv[2] = NULL;
|
||||||
|
|
||||||
return execv_git_cmd((char**) my_argv);
|
return execv_git_cmd(my_argv);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct commands {
|
static struct commands {
|
||||||
|
|
|
@ -46,7 +46,7 @@ static void create_pack_file(void)
|
||||||
if (!pid) {
|
if (!pid) {
|
||||||
int i;
|
int i;
|
||||||
int args;
|
int args;
|
||||||
char **argv;
|
const char **argv;
|
||||||
char *buf;
|
char *buf;
|
||||||
char **p;
|
char **p;
|
||||||
|
|
||||||
|
@ -56,9 +56,9 @@ static void create_pack_file(void)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
args = nr_has + nr_needs + 5;
|
args = nr_has + nr_needs + 5;
|
||||||
argv = xmalloc(args * sizeof(char *));
|
p = xmalloc(args * sizeof(char *));
|
||||||
|
argv = (const char **) p;
|
||||||
buf = xmalloc(args * 45);
|
buf = xmalloc(args * 45);
|
||||||
p = argv;
|
|
||||||
|
|
||||||
dup2(fd[1], 1);
|
dup2(fd[1], 1);
|
||||||
close(0);
|
close(0);
|
||||||
|
|
Loading…
Reference in a new issue