NetBSD Problem Report #48201
From www@NetBSD.org Tue Sep 10 04:56:58 2013
Return-Path: <www@NetBSD.org>
Received: from mail.netbsd.org (mail.netbsd.org [149.20.53.66])
(using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits))
(Client CN "mail.NetBSD.org", Issuer "Postmaster NetBSD.org" (verified OK))
by mollari.NetBSD.org (Postfix) with ESMTPS id 5055671008
for <gnats-bugs@gnats.NetBSD.org>; Tue, 10 Sep 2013 04:56:58 +0000 (UTC)
Message-Id: <20130910045656.ED140715ED@mollari.NetBSD.org>
Date: Tue, 10 Sep 2013 04:56:56 +0000 (UTC)
From: william@25thandclement.com
Reply-To: william@25thandclement.com
To: gnats-bugs@NetBSD.org
Subject: +noclobber option not POSIX compliant
X-Send-Pr-Version: www-1.0
>Number: 48201
>Category: bin
>Synopsis: +noclobber option not POSIX compliant
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: bin-bug-people
>State: closed
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Tue Sep 10 05:00:00 +0000 2013
>Closed-Date: Mon May 30 06:04:34 +0000 2016
>Last-Modified: Mon May 30 06:04:34 +0000 2016
>Originator: William Ahern
>Release: 6.1.1
>Organization:
N/A
>Environment:
NetBSD 6.1.1 NetBSD 6.1.1 (GENERIC) amd64
>Description:
POSIX says: "Output redirection using the '>' format shall fail if the noclobber option is set (see the description of set -C) and the file named by the expansion of word exists and is a regular file."
However, with +noclobber NetBSD's sh fails when redirecting to /dev/null, a character device. I had to fix my scripts to use the append (>>) operator. FreeBSD, OpenBSD, Linux, Solaris, and OS X all behave as POSIX describes.
>How-To-Repeat:
sh -c 'set -C; printf "" >/dev/null'
>Fix:
>Release-Note:
>Audit-Trail:
From: Miwa Susumu <miwarin@gmail.com>
To: gnats-bugs@NetBSD.org
Cc:
Subject: Re: bin/48201
Date: Wed, 15 Oct 2014 22:39:43 +0900
import from FreeBSD
https://svnweb.freebsd.org/base/head/bin/sh/redir.c
--- /usr/src/bin/sh/redir.c.orig 2014-10-15 22:18:54.000000000 +0900
+++ /usr/src/bin/sh/redir.c 2014-10-15 21:10:47.000000000 +0900
@@ -173,10 +173,11 @@
STATIC void
openredirect(union node *redir, char memory[10], int flags)
{
+ struct stat sb;
int fd = redir->nfile.fd;
char *fname;
int f;
- int oflags = O_WRONLY|O_CREAT|O_TRUNC, eflags;
+ int eflags;
/*
* We suppress interrupts so that we won't leave open file
@@ -203,12 +204,29 @@
goto ecreate;
break;
case NTO:
- if (Cflag)
- oflags |= O_EXCL;
+ if (Cflag) {
+ fname = redir->nfile.expfname;
+ if (stat(fname, &sb) == -1) {
+ if ((f = open(fname,
O_WRONLY|O_CREAT|O_EXCL, 0666)) < 0)
+ goto ecreate;
+ } else if (!S_ISREG(sb.st_mode)) {
+ if ((f = open(fname, O_WRONLY, 0666)) < 0)
+ goto ecreate;
+ if (fstat(f, &sb) != -1 &&
S_ISREG(sb.st_mode)) {
+ close(f);
+ errno = EEXIST;
+ goto ecreate;
+ }
+ } else {
+ errno = EEXIST;
+ goto ecreate;
+ }
+ break;
+ }
/* FALLTHROUGH */
case NCLOBBER:
fname = redir->nfile.expfname;
- if ((f = open(fname, oflags, 0666)) < 0)
+ if ((f = open(fname, O_WRONLY|O_CREAT|O_TRUNC, 0666)) < 0)
goto ecreate;
break;
case NAPPEND:
Detail
================================================
Shell Command Language
http://pubs.opengroup.org/onlinepubs/009604599/utilities/xcu_chap02.html
<<<
Output redirection using the '>' format shall fail if the noclobber
option is set (see the description of set -C) and the file named by
the expansion of word exists and is a regular file. Otherwise,
redirection using the '>' or ">|" formats shall cause the file whose
name results from the expansion of word to be created and opened for
output on the designated file descriptor, or standard output if none
is specified. If the file does not exist, it shall be created;
otherwise, it shall be truncated to be an empty file after being
opened
>>>
I think separately.
--------
(1) Output redirection using the '>' format shall fail
if the noclobber option is set (see the description of set -C)
the file named by the expansion of word exists
is a regular file.
(2) Otherwise, redirection using the '>' or ">|" formats shall cause
the file whose name results from the expansion of word to be created
opened for output on the designated file descriptor, or standard
output if none is specified.
(3) If the file does not exist,
it shall be created;
(4) otherwise,
it shall be truncated to be an empty file after being opened
--------
The patch of the above, I verify the operation.
--------
(1) It is an error ... ok
% touch hoge
% /bin/sh -c 'set -C; printf "" > hoge'
sh: cannot create hoge: file exists
(2) can be written to /dev/null ... ok
% /bin/sh -c 'set -C; printf "" > /dev/null'
(3) hoge is generated ... ok
% rm hoge
% /bin/sh -c 'set -C; printf "" > hoge'
% /bin/ls -l hoge
-rw-r--r-- 1 rin users 0 Oct 15 22:36 hoge
(4) hoge becomes empty ... ok
% /bin/sh -c 'printf "hoge\n" > hoge'
% cat hoge
hoge
% /bin/sh -c 'printf "" > hoge'
% cat hoge
--
miwarin
From: "Christos Zoulas" <christos@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc:
Subject: PR/48201 CVS commit: src/bin/sh
Date: Wed, 15 Oct 2014 10:54:25 -0400
Module Name: src
Committed By: christos
Date: Wed Oct 15 14:54:25 UTC 2014
Modified Files:
src/bin/sh: redir.c
Log Message:
PR/48201: Miwa Susumu: Fix set -C (no clobber) for POSIX; from FreeBSD
Can't use O_EXCL because of device nodes; also truncate.
To generate a diff of this commit:
cvs rdiff -u -r1.35 -r1.36 src/bin/sh/redir.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
State-Changed-From-To: open->closed
State-Changed-By: dholland@NetBSD.org
State-Changed-When: Mon, 30 May 2016 06:04:34 +0000
State-Changed-Why:
Committed by Christos in 2014
>Unformatted:
(Contact us)
$NetBSD: query-full-pr,v 1.39 2013/11/01 18:47:49 spz Exp $
$NetBSD: gnats_config.sh,v 1.8 2006/05/07 09:23:38 tsutsui Exp $
Copyright © 1994-2014
The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.